LCOV - code coverage report
Current view: top level - src/test - denialofservice_tests.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 98.7 % 237 234
Test Date: 2024-11-04 04:45:35 Functions: 100.0 % 12 12
Branches: 51.4 % 980 504

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2011-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                 :             : // Unit tests for denial-of-service detection/prevention code
       6                 :             : 
       7                 :             : #include <banman.h>
       8                 :             : #include <chainparams.h>
       9                 :             : #include <common/args.h>
      10                 :             : #include <net.h>
      11                 :             : #include <net_processing.h>
      12                 :             : #include <pubkey.h>
      13                 :             : #include <script/sign.h>
      14                 :             : #include <script/signingprovider.h>
      15                 :             : #include <serialize.h>
      16                 :             : #include <test/util/net.h>
      17                 :             : #include <test/util/random.h>
      18                 :             : #include <test/util/setup_common.h>
      19                 :             : #include <util/string.h>
      20                 :             : #include <util/time.h>
      21                 :             : #include <validation.h>
      22                 :             : 
      23                 :             : #include <array>
      24                 :             : #include <stdint.h>
      25                 :             : 
      26                 :             : #include <boost/test/unit_test.hpp>
      27                 :             : 
      28                 :          17 : static CService ip(uint32_t i)
      29                 :             : {
      30                 :          17 :     struct in_addr s;
      31                 :          17 :     s.s_addr = i;
      32         [ +  - ]:          34 :     return CService(CNetAddr(s), Params().GetDefaultPort());
      33                 :             : }
      34                 :             : 
      35                 :             : BOOST_FIXTURE_TEST_SUITE(denialofservice_tests, TestingSetup)
      36                 :             : 
      37                 :             : // Test eviction of an outbound peer whose chain never advances
      38                 :             : // Mock a node connection, and use mocktime to simulate a peer
      39                 :             : // which never sends any headers messages.  PeerLogic should
      40                 :             : // decide to evict that outbound peer, after the appropriate timeouts.
      41                 :             : // Note that we protect 4 outbound nodes from being subject to
      42                 :             : // this logic; this test takes advantage of that protection only
      43                 :             : // being applied to nodes which send headers with sufficient
      44                 :             : // work.
      45   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
      46                 :             : {
      47                 :           1 :     LOCK(NetEventsInterface::g_msgproc_mutex);
      48                 :             : 
      49         [ +  - ]:           1 :     ConnmanTestMsg& connman = static_cast<ConnmanTestMsg&>(*m_node.connman);
      50                 :             :     // Disable inactivity checks for this test to avoid interference
      51         [ +  - ]:           1 :     connman.SetPeerConnectTimeout(99999s);
      52                 :           1 :     PeerManager& peerman = *m_node.peerman;
      53                 :             : 
      54                 :             :     // Mock an outbound peer
      55         [ +  - ]:           1 :     CAddress addr1(ip(0xa0b0c001), NODE_NONE);
      56                 :           1 :     NodeId id{0};
      57                 :           1 :     CNode dummyNode1{id++,
      58                 :             :                      /*sock=*/nullptr,
      59                 :             :                      addr1,
      60                 :             :                      /*nKeyedNetGroupIn=*/0,
      61                 :             :                      /*nLocalHostNonceIn=*/0,
      62   [ +  -  -  + ]:           2 :                      CAddress(),
      63                 :             :                      /*addrNameIn=*/"",
      64                 :             :                      ConnectionType::OUTBOUND_FULL_RELAY,
      65   [ +  -  +  - ]:           2 :                      /*inbound_onion=*/false};
      66                 :             : 
      67         [ +  - ]:           1 :     connman.Handshake(
      68                 :             :         /*node=*/dummyNode1,
      69                 :             :         /*successfully_connected=*/true,
      70                 :             :         /*remote_services=*/ServiceFlags(NODE_NETWORK | NODE_WITNESS),
      71                 :             :         /*local_services=*/ServiceFlags(NODE_NETWORK | NODE_WITNESS),
      72                 :             :         /*version=*/PROTOCOL_VERSION,
      73                 :             :         /*relay_txs=*/true);
      74                 :             : 
      75                 :             :     // This test requires that we have a chain with non-zero work.
      76                 :           1 :     {
      77         [ +  - ]:           1 :         LOCK(cs_main);
      78   [ +  -  +  -  :           3 :         BOOST_CHECK(m_node.chainman->ActiveChain().Tip() != nullptr);
          +  -  +  -  +  
                      - ]
      79   [ +  -  +  -  :           4 :         BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->nChainWork > 0);
          +  -  +  -  +  
                -  +  - ]
      80                 :           0 :     }
      81                 :             : 
      82                 :             :     // Test starts here
      83   [ +  -  +  -  :           2 :     BOOST_CHECK(peerman.SendMessages(&dummyNode1)); // should result in getheaders
          +  -  +  -  +  
                      - ]
      84                 :             : 
      85                 :           1 :     {
      86         [ +  - ]:           1 :         LOCK(dummyNode1.cs_vSend);
      87         [ +  - ]:           1 :         const auto& [to_send, _more, _msg_type] = dummyNode1.m_transport->GetBytesToSend(false);
      88   [ +  -  +  -  :           2 :         BOOST_CHECK(!to_send.empty());
                   +  - ]
      89                 :           0 :     }
      90         [ +  - ]:           1 :     connman.FlushSendBuffer(dummyNode1);
      91                 :             : 
      92         [ +  - ]:           1 :     int64_t nStartTime = GetTime();
      93                 :             :     // Wait 21 minutes
      94         [ +  - ]:           1 :     SetMockTime(nStartTime+21*60);
      95   [ +  -  +  -  :           2 :     BOOST_CHECK(peerman.SendMessages(&dummyNode1)); // should result in getheaders
             +  -  +  - ]
      96                 :           1 :     {
      97         [ +  - ]:           1 :         LOCK(dummyNode1.cs_vSend);
      98         [ +  - ]:           1 :         const auto& [to_send, _more, _msg_type] = dummyNode1.m_transport->GetBytesToSend(false);
      99   [ +  -  +  -  :           2 :         BOOST_CHECK(!to_send.empty());
                   +  - ]
     100                 :           0 :     }
     101                 :             :     // Wait 3 more minutes
     102         [ +  - ]:           1 :     SetMockTime(nStartTime+24*60);
     103   [ +  -  +  -  :           2 :     BOOST_CHECK(peerman.SendMessages(&dummyNode1)); // should result in disconnect
             +  -  +  - ]
     104   [ +  -  +  -  :           2 :     BOOST_CHECK(dummyNode1.fDisconnect == true);
                   +  - ]
     105                 :             : 
     106         [ +  - ]:           1 :     peerman.FinalizeNode(dummyNode1);
     107   [ +  -  +  - ]:           3 : }
     108                 :             : 
     109                 :           4 : struct OutboundTest : TestingSetup {
     110                 :          14 : void AddRandomOutboundPeer(NodeId& id, std::vector<CNode*>& vNodes, PeerManager& peerLogic, ConnmanTestMsg& connman, ConnectionType connType, bool onion_peer = false)
     111                 :             : {
     112                 :          14 :     CAddress addr;
     113                 :             : 
     114         [ +  + ]:          14 :     if (onion_peer) {
     115                 :           2 :         auto tor_addr{m_rng.randbytes(ADDR_TORV3_SIZE)};
     116   [ +  -  +  -  :           4 :         BOOST_REQUIRE(addr.SetSpecial(OnionToString(tor_addr)));
             +  -  +  - ]
     117                 :           2 :     }
     118                 :             : 
     119   [ +  -  +  + ]:          26 :     while (!addr.IsRoutable()) {
     120         [ +  - ]:          12 :         addr = CAddress(ip(m_rng.randbits(32)), NODE_NONE);
     121                 :             :     }
     122                 :             : 
     123   [ +  -  -  - ]:          14 :     vNodes.emplace_back(new CNode{id++,
     124                 :             :                                   /*sock=*/nullptr,
     125                 :             :                                   addr,
     126                 :             :                                   /*nKeyedNetGroupIn=*/0,
     127                 :             :                                   /*nLocalHostNonceIn=*/0,
     128   [ +  -  -  + ]:          28 :                                   CAddress(),
     129                 :             :                                   /*addrNameIn=*/"",
     130                 :             :                                   connType,
     131   [ +  -  +  -  :          28 :                                   /*inbound_onion=*/false});
                   +  - ]
     132                 :          14 :     CNode &node = *vNodes.back();
     133         [ +  - ]:          14 :     node.SetCommonVersion(PROTOCOL_VERSION);
     134                 :             : 
     135         [ +  - ]:          14 :     peerLogic.InitializeNode(node, ServiceFlags(NODE_NETWORK | NODE_WITNESS));
     136         [ +  - ]:          14 :     node.fSuccessfullyConnected = true;
     137                 :             : 
     138         [ +  - ]:          14 :     connman.AddTestNode(node);
     139         [ +  - ]:          28 : }
     140                 :             : }; // struct OutboundTest
     141                 :             : 
     142   [ +  -  +  -  :           7 : BOOST_FIXTURE_TEST_CASE(stale_tip_peer_management, OutboundTest)
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     143                 :             : {
     144                 :           1 :     NodeId id{0};
     145                 :           1 :     auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params());
     146         [ +  - ]:           1 :     auto peerLogic = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
     147                 :             : 
     148                 :           1 :     constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS;
     149                 :           1 :     CConnman::Options options;
     150                 :           1 :     options.m_max_automatic_connections = DEFAULT_MAX_PEER_CONNECTIONS;
     151                 :             : 
     152                 :           1 :     const auto time_init{GetTime<std::chrono::seconds>()};
     153         [ +  - ]:           1 :     SetMockTime(time_init);
     154         [ +  - ]:           1 :     const auto time_later{time_init + 3 * std::chrono::seconds{m_node.chainman->GetConsensus().nPowTargetSpacing} + 1s};
     155         [ +  - ]:           1 :     connman->Init(options);
     156                 :           1 :     std::vector<CNode *> vNodes;
     157                 :             : 
     158                 :             :     // Mock some outbound peers
     159         [ +  + ]:           9 :     for (int i = 0; i < max_outbound_full_relay; ++i) {
     160         [ +  - ]:           8 :         AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY);
     161                 :             :     }
     162                 :             : 
     163         [ +  - ]:           1 :     peerLogic->CheckForStaleTipAndEvictPeers();
     164                 :             : 
     165                 :             :     // No nodes should be marked for disconnection while we have no extra peers
     166         [ +  + ]:           9 :     for (const CNode *node : vNodes) {
     167   [ +  -  +  - ]:          16 :         BOOST_CHECK(node->fDisconnect == false);
     168                 :             :     }
     169                 :             : 
     170         [ +  - ]:           1 :     SetMockTime(time_later);
     171                 :             : 
     172                 :             :     // Now tip should definitely be stale, and we should look for an extra
     173                 :             :     // outbound peer
     174         [ +  - ]:           1 :     peerLogic->CheckForStaleTipAndEvictPeers();
     175   [ +  -  +  -  :           2 :     BOOST_CHECK(connman->GetTryNewOutboundPeer());
                   +  - ]
     176                 :             : 
     177                 :             :     // Still no peers should be marked for disconnection
     178         [ +  + ]:           9 :     for (const CNode *node : vNodes) {
     179   [ +  -  +  - ]:          16 :         BOOST_CHECK(node->fDisconnect == false);
     180                 :             :     }
     181                 :             : 
     182                 :             :     // If we add one more peer, something should get marked for eviction
     183                 :             :     // on the next check (since we're mocking the time to be in the future, the
     184                 :             :     // required time connected check should be satisfied).
     185         [ +  - ]:           1 :     SetMockTime(time_init);
     186         [ +  - ]:           1 :     AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY);
     187         [ +  - ]:           1 :     SetMockTime(time_later);
     188                 :             : 
     189         [ +  - ]:           1 :     peerLogic->CheckForStaleTipAndEvictPeers();
     190         [ +  + ]:           9 :     for (int i = 0; i < max_outbound_full_relay; ++i) {
     191   [ +  -  +  - ]:          16 :         BOOST_CHECK(vNodes[i]->fDisconnect == false);
     192                 :             :     }
     193                 :             :     // Last added node should get marked for eviction
     194   [ +  -  +  -  :           2 :     BOOST_CHECK(vNodes.back()->fDisconnect == true);
                   +  - ]
     195                 :             : 
     196         [ +  - ]:           1 :     vNodes.back()->fDisconnect = false;
     197                 :             : 
     198                 :             :     // Update the last announced block time for the last
     199                 :             :     // peer, and check that the next newest node gets evicted.
     200   [ +  -  +  - ]:           1 :     peerLogic->UpdateLastBlockAnnounceTime(vNodes.back()->GetId(), GetTime());
     201                 :             : 
     202         [ +  - ]:           1 :     peerLogic->CheckForStaleTipAndEvictPeers();
     203         [ +  + ]:           8 :     for (int i = 0; i < max_outbound_full_relay - 1; ++i) {
     204   [ +  -  +  - ]:          14 :         BOOST_CHECK(vNodes[i]->fDisconnect == false);
     205                 :             :     }
     206   [ +  -  +  -  :           2 :     BOOST_CHECK(vNodes[max_outbound_full_relay-1]->fDisconnect == true);
                   +  - ]
     207   [ +  -  +  -  :           2 :     BOOST_CHECK(vNodes.back()->fDisconnect == false);
                   +  - ]
     208                 :             : 
     209         [ +  - ]:           1 :     vNodes[max_outbound_full_relay - 1]->fDisconnect = false;
     210                 :             : 
     211                 :             :     // Add an onion peer, that will be protected because it is the only one for
     212                 :             :     // its network, so another peer gets disconnected instead.
     213         [ +  - ]:           1 :     SetMockTime(time_init);
     214         [ +  - ]:           1 :     AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY, /*onion_peer=*/true);
     215         [ +  - ]:           1 :     SetMockTime(time_later);
     216         [ +  - ]:           1 :     peerLogic->CheckForStaleTipAndEvictPeers();
     217                 :             : 
     218         [ +  + ]:           7 :     for (int i = 0; i < max_outbound_full_relay - 2; ++i) {
     219   [ +  -  +  - ]:          12 :         BOOST_CHECK(vNodes[i]->fDisconnect == false);
     220                 :             :     }
     221   [ +  -  +  -  :           2 :     BOOST_CHECK(vNodes[max_outbound_full_relay - 2]->fDisconnect == false);
                   +  - ]
     222   [ +  -  +  -  :           2 :     BOOST_CHECK(vNodes[max_outbound_full_relay - 1]->fDisconnect == true);
                   +  - ]
     223   [ +  -  +  -  :           2 :     BOOST_CHECK(vNodes[max_outbound_full_relay]->fDisconnect == false);
                   +  - ]
     224                 :             : 
     225                 :             :     // Add a second onion peer which won't be protected
     226         [ +  - ]:           1 :     SetMockTime(time_init);
     227         [ +  - ]:           1 :     AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY, /*onion_peer=*/true);
     228         [ +  - ]:           1 :     SetMockTime(time_later);
     229         [ +  - ]:           1 :     peerLogic->CheckForStaleTipAndEvictPeers();
     230                 :             : 
     231   [ +  -  +  - ]:           2 :     BOOST_CHECK(vNodes.back()->fDisconnect == true);
     232                 :             : 
     233         [ +  + ]:          12 :     for (const CNode *node : vNodes) {
     234         [ +  - ]:          11 :         peerLogic->FinalizeNode(*node);
     235                 :             :     }
     236                 :             : 
     237         [ +  - ]:           1 :     connman->ClearTestNodes();
     238                 :           1 : }
     239                 :             : 
     240   [ +  -  +  -  :           7 : BOOST_FIXTURE_TEST_CASE(block_relay_only_eviction, OutboundTest)
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     241                 :             : {
     242                 :           1 :     NodeId id{0};
     243                 :           1 :     auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params());
     244         [ +  - ]:           1 :     auto peerLogic = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
     245                 :             : 
     246                 :           1 :     constexpr int max_outbound_block_relay{MAX_BLOCK_RELAY_ONLY_CONNECTIONS};
     247                 :           1 :     constexpr int64_t MINIMUM_CONNECT_TIME{30};
     248                 :           1 :     CConnman::Options options;
     249                 :           1 :     options.m_max_automatic_connections = DEFAULT_MAX_PEER_CONNECTIONS;
     250                 :             : 
     251         [ +  - ]:           1 :     connman->Init(options);
     252                 :           1 :     std::vector<CNode*> vNodes;
     253                 :             : 
     254                 :             :     // Add block-relay-only peers up to the limit
     255         [ +  + ]:           3 :     for (int i = 0; i < max_outbound_block_relay; ++i) {
     256         [ +  - ]:           2 :         AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::BLOCK_RELAY);
     257                 :             :     }
     258         [ +  - ]:           1 :     peerLogic->CheckForStaleTipAndEvictPeers();
     259                 :             : 
     260         [ +  + ]:           3 :     for (int i = 0; i < max_outbound_block_relay; ++i) {
     261   [ +  -  +  - ]:           4 :         BOOST_CHECK(vNodes[i]->fDisconnect == false);
     262                 :             :     }
     263                 :             : 
     264                 :             :     // Add an extra block-relay-only peer breaking the limit (mocks logic in ThreadOpenConnections)
     265         [ +  - ]:           1 :     AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::BLOCK_RELAY);
     266         [ +  - ]:           1 :     peerLogic->CheckForStaleTipAndEvictPeers();
     267                 :             : 
     268                 :             :     // The extra peer should only get marked for eviction after MINIMUM_CONNECT_TIME
     269         [ +  + ]:           3 :     for (int i = 0; i < max_outbound_block_relay; ++i) {
     270   [ +  -  +  - ]:           4 :         BOOST_CHECK(vNodes[i]->fDisconnect == false);
     271                 :             :     }
     272   [ +  -  +  -  :           2 :     BOOST_CHECK(vNodes.back()->fDisconnect == false);
                   +  - ]
     273                 :             : 
     274   [ +  -  +  - ]:           1 :     SetMockTime(GetTime() + MINIMUM_CONNECT_TIME + 1);
     275         [ +  - ]:           1 :     peerLogic->CheckForStaleTipAndEvictPeers();
     276         [ +  + ]:           3 :     for (int i = 0; i < max_outbound_block_relay; ++i) {
     277   [ +  -  +  - ]:           4 :         BOOST_CHECK(vNodes[i]->fDisconnect == false);
     278                 :             :     }
     279   [ +  -  +  - ]:           2 :     BOOST_CHECK(vNodes.back()->fDisconnect == true);
     280                 :             : 
     281                 :             :     // Update the last block time for the extra peer,
     282                 :             :     // and check that the next youngest peer gets evicted.
     283                 :           1 :     vNodes.back()->fDisconnect = false;
     284                 :           1 :     vNodes.back()->m_last_block_time = GetTime<std::chrono::seconds>();
     285                 :             : 
     286         [ +  - ]:           1 :     peerLogic->CheckForStaleTipAndEvictPeers();
     287         [ +  + ]:           2 :     for (int i = 0; i < max_outbound_block_relay - 1; ++i) {
     288   [ +  -  +  - ]:           2 :         BOOST_CHECK(vNodes[i]->fDisconnect == false);
     289                 :             :     }
     290   [ +  -  +  -  :           2 :     BOOST_CHECK(vNodes[max_outbound_block_relay - 1]->fDisconnect == true);
                   +  - ]
     291   [ +  -  +  - ]:           2 :     BOOST_CHECK(vNodes.back()->fDisconnect == false);
     292                 :             : 
     293         [ +  + ]:           4 :     for (const CNode* node : vNodes) {
     294         [ +  - ]:           3 :         peerLogic->FinalizeNode(*node);
     295                 :             :     }
     296         [ +  - ]:           1 :     connman->ClearTestNodes();
     297                 :           1 : }
     298                 :             : 
     299   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(peer_discouragement)
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     300                 :             : {
     301                 :           1 :     LOCK(NetEventsInterface::g_msgproc_mutex);
     302                 :             : 
     303   [ +  -  +  -  :           3 :     auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
                   +  - ]
     304   [ +  -  +  - ]:           1 :     auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params());
     305         [ +  - ]:           1 :     auto peerLogic = PeerManager::make(*connman, *m_node.addrman, banman.get(), *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
     306                 :             : 
     307         [ +  - ]:           1 :     CNetAddr tor_netaddr;
     308   [ +  -  +  -  :           2 :     BOOST_REQUIRE(
          +  -  +  -  +  
                      - ]
     309                 :             :         tor_netaddr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
     310   [ +  -  +  - ]:           1 :     const CService tor_service{tor_netaddr, Params().GetDefaultPort()};
     311                 :             : 
     312         [ +  - ]:           1 :     const std::array<CAddress, 3> addr{CAddress{ip(0xa0b0c001), NODE_NONE},
     313         [ +  - ]:           2 :                                        CAddress{ip(0xa0b0c002), NODE_NONE},
     314         [ -  - ]:           2 :                                        CAddress{tor_service, NODE_NONE}};
     315                 :             : 
     316         [ +  - ]:           1 :     const CNetAddr other_addr{ip(0xa0b0ff01)}; // Not any of addr[].
     317                 :             : 
     318                 :           1 :     std::array<CNode*, 3> nodes;
     319                 :             : 
     320         [ +  - ]:           1 :     banman->ClearBanned();
     321                 :           1 :     NodeId id{0};
     322                 :           1 :     nodes[0] = new CNode{id++,
     323                 :             :                          /*sock=*/nullptr,
     324         [ +  - ]:           1 :                          addr[0],
     325                 :             :                          /*nKeyedNetGroupIn=*/0,
     326                 :             :                          /*nLocalHostNonceIn=*/0,
     327   [ +  -  -  + ]:           2 :                          CAddress(),
     328                 :             :                          /*addrNameIn=*/"",
     329                 :             :                          ConnectionType::INBOUND,
     330   [ +  -  +  -  :           2 :                          /*inbound_onion=*/false};
                   +  - ]
     331         [ +  - ]:           1 :     nodes[0]->SetCommonVersion(PROTOCOL_VERSION);
     332         [ +  - ]:           1 :     peerLogic->InitializeNode(*nodes[0], NODE_NETWORK);
     333         [ +  - ]:           1 :     nodes[0]->fSuccessfullyConnected = true;
     334         [ +  - ]:           1 :     connman->AddTestNode(*nodes[0]);
     335         [ +  - ]:           1 :     peerLogic->UnitTestMisbehaving(nodes[0]->GetId()); // Should be discouraged
     336   [ +  -  +  -  :           2 :     BOOST_CHECK(peerLogic->SendMessages(nodes[0]));
             +  -  +  - ]
     337                 :             : 
     338   [ +  -  +  -  :           2 :     BOOST_CHECK(banman->IsDiscouraged(addr[0]));
             +  -  +  - ]
     339   [ +  -  +  -  :           2 :     BOOST_CHECK(nodes[0]->fDisconnect);
                   +  - ]
     340   [ +  -  +  -  :           2 :     BOOST_CHECK(!banman->IsDiscouraged(other_addr)); // Different address, not discouraged
             +  -  +  - ]
     341                 :             : 
     342                 :           1 :     nodes[1] = new CNode{id++,
     343                 :             :                          /*sock=*/nullptr,
     344         [ +  - ]:           1 :                          addr[1],
     345                 :             :                          /*nKeyedNetGroupIn=*/1,
     346                 :             :                          /*nLocalHostNonceIn=*/1,
     347   [ +  -  -  + ]:           2 :                          CAddress(),
     348                 :             :                          /*addrNameIn=*/"",
     349                 :             :                          ConnectionType::INBOUND,
     350   [ +  -  +  -  :           2 :                          /*inbound_onion=*/false};
                   +  - ]
     351         [ +  - ]:           1 :     nodes[1]->SetCommonVersion(PROTOCOL_VERSION);
     352         [ +  - ]:           1 :     peerLogic->InitializeNode(*nodes[1], NODE_NETWORK);
     353         [ +  - ]:           1 :     nodes[1]->fSuccessfullyConnected = true;
     354         [ +  - ]:           1 :     connman->AddTestNode(*nodes[1]);
     355   [ +  -  +  -  :           2 :     BOOST_CHECK(peerLogic->SendMessages(nodes[1]));
             +  -  +  - ]
     356                 :             :     // [0] is still discouraged/disconnected.
     357   [ +  -  +  -  :           2 :     BOOST_CHECK(banman->IsDiscouraged(addr[0]));
             +  -  +  - ]
     358   [ +  -  +  -  :           2 :     BOOST_CHECK(nodes[0]->fDisconnect);
                   +  - ]
     359                 :             :     // [1] is not discouraged/disconnected yet.
     360   [ +  -  +  -  :           2 :     BOOST_CHECK(!banman->IsDiscouraged(addr[1]));
             +  -  +  - ]
     361   [ +  -  +  -  :           2 :     BOOST_CHECK(!nodes[1]->fDisconnect);
                   +  - ]
     362         [ +  - ]:           1 :     peerLogic->UnitTestMisbehaving(nodes[1]->GetId());
     363   [ +  -  +  -  :           2 :     BOOST_CHECK(peerLogic->SendMessages(nodes[1]));
             +  -  +  - ]
     364                 :             :     // Expect both [0] and [1] to be discouraged/disconnected now.
     365   [ +  -  +  -  :           2 :     BOOST_CHECK(banman->IsDiscouraged(addr[0]));
             +  -  +  - ]
     366   [ +  -  +  -  :           2 :     BOOST_CHECK(nodes[0]->fDisconnect);
                   +  - ]
     367   [ +  -  +  -  :           2 :     BOOST_CHECK(banman->IsDiscouraged(addr[1]));
             +  -  +  - ]
     368   [ +  -  +  -  :           2 :     BOOST_CHECK(nodes[1]->fDisconnect);
                   +  - ]
     369                 :             : 
     370                 :             :     // Make sure non-IP peers are discouraged and disconnected properly.
     371                 :             : 
     372                 :           1 :     nodes[2] = new CNode{id++,
     373                 :             :                          /*sock=*/nullptr,
     374         [ +  - ]:           1 :                          addr[2],
     375                 :             :                          /*nKeyedNetGroupIn=*/1,
     376                 :             :                          /*nLocalHostNonceIn=*/1,
     377   [ +  -  -  + ]:           2 :                          CAddress(),
     378                 :             :                          /*addrNameIn=*/"",
     379                 :             :                          ConnectionType::OUTBOUND_FULL_RELAY,
     380   [ +  -  +  -  :           2 :                          /*inbound_onion=*/false};
                   +  - ]
     381         [ +  - ]:           1 :     nodes[2]->SetCommonVersion(PROTOCOL_VERSION);
     382         [ +  - ]:           1 :     peerLogic->InitializeNode(*nodes[2], NODE_NETWORK);
     383         [ +  - ]:           1 :     nodes[2]->fSuccessfullyConnected = true;
     384         [ +  - ]:           1 :     connman->AddTestNode(*nodes[2]);
     385         [ +  - ]:           1 :     peerLogic->UnitTestMisbehaving(nodes[2]->GetId());
     386   [ +  -  +  -  :           2 :     BOOST_CHECK(peerLogic->SendMessages(nodes[2]));
             +  -  +  - ]
     387   [ +  -  +  -  :           2 :     BOOST_CHECK(banman->IsDiscouraged(addr[0]));
             +  -  +  - ]
     388   [ +  -  +  -  :           2 :     BOOST_CHECK(banman->IsDiscouraged(addr[1]));
             +  -  +  - ]
     389   [ +  -  +  -  :           2 :     BOOST_CHECK(banman->IsDiscouraged(addr[2]));
             +  -  +  - ]
     390   [ +  -  +  -  :           2 :     BOOST_CHECK(nodes[0]->fDisconnect);
                   +  - ]
     391   [ +  -  +  -  :           2 :     BOOST_CHECK(nodes[1]->fDisconnect);
                   +  - ]
     392   [ +  -  +  - ]:           2 :     BOOST_CHECK(nodes[2]->fDisconnect);
     393                 :             : 
     394         [ +  + ]:           4 :     for (CNode* node : nodes) {
     395         [ +  - ]:           3 :         peerLogic->FinalizeNode(*node);
     396                 :             :     }
     397         [ +  - ]:           1 :     connman->ClearTestNodes();
     398   [ +  -  +  -  :           6 : }
             +  -  +  - ]
     399                 :             : 
     400   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(DoS_bantime)
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     401                 :             : {
     402                 :           1 :     LOCK(NetEventsInterface::g_msgproc_mutex);
     403                 :             : 
     404   [ +  -  +  -  :           3 :     auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
                   +  - ]
     405   [ +  -  +  - ]:           1 :     auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params());
     406         [ +  - ]:           1 :     auto peerLogic = PeerManager::make(*connman, *m_node.addrman, banman.get(), *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
     407                 :             : 
     408         [ +  - ]:           1 :     banman->ClearBanned();
     409         [ +  - ]:           1 :     int64_t nStartTime = GetTime();
     410         [ +  - ]:           1 :     SetMockTime(nStartTime); // Overrides future calls to GetTime()
     411                 :             : 
     412         [ +  - ]:           1 :     CAddress addr(ip(0xa0b0c001), NODE_NONE);
     413                 :           1 :     NodeId id{0};
     414                 :           1 :     CNode dummyNode{id++,
     415                 :             :                     /*sock=*/nullptr,
     416                 :             :                     addr,
     417                 :             :                     /*nKeyedNetGroupIn=*/4,
     418                 :             :                     /*nLocalHostNonceIn=*/4,
     419   [ +  -  -  + ]:           2 :                     CAddress(),
     420                 :             :                     /*addrNameIn=*/"",
     421                 :             :                     ConnectionType::INBOUND,
     422   [ +  -  +  - ]:           2 :                     /*inbound_onion=*/false};
     423         [ +  - ]:           1 :     dummyNode.SetCommonVersion(PROTOCOL_VERSION);
     424         [ +  - ]:           1 :     peerLogic->InitializeNode(dummyNode, NODE_NETWORK);
     425         [ +  - ]:           1 :     dummyNode.fSuccessfullyConnected = true;
     426                 :             : 
     427         [ +  - ]:           1 :     peerLogic->UnitTestMisbehaving(dummyNode.GetId());
     428   [ +  -  +  -  :           2 :     BOOST_CHECK(peerLogic->SendMessages(&dummyNode));
             +  -  +  - ]
     429   [ +  -  +  -  :           2 :     BOOST_CHECK(banman->IsDiscouraged(addr));
             +  -  +  - ]
     430                 :             : 
     431         [ +  - ]:           1 :     peerLogic->FinalizeNode(dummyNode);
     432   [ +  -  +  - ]:           3 : }
     433                 :             : 
     434                 :             : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1