LCOV - code coverage report
Current view: top level - src/test/fuzz - connman.cpp (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 100.0 % 235 235
Test Date: 2026-11-11 05:55:56 Functions: 100.0 % 29 29
Branches: 60.7 % 234 142

             Branch data     Line data    Source code
       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                 :             : #include <addrman.h>
       6                 :             : #include <chainparams.h>
       7                 :             : #include <common/args.h>
       8                 :             : #include <net.h>
       9                 :             : #include <net_processing.h>
      10                 :             : #include <netaddress.h>
      11                 :             : #include <protocol.h>
      12                 :             : #include <test/fuzz/FuzzedDataProvider.h>
      13                 :             : #include <test/fuzz/fuzz.h>
      14                 :             : #include <test/fuzz/util.h>
      15                 :             : #include <test/fuzz/util/net.h>
      16                 :             : #include <test/fuzz/util/threadinterrupt.h>
      17                 :             : #include <test/util/setup_common.h>
      18                 :             : #include <test/util/time.h>
      19                 :             : #include <util/check.h>
      20                 :             : #include <util/translation.h>
      21                 :             : 
      22                 :             : #include <cstdint>
      23                 :             : #include <vector>
      24                 :             : 
      25                 :             : namespace {
      26                 :             : const TestingSetup* g_setup;
      27                 :             : 
      28                 :        5779 : int32_t GetCheckRatio()
      29                 :             : {
      30         [ +  - ]:       17337 :     return std::clamp<int32_t>(g_setup->m_node.args->GetIntArg("-checkaddrman", 0), 0, 1000000);
      31                 :             : }
      32                 :             : 
      33                 :             : } // namespace
      34                 :             : 
      35                 :           1 : void initialize_connman()
      36                 :             : {
      37   [ +  -  +  -  :           1 :     static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
                   +  - ]
      38                 :           1 :     g_setup = testing_setup.get();
      39                 :           1 : }
      40                 :             : 
      41         [ +  - ]:        4917 : FUZZ_TARGET(connman, .init = initialize_connman)
      42                 :             : {
      43                 :        4441 :     SeedRandomStateForTest(SeedRand::ZEROS);
      44                 :        4441 :     FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
      45                 :        4441 :     FakeNodeClock clock{ConsumeTime(fuzzed_data_provider)};
      46         [ +  - ]:        4441 :     FakeSteadyClock steady_clock;
      47                 :        4441 :     auto netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
      48   [ +  -  +  - ]:        4441 :     auto addr_man_ptr{std::make_unique<AddrManDeterministic>(netgroupman, fuzzed_data_provider, GetCheckRatio())};
      49         [ +  + ]:        4441 :     if (fuzzed_data_provider.ConsumeBool()) {
      50                 :        2111 :         const std::vector<uint8_t> serialized_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
      51   [ -  +  +  - ]:        2111 :         DataStream ds{serialized_data};
      52                 :        2111 :         try {
      53         [ +  + ]:        4222 :             ds >> *addr_man_ptr;
      54         [ -  + ]:        1338 :         } catch (const std::ios_base::failure&) {
      55   [ +  -  +  - ]:        2676 :             addr_man_ptr = std::make_unique<AddrManDeterministic>(netgroupman, fuzzed_data_provider, GetCheckRatio());
      56                 :        1338 :         }
      57                 :        2111 :     }
      58         [ +  - ]:        4441 :     AddrManDeterministic& addr_man{*addr_man_ptr};
      59         [ +  - ]:        4441 :     auto net_events{ConsumeNetEvents(fuzzed_data_provider)};
      60                 :             : 
      61                 :             :     // Mock CreateSock() to create FuzzedSock.
      62         [ +  - ]:        4441 :     auto CreateSockOrig = CreateSock;
      63                 :        4441 :     CreateSock = [&fuzzed_data_provider, &steady_clock](int, int, int) {
      64                 :      108577 :         return std::make_unique<FuzzedSock>(fuzzed_data_provider, steady_clock);
      65                 :        4441 :     };
      66                 :             : 
      67                 :             :     // Mock g_dns_lookup() to return a fuzzed address.
      68         [ +  - ]:        4441 :     auto g_dns_lookup_orig = g_dns_lookup;
      69                 :       50012 :     g_dns_lookup = [&fuzzed_data_provider](const std::string&, bool) {
      70   [ +  -  +  +  :      136713 :         return std::vector<CNetAddr>{ConsumeNetAddr(fuzzed_data_provider)};
                   -  - ]
      71                 :       50012 :     };
      72                 :             : 
      73                 :        4441 :     ConnmanTestMsg connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
      74                 :             :                      fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
      75                 :             :                      addr_man,
      76                 :             :                      netgroupman,
      77                 :             :                      Params(),
      78                 :        4441 :                      fuzzed_data_provider.ConsumeBool(),
      79   [ +  -  +  -  :        8882 :                      ConsumeThreadInterrupt(fuzzed_data_provider)};
                   +  - ]
      80                 :             : 
      81                 :        4441 :     const uint64_t max_outbound_limit{fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
      82                 :        4441 :     CConnman::Options options;
      83                 :        4441 :     options.m_msgproc = &net_events;
      84                 :        4441 :     options.nMaxOutboundLimit = max_outbound_limit;
      85                 :             : 
      86                 :        4441 :     const auto local_services{ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS)};
      87                 :        4441 :     options.m_local_services = local_services;
      88                 :             : 
      89                 :        4441 :     const auto use_addrman_outgoing{fuzzed_data_provider.ConsumeBool()};
      90                 :        4441 :     options.m_use_addrman_outgoing = use_addrman_outgoing;
      91                 :        4441 :     options.m_max_automatic_connections = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 1000);
      92                 :             : 
      93                 :       13323 :     auto consume_whitelist = [&]() {
      94                 :        8882 :         std::vector<NetWhitelistPermissions> result(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 3));
      95         [ +  + ]:       15925 :         for (auto& entry : result) {
      96                 :        7043 :             entry.m_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);
      97                 :        7043 :             entry.m_subnet = ConsumeSubNet(fuzzed_data_provider);
      98                 :             :         }
      99                 :        8882 :         return result;
     100                 :        4441 :     };
     101         [ +  - ]:        8882 :     options.vWhitelistedRangeIncoming = consume_whitelist();
     102         [ +  - ]:        8882 :     options.vWhitelistedRangeOutgoing = consume_whitelist();
     103                 :             : 
     104         [ +  - ]:        4441 :     connman.Init(options);
     105                 :             : 
     106         [ +  - ]:        4441 :     const uint64_t total_bytes_recv_initial{connman.GetTotalBytesRecv()};
     107         [ +  - ]:        4441 :     const uint64_t total_bytes_sent_initial{connman.GetTotalBytesSent()};
     108                 :             : 
     109         [ +  - ]:        4441 :     CNetAddr random_netaddr;
     110         [ +  - ]:        4441 :     CAddress random_address;
     111                 :        4441 :     CNode random_node = ConsumeNode(fuzzed_data_provider, steady_clock);
     112         [ +  - ]:        4441 :     CSubNet random_subnet;
     113                 :        4441 :     std::string random_string;
     114                 :        4441 :     std::vector<NodeId> node_ids;
     115                 :        4441 :     std::vector<std::string> node_addr_names;
     116                 :             : 
     117   [ +  +  +  + ]:       70769 :     LIMITED_WHILE (fuzzed_data_provider.ConsumeBool(), 100) {
     118                 :       66328 :         CNode& p2p_node{*ConsumeNodeAsUniquePtr(fuzzed_data_provider, steady_clock).release()};
     119                 :             :         // Simulate post-handshake state.
     120         [ +  - ]:       66328 :         p2p_node.fSuccessfullyConnected = true;
     121         [ +  - ]:       66328 :         connman.AddTestNode(p2p_node);
     122         [ +  - ]:       66328 :         node_ids.push_back(p2p_node.GetId());
     123         [ +  - ]:       66328 :         node_addr_names.push_back(p2p_node.m_addr_name);
     124                 :             :     }
     125                 :             : 
     126   [ +  +  +  + ]:     1178936 :     LIMITED_WHILE (fuzzed_data_provider.ConsumeBool(), 10000) {
     127         [ +  - ]:     1174495 :         CallOneOf(
     128                 :             :             fuzzed_data_provider,
     129                 :       23861 :             [&] {
     130                 :       23861 :                 random_netaddr = ConsumeNetAddr(fuzzed_data_provider);
     131                 :       23861 :             },
     132                 :       45739 :             [&] {
     133                 :       45739 :                 random_address = ConsumeAddress(fuzzed_data_provider);
     134                 :       45739 :             },
     135                 :       10397 :             [&] {
     136                 :       10397 :                 random_subnet = ConsumeSubNet(fuzzed_data_provider);
     137                 :       10397 :             },
     138                 :       40326 :             [&] {
     139                 :       40326 :                 random_string = fuzzed_data_provider.ConsumeRandomLengthString(64);
     140                 :       40326 :             },
     141                 :       30718 :             [&] {
     142         [ +  + ]:       22663 :                 const std::string& node_str = (!node_addr_names.empty() && fuzzed_data_provider.ConsumeBool())
     143         [ +  + ]:       52985 :                     ? PickValue(fuzzed_data_provider, node_addr_names)
     144                 :       30718 :                     : random_string;
     145                 :       30718 :                 const auto added_node_info{connman.GetAddedNodeInfo(/*include_connected=*/true)};
     146         [ -  + ]:       61436 :                 const auto add_node{connman.AddNode({node_str, /*use_v2transport=*/fuzzed_data_provider.ConsumeBool()})};
     147         [ +  + ]:       30718 :                 if (add_node) {
     148   [ -  +  -  + ]:       43108 :                     assert(!connman.AddNode({node_str, /*use_v2transport=*/fuzzed_data_provider.ConsumeBool()}));
     149   [ -  +  +  -  :       43108 :                     assert(added_node_info.size() < connman.GetAddedNodeInfo(/*include_connected=*/true).size());
                   -  + ]
     150                 :       21554 :                     const auto remove{fuzzed_data_provider.ConsumeBool()};
     151         [ +  + ]:       21554 :                     if (remove) {
     152   [ -  +  +  -  :       20611 :                         assert(connman.RemoveAddedNode(node_str));
                   -  + ]
     153   [ -  +  +  -  :       41222 :                         assert(added_node_info.size() == connman.GetAddedNodeInfo(/*include_connected=*/true).size());
                   -  + ]
     154                 :             :                     }
     155                 :             :                 }
     156   [ +  -  +  - ]:       82990 :             },
     157                 :       73361 :             [&] {
     158         [ -  + ]:       73361 :                 (void)connman.RemoveAddedNode(random_string);
     159                 :       73361 :             },
     160                 :        5133 :             [&] {
     161                 :        5133 :                 connman.CheckIncomingNonce(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
     162                 :        5133 :             },
     163                 :        4640 :             [&] {
     164                 :        4640 :                 connman.DisconnectNode(fuzzed_data_provider.ConsumeIntegral<NodeId>());
     165                 :        4640 :             },
     166                 :        7977 :             [&] {
     167                 :        7977 :                 connman.DisconnectNode(random_netaddr);
     168                 :        7977 :             },
     169                 :        8718 :             [&] {
     170         [ -  + ]:        8718 :                 connman.DisconnectNode(random_string);
     171                 :        8718 :             },
     172                 :       51772 :             [&] {
     173                 :       51772 :                 connman.DisconnectNode(random_subnet);
     174                 :       51772 :             },
     175                 :        2439 :             [&] {
     176         [ +  + ]:        1188 :                 NodeId id = node_ids.empty() || fuzzed_data_provider.ConsumeBool()
     177         [ +  + ]:        3295 :                     ? fuzzed_data_provider.ConsumeIntegral<NodeId>()
     178                 :        2439 :                     : PickValue(fuzzed_data_provider, node_ids);
     179         [ +  - ]:        2439 :                 (void)connman.ForNode(id, [&](CNode* pnode) {
     180                 :             :                     (void)pnode->GetId();
     181                 :             :                     (void)pnode->IsInboundConn();
     182                 :             :                     (void)pnode->IsFullOutboundConn();
     183                 :             :                     return true;
     184                 :             :                 });
     185                 :        2439 :             },
     186                 :       32616 :             [&] {
     187                 :       32616 :                 auto max_addresses = fuzzed_data_provider.ConsumeIntegral<size_t>();
     188                 :       32616 :                 auto max_pct = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 100);
     189                 :       32616 :                 auto filtered = fuzzed_data_provider.ConsumeBool();
     190                 :       32616 :                 (void)connman.GetAddressesUnsafe(max_addresses, max_pct, /*network=*/std::nullopt, filtered);
     191                 :       32616 :             },
     192                 :        2808 :             [&] {
     193                 :        2808 :                 auto max_addresses = fuzzed_data_provider.ConsumeIntegral<size_t>();
     194                 :        2808 :                 auto max_pct = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 100);
     195                 :        2808 :                 (void)connman.GetAddresses(/*requestor=*/random_node, max_addresses, max_pct);
     196                 :        2808 :             },
     197                 :        1172 :             [&] {
     198                 :        1172 :                 (void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
     199                 :        1172 :             },
     200                 :       13070 :             [&] {
     201                 :       13070 :                 (void)connman.GetNodeCount(fuzzed_data_provider.PickValueInArray({ConnectionDirection::None, ConnectionDirection::In, ConnectionDirection::Out, ConnectionDirection::Both}));
     202                 :       13070 :             },
     203                 :      338061 :             [&] {
     204                 :      338061 :                 (void)connman.OutboundTargetReached(fuzzed_data_provider.ConsumeBool());
     205                 :      338061 :             },
     206                 :       93980 :             [&] {
     207         [ +  - ]:       93980 :                 CSerializedNetMsg serialized_net_msg;
     208         [ +  - ]:       93980 :                 serialized_net_msg.m_type = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::MESSAGE_TYPE_SIZE);
     209                 :       93980 :                 serialized_net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
     210         [ +  - ]:       93980 :                 const auto nodes{connman.TestNodes()};
     211         [ +  + ]:       93980 :                 if (nodes.empty()) return;
     212                 :       84051 :                 CNode* receiver{PickValue(fuzzed_data_provider, nodes)};
     213         [ +  - ]:       84051 :                 connman.PushMessage(receiver, std::move(serialized_net_msg));
     214                 :      187960 :             },
     215                 :        7840 :             [&] {
     216                 :        7840 :                 const auto set_active{fuzzed_data_provider.ConsumeBool()};
     217                 :        7840 :                 connman.SetNetworkActive(set_active);
     218         [ -  + ]:        7840 :                 assert(connman.GetNetworkActive() == set_active);
     219                 :        7840 :             },
     220                 :      231572 :             [&] {
     221                 :      231572 :                 connman.SetTryNewOutboundPeer(fuzzed_data_provider.ConsumeBool());
     222                 :      231572 :             },
     223                 :        1891 :             [&] {
     224                 :        1891 :                 const auto services{ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS)};
     225                 :        1891 :                 const auto before{connman.GetLocalServices()};
     226         [ +  + ]:        1891 :                 if (fuzzed_data_provider.ConsumeBool()) {
     227                 :         761 :                     connman.AddLocalServices(services);
     228         [ -  + ]:         761 :                     assert((connman.GetLocalServices() & services) == services);
     229                 :             :                     // Restore by clearing only the bits that weren't already set.
     230                 :         761 :                     connman.RemoveLocalServices(ServiceFlags(services & ~before));
     231                 :             :                 } else {
     232                 :        1130 :                     connman.RemoveLocalServices(services);
     233         [ -  + ]:        1130 :                     assert((connman.GetLocalServices() & services) == 0);
     234                 :             :                     // Restore by re-adding only the bits that were previously set.
     235                 :        1130 :                     connman.AddLocalServices(ServiceFlags(services & before));
     236                 :             :                 }
     237         [ -  + ]:        1891 :                 assert(connman.GetLocalServices() == before);
     238                 :        1891 :             },
     239                 :       28190 :             [&] {
     240                 :       28190 :                 ConnectionType conn_type{
     241                 :       28190 :                     fuzzed_data_provider.PickValueInArray(ALL_CONNECTION_TYPES)};
     242         [ +  + ]:       28190 :                 if (conn_type == ConnectionType::INBOUND) { // INBOUND is not allowed
     243                 :        2797 :                     conn_type = ConnectionType::OUTBOUND_FULL_RELAY;
     244                 :             :                 }
     245                 :             : 
     246                 :       28190 :                 std::optional<Proxy> proxy_override;
     247   [ +  +  +  + ]:       28190 :                 if (conn_type == ConnectionType::PRIVATE_BROADCAST || fuzzed_data_provider.ConsumeBool()) {
     248                 :       22514 :                     proxy_override.emplace(ConsumeService(fuzzed_data_provider));
     249                 :             :                 }
     250                 :             : 
     251         [ +  + ]:       28190 :                 connman.OpenNetworkConnection(
     252                 :             :                     /*addrConnect=*/random_address,
     253         [ +  - ]:       28190 :                     /*fCountFailure=*/fuzzed_data_provider.ConsumeBool(),
     254                 :             :                     /*grant_outbound=*/{},
     255         [ +  + ]:       28190 :                     /*pszDest=*/fuzzed_data_provider.ConsumeBool() ? nullptr : random_string.c_str(),
     256                 :             :                     /*conn_type=*/conn_type,
     257                 :       28190 :                     /*use_v2transport=*/fuzzed_data_provider.ConsumeBool(),
     258                 :             :                     /*proxy_override=*/proxy_override);
     259                 :       28190 :             },
     260                 :       64728 :             [&] {
     261                 :       64728 :                 connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool());
     262                 :       64728 :                 const auto peer = ConsumeAddress(fuzzed_data_provider);
     263                 :       64728 :                 connman.CreateNodeFromAcceptedSocketPublic(
     264         [ +  - ]:      129456 :                     /*sock=*/CreateSock(AF_INET, SOCK_STREAM, IPPROTO_TCP),
     265                 :             :                     /*permissions=*/ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS),
     266                 :      129456 :                     /*addr_bind=*/ConsumeAddress(fuzzed_data_provider),
     267                 :             :                     /*addr_peer=*/peer);
     268                 :       64728 :             },
     269                 :       26147 :             [&] {
     270                 :       26147 :                 CConnman::Options options;
     271                 :             : 
     272                 :       26147 :                 options.vBinds = ConsumeServiceVector(fuzzed_data_provider);
     273                 :             : 
     274                 :       26147 :                 options.vWhiteBinds = std::vector<NetWhitebindPermissions>{
     275         [ +  - ]:       52294 :                     fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 5)};
     276         [ +  + ]:       56048 :                 for (auto& wb : options.vWhiteBinds) {
     277                 :       29901 :                     wb.m_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);
     278                 :       29901 :                     wb.m_service = ConsumeService(fuzzed_data_provider);
     279                 :             :                 }
     280                 :             : 
     281                 :       26147 :                 options.onion_binds = ConsumeServiceVector(fuzzed_data_provider);
     282                 :             : 
     283   [ +  +  +  + ]:       26147 :                 options.bind_on_any = options.vBinds.empty() && options.vWhiteBinds.empty() &&
     284         [ +  + ]:        7571 :                                       options.onion_binds.empty();
     285                 :             : 
     286         [ +  - ]:       26147 :                 connman.InitBindsPublic(options);
     287                 :       26147 :             },
     288                 :       27339 :             [&] {
     289                 :       27339 :                 connman.SocketHandlerPublic();
     290                 :       27339 :             });
     291                 :             :     }
     292         [ +  - ]:       65098 :     connman.ForEachNode([](CNode* pnode) {
     293                 :       60657 :         (void)pnode->GetId();
     294                 :       60657 :         (void)pnode->IsInboundConn();
     295                 :       60657 :         (void)pnode->IsFullOutboundConn();
     296                 :       60657 :         (void)pnode->ConnectionTypeAsString();
     297                 :       60657 :     });
     298         [ +  - ]:        4441 :     (void)connman.GetAddedNodeInfo(/*include_connected=*/false);
     299         [ +  - ]:        4441 :     (void)connman.GetExtraFullOutboundCount();
     300   [ +  -  -  + ]:        4441 :     assert(connman.GetLocalServices() == local_services);
     301   [ +  -  -  + ]:        4441 :     assert(connman.GetMaxOutboundTarget() == max_outbound_limit);
     302         [ +  - ]:        4441 :     const auto time_left_in_cycle{connman.GetMaxOutboundTimeLeftInCycle()};
     303                 :        4441 :     std::vector<CNodeStats> stats;
     304         [ +  - ]:        4441 :     connman.GetNodeStats(stats);
     305         [ +  - ]:        4441 :     const auto bytes_left{connman.GetOutboundTargetBytesLeft()};
     306         [ -  + ]:        4441 :     assert(bytes_left <= max_outbound_limit);
     307         [ +  + ]:        4441 :     if (max_outbound_limit == 0) {
     308         [ -  + ]:        1067 :         assert(bytes_left == 0);
     309         [ -  + ]:        1067 :         assert(time_left_in_cycle == std::chrono::seconds{0});
     310   [ +  -  -  + ]:        1067 :         assert(!connman.OutboundTargetReached(/*historicalBlockServingLimit=*/false));
     311   [ +  -  -  + ]:        1067 :         assert(!connman.OutboundTargetReached(/*historicalBlockServingLimit=*/true));
     312                 :             :     }
     313   [ +  -  -  + ]:        4441 :     assert(connman.GetTotalBytesRecv() >= total_bytes_recv_initial);
     314   [ +  -  -  + ]:        4441 :     assert(connman.GetTotalBytesSent() >= total_bytes_sent_initial);
     315         [ +  - ]:        4441 :     (void)connman.GetTryNewOutboundPeer();
     316         [ -  + ]:        4441 :     assert(connman.GetUseAddrmanOutgoing() == use_addrman_outgoing);
     317         [ +  - ]:        4441 :     (void)connman.ASMapHealthCheck();
     318                 :             : 
     319         [ +  - ]:        4441 :     connman.ClearTestNodes();
     320         [ +  - ]:        4441 :     g_dns_lookup = g_dns_lookup_orig;
     321         [ +  - ]:        4441 :     CreateSock = CreateSockOrig;
     322                 :        4441 : }
        

Generated by: LCOV version 2.5.0-full