Line data Source code
1 : // Copyright (c) 2020-2021 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 1 : void SetPeerConnectTimeout(std::chrono::seconds timeout)
38 : {
39 1 : m_peer_connect_timeout = timeout;
40 1 : }
41 :
42 4 : std::vector<CNode*> TestNodes()
43 : {
44 4 : READ_LOCK(m_nodes_mutex);
45 4 : return m_nodes;
46 4 : }
47 :
48 23 : void AddTestNode(CNode& node)
49 : {
50 23 : LOCK(m_nodes_mutex);
51 23 : m_nodes.push_back(&node);
52 :
53 23 : if (node.IsManualOrFullOutboundConn()) ++m_network_conn_counts[node.addr.GetNetwork()];
54 23 : }
55 :
56 4 : void ClearTestNodes()
57 : {
58 4 : LOCK(m_nodes_mutex);
59 27 : for (CNode* node : m_nodes) {
60 23 : delete node;
61 : }
62 4 : m_nodes.clear();
63 4 : }
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 2 : bool ProcessMessagesOnce(CNode& node) EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex)
74 : {
75 2 : 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 6 : 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_COMPACT_FILTERS,
94 : NODE_NETWORK_LIMITED,
95 : NODE_HEADERS_COMPRESSED,
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 48 : explicit StaticContentsSock(const std::string& contents) : m_contents{contents}
140 32 : {
141 : // Just a dummy number that is not INVALID_SOCKET.
142 16 : m_socket = INVALID_SOCKET - 1;
143 32 : }
144 :
145 48 : ~StaticContentsSock() override { m_socket = INVALID_SOCKET; }
146 :
147 0 : StaticContentsSock& operator=(Sock&& other) override
148 : {
149 0 : assert(false && "Move of Sock into MockSock not allowed.");
150 : return *this;
151 : }
152 :
153 32 : ssize_t Send(const void*, size_t len, int) const override { return len; }
154 :
155 332 : ssize_t Recv(void* buf, size_t len, int flags) const override
156 : {
157 332 : const size_t consume_bytes{std::min(len, m_contents.size() - m_consumed)};
158 332 : std::memcpy(buf, m_contents.data() + m_consumed, consume_bytes);
159 332 : if ((flags & MSG_PEEK) == 0) {
160 166 : m_consumed += consume_bytes;
161 166 : }
162 332 : return consume_bytes;
163 : }
164 :
165 16 : int Connect(const sockaddr*, socklen_t) const override { return 0; }
166 :
167 0 : int Bind(const sockaddr*, socklen_t) const override { return 0; }
168 :
169 0 : int Listen(int) const override { return 0; }
170 :
171 0 : std::unique_ptr<Sock> Accept(sockaddr* addr, socklen_t* addr_len) const override
172 : {
173 0 : if (addr != nullptr) {
174 : // Pretend all connections come from 5.5.5.5:6789
175 0 : memset(addr, 0x00, *addr_len);
176 0 : const socklen_t write_len = static_cast<socklen_t>(sizeof(sockaddr_in));
177 0 : if (*addr_len >= write_len) {
178 0 : *addr_len = write_len;
179 0 : sockaddr_in* addr_in = reinterpret_cast<sockaddr_in*>(addr);
180 0 : addr_in->sin_family = AF_INET;
181 0 : memset(&addr_in->sin_addr, 0x05, sizeof(addr_in->sin_addr));
182 0 : addr_in->sin_port = htons(6789);
183 0 : }
184 0 : }
185 0 : return std::make_unique<StaticContentsSock>("");
186 : };
187 :
188 0 : int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const override
189 : {
190 0 : std::memset(opt_val, 0x0, *opt_len);
191 0 : return 0;
192 : }
193 :
194 0 : int SetSockOpt(int, int, const void*, socklen_t) const override { return 0; }
195 :
196 0 : int GetSockName(sockaddr* name, socklen_t* name_len) const override
197 : {
198 0 : std::memset(name, 0x0, *name_len);
199 0 : return 0;
200 : }
201 :
202 0 : bool SetNonBlocking() const override { return true; }
203 :
204 0 : bool IsSelectable(bool is_select) const override { return true; }
205 :
206 135 : bool Wait(std::chrono::milliseconds timeout,
207 : Event requested,
208 : SocketEventsParams event_params,
209 : Event* occurred = nullptr) const override
210 : {
211 135 : if (occurred != nullptr) {
212 5 : *occurred = requested;
213 5 : }
214 135 : return true;
215 : }
216 :
217 0 : bool WaitMany(std::chrono::milliseconds timeout,
218 : EventsPerSock& events_per_sock,
219 : SocketEventsParams event_params) const override
220 : {
221 0 : for (auto& [sock, events] : events_per_sock) {
222 : (void)sock;
223 0 : events.occurred = events.requested;
224 : }
225 0 : return true;
226 : }
227 :
228 : private:
229 : const std::string m_contents;
230 16 : mutable size_t m_consumed{0};
231 : };
232 :
233 : std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context);
234 :
235 : #endif // BITCOIN_TEST_UTIL_NET_H
|