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 % 232 232
Test Date: 2026-06-29 07:05:34 Functions: 100.0 % 29 29
Branches: 60.1 % 228 137

             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/translation.h>
      20                 :             : 
      21                 :             : #include <cstdint>
      22                 :             : #include <vector>
      23                 :             : 
      24                 :             : namespace {
      25                 :             : const TestingSetup* g_setup;
      26                 :             : 
      27                 :        4549 : int32_t GetCheckRatio()
      28                 :             : {
      29         [ +  - ]:       13647 :     return std::clamp<int32_t>(g_setup->m_node.args->GetIntArg("-checkaddrman", 0), 0, 1000000);
      30                 :             : }
      31                 :             : 
      32                 :             : } // namespace
      33                 :             : 
      34                 :           1 : void initialize_connman()
      35                 :             : {
      36   [ +  -  +  -  :           1 :     static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
                   +  - ]
      37                 :           1 :     g_setup = testing_setup.get();
      38                 :           1 : }
      39                 :             : 
      40         [ +  - ]:        3857 : FUZZ_TARGET(connman, .init = initialize_connman)
      41                 :             : {
      42                 :        3391 :     SeedRandomStateForTest(SeedRand::ZEROS);
      43                 :        3391 :     FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
      44                 :        3391 :     FakeNodeClock clock{ConsumeTime(fuzzed_data_provider)};
      45         [ +  - ]:        3391 :     FakeSteadyClock steady_clock;
      46                 :        3391 :     auto netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
      47   [ +  -  +  - ]:        3391 :     auto addr_man_ptr{std::make_unique<AddrManDeterministic>(netgroupman, fuzzed_data_provider, GetCheckRatio())};
      48         [ +  + ]:        3391 :     if (fuzzed_data_provider.ConsumeBool()) {
      49                 :        1801 :         const std::vector<uint8_t> serialized_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
      50   [ -  +  +  - ]:        1801 :         DataStream ds{serialized_data};
      51                 :        1801 :         try {
      52         [ +  + ]:        3602 :             ds >> *addr_man_ptr;
      53         [ -  + ]:        1158 :         } catch (const std::ios_base::failure&) {
      54   [ +  -  +  - ]:        2316 :             addr_man_ptr = std::make_unique<AddrManDeterministic>(netgroupman, fuzzed_data_provider, GetCheckRatio());
      55                 :        1158 :         }
      56                 :        1801 :     }
      57         [ +  - ]:        3391 :     AddrManDeterministic& addr_man{*addr_man_ptr};
      58         [ +  - ]:        3391 :     auto net_events{ConsumeNetEvents(fuzzed_data_provider)};
      59                 :             : 
      60                 :             :     // Mock CreateSock() to create FuzzedSock.
      61         [ +  - ]:        3391 :     auto CreateSockOrig = CreateSock;
      62                 :       14094 :     CreateSock = [&fuzzed_data_provider, &steady_clock](int, int, int) {
      63                 :       10703 :         return std::make_unique<FuzzedSock>(fuzzed_data_provider, steady_clock);
      64                 :        3391 :     };
      65                 :             : 
      66                 :             :     // Mock g_dns_lookup() to return a fuzzed address.
      67         [ +  - ]:        3391 :     auto g_dns_lookup_orig = g_dns_lookup;
      68                 :       12430 :     g_dns_lookup = [&fuzzed_data_provider](const std::string&, bool) {
      69   [ +  -  +  +  :       27117 :         return std::vector<CNetAddr>{ConsumeNetAddr(fuzzed_data_provider)};
                   -  - ]
      70                 :       12430 :     };
      71                 :             : 
      72                 :        3391 :     ConnmanTestMsg connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
      73                 :             :                      fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
      74                 :             :                      addr_man,
      75                 :             :                      netgroupman,
      76                 :             :                      Params(),
      77                 :        3391 :                      fuzzed_data_provider.ConsumeBool(),
      78   [ +  -  +  -  :        6782 :                      ConsumeThreadInterrupt(fuzzed_data_provider)};
                   +  - ]
      79                 :             : 
      80                 :        3391 :     const uint64_t max_outbound_limit{fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
      81                 :        3391 :     CConnman::Options options;
      82                 :        3391 :     options.m_msgproc = &net_events;
      83                 :        3391 :     options.nMaxOutboundLimit = max_outbound_limit;
      84                 :             : 
      85                 :        3391 :     const auto local_services{ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS)};
      86                 :        3391 :     options.m_local_services = local_services;
      87                 :             : 
      88                 :        3391 :     const auto use_addrman_outgoing{fuzzed_data_provider.ConsumeBool()};
      89                 :        3391 :     options.m_use_addrman_outgoing = use_addrman_outgoing;
      90                 :        3391 :     options.m_max_automatic_connections = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 1000);
      91                 :             : 
      92                 :       10173 :     auto consume_whitelist = [&]() {
      93                 :        6782 :         std::vector<NetWhitelistPermissions> result(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 3));
      94         [ +  + ]:       13963 :         for (auto& entry : result) {
      95                 :        7181 :             entry.m_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);
      96                 :        7181 :             entry.m_subnet = ConsumeSubNet(fuzzed_data_provider);
      97                 :             :         }
      98                 :        6782 :         return result;
      99                 :        3391 :     };
     100         [ +  - ]:        6782 :     options.vWhitelistedRangeIncoming = consume_whitelist();
     101         [ +  - ]:        6782 :     options.vWhitelistedRangeOutgoing = consume_whitelist();
     102                 :             : 
     103         [ +  - ]:        3391 :     connman.Init(options);
     104                 :             : 
     105         [ +  - ]:        3391 :     const uint64_t total_bytes_recv_initial{connman.GetTotalBytesRecv()};
     106         [ +  - ]:        3391 :     const uint64_t total_bytes_sent_initial{connman.GetTotalBytesSent()};
     107                 :             : 
     108         [ +  - ]:        3391 :     CNetAddr random_netaddr;
     109         [ +  - ]:        3391 :     CAddress random_address;
     110                 :        3391 :     CNode random_node = ConsumeNode(fuzzed_data_provider, steady_clock);
     111         [ +  - ]:        3391 :     CSubNet random_subnet;
     112                 :        3391 :     std::string random_string;
     113                 :        3391 :     std::vector<NodeId> node_ids;
     114                 :        3391 :     std::vector<std::string> node_addr_names;
     115                 :             : 
     116   [ +  +  +  + ]:       42558 :     LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 100) {
     117                 :       39167 :         CNode& p2p_node{*ConsumeNodeAsUniquePtr(fuzzed_data_provider, steady_clock).release()};
     118                 :             :         // Simulate post-handshake state.
     119         [ +  - ]:       39167 :         p2p_node.fSuccessfullyConnected = true;
     120         [ +  - ]:       39167 :         connman.AddTestNode(p2p_node);
     121         [ +  - ]:       39167 :         node_ids.push_back(p2p_node.GetId());
     122         [ +  - ]:       39167 :         node_addr_names.push_back(p2p_node.m_addr_name);
     123                 :             :     }
     124                 :             : 
     125   [ +  +  +  + ]:      262910 :     LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
     126         [ +  - ]:      259519 :         CallOneOf(
     127                 :             :             fuzzed_data_provider,
     128                 :        3660 :             [&] {
     129                 :        3660 :                 random_netaddr = ConsumeNetAddr(fuzzed_data_provider);
     130                 :        3660 :             },
     131                 :       26326 :             [&] {
     132                 :       26326 :                 random_address = ConsumeAddress(fuzzed_data_provider);
     133                 :       26326 :             },
     134                 :        2279 :             [&] {
     135                 :        2279 :                 random_subnet = ConsumeSubNet(fuzzed_data_provider);
     136                 :        2279 :             },
     137                 :        8277 :             [&] {
     138                 :        8277 :                 random_string = fuzzed_data_provider.ConsumeRandomLengthString(64);
     139                 :        8277 :             },
     140                 :        4026 :             [&] {
     141         [ +  + ]:        3825 :                 const std::string& node_str = (!node_addr_names.empty() && fuzzed_data_provider.ConsumeBool())
     142         [ +  + ]:        7820 :                     ? PickValue(fuzzed_data_provider, node_addr_names)
     143                 :        4026 :                     : random_string;
     144                 :        4026 :                 const auto added_node_info{connman.GetAddedNodeInfo(/*include_connected=*/true)};
     145         [ -  + ]:        8052 :                 const auto add_node{connman.AddNode({node_str, /*use_v2transport=*/fuzzed_data_provider.ConsumeBool()})};
     146         [ +  + ]:        4026 :                 if (add_node) {
     147   [ -  +  -  + ]:        7180 :                     assert(!connman.AddNode({node_str, /*use_v2transport=*/fuzzed_data_provider.ConsumeBool()}));
     148   [ -  +  +  -  :        7180 :                     assert(added_node_info.size() < connman.GetAddedNodeInfo(/*include_connected=*/true).size());
                   -  + ]
     149                 :        3590 :                     const auto remove{fuzzed_data_provider.ConsumeBool()};
     150         [ +  + ]:        3590 :                     if (remove) {
     151   [ -  +  -  + ]:        7052 :                         assert(connman.RemoveAddedNode(node_str));
     152   [ -  +  +  -  :        7052 :                         assert(added_node_info.size() == connman.GetAddedNodeInfo(/*include_connected=*/true).size());
                   -  + ]
     153                 :             :                     }
     154                 :             :                 }
     155   [ +  -  +  - ]:       11642 :             },
     156                 :        9712 :             [&] {
     157         [ -  + ]:        9712 :                 (void)connman.RemoveAddedNode(random_string);
     158                 :        9712 :             },
     159                 :        1342 :             [&] {
     160                 :        1342 :                 connman.CheckIncomingNonce(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
     161                 :        1342 :             },
     162                 :         528 :             [&] {
     163                 :         528 :                 connman.DisconnectNode(fuzzed_data_provider.ConsumeIntegral<NodeId>());
     164                 :         528 :             },
     165                 :        1008 :             [&] {
     166                 :        1008 :                 connman.DisconnectNode(random_netaddr);
     167                 :        1008 :             },
     168                 :          83 :             [&] {
     169         [ -  + ]:          83 :                 connman.DisconnectNode(random_string);
     170                 :          83 :             },
     171                 :       19031 :             [&] {
     172                 :       19031 :                 connman.DisconnectNode(random_subnet);
     173                 :       19031 :             },
     174                 :         371 :             [&] {
     175         [ +  + ]:         160 :                 NodeId id = node_ids.empty() || fuzzed_data_provider.ConsumeBool()
     176         [ +  + ]:         502 :                     ? fuzzed_data_provider.ConsumeIntegral<NodeId>()
     177                 :         371 :                     : PickValue(fuzzed_data_provider, node_ids);
     178         [ +  - ]:         371 :                 (void)connman.ForNode(id, [&](CNode* pnode) {
     179                 :             :                     (void)pnode->GetId();
     180                 :             :                     (void)pnode->IsInboundConn();
     181                 :             :                     (void)pnode->IsFullOutboundConn();
     182                 :             :                     return true;
     183                 :             :                 });
     184                 :         371 :             },
     185                 :       12263 :             [&] {
     186                 :       12263 :                 auto max_addresses = fuzzed_data_provider.ConsumeIntegral<size_t>();
     187                 :       12263 :                 auto max_pct = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 100);
     188                 :       12263 :                 auto filtered = fuzzed_data_provider.ConsumeBool();
     189                 :       12263 :                 (void)connman.GetAddressesUnsafe(max_addresses, max_pct, /*network=*/std::nullopt, filtered);
     190                 :       12263 :             },
     191                 :         367 :             [&] {
     192                 :         367 :                 auto max_addresses = fuzzed_data_provider.ConsumeIntegral<size_t>();
     193                 :         367 :                 auto max_pct = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 100);
     194                 :         367 :                 (void)connman.GetAddresses(/*requestor=*/random_node, max_addresses, max_pct);
     195                 :         367 :             },
     196                 :          48 :             [&] {
     197                 :          48 :                 (void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
     198                 :          48 :             },
     199                 :        3357 :             [&] {
     200                 :        3357 :                 (void)connman.GetNodeCount(fuzzed_data_provider.PickValueInArray({ConnectionDirection::None, ConnectionDirection::In, ConnectionDirection::Out, ConnectionDirection::Both}));
     201                 :        3357 :             },
     202                 :       84396 :             [&] {
     203                 :       84396 :                 (void)connman.OutboundTargetReached(fuzzed_data_provider.ConsumeBool());
     204                 :       84396 :             },
     205                 :       46389 :             [&] {
     206         [ +  - ]:       46389 :                 CSerializedNetMsg serialized_net_msg;
     207         [ +  - ]:       46389 :                 serialized_net_msg.m_type = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::MESSAGE_TYPE_SIZE);
     208                 :       46389 :                 serialized_net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
     209         [ +  - ]:       46389 :                 connman.PushMessage(&random_node, std::move(serialized_net_msg));
     210                 :       46389 :             },
     211                 :        1744 :             [&] {
     212                 :        1744 :                 const auto set_active{fuzzed_data_provider.ConsumeBool()};
     213                 :        1744 :                 connman.SetNetworkActive(set_active);
     214         [ -  + ]:        1744 :                 assert(connman.GetNetworkActive() == set_active);
     215                 :        1744 :             },
     216                 :       17287 :             [&] {
     217                 :       17287 :                 connman.SetTryNewOutboundPeer(fuzzed_data_provider.ConsumeBool());
     218                 :       17287 :             },
     219                 :         190 :             [&] {
     220                 :         190 :                 const auto services{ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS)};
     221                 :         190 :                 const auto before{connman.GetLocalServices()};
     222         [ +  + ]:         190 :                 if (fuzzed_data_provider.ConsumeBool()) {
     223                 :          49 :                     connman.AddLocalServices(services);
     224         [ -  + ]:          49 :                     assert((connman.GetLocalServices() & services) == services);
     225                 :             :                     // Restore by clearing only the bits that weren't already set.
     226                 :          49 :                     connman.RemoveLocalServices(ServiceFlags(services & ~before));
     227                 :             :                 } else {
     228                 :         141 :                     connman.RemoveLocalServices(services);
     229         [ -  + ]:         141 :                     assert((connman.GetLocalServices() & services) == 0);
     230                 :             :                     // Restore by re-adding only the bits that were previously set.
     231                 :         141 :                     connman.AddLocalServices(ServiceFlags(services & before));
     232                 :             :                 }
     233         [ -  + ]:         190 :                 assert(connman.GetLocalServices() == before);
     234                 :         190 :             },
     235                 :        5128 :             [&] {
     236                 :        5128 :                 ConnectionType conn_type{
     237                 :        5128 :                     fuzzed_data_provider.PickValueInArray(ALL_CONNECTION_TYPES)};
     238         [ +  + ]:        5128 :                 if (conn_type == ConnectionType::INBOUND) { // INBOUND is not allowed
     239                 :          85 :                     conn_type = ConnectionType::OUTBOUND_FULL_RELAY;
     240                 :             :                 }
     241                 :             : 
     242                 :        5128 :                 std::optional<Proxy> proxy_override;
     243   [ +  +  +  + ]:        5128 :                 if (conn_type == ConnectionType::PRIVATE_BROADCAST || fuzzed_data_provider.ConsumeBool()) {
     244                 :        5019 :                     proxy_override.emplace(ConsumeService(fuzzed_data_provider));
     245                 :             :                 }
     246                 :             : 
     247         [ +  + ]:        5128 :                 connman.OpenNetworkConnection(
     248                 :             :                     /*addrConnect=*/random_address,
     249         [ +  - ]:        5128 :                     /*fCountFailure=*/fuzzed_data_provider.ConsumeBool(),
     250                 :             :                     /*grant_outbound=*/{},
     251         [ +  + ]:        5128 :                     /*pszDest=*/fuzzed_data_provider.ConsumeBool() ? nullptr : random_string.c_str(),
     252                 :             :                     /*conn_type=*/conn_type,
     253                 :        5128 :                     /*use_v2transport=*/fuzzed_data_provider.ConsumeBool(),
     254                 :             :                     /*proxy_override=*/proxy_override);
     255                 :        5128 :             },
     256                 :        6843 :             [&] {
     257                 :        6843 :                 connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool());
     258                 :        6843 :                 const auto peer = ConsumeAddress(fuzzed_data_provider);
     259                 :        6843 :                 connman.CreateNodeFromAcceptedSocketPublic(
     260         [ +  - ]:       13686 :                     /*sock=*/CreateSock(AF_INET, SOCK_STREAM, IPPROTO_TCP),
     261                 :             :                     /*permissions=*/ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS),
     262                 :       13686 :                     /*addr_bind=*/ConsumeAddress(fuzzed_data_provider),
     263                 :             :                     /*addr_peer=*/peer);
     264                 :        6843 :             },
     265                 :        3869 :             [&] {
     266                 :        3869 :                 CConnman::Options options;
     267                 :             : 
     268                 :        3869 :                 options.vBinds = ConsumeServiceVector(fuzzed_data_provider);
     269                 :             : 
     270                 :        3869 :                 options.vWhiteBinds = std::vector<NetWhitebindPermissions>{
     271         [ +  - ]:        7738 :                     fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 5)};
     272         [ +  + ]:        9013 :                 for (auto& wb : options.vWhiteBinds) {
     273                 :        5144 :                     wb.m_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);
     274                 :        5144 :                     wb.m_service = ConsumeService(fuzzed_data_provider);
     275                 :             :                 }
     276                 :             : 
     277                 :        3869 :                 options.onion_binds = ConsumeServiceVector(fuzzed_data_provider);
     278                 :             : 
     279   [ +  +  +  + ]:        3869 :                 options.bind_on_any = options.vBinds.empty() && options.vWhiteBinds.empty() &&
     280         [ -  + ]:          93 :                                       options.onion_binds.empty();
     281                 :             : 
     282         [ +  - ]:        3869 :                 connman.InitBindsPublic(options);
     283                 :        3869 :             },
     284                 :         995 :             [&] {
     285                 :         995 :                 connman.SocketHandlerPublic();
     286                 :         995 :             });
     287                 :             :     }
     288         [ +  - ]:       42301 :     connman.ForEachNode([](CNode* pnode) {
     289                 :       38910 :         (void)pnode->GetId();
     290                 :       38910 :         (void)pnode->IsInboundConn();
     291                 :       38910 :         (void)pnode->IsFullOutboundConn();
     292                 :       38910 :         (void)pnode->ConnectionTypeAsString();
     293                 :       38910 :     });
     294         [ +  - ]:        3391 :     (void)connman.GetAddedNodeInfo(/*include_connected=*/false);
     295         [ +  - ]:        3391 :     (void)connman.GetExtraFullOutboundCount();
     296   [ +  -  -  + ]:        3391 :     assert(connman.GetLocalServices() == local_services);
     297   [ +  -  -  + ]:        3391 :     assert(connman.GetMaxOutboundTarget() == max_outbound_limit);
     298         [ +  - ]:        3391 :     const auto time_left_in_cycle{connman.GetMaxOutboundTimeLeftInCycle()};
     299                 :        3391 :     std::vector<CNodeStats> stats;
     300         [ +  - ]:        3391 :     connman.GetNodeStats(stats);
     301         [ +  - ]:        3391 :     const auto bytes_left{connman.GetOutboundTargetBytesLeft()};
     302         [ -  + ]:        3391 :     assert(bytes_left <= max_outbound_limit);
     303         [ +  + ]:        3391 :     if (max_outbound_limit == 0) {
     304         [ -  + ]:        1022 :         assert(bytes_left == 0);
     305         [ -  + ]:        1022 :         assert(time_left_in_cycle == std::chrono::seconds{0});
     306   [ +  -  -  + ]:        1022 :         assert(!connman.OutboundTargetReached(/*historicalBlockServingLimit=*/false));
     307   [ +  -  -  + ]:        1022 :         assert(!connman.OutboundTargetReached(/*historicalBlockServingLimit=*/true));
     308                 :             :     }
     309   [ +  -  -  + ]:        3391 :     assert(connman.GetTotalBytesRecv() >= total_bytes_recv_initial);
     310   [ +  -  -  + ]:        3391 :     assert(connman.GetTotalBytesSent() >= total_bytes_sent_initial);
     311         [ +  - ]:        3391 :     (void)connman.GetTryNewOutboundPeer();
     312         [ -  + ]:        3391 :     assert(connman.GetUseAddrmanOutgoing() == use_addrman_outgoing);
     313         [ +  - ]:        3391 :     (void)connman.ASMapHealthCheck();
     314                 :             : 
     315         [ +  - ]:        3391 :     connman.ClearTestNodes();
     316         [ +  - ]:        3391 :     g_dns_lookup = g_dns_lookup_orig;
     317         [ +  - ]:        3391 :     CreateSock = CreateSockOrig;
     318                 :        3391 : }
        

Generated by: LCOV version 2.0-1