/ src / test / fuzz / connman.cpp
connman.cpp
  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  #include <addrman.h>
  6  #include <chainparams.h>
  7  #include <common/args.h>
  8  #include <net.h>
  9  #include <netaddress.h>
 10  #include <protocol.h>
 11  #include <test/fuzz/FuzzedDataProvider.h>
 12  #include <test/fuzz/fuzz.h>
 13  #include <test/fuzz/util.h>
 14  #include <test/fuzz/util/net.h>
 15  #include <test/util/setup_common.h>
 16  #include <util/translation.h>
 17  
 18  #include <cstdint>
 19  #include <vector>
 20  
 21  namespace {
 22  const TestingSetup* g_setup;
 23  
 24  int32_t GetCheckRatio()
 25  {
 26      return std::clamp<int32_t>(g_setup->m_node.args->GetIntArg("-checkaddrman", 0), 0, 1000000);
 27  }
 28  
 29  } // namespace
 30  
 31  void initialize_connman()
 32  {
 33      static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
 34      g_setup = testing_setup.get();
 35  }
 36  
 37  FUZZ_TARGET(connman, .init = initialize_connman)
 38  {
 39      SeedRandomStateForTest(SeedRand::ZEROS);
 40      FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
 41      SetMockTime(ConsumeTime(fuzzed_data_provider));
 42      auto netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
 43      auto addr_man_ptr{std::make_unique<AddrManDeterministic>(netgroupman, fuzzed_data_provider, GetCheckRatio())};
 44      if (fuzzed_data_provider.ConsumeBool()) {
 45          const std::vector<uint8_t> serialized_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
 46          DataStream ds{serialized_data};
 47          try {
 48              ds >> *addr_man_ptr;
 49          } catch (const std::ios_base::failure&) {
 50              addr_man_ptr = std::make_unique<AddrManDeterministic>(netgroupman, fuzzed_data_provider, GetCheckRatio());
 51          }
 52      }
 53      AddrManDeterministic& addr_man{*addr_man_ptr};
 54      ConnmanTestMsg connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
 55                       fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
 56                       addr_man,
 57                       netgroupman,
 58                       Params(),
 59                       fuzzed_data_provider.ConsumeBool()};
 60  
 61      const uint64_t max_outbound_limit{fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
 62      CConnman::Options options;
 63      options.nMaxOutboundLimit = max_outbound_limit;
 64      connman.Init(options);
 65  
 66      CNetAddr random_netaddr;
 67      CNode random_node = ConsumeNode(fuzzed_data_provider);
 68      CSubNet random_subnet;
 69      std::string random_string;
 70  
 71      LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 100) {
 72          CNode& p2p_node{*ConsumeNodeAsUniquePtr(fuzzed_data_provider).release()};
 73          connman.AddTestNode(p2p_node);
 74      }
 75  
 76      LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
 77          CallOneOf(
 78              fuzzed_data_provider,
 79              [&] {
 80                  random_netaddr = ConsumeNetAddr(fuzzed_data_provider);
 81              },
 82              [&] {
 83                  random_subnet = ConsumeSubNet(fuzzed_data_provider);
 84              },
 85              [&] {
 86                  random_string = fuzzed_data_provider.ConsumeRandomLengthString(64);
 87              },
 88              [&] {
 89                  connman.AddNode({random_string, fuzzed_data_provider.ConsumeBool()});
 90              },
 91              [&] {
 92                  connman.CheckIncomingNonce(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
 93              },
 94              [&] {
 95                  connman.DisconnectNode(fuzzed_data_provider.ConsumeIntegral<NodeId>());
 96              },
 97              [&] {
 98                  connman.DisconnectNode(random_netaddr);
 99              },
100              [&] {
101                  connman.DisconnectNode(random_string);
102              },
103              [&] {
104                  connman.DisconnectNode(random_subnet);
105              },
106              [&] {
107                  connman.ForEachNode([](auto) {});
108              },
109              [&] {
110                  (void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral<NodeId>(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); });
111              },
112              [&] {
113                  auto max_addresses = fuzzed_data_provider.ConsumeIntegral<size_t>();
114                  auto max_pct = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 100);
115                  auto filtered = fuzzed_data_provider.ConsumeBool();
116                  (void)connman.GetAddresses(max_addresses, max_pct, /*network=*/std::nullopt, filtered);
117              },
118              [&] {
119                  auto max_addresses = fuzzed_data_provider.ConsumeIntegral<size_t>();
120                  auto max_pct = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 100);
121                  (void)connman.GetAddresses(/*requestor=*/random_node, max_addresses, max_pct);
122              },
123              [&] {
124                  (void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
125              },
126              [&] {
127                  (void)connman.GetNodeCount(fuzzed_data_provider.PickValueInArray({ConnectionDirection::None, ConnectionDirection::In, ConnectionDirection::Out, ConnectionDirection::Both}));
128              },
129              [&] {
130                  (void)connman.OutboundTargetReached(fuzzed_data_provider.ConsumeBool());
131              },
132              [&] {
133                  CSerializedNetMsg serialized_net_msg;
134                  serialized_net_msg.m_type = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::MESSAGE_TYPE_SIZE);
135                  serialized_net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
136                  connman.PushMessage(&random_node, std::move(serialized_net_msg));
137              },
138              [&] {
139                  connman.RemoveAddedNode(random_string);
140              },
141              [&] {
142                  connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool());
143              },
144              [&] {
145                  connman.SetTryNewOutboundPeer(fuzzed_data_provider.ConsumeBool());
146              });
147      }
148      (void)connman.GetAddedNodeInfo(fuzzed_data_provider.ConsumeBool());
149      (void)connman.GetExtraFullOutboundCount();
150      (void)connman.GetLocalServices();
151      assert(connman.GetMaxOutboundTarget() == max_outbound_limit);
152      (void)connman.GetMaxOutboundTimeframe();
153      (void)connman.GetMaxOutboundTimeLeftInCycle();
154      (void)connman.GetNetworkActive();
155      std::vector<CNodeStats> stats;
156      connman.GetNodeStats(stats);
157      (void)connman.GetOutboundTargetBytesLeft();
158      (void)connman.GetTotalBytesRecv();
159      (void)connman.GetTotalBytesSent();
160      (void)connman.GetTryNewOutboundPeer();
161      (void)connman.GetUseAddrmanOutgoing();
162      (void)connman.ASMapHealthCheck();
163  
164      connman.ClearTestNodes();
165  }