From ad4369fd833ff5396453b34aca15d03b64cac5d8 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Wed, 20 Jan 2021 11:26:43 +0100 Subject: [PATCH] merge bitcoin#21571: make sure non-IP peers get discouraged and disconnected --- src/test/denialofservice_tests.cpp | 143 +++++++++++++++++++---------- 1 file changed, 97 insertions(+), 46 deletions(-) diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index e3f9d71039..457106d0f5 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -230,66 +230,117 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) { const CChainParams& chainparams = Params(); auto banman = std::make_unique(m_args.GetDataDirPath() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME); - auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman); + auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman); auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, *m_node.govman, *m_node.sporkman, /* mn_activeman = */ nullptr, m_node.dmnman, m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); + CNetAddr tor_netaddr; + BOOST_REQUIRE( + tor_netaddr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion")); + const CService tor_service{tor_netaddr, Params().GetDefaultPort()}; + + const std::array addr{CAddress{ip(0xa0b0c001), NODE_NONE}, + CAddress{ip(0xa0b0c002), NODE_NONE}, + CAddress{tor_service, NODE_NONE}}; + + const CNetAddr other_addr{ip(0xa0b0ff01)}; // Not any of addr[]. + + std::array nodes; + banman->ClearBanned(); - CAddress addr1(ip(0xa0b0c001), NODE_NONE); - CNode dummyNode1{id++, - NODE_NETWORK, - /*sock=*/nullptr, - addr1, - /*nKeyedNetGroupIn=*/0, - /*nLocalHostNonceIn=*/0, - CAddress(), - /*addrNameIn=*/"", - ConnectionType::INBOUND, - /*inbound_onion=*/false}; - dummyNode1.SetCommonVersion(PROTOCOL_VERSION); - peerLogic->InitializeNode(&dummyNode1); - dummyNode1.fSuccessfullyConnected = true; - peerLogic->Misbehaving(dummyNode1.GetId(), DISCOURAGEMENT_THRESHOLD); // Should be discouraged + nodes[0] = new CNode{id++, + NODE_NETWORK, + /*sock=*/nullptr, + addr[0], + /*nKeyedNetGroupIn=*/0, + /*nLocalHostNonceIn=*/0, + CAddress(), + /*addrNameIn=*/"", + ConnectionType::INBOUND, + /*inbound_onion=*/false}; + nodes[0]->SetCommonVersion(PROTOCOL_VERSION); + peerLogic->InitializeNode(nodes[0]); + nodes[0]->fSuccessfullyConnected = true; + connman->AddTestNode(*nodes[0]); + peerLogic->Misbehaving(nodes[0]->GetId(), DISCOURAGEMENT_THRESHOLD); // Should be discouraged { - LOCK(dummyNode1.cs_sendProcessing); - BOOST_CHECK(peerLogic->SendMessages(&dummyNode1)); + LOCK(nodes[0]->cs_sendProcessing); + BOOST_CHECK(peerLogic->SendMessages(nodes[0])); } - BOOST_CHECK(banman->IsDiscouraged(addr1)); - BOOST_CHECK(!banman->IsDiscouraged(ip(0xa0b0c001|0x0000ff00))); // Different IP, not discouraged + BOOST_CHECK(banman->IsDiscouraged(addr[0])); + BOOST_CHECK(nodes[0]->fDisconnect); + BOOST_CHECK(!banman->IsDiscouraged(other_addr)); // Different address, not discouraged - CAddress addr2(ip(0xa0b0c002), NODE_NONE); - CNode dummyNode2{id++, - NODE_NETWORK, - /*sock=*/nullptr, - addr2, - /*nKeyedNetGroupIn=*/1, - /*nLocalHostNonceIn=*/1, - CAddress(), - /*pszDest=*/"", - ConnectionType::INBOUND, - /*inbound_onion=*/false}; - dummyNode2.SetCommonVersion(PROTOCOL_VERSION); - peerLogic->InitializeNode(&dummyNode2); - dummyNode2.fSuccessfullyConnected = true; - peerLogic->Misbehaving(dummyNode2.GetId(), DISCOURAGEMENT_THRESHOLD - 1); + nodes[1] = new CNode{id++, + NODE_NETWORK, + /*sock=*/nullptr, + addr[1], + /*nKeyedNetGroupIn=*/1, + /*nLocalHostNonceIn=*/1, + CAddress(), + /*pszDest=*/"", + ConnectionType::INBOUND, + /*inbound_onion=*/false}; + nodes[1]->SetCommonVersion(PROTOCOL_VERSION); + peerLogic->InitializeNode(nodes[1]); + nodes[1]->fSuccessfullyConnected = true; + connman->AddTestNode(*nodes[1]); + peerLogic->Misbehaving(nodes[1]->GetId(), DISCOURAGEMENT_THRESHOLD - 1); { - LOCK(dummyNode2.cs_sendProcessing); - BOOST_CHECK(peerLogic->SendMessages(&dummyNode2)); + LOCK(nodes[1]->cs_sendProcessing); + BOOST_CHECK(peerLogic->SendMessages(nodes[1])); } - BOOST_CHECK(!banman->IsDiscouraged(addr2)); // 2 not discouraged yet... - BOOST_CHECK(banman->IsDiscouraged(addr1)); // ... but 1 still should be - peerLogic->Misbehaving(dummyNode2.GetId(), 1); // 2 reaches discouragement threshold + // [0] is still discouraged/disconnected. + BOOST_CHECK(banman->IsDiscouraged(addr[0])); + BOOST_CHECK(nodes[0]->fDisconnect); + // [1] is not discouraged/disconnected yet. + BOOST_CHECK(!banman->IsDiscouraged(addr[1])); + BOOST_CHECK(!nodes[1]->fDisconnect); + peerLogic->Misbehaving(nodes[1]->GetId(), 1); // [1] reaches discouragement threshold { - LOCK(dummyNode2.cs_sendProcessing); - BOOST_CHECK(peerLogic->SendMessages(&dummyNode2)); + LOCK(nodes[1]->cs_sendProcessing); + BOOST_CHECK(peerLogic->SendMessages(nodes[1])); } - BOOST_CHECK(banman->IsDiscouraged(addr1)); // Expect both 1 and 2 - BOOST_CHECK(banman->IsDiscouraged(addr2)); // to be discouraged now + // Expect both [0] and [1] to be discouraged/disconnected now. + BOOST_CHECK(banman->IsDiscouraged(addr[0])); + BOOST_CHECK(nodes[0]->fDisconnect); + BOOST_CHECK(banman->IsDiscouraged(addr[1])); + BOOST_CHECK(nodes[1]->fDisconnect); - peerLogic->FinalizeNode(dummyNode1); - peerLogic->FinalizeNode(dummyNode2); + // Make sure non-IP peers are discouraged and disconnected properly. + + nodes[2] = new CNode{id++, + NODE_NETWORK, + /*sock=*/nullptr, + addr[2], + /*nKeyedNetGroupIn=*/1, + /*nLocalHostNonceIn=*/1, + CAddress(), + /*pszDest=*/"", + ConnectionType::OUTBOUND_FULL_RELAY, + /*inbound_onion=*/false}; + nodes[2]->SetCommonVersion(PROTOCOL_VERSION); + peerLogic->InitializeNode(nodes[2]); + nodes[2]->fSuccessfullyConnected = true; + connman->AddTestNode(*nodes[2]); + peerLogic->Misbehaving(nodes[2]->GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ ""); + { + LOCK(nodes[2]->cs_sendProcessing); + BOOST_CHECK(peerLogic->SendMessages(nodes[2])); + } + BOOST_CHECK(banman->IsDiscouraged(addr[0])); + BOOST_CHECK(banman->IsDiscouraged(addr[1])); + BOOST_CHECK(banman->IsDiscouraged(addr[2])); + BOOST_CHECK(nodes[0]->fDisconnect); + BOOST_CHECK(nodes[1]->fDisconnect); + BOOST_CHECK(nodes[2]->fDisconnect); + + for (CNode* node : nodes) { + peerLogic->FinalizeNode(*node); + } + connman->ClearTestNodes(); } BOOST_AUTO_TEST_CASE(DoS_bantime)