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