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