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 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 : };
69 :
70 : constexpr NetPermissionFlags ALL_NET_PERMISSION_FLAGS[]{
71 : NetPermissionFlags::None,
72 : NetPermissionFlags::BloomFilter,
73 : NetPermissionFlags::Relay,
74 : NetPermissionFlags::ForceRelay,
75 : NetPermissionFlags::NoBan,
76 : NetPermissionFlags::Mempool,
77 : NetPermissionFlags::Addr,
78 : NetPermissionFlags::Download,
79 : NetPermissionFlags::Implicit,
80 : NetPermissionFlags::All,
81 : };
82 :
83 : constexpr ConnectionType ALL_CONNECTION_TYPES[]{
84 : ConnectionType::INBOUND,
85 : ConnectionType::OUTBOUND_FULL_RELAY,
86 : ConnectionType::MANUAL,
87 : ConnectionType::FEELER,
88 : ConnectionType::BLOCK_RELAY,
89 : ConnectionType::ADDR_FETCH,
90 : };
91 :
92 : constexpr auto ALL_NETWORKS = std::array{
93 : Network::NET_UNROUTABLE,
94 : Network::NET_IPV4,
95 : Network::NET_IPV6,
96 : Network::NET_ONION,
97 : Network::NET_I2P,
98 : Network::NET_CJDNS,
99 : Network::NET_INTERNAL,
100 : };
101 :
102 : /**
103 : * A mocked Sock alternative that returns a statically contained data upon read and succeeds
104 : * and ignores all writes. The data to be returned is given to the constructor and when it is
105 : * exhausted an EOF is returned by further reads.
106 : */
107 : class StaticContentsSock : public Sock
108 : {
109 : public:
110 : explicit StaticContentsSock(const std::string& contents) : m_contents{contents}
111 : {
112 : // Just a dummy number that is not INVALID_SOCKET.
113 : m_socket = INVALID_SOCKET - 1;
114 : }
115 :
116 : ~StaticContentsSock() override { m_socket = INVALID_SOCKET; }
117 :
118 : StaticContentsSock& operator=(Sock&& other) override
119 : {
120 : assert(false && "Move of Sock into MockSock not allowed.");
121 : return *this;
122 : }
123 :
124 : ssize_t Send(const void*, size_t len, int) const override { return len; }
125 :
126 : ssize_t Recv(void* buf, size_t len, int flags) const override
127 : {
128 : const size_t consume_bytes{std::min(len, m_contents.size() - m_consumed)};
129 : std::memcpy(buf, m_contents.data() + m_consumed, consume_bytes);
130 : if ((flags & MSG_PEEK) == 0) {
131 : m_consumed += consume_bytes;
132 : }
133 : return consume_bytes;
134 : }
135 :
136 : int Connect(const sockaddr*, socklen_t) const override { return 0; }
137 :
138 : int Bind(const sockaddr*, socklen_t) const override { return 0; }
139 :
140 : int Listen(int) const override { return 0; }
141 :
142 : std::unique_ptr<Sock> Accept(sockaddr* addr, socklen_t* addr_len) const override
143 : {
144 : if (addr != nullptr) {
145 : // Pretend all connections come from 5.5.5.5:6789
146 : memset(addr, 0x00, *addr_len);
147 : const socklen_t write_len = static_cast<socklen_t>(sizeof(sockaddr_in));
148 : if (*addr_len >= write_len) {
149 : *addr_len = write_len;
150 : sockaddr_in* addr_in = reinterpret_cast<sockaddr_in*>(addr);
151 : addr_in->sin_family = AF_INET;
152 : memset(&addr_in->sin_addr, 0x05, sizeof(addr_in->sin_addr));
153 : addr_in->sin_port = htons(6789);
154 : }
155 : }
156 : return std::make_unique<StaticContentsSock>("");
157 : };
158 :
159 : int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const override
160 : {
161 : std::memset(opt_val, 0x0, *opt_len);
162 : return 0;
163 : }
164 :
165 : int SetSockOpt(int, int, const void*, socklen_t) const override { return 0; }
166 :
167 : int GetSockName(sockaddr* name, socklen_t* name_len) const override
168 : {
169 : std::memset(name, 0x0, *name_len);
170 : return 0;
171 : }
172 :
173 : bool SetNonBlocking() const override { return true; }
174 :
175 : bool IsSelectable() const override { return true; }
176 :
177 : bool Wait(std::chrono::milliseconds timeout,
178 : Event requested,
179 : Event* occurred = nullptr) const override
180 : {
181 : if (occurred != nullptr) {
182 : *occurred = requested;
183 : }
184 : return true;
185 : }
186 :
187 : bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const override
188 : {
189 : for (auto& [sock, events] : events_per_sock) {
190 : (void)sock;
191 : events.occurred = events.requested;
192 : }
193 : return true;
194 : }
195 :
196 : private:
197 : const std::string m_contents;
198 : mutable size_t m_consumed{0};
199 : };
200 :
201 : std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context);
202 :
203 : #endif // BITCOIN_TEST_UTIL_NET_H
|