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 }