/ src / test / util / net.h
net.h
  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