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
397