Branch data Line data Source code
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 : 0 : struct ConnmanTestMsg : public CConnman {
35 : 0 : 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 : 0 : void AddTestNode(CNode& node)
49 : : {
50 : 0 : LOCK(m_nodes_mutex);
51 [ # # ]: 0 : m_nodes.push_back(&node);
52 : :
53 [ # # ][ # # ]: 0 : if (node.IsManualOrFullOutboundConn()) ++m_network_conn_counts[node.addr.GetNetwork()];
[ # # ]
54 : 0 : }
55 : :
56 : 0 : void ClearTestNodes()
57 : : {
58 : 0 : LOCK(m_nodes_mutex);
59 [ # # ]: 0 : for (CNode* node : m_nodes) {
60 [ # # ]: 0 : delete node;
61 : : }
62 : 0 : m_nodes.clear();
63 : 0 : }
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 : 0 : bool ProcessMessagesOnce(CNode& node) EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex)
74 : : {
75 : 0 : 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
|