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