mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-13 07:28:59 +01:00
Make AddrMan support multiple ports per IP
This commit is contained in:
@@ -89,7 +89,7 @@ public:
|
||||
deterministic = makeDeterministic;
|
||||
}
|
||||
|
||||
AddrInfo* Find(const CNetAddr& addr, int* pnId = nullptr)
|
||||
AddrInfo* Find(const CService& addr, int* pnId = nullptr)
|
||||
{
|
||||
LOCK(m_impl->cs);
|
||||
return m_impl->Find(addr, pnId);
|
||||
@@ -222,15 +222,15 @@ BOOST_AUTO_TEST_CASE(addrman_ports)
|
||||
BOOST_CHECK_EQUAL(addrman.size(), 1U);
|
||||
|
||||
CService addr1_port = ResolveService("250.1.1.1", 8334);
|
||||
BOOST_CHECK(!addrman.Add({CAddress(addr1_port, NODE_NONE)}, source));
|
||||
BOOST_CHECK_EQUAL(addrman.size(), 1U);
|
||||
BOOST_CHECK(addrman.Add({CAddress(addr1_port, NODE_NONE)}, source));
|
||||
BOOST_CHECK_EQUAL(addrman.size(), 2U);
|
||||
auto addr_ret2 = addrman.Select().first;
|
||||
BOOST_CHECK_EQUAL(addr_ret2.ToString(), "250.1.1.1:8333");
|
||||
BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333" || addr_ret2.ToString() == "250.1.1.1:8334");
|
||||
|
||||
// Test: Add same IP but diff port to tried table, it doesn't get added.
|
||||
// Perhaps this is not ideal behavior but it is the current behavior.
|
||||
// Test: Add same IP but diff port to tried table; this converts the entry with
|
||||
// the specified port to tried, but not the other.
|
||||
addrman.Good(CAddress(addr1_port, NODE_NONE));
|
||||
BOOST_CHECK_EQUAL(addrman.size(), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman.size(), 2U);
|
||||
bool newOnly = true;
|
||||
auto addr_ret3 = addrman.Select(newOnly).first;
|
||||
BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333");
|
||||
@@ -369,18 +369,18 @@ BOOST_AUTO_TEST_CASE(addrman_find)
|
||||
CNetAddr source2 = ResolveIP("250.1.2.2");
|
||||
|
||||
BOOST_CHECK(addrman.Add({addr1}, source1));
|
||||
BOOST_CHECK(!addrman.Add({addr2}, source2));
|
||||
BOOST_CHECK(addrman.Add({addr2}, source2));
|
||||
BOOST_CHECK(addrman.Add({addr3}, source1));
|
||||
|
||||
// Test: ensure Find returns an IP matching what we searched on.
|
||||
// Test: ensure Find returns an IP/port matching what we searched on.
|
||||
AddrInfo* info1 = addrman.Find(addr1);
|
||||
BOOST_REQUIRE(info1);
|
||||
BOOST_CHECK_EQUAL(info1->ToString(), "250.1.2.1:8333");
|
||||
|
||||
// Test 18; Find does not discriminate by port number.
|
||||
// Test; Find discriminates by port number.
|
||||
AddrInfo* info2 = addrman.Find(addr2);
|
||||
BOOST_REQUIRE(info2);
|
||||
BOOST_CHECK_EQUAL(info2->ToString(), info1->ToString());
|
||||
BOOST_CHECK_EQUAL(info2->ToString(), "250.1.2.1:9999");
|
||||
|
||||
// Test: Find returns another IP matching what we searched on.
|
||||
AddrInfo* info3 = addrman.Find(addr3);
|
||||
|
||||
@@ -137,24 +137,29 @@ public:
|
||||
// Check that all values in `mapInfo` are equal to all values in `other.mapInfo`.
|
||||
// Keys may be different.
|
||||
|
||||
using AddrInfoHasher = std::function<size_t(const AddrInfo&)>;
|
||||
using AddrInfoEq = std::function<bool(const AddrInfo&, const AddrInfo&)>;
|
||||
|
||||
CNetAddrHash netaddr_hasher;
|
||||
|
||||
AddrInfoHasher addrinfo_hasher = [&netaddr_hasher](const AddrInfo& a) {
|
||||
return netaddr_hasher(static_cast<CNetAddr>(a)) ^ netaddr_hasher(a.source) ^
|
||||
a.nLastSuccess ^ a.nAttempts ^ a.nRefCount ^ a.fInTried;
|
||||
auto addrinfo_hasher = [](const AddrInfo& a) {
|
||||
CSipHasher hasher(0, 0);
|
||||
auto addr_key = a.GetKey();
|
||||
auto source_key = a.source.GetAddrBytes();
|
||||
hasher.Write(a.nLastSuccess);
|
||||
hasher.Write(a.nAttempts);
|
||||
hasher.Write(a.nRefCount);
|
||||
hasher.Write(a.fInTried);
|
||||
hasher.Write(a.GetNetwork());
|
||||
hasher.Write(a.source.GetNetwork());
|
||||
hasher.Write(addr_key.size());
|
||||
hasher.Write(source_key.size());
|
||||
hasher.Write(addr_key.data(), addr_key.size());
|
||||
hasher.Write(source_key.data(), source_key.size());
|
||||
return (size_t)hasher.Finalize();
|
||||
};
|
||||
|
||||
AddrInfoEq addrinfo_eq = [](const AddrInfo& lhs, const AddrInfo& rhs) {
|
||||
return static_cast<CNetAddr>(lhs) == static_cast<CNetAddr>(rhs) &&
|
||||
lhs.source == rhs.source && lhs.nLastSuccess == rhs.nLastSuccess &&
|
||||
lhs.nAttempts == rhs.nAttempts && lhs.nRefCount == rhs.nRefCount &&
|
||||
lhs.fInTried == rhs.fInTried;
|
||||
auto addrinfo_eq = [](const AddrInfo& lhs, const AddrInfo& rhs) {
|
||||
return std::tie(static_cast<const CService&>(lhs), lhs.source, lhs.nLastSuccess, lhs.nAttempts, lhs.nRefCount, lhs.fInTried) ==
|
||||
std::tie(static_cast<const CService&>(rhs), rhs.source, rhs.nLastSuccess, rhs.nAttempts, rhs.nRefCount, rhs.fInTried);
|
||||
};
|
||||
|
||||
using Addresses = std::unordered_set<AddrInfo, AddrInfoHasher, AddrInfoEq>;
|
||||
using Addresses = std::unordered_set<AddrInfo, decltype(addrinfo_hasher), decltype(addrinfo_eq)>;
|
||||
|
||||
const size_t num_addresses{m_impl->mapInfo.size()};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user