LCOV - code coverage report
Current view: top level - src/test/fuzz/util - net.h (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 0 29 0.0 %
Date: 2023-09-26 12:08:55 Functions: 0 6 0.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-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_FUZZ_UTIL_NET_H
       6             : #define BITCOIN_TEST_FUZZ_UTIL_NET_H
       7             : 
       8             : #include <net.h>
       9             : #include <net_permissions.h>
      10             : #include <netaddress.h>
      11             : #include <node/connection_types.h>
      12             : #include <node/eviction.h>
      13             : #include <protocol.h>
      14             : #include <test/fuzz/FuzzedDataProvider.h>
      15             : #include <test/fuzz/util.h>
      16             : #include <test/util/net.h>
      17             : #include <threadsafety.h>
      18             : #include <util/sock.h>
      19             : 
      20             : #include <chrono>
      21             : #include <cstdint>
      22             : #include <limits>
      23             : #include <memory>
      24             : #include <optional>
      25             : #include <string>
      26             : 
      27             : CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept;
      28             : 
      29             : class FuzzedSock : public Sock
      30             : {
      31             :     FuzzedDataProvider& m_fuzzed_data_provider;
      32             : 
      33             :     /**
      34             :      * Data to return when `MSG_PEEK` is used as a `Recv()` flag.
      35             :      * If `MSG_PEEK` is used, then our `Recv()` returns some random data as usual, but on the next
      36             :      * `Recv()` call we must return the same data, thus we remember it here.
      37             :      */
      38             :     mutable std::optional<uint8_t> m_peek_data;
      39             : 
      40             :     /**
      41             :      * Whether to pretend that the socket is select(2)-able. This is randomly set in the
      42             :      * constructor. It should remain constant so that repeated calls to `IsSelectable()`
      43             :      * return the same value.
      44             :      */
      45             :     const bool m_selectable;
      46             : 
      47             : public:
      48             :     explicit FuzzedSock(FuzzedDataProvider& fuzzed_data_provider);
      49             : 
      50             :     ~FuzzedSock() override;
      51             : 
      52             :     FuzzedSock& operator=(Sock&& other) override;
      53             : 
      54             :     ssize_t Send(const void* data, size_t len, int flags) const override;
      55             : 
      56             :     ssize_t Recv(void* buf, size_t len, int flags) const override;
      57             : 
      58             :     int Connect(const sockaddr*, socklen_t) const override;
      59             : 
      60             :     int Bind(const sockaddr*, socklen_t) const override;
      61             : 
      62             :     int Listen(int backlog) const override;
      63             : 
      64             :     std::unique_ptr<Sock> Accept(sockaddr* addr, socklen_t* addr_len) const override;
      65             : 
      66             :     int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const override;
      67             : 
      68             :     int SetSockOpt(int level, int opt_name, const void* opt_val, socklen_t opt_len) const override;
      69             : 
      70             :     int GetSockName(sockaddr* name, socklen_t* name_len) const override;
      71             : 
      72             :     bool SetNonBlocking() const override;
      73             : 
      74             :     bool IsSelectable() const override;
      75             : 
      76             :     bool Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred = nullptr) const override;
      77             : 
      78             :     bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const override;
      79             : 
      80             :     bool IsConnected(std::string& errmsg) const override;
      81             : };
      82             : 
      83           0 : [[nodiscard]] inline FuzzedSock ConsumeSock(FuzzedDataProvider& fuzzed_data_provider)
      84             : {
      85           0 :     return FuzzedSock{fuzzed_data_provider};
      86             : }
      87             : 
      88           0 : inline CSubNet ConsumeSubNet(FuzzedDataProvider& fuzzed_data_provider) noexcept
      89             : {
      90           0 :     return {ConsumeNetAddr(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<uint8_t>()};
      91             : }
      92             : 
      93           0 : inline CService ConsumeService(FuzzedDataProvider& fuzzed_data_provider) noexcept
      94             : {
      95           0 :     return {ConsumeNetAddr(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<uint16_t>()};
      96             : }
      97             : 
      98             : CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept;
      99             : 
     100             : template <bool ReturnUniquePtr = false>
     101           0 : auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional<NodeId>& node_id_in = std::nullopt) noexcept
     102             : {
     103           0 :     const NodeId node_id = node_id_in.value_or(fuzzed_data_provider.ConsumeIntegralInRange<NodeId>(0, std::numeric_limits<NodeId>::max()));
     104           0 :     const auto sock = std::make_shared<FuzzedSock>(fuzzed_data_provider);
     105           0 :     const CAddress address = ConsumeAddress(fuzzed_data_provider);
     106           0 :     const uint64_t keyed_net_group = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
     107           0 :     const uint64_t local_host_nonce = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
     108           0 :     const CAddress addr_bind = ConsumeAddress(fuzzed_data_provider);
     109           0 :     const std::string addr_name = fuzzed_data_provider.ConsumeRandomLengthString(64);
     110           0 :     const ConnectionType conn_type = fuzzed_data_provider.PickValueInArray(ALL_CONNECTION_TYPES);
     111           0 :     const bool inbound_onion{conn_type == ConnectionType::INBOUND ? fuzzed_data_provider.ConsumeBool() : false};
     112           0 :     NetPermissionFlags permission_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);
     113             :     if constexpr (ReturnUniquePtr) {
     114           0 :         return std::make_unique<CNode>(node_id,
     115             :                                        sock,
     116             :                                        address,
     117             :                                        keyed_net_group,
     118             :                                        local_host_nonce,
     119             :                                        addr_bind,
     120             :                                        addr_name,
     121             :                                        conn_type,
     122             :                                        inbound_onion,
     123           0 :                                        CNodeOptions{ .permission_flags = permission_flags });
     124             :     } else {
     125           0 :         return CNode{node_id,
     126           0 :                      sock,
     127             :                      address,
     128           0 :                      keyed_net_group,
     129           0 :                      local_host_nonce,
     130             :                      addr_bind,
     131             :                      addr_name,
     132           0 :                      conn_type,
     133           0 :                      inbound_onion,
     134           0 :                      CNodeOptions{ .permission_flags = permission_flags }};
     135             :     }
     136           0 : }
     137           0 : inline std::unique_ptr<CNode> ConsumeNodeAsUniquePtr(FuzzedDataProvider& fdp, const std::optional<NodeId>& node_id_in = std::nullopt) { return ConsumeNode<true>(fdp, node_id_in); }
     138             : 
     139             : void FillNode(FuzzedDataProvider& fuzzed_data_provider, ConnmanTestMsg& connman, CNode& node) noexcept EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex);
     140             : 
     141             : #endif // BITCOIN_TEST_FUZZ_UTIL_NET_H

Generated by: LCOV version 1.14