net.h
1 // Copyright (c) 2020-2022 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 <net.h> 10 #include <net_permissions.h> 11 #include <net_processing.h> 12 #include <netaddress.h> 13 #include <node/connection_types.h> 14 #include <node/eviction.h> 15 #include <sync.h> 16 #include <util/sock.h> 17 18 #include <algorithm> 19 #include <array> 20 #include <cassert> 21 #include <chrono> 22 #include <cstdint> 23 #include <cstring> 24 #include <memory> 25 #include <string> 26 #include <unordered_map> 27 #include <vector> 28 29 class FastRandomContext; 30 31 template <typename C> 32 class Span; 33 34 struct ConnmanTestMsg : public CConnman { 35 using CConnman::CConnman; 36 37 void SetPeerConnectTimeout(std::chrono::seconds timeout) 38 { 39 m_peer_connect_timeout = timeout; 40 } 41 42 std::vector<CNode*> TestNodes() 43 { 44 LOCK(m_nodes_mutex); 45 return m_nodes; 46 } 47 48 void AddTestNode(CNode& node) 49 { 50 LOCK(m_nodes_mutex); 51 m_nodes.push_back(&node); 52 53 if (node.IsManualOrFullOutboundConn()) ++m_network_conn_counts[node.addr.GetNetwork()]; 54 } 55 56 void ClearTestNodes() 57 { 58 LOCK(m_nodes_mutex); 59 for (CNode* node : m_nodes) { 60 delete node; 61 } 62 m_nodes.clear(); 63 } 64 65 void Handshake(CNode& node, 66 bool successfully_connected, 67 ServiceFlags remote_services, 68 ServiceFlags local_services, 69 int32_t version, 70 bool relay_txs) 71 EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex); 72 73 bool ProcessMessagesOnce(CNode& node) EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex) 74 { 75 return m_msgproc->ProcessMessages(&node, flagInterruptMsgProc); 76 } 77 78 void NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_bytes, bool& complete) const; 79 80 bool ReceiveMsgFrom(CNode& node, CSerializedNetMsg&& ser_msg) const; 81 void FlushSendBuffer(CNode& node) const; 82 83 bool AlreadyConnectedPublic(const CAddress& addr) { return AlreadyConnectedToAddress(addr); }; 84 85 CNode* ConnectNodePublic(PeerManager& peerman, const char* pszDest, ConnectionType conn_type) 86 EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex); 87 }; 88 89 constexpr ServiceFlags ALL_SERVICE_FLAGS[]{ 90 NODE_NONE, 91 NODE_NETWORK, 92 NODE_BLOOM, 93 NODE_WITNESS, 94 NODE_COMPACT_FILTERS, 95 NODE_NETWORK_LIMITED, 96 NODE_P2P_V2, 97 }; 98 99 constexpr NetPermissionFlags ALL_NET_PERMISSION_FLAGS[]{ 100 NetPermissionFlags::None, 101 NetPermissionFlags::BloomFilter, 102 NetPermissionFlags::Relay, 103 NetPermissionFlags::ForceRelay, 104 NetPermissionFlags::NoBan, 105 NetPermissionFlags::Mempool, 106 NetPermissionFlags::Addr, 107 NetPermissionFlags::Download, 108 NetPermissionFlags::Implicit, 109 NetPermissionFlags::All, 110 }; 111 112 constexpr ConnectionType ALL_CONNECTION_TYPES[]{ 113 ConnectionType::INBOUND, 114 ConnectionType::OUTBOUND_FULL_RELAY, 115 ConnectionType::MANUAL, 116 ConnectionType::FEELER, 117 ConnectionType::BLOCK_RELAY, 118 ConnectionType::ADDR_FETCH, 119 }; 120 121 constexpr auto ALL_NETWORKS = std::array{ 122 Network::NET_UNROUTABLE, 123 Network::NET_IPV4, 124 Network::NET_IPV6, 125 Network::NET_ONION, 126 Network::NET_I2P, 127 Network::NET_CJDNS, 128 Network::NET_INTERNAL, 129 }; 130 131 /** 132 * A mocked Sock alternative that returns a statically contained data upon read and succeeds 133 * and ignores all writes. The data to be returned is given to the constructor and when it is 134 * exhausted an EOF is returned by further reads. 135 */ 136 class StaticContentsSock : public Sock 137 { 138 public: 139 explicit StaticContentsSock(const std::string& contents) 140 : Sock{INVALID_SOCKET}, 141 m_contents{contents} 142 { 143 } 144 145 ~StaticContentsSock() override { m_socket = INVALID_SOCKET; } 146 147 StaticContentsSock& operator=(Sock&& other) override 148 { 149 assert(false && "Move of Sock into MockSock not allowed."); 150 return *this; 151 } 152 153 ssize_t Send(const void*, size_t len, int) const override { return len; } 154 155 ssize_t Recv(void* buf, size_t len, int flags) const override 156 { 157 const size_t consume_bytes{std::min(len, m_contents.size() - m_consumed)}; 158 std::memcpy(buf, m_contents.data() + m_consumed, consume_bytes); 159 if ((flags & MSG_PEEK) == 0) { 160 m_consumed += consume_bytes; 161 } 162 return consume_bytes; 163 } 164 165 int Connect(const sockaddr*, socklen_t) const override { return 0; } 166 167 int Bind(const sockaddr*, socklen_t) const override { return 0; } 168 169 int Listen(int) const override { return 0; } 170 171 std::unique_ptr<Sock> Accept(sockaddr* addr, socklen_t* addr_len) const override 172 { 173 if (addr != nullptr) { 174 // Pretend all connections come from 5.5.5.5:6789 175 memset(addr, 0x00, *addr_len); 176 const socklen_t write_len = static_cast<socklen_t>(sizeof(sockaddr_in)); 177 if (*addr_len >= write_len) { 178 *addr_len = write_len; 179 sockaddr_in* addr_in = reinterpret_cast<sockaddr_in*>(addr); 180 addr_in->sin_family = AF_INET; 181 memset(&addr_in->sin_addr, 0x05, sizeof(addr_in->sin_addr)); 182 addr_in->sin_port = htons(6789); 183 } 184 } 185 return std::make_unique<StaticContentsSock>(""); 186 }; 187 188 int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const override 189 { 190 std::memset(opt_val, 0x0, *opt_len); 191 return 0; 192 } 193 194 int SetSockOpt(int, int, const void*, socklen_t) const override { return 0; } 195 196 int GetSockName(sockaddr* name, socklen_t* name_len) const override 197 { 198 std::memset(name, 0x0, *name_len); 199 return 0; 200 } 201 202 bool SetNonBlocking() const override { return true; } 203 204 bool IsSelectable() const override { return true; } 205 206 bool Wait(std::chrono::milliseconds timeout, 207 Event requested, 208 Event* occurred = nullptr) const override 209 { 210 if (occurred != nullptr) { 211 *occurred = requested; 212 } 213 return true; 214 } 215 216 bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const override 217 { 218 for (auto& [sock, events] : events_per_sock) { 219 (void)sock; 220 events.occurred = events.requested; 221 } 222 return true; 223 } 224 225 bool IsConnected(std::string&) const override 226 { 227 return true; 228 } 229 230 private: 231 const std::string m_contents; 232 mutable size_t m_consumed{0}; 233 }; 234 235 std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context); 236 237 #endif // BITCOIN_TEST_UTIL_NET_H