net.h
1 // Copyright (c) 2020-present The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 5 #ifndef BITCOIN_TEST_UTIL_NET_H 6 #define BITCOIN_TEST_UTIL_NET_H 7 8 #include <compat/compat.h> 9 #include <netmessagemaker.h> 10 #include <net.h> 11 #include <net_permissions.h> 12 #include <net_processing.h> 13 #include <netaddress.h> 14 #include <node/connection_types.h> 15 #include <node/eviction.h> 16 #include <span.h> 17 #include <sync.h> 18 #include <util/sock.h> 19 20 #include <algorithm> 21 #include <array> 22 #include <cassert> 23 #include <chrono> 24 #include <condition_variable> 25 #include <cstdint> 26 #include <cstring> 27 #include <memory> 28 #include <optional> 29 #include <string> 30 #include <unordered_map> 31 #include <vector> 32 33 class FastRandomContext; 34 35 struct ConnmanTestMsg : public CConnman { 36 using CConnman::CConnman; 37 38 void SetMsgProc(NetEventsInterface* msgproc) 39 { 40 m_msgproc = msgproc; 41 } 42 43 void SetAddrman(AddrMan& in) { addrman = in; } 44 45 void SetPeerConnectTimeout(std::chrono::seconds timeout) 46 { 47 m_peer_connect_timeout = timeout; 48 } 49 50 void ResetAddrCache(); 51 void ResetMaxOutboundCycle(); 52 /// Reset the internal state. 53 void Reset(); 54 55 std::vector<CNode*> TestNodes() 56 { 57 LOCK(m_nodes_mutex); 58 return m_nodes; 59 } 60 61 void AddTestNode(CNode& node) 62 { 63 LOCK(m_nodes_mutex); 64 m_nodes.push_back(&node); 65 66 if (node.IsManualOrFullOutboundConn()) ++m_network_conn_counts[node.addr.GetNetwork()]; 67 } 68 69 void ClearTestNodes() 70 { 71 LOCK(m_nodes_mutex); 72 for (CNode* node : m_nodes) { 73 delete node; 74 } 75 m_nodes.clear(); 76 } 77 78 void CreateNodeFromAcceptedSocketPublic(std::unique_ptr<Sock> sock, 79 NetPermissionFlags permissions, 80 const CAddress& addr_bind, 81 const CAddress& addr_peer) 82 { 83 CreateNodeFromAcceptedSocket(std::move(sock), permissions, addr_bind, addr_peer); 84 } 85 86 bool InitBindsPublic(const CConnman::Options& options) 87 { 88 return InitBinds(options); 89 } 90 91 void SocketHandlerPublic() 92 { 93 SocketHandler(); 94 } 95 96 void Handshake(CNode& node, 97 bool successfully_connected, 98 ServiceFlags remote_services, 99 ServiceFlags local_services, 100 int32_t version, 101 bool relay_txs) 102 EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex); 103 104 bool ProcessMessagesOnce(CNode& node) EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex) 105 { 106 return m_msgproc->ProcessMessages(node, flagInterruptMsgProc); 107 } 108 109 void NodeReceiveMsgBytes(CNode& node, std::span<const uint8_t> msg_bytes, bool& complete) const; 110 111 bool ReceiveMsgFrom(CNode& node, CSerializedNetMsg&& ser_msg) const; 112 void FlushSendBuffer(CNode& node) const; 113 114 bool AlreadyConnectedToAddressPublic(const CNetAddr& addr) { return AlreadyConnectedToAddress(addr); }; 115 116 CNode* ConnectNodePublic(PeerManager& peerman, const char* pszDest, ConnectionType conn_type) 117 EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex); 118 }; 119 120 constexpr ServiceFlags ALL_SERVICE_FLAGS[]{ 121 NODE_NONE, 122 NODE_NETWORK, 123 NODE_BLOOM, 124 NODE_WITNESS, 125 NODE_COMPACT_FILTERS, 126 NODE_NETWORK_LIMITED, 127 NODE_P2P_V2, 128 }; 129 130 constexpr NetPermissionFlags ALL_NET_PERMISSION_FLAGS[]{ 131 NetPermissionFlags::None, 132 NetPermissionFlags::BloomFilter, 133 NetPermissionFlags::Relay, 134 NetPermissionFlags::ForceRelay, 135 NetPermissionFlags::NoBan, 136 NetPermissionFlags::Mempool, 137 NetPermissionFlags::Addr, 138 NetPermissionFlags::Download, 139 NetPermissionFlags::Implicit, 140 NetPermissionFlags::All, 141 }; 142 143 constexpr ConnectionType ALL_CONNECTION_TYPES[]{ 144 ConnectionType::INBOUND, 145 ConnectionType::OUTBOUND_FULL_RELAY, 146 ConnectionType::MANUAL, 147 ConnectionType::FEELER, 148 ConnectionType::BLOCK_RELAY, 149 ConnectionType::ADDR_FETCH, 150 ConnectionType::PRIVATE_BROADCAST, 151 }; 152 153 constexpr auto ALL_NETWORKS = std::array{ 154 Network::NET_UNROUTABLE, 155 Network::NET_IPV4, 156 Network::NET_IPV6, 157 Network::NET_ONION, 158 Network::NET_I2P, 159 Network::NET_CJDNS, 160 Network::NET_INTERNAL, 161 }; 162 163 /** 164 * A mocked Sock alternative that succeeds on all operations. 165 * Returns infinite amount of 0x0 bytes on reads. 166 */ 167 class ZeroSock : public Sock 168 { 169 public: 170 ZeroSock(); 171 172 ~ZeroSock() override; 173 174 ssize_t Send(const void*, size_t len, int) const override; 175 176 ssize_t Recv(void* buf, size_t len, int flags) const override; 177 178 int Connect(const sockaddr*, socklen_t) const override; 179 180 int Bind(const sockaddr*, socklen_t) const override; 181 182 int Listen(int) const override; 183 184 std::unique_ptr<Sock> Accept(sockaddr* addr, socklen_t* addr_len) const override; 185 186 int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const override; 187 188 int SetSockOpt(int, int, const void*, socklen_t) const override; 189 190 int GetSockName(sockaddr* name, socklen_t* name_len) const override; 191 192 bool SetNonBlocking() const override; 193 194 bool IsSelectable() const override; 195 196 bool Wait(std::chrono::milliseconds timeout, 197 Event requested, 198 Event* occurred = nullptr) const override; 199 200 bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const override; 201 202 private: 203 ZeroSock& operator=(Sock&& other) override; 204 }; 205 206 /** 207 * A mocked Sock alternative that returns a statically contained data upon read and succeeds 208 * and ignores all writes. The data to be returned is given to the constructor and when it is 209 * exhausted an EOF is returned by further reads. 210 */ 211 class StaticContentsSock : public ZeroSock 212 { 213 public: 214 explicit StaticContentsSock(const std::string& contents); 215 216 /** 217 * Return parts of the contents that was provided at construction until it is exhausted 218 * and then return 0 (EOF). 219 */ 220 ssize_t Recv(void* buf, size_t len, int flags) const override; 221 222 bool IsConnected(std::string&) const override 223 { 224 return true; 225 } 226 227 private: 228 StaticContentsSock& operator=(Sock&& other) override; 229 230 const std::string m_contents; 231 mutable size_t m_consumed{0}; 232 }; 233 234 /** 235 * A mocked Sock alternative that allows providing the data to be returned by Recv() 236 * and inspecting the data that has been supplied to Send(). 237 */ 238 class DynSock : public ZeroSock 239 { 240 public: 241 /** 242 * Unidirectional bytes or CNetMessage queue (FIFO). 243 */ 244 class Pipe 245 { 246 public: 247 /** 248 * Get bytes and remove them from the pipe. 249 * @param[in] buf Destination to write bytes to. 250 * @param[in] len Write up to this number of bytes. 251 * @param[in] flags Same as the flags of `recv(2)`. Just `MSG_PEEK` is honored. 252 * @return The number of bytes written to `buf`. `0` if `Eof()` has been called. 253 * If no bytes are available then `-1` is returned and `errno` is set to `EAGAIN`. 254 */ 255 ssize_t GetBytes(void* buf, size_t len, int flags = 0) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 256 257 /** 258 * Deserialize a `CNetMessage` and remove it from the pipe. 259 * If not enough bytes are available then the function will wait. If parsing fails 260 * or EOF is signaled to the pipe, then `std::nullopt` is returned. 261 */ 262 std::optional<CNetMessage> GetNetMsg() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 263 264 /** 265 * Push bytes to the pipe. 266 */ 267 void PushBytes(const void* buf, size_t len) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 268 269 /** 270 * Construct and push CNetMessage to the pipe. 271 */ 272 template <typename... Args> 273 void PushNetMsg(const std::string& type, Args&&... payload) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 274 275 /** 276 * Signal end-of-file on the receiving end (`GetBytes()` or `GetNetMsg()`). 277 */ 278 void Eof() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 279 280 private: 281 /** 282 * Return when there is some data to read or EOF has been signaled. 283 * @param[in,out] lock Unique lock that must have been derived from `m_mutex` by `WAIT_LOCK(m_mutex, lock)`. 284 */ 285 void WaitForDataOrEof(UniqueLock<Mutex>& lock) EXCLUSIVE_LOCKS_REQUIRED(m_mutex); 286 287 Mutex m_mutex; 288 std::condition_variable m_cond; 289 std::vector<uint8_t> m_data GUARDED_BY(m_mutex); 290 bool m_eof GUARDED_BY(m_mutex){false}; 291 }; 292 293 struct Pipes { 294 Pipe recv; 295 Pipe send; 296 }; 297 298 /** 299 * A basic thread-safe queue, used for queuing sockets to be returned by Accept(). 300 */ 301 class Queue 302 { 303 public: 304 using S = std::unique_ptr<DynSock>; 305 306 void Push(S s) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) 307 { 308 LOCK(m_mutex); 309 m_queue.push(std::move(s)); 310 } 311 312 std::optional<S> Pop() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) 313 { 314 LOCK(m_mutex); 315 if (m_queue.empty()) { 316 return std::nullopt; 317 } 318 S front{std::move(m_queue.front())}; 319 m_queue.pop(); 320 return front; 321 } 322 323 bool Empty() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) 324 { 325 LOCK(m_mutex); 326 return m_queue.empty(); 327 } 328 329 private: 330 mutable Mutex m_mutex; 331 std::queue<S> m_queue GUARDED_BY(m_mutex); 332 }; 333 334 /** 335 * Create a new mocked sock. 336 * @param[in] pipes Send/recv pipes used by the Send() and Recv() methods. 337 * @param[in] accept_sockets Sockets to return by the Accept() method. 338 */ 339 explicit DynSock(std::shared_ptr<Pipes> pipes, std::shared_ptr<Queue> accept_sockets); 340 341 ~DynSock(); 342 343 ssize_t Recv(void* buf, size_t len, int flags) const override; 344 345 ssize_t Send(const void* buf, size_t len, int) const override; 346 347 std::unique_ptr<Sock> Accept(sockaddr* addr, socklen_t* addr_len) const override; 348 349 bool Wait(std::chrono::milliseconds timeout, 350 Event requested, 351 Event* occurred = nullptr) const override; 352 353 bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const override; 354 355 private: 356 DynSock& operator=(Sock&&) override; 357 358 std::shared_ptr<Pipes> m_pipes; 359 std::shared_ptr<Queue> m_accept_sockets; 360 }; 361 362 template <typename... Args> 363 void DynSock::Pipe::PushNetMsg(const std::string& type, Args&&... payload) 364 { 365 auto msg = NetMsg::Make(type, std::forward<Args>(payload)...); 366 V1Transport transport{NodeId{0}}; 367 368 const bool queued{transport.SetMessageToSend(msg)}; 369 assert(queued); 370 371 LOCK(m_mutex); 372 373 for (;;) { 374 const auto& [bytes, _more, _msg_type] = transport.GetBytesToSend(/*have_next_message=*/true); 375 if (bytes.empty()) { 376 break; 377 } 378 m_data.insert(m_data.end(), bytes.begin(), bytes.end()); 379 transport.MarkBytesSent(bytes.size()); 380 } 381 382 m_cond.notify_all(); 383 } 384 385 std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context); 386 387 #endif // BITCOIN_TEST_UTIL_NET_H