merge bitcoin#21571: make sure non-IP peers get discouraged and disconnected

This commit is contained in:
Kittywhiskers Van Gogh 2021-01-20 11:26:43 +01:00
parent e4b22a6d2a
commit ad4369fd83
No known key found for this signature in database
GPG Key ID: 30CD0C065E5C4AAD

View File

@ -230,66 +230,117 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
{ {
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
auto banman = std::make_unique<BanMan>(m_args.GetDataDirPath() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto banman = std::make_unique<BanMan>(m_args.GetDataDirPath() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman); auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman);
auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.scheduler, 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.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.govman, *m_node.sporkman, /* mn_activeman = */ nullptr, m_node.dmnman,
m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); 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<CAddress, 3> 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<CNode*, 3> nodes;
banman->ClearBanned(); banman->ClearBanned();
CAddress addr1(ip(0xa0b0c001), NODE_NONE); nodes[0] = new CNode{id++,
CNode dummyNode1{id++, NODE_NETWORK,
NODE_NETWORK, /*sock=*/nullptr,
/*sock=*/nullptr, addr[0],
addr1, /*nKeyedNetGroupIn=*/0,
/*nKeyedNetGroupIn=*/0, /*nLocalHostNonceIn=*/0,
/*nLocalHostNonceIn=*/0, CAddress(),
CAddress(), /*addrNameIn=*/"",
/*addrNameIn=*/"", ConnectionType::INBOUND,
ConnectionType::INBOUND, /*inbound_onion=*/false};
/*inbound_onion=*/false}; nodes[0]->SetCommonVersion(PROTOCOL_VERSION);
dummyNode1.SetCommonVersion(PROTOCOL_VERSION); peerLogic->InitializeNode(nodes[0]);
peerLogic->InitializeNode(&dummyNode1); nodes[0]->fSuccessfullyConnected = true;
dummyNode1.fSuccessfullyConnected = true; connman->AddTestNode(*nodes[0]);
peerLogic->Misbehaving(dummyNode1.GetId(), DISCOURAGEMENT_THRESHOLD); // Should be discouraged peerLogic->Misbehaving(nodes[0]->GetId(), DISCOURAGEMENT_THRESHOLD); // Should be discouraged
{ {
LOCK(dummyNode1.cs_sendProcessing); LOCK(nodes[0]->cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode1)); BOOST_CHECK(peerLogic->SendMessages(nodes[0]));
} }
BOOST_CHECK(banman->IsDiscouraged(addr1)); BOOST_CHECK(banman->IsDiscouraged(addr[0]));
BOOST_CHECK(!banman->IsDiscouraged(ip(0xa0b0c001|0x0000ff00))); // Different IP, not discouraged BOOST_CHECK(nodes[0]->fDisconnect);
BOOST_CHECK(!banman->IsDiscouraged(other_addr)); // Different address, not discouraged
CAddress addr2(ip(0xa0b0c002), NODE_NONE); nodes[1] = new CNode{id++,
CNode dummyNode2{id++, NODE_NETWORK,
NODE_NETWORK, /*sock=*/nullptr,
/*sock=*/nullptr, addr[1],
addr2, /*nKeyedNetGroupIn=*/1,
/*nKeyedNetGroupIn=*/1, /*nLocalHostNonceIn=*/1,
/*nLocalHostNonceIn=*/1, CAddress(),
CAddress(), /*pszDest=*/"",
/*pszDest=*/"", ConnectionType::INBOUND,
ConnectionType::INBOUND, /*inbound_onion=*/false};
/*inbound_onion=*/false}; nodes[1]->SetCommonVersion(PROTOCOL_VERSION);
dummyNode2.SetCommonVersion(PROTOCOL_VERSION); peerLogic->InitializeNode(nodes[1]);
peerLogic->InitializeNode(&dummyNode2); nodes[1]->fSuccessfullyConnected = true;
dummyNode2.fSuccessfullyConnected = true; connman->AddTestNode(*nodes[1]);
peerLogic->Misbehaving(dummyNode2.GetId(), DISCOURAGEMENT_THRESHOLD - 1); peerLogic->Misbehaving(nodes[1]->GetId(), DISCOURAGEMENT_THRESHOLD - 1);
{ {
LOCK(dummyNode2.cs_sendProcessing); LOCK(nodes[1]->cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode2)); BOOST_CHECK(peerLogic->SendMessages(nodes[1]));
} }
BOOST_CHECK(!banman->IsDiscouraged(addr2)); // 2 not discouraged yet... // [0] is still discouraged/disconnected.
BOOST_CHECK(banman->IsDiscouraged(addr1)); // ... but 1 still should be BOOST_CHECK(banman->IsDiscouraged(addr[0]));
peerLogic->Misbehaving(dummyNode2.GetId(), 1); // 2 reaches discouragement threshold 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); LOCK(nodes[1]->cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode2)); BOOST_CHECK(peerLogic->SendMessages(nodes[1]));
} }
BOOST_CHECK(banman->IsDiscouraged(addr1)); // Expect both 1 and 2 // Expect both [0] and [1] to be discouraged/disconnected now.
BOOST_CHECK(banman->IsDiscouraged(addr2)); // to be discouraged 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); // Make sure non-IP peers are discouraged and disconnected properly.
peerLogic->FinalizeNode(dummyNode2);
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) BOOST_AUTO_TEST_CASE(DoS_bantime)