/ 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 <compat/compat.h>
  9  #include <netmessagemaker.h>
 10  #include <net.h>
 11  #include <net_permissions.h>
 12  #include <net_processing.h>
 13  #include <netaddress.h>
 14  #include <node/connection_types.h>
 15  #include <node/eviction.h>
 16  #include <span.h>
 17  #include <sync.h>
 18  #include <util/sock.h>
 19  
 20  #include <algorithm>
 21  #include <array>
 22  #include <cassert>
 23  #include <chrono>
 24  #include <condition_variable>
 25  #include <cstdint>
 26  #include <cstring>
 27  #include <memory>
 28  #include <optional>
 29  #include <string>
 30  #include <unordered_map>
 31  #include <vector>
 32  
 33  class FastRandomContext;
 34  
 35  struct ConnmanTestMsg : public CConnman {
 36      using CConnman::CConnman;
 37  
 38      void SetMsgProc(NetEventsInterface* msgproc)
 39      {
 40          m_msgproc = msgproc;
 41      }
 42  
 43      void SetAddrman(AddrMan& in) { addrman = in; }
 44  
 45      void SetPeerConnectTimeout(std::chrono::seconds timeout)
 46      {
 47          m_peer_connect_timeout = timeout;
 48      }
 49  
 50      void ResetAddrCache();
 51      void ResetMaxOutboundCycle();
 52      /// Reset the internal state.
 53      void Reset();
 54  
 55      std::vector<CNode*> TestNodes()
 56      {
 57          LOCK(m_nodes_mutex);
 58          return m_nodes;
 59      }
 60  
 61      void AddTestNode(CNode& node)
 62      {
 63          LOCK(m_nodes_mutex);
 64          m_nodes.push_back(&node);
 65  
 66          if (node.IsManualOrFullOutboundConn()) ++m_network_conn_counts[node.addr.GetNetwork()];
 67      }
 68  
 69      void ClearTestNodes()
 70      {
 71          LOCK(m_nodes_mutex);
 72          for (CNode* node : m_nodes) {
 73              delete node;
 74          }
 75          m_nodes.clear();
 76      }
 77  
 78      void CreateNodeFromAcceptedSocketPublic(std::unique_ptr<Sock> sock,
 79                                              NetPermissionFlags permissions,
 80                                              const CAddress& addr_bind,
 81                                              const CAddress& addr_peer)
 82      {
 83          CreateNodeFromAcceptedSocket(std::move(sock), permissions, addr_bind, addr_peer);
 84      }
 85  
 86      bool InitBindsPublic(const CConnman::Options& options)
 87      {
 88          return InitBinds(options);
 89      }
 90  
 91      void SocketHandlerPublic()
 92      {
 93          SocketHandler();
 94      }
 95  
 96      void Handshake(CNode& node,
 97                     bool successfully_connected,
 98                     ServiceFlags remote_services,
 99                     ServiceFlags local_services,
100                     int32_t version,
101                     bool relay_txs)
102          EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex);
103  
104      bool ProcessMessagesOnce(CNode& node) EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex)
105      {
106          return m_msgproc->ProcessMessages(node, flagInterruptMsgProc);
107      }
108  
109      void NodeReceiveMsgBytes(CNode& node, std::span<const uint8_t> msg_bytes, bool& complete) const;
110  
111      bool ReceiveMsgFrom(CNode& node, CSerializedNetMsg&& ser_msg) const;
112      void FlushSendBuffer(CNode& node) const;
113  
114      bool AlreadyConnectedToAddressPublic(const CNetAddr& addr) { return AlreadyConnectedToAddress(addr); };
115  
116      CNode* ConnectNodePublic(PeerManager& peerman, const char* pszDest, ConnectionType conn_type)
117          EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
118  };
119  
120  constexpr ServiceFlags ALL_SERVICE_FLAGS[]{
121      NODE_NONE,
122      NODE_NETWORK,
123      NODE_BLOOM,
124      NODE_WITNESS,
125      NODE_COMPACT_FILTERS,
126      NODE_NETWORK_LIMITED,
127      NODE_P2P_V2,
128  };
129  
130  constexpr NetPermissionFlags ALL_NET_PERMISSION_FLAGS[]{
131      NetPermissionFlags::None,
132      NetPermissionFlags::BloomFilter,
133      NetPermissionFlags::Relay,
134      NetPermissionFlags::ForceRelay,
135      NetPermissionFlags::NoBan,
136      NetPermissionFlags::Mempool,
137      NetPermissionFlags::Addr,
138      NetPermissionFlags::Download,
139      NetPermissionFlags::Implicit,
140      NetPermissionFlags::All,
141  };
142  
143  constexpr ConnectionType ALL_CONNECTION_TYPES[]{
144      ConnectionType::INBOUND,
145      ConnectionType::OUTBOUND_FULL_RELAY,
146      ConnectionType::MANUAL,
147      ConnectionType::FEELER,
148      ConnectionType::BLOCK_RELAY,
149      ConnectionType::ADDR_FETCH,
150      ConnectionType::PRIVATE_BROADCAST,
151  };
152  
153  constexpr auto ALL_NETWORKS = std::array{
154      Network::NET_UNROUTABLE,
155      Network::NET_IPV4,
156      Network::NET_IPV6,
157      Network::NET_ONION,
158      Network::NET_I2P,
159      Network::NET_CJDNS,
160      Network::NET_INTERNAL,
161  };
162  
163  /**
164   * A mocked Sock alternative that succeeds on all operations.
165   * Returns infinite amount of 0x0 bytes on reads.
166   */
167  class ZeroSock : public Sock
168  {
169  public:
170      ZeroSock();
171  
172      ~ZeroSock() override;
173  
174      ssize_t Send(const void*, size_t len, int) const override;
175  
176      ssize_t Recv(void* buf, size_t len, int flags) const override;
177  
178      int Connect(const sockaddr*, socklen_t) const override;
179  
180      int Bind(const sockaddr*, socklen_t) const override;
181  
182      int Listen(int) const override;
183  
184      std::unique_ptr<Sock> Accept(sockaddr* addr, socklen_t* addr_len) const override;
185  
186      int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const override;
187  
188      int SetSockOpt(int, int, const void*, socklen_t) const override;
189  
190      int GetSockName(sockaddr* name, socklen_t* name_len) const override;
191  
192      bool SetNonBlocking() const override;
193  
194      bool IsSelectable() const override;
195  
196      bool Wait(std::chrono::milliseconds timeout,
197                Event requested,
198                Event* occurred = nullptr) const override;
199  
200      bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const override;
201  
202  private:
203      ZeroSock& operator=(Sock&& other) override;
204  };
205  
206  /**
207   * A mocked Sock alternative that returns a statically contained data upon read and succeeds
208   * and ignores all writes. The data to be returned is given to the constructor and when it is
209   * exhausted an EOF is returned by further reads.
210   */
211  class StaticContentsSock : public ZeroSock
212  {
213  public:
214      explicit StaticContentsSock(const std::string& contents);
215  
216      /**
217       * Return parts of the contents that was provided at construction until it is exhausted
218       * and then return 0 (EOF).
219       */
220      ssize_t Recv(void* buf, size_t len, int flags) const override;
221  
222      bool IsConnected(std::string&) const override
223      {
224          return true;
225      }
226  
227  private:
228      StaticContentsSock& operator=(Sock&& other) override;
229  
230      const std::string m_contents;
231      mutable size_t m_consumed{0};
232  };
233  
234  /**
235   * A mocked Sock alternative that allows providing the data to be returned by Recv()
236   * and inspecting the data that has been supplied to Send().
237   */
238  class DynSock : public ZeroSock
239  {
240  public:
241      /**
242       * Unidirectional bytes or CNetMessage queue (FIFO).
243       */
244      class Pipe
245      {
246      public:
247          /**
248           * Get bytes and remove them from the pipe.
249           * @param[in] buf Destination to write bytes to.
250           * @param[in] len Write up to this number of bytes.
251           * @param[in] flags Same as the flags of `recv(2)`. Just `MSG_PEEK` is honored.
252           * @return The number of bytes written to `buf`. `0` if `Eof()` has been called.
253           * If no bytes are available then `-1` is returned and `errno` is set to `EAGAIN`.
254           */
255          ssize_t GetBytes(void* buf, size_t len, int flags = 0) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
256  
257          /**
258           * Deserialize a `CNetMessage` and remove it from the pipe.
259           * If not enough bytes are available then the function will wait. If parsing fails
260           * or EOF is signaled to the pipe, then `std::nullopt` is returned.
261           */
262          std::optional<CNetMessage> GetNetMsg() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
263  
264          /**
265           * Push bytes to the pipe.
266           */
267          void PushBytes(const void* buf, size_t len) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
268  
269          /**
270           * Construct and push CNetMessage to the pipe.
271           */
272          template <typename... Args>
273          void PushNetMsg(const std::string& type, Args&&... payload) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
274  
275          /**
276           * Signal end-of-file on the receiving end (`GetBytes()` or `GetNetMsg()`).
277           */
278          void Eof() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
279  
280      private:
281          /**
282           * Return when there is some data to read or EOF has been signaled.
283           * @param[in,out] lock Unique lock that must have been derived from `m_mutex` by `WAIT_LOCK(m_mutex, lock)`.
284           */
285          void WaitForDataOrEof(UniqueLock<Mutex>& lock) EXCLUSIVE_LOCKS_REQUIRED(m_mutex);
286  
287          Mutex m_mutex;
288          std::condition_variable m_cond;
289          std::vector<uint8_t> m_data GUARDED_BY(m_mutex);
290          bool m_eof GUARDED_BY(m_mutex){false};
291      };
292  
293      struct Pipes {
294          Pipe recv;
295          Pipe send;
296      };
297  
298      /**
299       * A basic thread-safe queue, used for queuing sockets to be returned by Accept().
300       */
301      class Queue
302      {
303      public:
304          using S = std::unique_ptr<DynSock>;
305  
306          void Push(S s) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
307          {
308              LOCK(m_mutex);
309              m_queue.push(std::move(s));
310          }
311  
312          std::optional<S> Pop() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
313          {
314              LOCK(m_mutex);
315              if (m_queue.empty()) {
316                  return std::nullopt;
317              }
318              S front{std::move(m_queue.front())};
319              m_queue.pop();
320              return front;
321          }
322  
323          bool Empty() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
324          {
325              LOCK(m_mutex);
326              return m_queue.empty();
327          }
328  
329      private:
330          mutable Mutex m_mutex;
331          std::queue<S> m_queue GUARDED_BY(m_mutex);
332      };
333  
334      /**
335       * Create a new mocked sock.
336       * @param[in] pipes Send/recv pipes used by the Send() and Recv() methods.
337       * @param[in] accept_sockets Sockets to return by the Accept() method.
338       */
339      explicit DynSock(std::shared_ptr<Pipes> pipes, std::shared_ptr<Queue> accept_sockets);
340  
341      ~DynSock();
342  
343      ssize_t Recv(void* buf, size_t len, int flags) const override;
344  
345      ssize_t Send(const void* buf, size_t len, int) const override;
346  
347      std::unique_ptr<Sock> Accept(sockaddr* addr, socklen_t* addr_len) const override;
348  
349      bool Wait(std::chrono::milliseconds timeout,
350                Event requested,
351                Event* occurred = nullptr) const override;
352  
353      bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const override;
354  
355  private:
356      DynSock& operator=(Sock&&) override;
357  
358      std::shared_ptr<Pipes> m_pipes;
359      std::shared_ptr<Queue> m_accept_sockets;
360  };
361  
362  template <typename... Args>
363  void DynSock::Pipe::PushNetMsg(const std::string& type, Args&&... payload)
364  {
365      auto msg = NetMsg::Make(type, std::forward<Args>(payload)...);
366      V1Transport transport{NodeId{0}};
367  
368      const bool queued{transport.SetMessageToSend(msg)};
369      assert(queued);
370  
371      LOCK(m_mutex);
372  
373      for (;;) {
374          const auto& [bytes, _more, _msg_type] = transport.GetBytesToSend(/*have_next_message=*/true);
375          if (bytes.empty()) {
376              break;
377          }
378          m_data.insert(m_data.end(), bytes.begin(), bytes.end());
379          transport.MarkBytesSent(bytes.size());
380      }
381  
382      m_cond.notify_all();
383  }
384  
385  std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context);
386  
387  #endif // BITCOIN_TEST_UTIL_NET_H