mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-09 12:50:18 +02:00
[netgroupman] Add GetMappedAS() and GetGroup()
These currently call through to the CNetAddr methods. The logic will be moved in a future commit.
This commit is contained in:
parent
19431560e3
commit
6b2268162e
@ -43,17 +43,17 @@ static constexpr size_t ADDRMAN_SET_TRIED_COLLISION_SIZE{10};
|
||||
/** The maximum time we'll spend trying to resolve a tried table collision, in seconds */
|
||||
static constexpr int64_t ADDRMAN_TEST_WINDOW{40*60}; // 40 minutes
|
||||
|
||||
int AddrInfo::GetTriedBucket(const uint256& nKey, const std::vector<bool>& asmap) const
|
||||
int AddrInfo::GetTriedBucket(const uint256& nKey, const NetGroupManager& netgroupman) const
|
||||
{
|
||||
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey()).GetCheapHash();
|
||||
uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup(asmap) << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP)).GetCheapHash();
|
||||
uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << netgroupman.GetGroup(*this) << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP)).GetCheapHash();
|
||||
return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
|
||||
}
|
||||
|
||||
int AddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src, const std::vector<bool>& asmap) const
|
||||
int AddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src, const NetGroupManager& netgroupman) const
|
||||
{
|
||||
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup(asmap);
|
||||
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup(asmap) << vchSourceGroupKey).GetCheapHash();
|
||||
std::vector<unsigned char> vchSourceGroupKey = netgroupman.GetGroup(src);
|
||||
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << netgroupman.GetGroup(*this) << vchSourceGroupKey).GetCheapHash();
|
||||
uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP)).GetCheapHash();
|
||||
return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
|
||||
}
|
||||
@ -298,7 +298,7 @@ void AddrManImpl::Unserialize(Stream& s_)
|
||||
for (int n = 0; n < nTried; n++) {
|
||||
AddrInfo info;
|
||||
s >> info;
|
||||
int nKBucket = info.GetTriedBucket(nKey, m_netgroupman.GetAsmap());
|
||||
int nKBucket = info.GetTriedBucket(nKey, m_netgroupman);
|
||||
int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
|
||||
if (info.IsValid()
|
||||
&& vvTried[nKBucket][nKBucketPos] == -1) {
|
||||
@ -371,7 +371,7 @@ void AddrManImpl::Unserialize(Stream& s_)
|
||||
} else {
|
||||
// In case the new table data cannot be used (bucket count wrong or new asmap),
|
||||
// try to give them a reference based on their primary source address.
|
||||
bucket = info.GetNewBucket(nKey, m_netgroupman.GetAsmap());
|
||||
bucket = info.GetNewBucket(nKey, m_netgroupman);
|
||||
bucket_position = info.GetBucketPosition(nKey, true, bucket);
|
||||
if (vvNew[bucket][bucket_position] == -1) {
|
||||
vvNew[bucket][bucket_position] = entry_index;
|
||||
@ -495,7 +495,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId)
|
||||
AssertLockHeld(cs);
|
||||
|
||||
// remove the entry from all new buckets
|
||||
const int start_bucket{info.GetNewBucket(nKey, m_netgroupman.GetAsmap())};
|
||||
const int start_bucket{info.GetNewBucket(nKey, m_netgroupman)};
|
||||
for (int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; ++n) {
|
||||
const int bucket{(start_bucket + n) % ADDRMAN_NEW_BUCKET_COUNT};
|
||||
const int pos{info.GetBucketPosition(nKey, true, bucket)};
|
||||
@ -510,7 +510,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId)
|
||||
assert(info.nRefCount == 0);
|
||||
|
||||
// which tried bucket to move the entry to
|
||||
int nKBucket = info.GetTriedBucket(nKey, m_netgroupman.GetAsmap());
|
||||
int nKBucket = info.GetTriedBucket(nKey, m_netgroupman);
|
||||
int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
|
||||
|
||||
// first make space to add it (the existing tried entry there is moved to new, deleting whatever is there).
|
||||
@ -526,7 +526,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId)
|
||||
nTried--;
|
||||
|
||||
// find which new bucket it belongs to
|
||||
int nUBucket = infoOld.GetNewBucket(nKey, m_netgroupman.GetAsmap());
|
||||
int nUBucket = infoOld.GetNewBucket(nKey, m_netgroupman);
|
||||
int nUBucketPos = infoOld.GetBucketPosition(nKey, true, nUBucket);
|
||||
ClearNew(nUBucket, nUBucketPos);
|
||||
assert(vvNew[nUBucket][nUBucketPos] == -1);
|
||||
@ -594,7 +594,7 @@ bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, int64_
|
||||
nNew++;
|
||||
}
|
||||
|
||||
int nUBucket = pinfo->GetNewBucket(nKey, source, m_netgroupman.GetAsmap());
|
||||
int nUBucket = pinfo->GetNewBucket(nKey, source, m_netgroupman);
|
||||
int nUBucketPos = pinfo->GetBucketPosition(nKey, true, nUBucket);
|
||||
bool fInsert = vvNew[nUBucket][nUBucketPos] == -1;
|
||||
if (vvNew[nUBucket][nUBucketPos] != nId) {
|
||||
@ -650,7 +650,7 @@ bool AddrManImpl::Good_(const CService& addr, bool test_before_evict, int64_t nT
|
||||
|
||||
|
||||
// which tried bucket to move the entry to
|
||||
int tried_bucket = info.GetTriedBucket(nKey, m_netgroupman.GetAsmap());
|
||||
int tried_bucket = info.GetTriedBucket(nKey, m_netgroupman);
|
||||
int tried_bucket_pos = info.GetBucketPosition(nKey, false, tried_bucket);
|
||||
|
||||
// Will moving this address into tried evict another entry?
|
||||
@ -863,7 +863,7 @@ void AddrManImpl::ResolveCollisions_()
|
||||
AddrInfo& info_new = mapInfo[id_new];
|
||||
|
||||
// Which tried bucket to move the entry to.
|
||||
int tried_bucket = info_new.GetTriedBucket(nKey, m_netgroupman.GetAsmap());
|
||||
int tried_bucket = info_new.GetTriedBucket(nKey, m_netgroupman);
|
||||
int tried_bucket_pos = info_new.GetBucketPosition(nKey, false, tried_bucket);
|
||||
if (!info_new.IsValid()) { // id_new may no longer map to a valid address
|
||||
erase_collision = true;
|
||||
@ -929,7 +929,7 @@ std::pair<CAddress, int64_t> AddrManImpl::SelectTriedCollision_()
|
||||
const AddrInfo& newInfo = mapInfo[id_new];
|
||||
|
||||
// which tried bucket to move the entry to
|
||||
int tried_bucket = newInfo.GetTriedBucket(nKey, m_netgroupman.GetAsmap());
|
||||
int tried_bucket = newInfo.GetTriedBucket(nKey, m_netgroupman);
|
||||
int tried_bucket_pos = newInfo.GetBucketPosition(nKey, false, tried_bucket);
|
||||
|
||||
const AddrInfo& info_old = mapInfo[vvTried[tried_bucket][tried_bucket_pos]];
|
||||
@ -945,13 +945,13 @@ std::optional<AddressPosition> AddrManImpl::FindAddressEntry_(const CAddress& ad
|
||||
if (!addr_info) return std::nullopt;
|
||||
|
||||
if(addr_info->fInTried) {
|
||||
int bucket{addr_info->GetTriedBucket(nKey, m_netgroupman.GetAsmap())};
|
||||
int bucket{addr_info->GetTriedBucket(nKey, m_netgroupman)};
|
||||
return AddressPosition(/*tried_in=*/true,
|
||||
/*multiplicity_in=*/1,
|
||||
/*bucket_in=*/bucket,
|
||||
/*position_in=*/addr_info->GetBucketPosition(nKey, false, bucket));
|
||||
} else {
|
||||
int bucket{addr_info->GetNewBucket(nKey, m_netgroupman.GetAsmap())};
|
||||
int bucket{addr_info->GetNewBucket(nKey, m_netgroupman)};
|
||||
return AddressPosition(/*tried_in=*/false,
|
||||
/*multiplicity_in=*/addr_info->nRefCount,
|
||||
/*bucket_in=*/bucket,
|
||||
@ -1026,7 +1026,7 @@ int AddrManImpl::CheckAddrman() const
|
||||
if (!setTried.count(vvTried[n][i]))
|
||||
return -11;
|
||||
const auto it{mapInfo.find(vvTried[n][i])};
|
||||
if (it == mapInfo.end() || it->second.GetTriedBucket(nKey, m_netgroupman.GetAsmap()) != n) {
|
||||
if (it == mapInfo.end() || it->second.GetTriedBucket(nKey, m_netgroupman) != n) {
|
||||
return -17;
|
||||
}
|
||||
if (it->second.GetBucketPosition(nKey, false, n) != i) {
|
||||
|
@ -76,15 +76,15 @@ public:
|
||||
}
|
||||
|
||||
//! Calculate in which "tried" bucket this entry belongs
|
||||
int GetTriedBucket(const uint256 &nKey, const std::vector<bool> &asmap) const;
|
||||
int GetTriedBucket(const uint256& nKey, const NetGroupManager& netgroupman) const;
|
||||
|
||||
//! Calculate in which "new" bucket this entry belongs, given a certain source
|
||||
int GetNewBucket(const uint256 &nKey, const CNetAddr& src, const std::vector<bool> &asmap) const;
|
||||
int GetNewBucket(const uint256& nKey, const CNetAddr& src, const NetGroupManager& netgroupman) const;
|
||||
|
||||
//! Calculate in which "new" bucket this entry belongs, using its default source
|
||||
int GetNewBucket(const uint256 &nKey, const std::vector<bool> &asmap) const
|
||||
int GetNewBucket(const uint256& nKey, const NetGroupManager& netgroupman) const
|
||||
{
|
||||
return GetNewBucket(nKey, source, asmap);
|
||||
return GetNewBucket(nKey, source, netgroupman);
|
||||
}
|
||||
|
||||
//! Calculate in which position of a bucket to store this entry.
|
||||
|
12
src/net.cpp
12
src/net.cpp
@ -1997,7 +1997,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
||||
case ConnectionType::BLOCK_RELAY:
|
||||
case ConnectionType::ADDR_FETCH:
|
||||
case ConnectionType::FEELER:
|
||||
setConnected.insert(pnode->addr.GetGroup(m_netgroupman.GetAsmap()));
|
||||
setConnected.insert(m_netgroupman.GetGroup(pnode->addr));
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
}
|
||||
}
|
||||
@ -2071,7 +2071,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
||||
m_anchors.pop_back();
|
||||
if (!addr.IsValid() || IsLocal(addr) || !IsReachable(addr) ||
|
||||
!HasAllDesirableServiceFlags(addr.nServices) ||
|
||||
setConnected.count(addr.GetGroup(m_netgroupman.GetAsmap()))) continue;
|
||||
setConnected.count(m_netgroupman.GetGroup(addr))) continue;
|
||||
addrConnect = addr;
|
||||
LogPrint(BCLog::NET, "Trying to make an anchor connection to %s\n", addrConnect.ToString());
|
||||
break;
|
||||
@ -2112,7 +2112,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
||||
}
|
||||
|
||||
// Require outbound connections, other than feelers, to be to distinct network groups
|
||||
if (!fFeeler && setConnected.count(addr.GetGroup(m_netgroupman.GetAsmap()))) {
|
||||
if (!fFeeler && setConnected.count(m_netgroupman.GetGroup(addr))) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2863,7 +2863,7 @@ void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats) const
|
||||
for (CNode* pnode : m_nodes) {
|
||||
vstats.emplace_back();
|
||||
pnode->CopyStats(vstats.back());
|
||||
vstats.back().m_mapped_as = pnode->addr.GetMappedAS(m_netgroupman.GetAsmap());
|
||||
vstats.back().m_mapped_as = m_netgroupman.GetMappedAS(pnode->addr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3096,9 +3096,9 @@ CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const
|
||||
return CSipHasher(nSeed0, nSeed1).Write(id);
|
||||
}
|
||||
|
||||
uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad) const
|
||||
uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& address) const
|
||||
{
|
||||
std::vector<unsigned char> vchNetGroup(ad.GetGroup(m_netgroupman.GetAsmap()));
|
||||
std::vector<unsigned char> vchNetGroup(m_netgroupman.GetGroup(address));
|
||||
|
||||
return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup.data(), vchNetGroup.size()).Finalize();
|
||||
}
|
||||
|
@ -3,3 +3,13 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <netgroup.h>
|
||||
|
||||
std::vector<unsigned char> NetGroupManager::GetGroup(const CNetAddr& address) const
|
||||
{
|
||||
return address.GetGroup(m_asmap);
|
||||
}
|
||||
|
||||
uint32_t NetGroupManager::GetMappedAS(const CNetAddr& address) const
|
||||
{
|
||||
return address.GetMappedAS(m_asmap);
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef BITCOIN_NETGROUP_H
|
||||
#define BITCOIN_NETGROUP_H
|
||||
|
||||
#include <netaddress.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
@ -20,6 +22,10 @@ public:
|
||||
* exists, since the data is const. */
|
||||
const std::vector<bool>& GetAsmap() const { return m_asmap; }
|
||||
|
||||
std::vector<unsigned char> GetGroup(const CNetAddr& address) const;
|
||||
|
||||
uint32_t GetMappedAS(const CNetAddr& address) const;
|
||||
|
||||
private:
|
||||
/** Compressed IP->ASN mapping, loaded from a file when a node starts.
|
||||
*
|
||||
|
@ -357,27 +357,25 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket_legacy)
|
||||
uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
|
||||
uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();
|
||||
|
||||
std::vector<bool> asmap; // use /16
|
||||
|
||||
BOOST_CHECK_EQUAL(info1.GetTriedBucket(nKey1, asmap), 40);
|
||||
BOOST_CHECK_EQUAL(info1.GetTriedBucket(nKey1, EMPTY_NETGROUPMAN), 40);
|
||||
|
||||
// Test: Make sure key actually randomizes bucket placement. A fail on
|
||||
// this test could be a security issue.
|
||||
BOOST_CHECK(info1.GetTriedBucket(nKey1, asmap) != info1.GetTriedBucket(nKey2, asmap));
|
||||
BOOST_CHECK(info1.GetTriedBucket(nKey1, EMPTY_NETGROUPMAN) != info1.GetTriedBucket(nKey2, EMPTY_NETGROUPMAN));
|
||||
|
||||
// Test: Two addresses with same IP but different ports can map to
|
||||
// different buckets because they have different keys.
|
||||
AddrInfo info2 = AddrInfo(addr2, source1);
|
||||
|
||||
BOOST_CHECK(info1.GetKey() != info2.GetKey());
|
||||
BOOST_CHECK(info1.GetTriedBucket(nKey1, asmap) != info2.GetTriedBucket(nKey1, asmap));
|
||||
BOOST_CHECK(info1.GetTriedBucket(nKey1, EMPTY_NETGROUPMAN) != info2.GetTriedBucket(nKey1, EMPTY_NETGROUPMAN));
|
||||
|
||||
std::set<int> buckets;
|
||||
for (int i = 0; i < 255; i++) {
|
||||
AddrInfo infoi = AddrInfo(
|
||||
CAddress(ResolveService("250.1.1." + ToString(i)), NODE_NONE),
|
||||
ResolveIP("250.1.1." + ToString(i)));
|
||||
int bucket = infoi.GetTriedBucket(nKey1, asmap);
|
||||
int bucket = infoi.GetTriedBucket(nKey1, EMPTY_NETGROUPMAN);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test: IP addresses in the same /16 prefix should
|
||||
@ -389,7 +387,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket_legacy)
|
||||
AddrInfo infoj = AddrInfo(
|
||||
CAddress(ResolveService("250." + ToString(j) + ".1.1"), NODE_NONE),
|
||||
ResolveIP("250." + ToString(j) + ".1.1"));
|
||||
int bucket = infoj.GetTriedBucket(nKey1, asmap);
|
||||
int bucket = infoj.GetTriedBucket(nKey1, EMPTY_NETGROUPMAN);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test: IP addresses in the different /16 prefix should map to more than
|
||||
@ -409,27 +407,25 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket_legacy)
|
||||
uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
|
||||
uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();
|
||||
|
||||
std::vector<bool> asmap; // use /16
|
||||
|
||||
// Test: Make sure the buckets are what we expect
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, asmap), 786);
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, source1, asmap), 786);
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, EMPTY_NETGROUPMAN), 786);
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, source1, EMPTY_NETGROUPMAN), 786);
|
||||
|
||||
// Test: Make sure key actually randomizes bucket placement. A fail on
|
||||
// this test could be a security issue.
|
||||
BOOST_CHECK(info1.GetNewBucket(nKey1, asmap) != info1.GetNewBucket(nKey2, asmap));
|
||||
BOOST_CHECK(info1.GetNewBucket(nKey1, EMPTY_NETGROUPMAN) != info1.GetNewBucket(nKey2, EMPTY_NETGROUPMAN));
|
||||
|
||||
// Test: Ports should not affect bucket placement in the addr
|
||||
AddrInfo info2 = AddrInfo(addr2, source1);
|
||||
BOOST_CHECK(info1.GetKey() != info2.GetKey());
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, asmap), info2.GetNewBucket(nKey1, asmap));
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, EMPTY_NETGROUPMAN), info2.GetNewBucket(nKey1, EMPTY_NETGROUPMAN));
|
||||
|
||||
std::set<int> buckets;
|
||||
for (int i = 0; i < 255; i++) {
|
||||
AddrInfo infoi = AddrInfo(
|
||||
CAddress(ResolveService("250.1.1." + ToString(i)), NODE_NONE),
|
||||
ResolveIP("250.1.1." + ToString(i)));
|
||||
int bucket = infoi.GetNewBucket(nKey1, asmap);
|
||||
int bucket = infoi.GetNewBucket(nKey1, EMPTY_NETGROUPMAN);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test: IP addresses in the same group (\16 prefix for IPv4) should
|
||||
@ -442,7 +438,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket_legacy)
|
||||
ResolveService(
|
||||
ToString(250 + (j / 255)) + "." + ToString(j % 256) + ".1.1"), NODE_NONE),
|
||||
ResolveIP("251.4.1.1"));
|
||||
int bucket = infoj.GetNewBucket(nKey1, asmap);
|
||||
int bucket = infoj.GetNewBucket(nKey1, EMPTY_NETGROUPMAN);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test: IP addresses in the same source groups should map to NO MORE
|
||||
@ -454,7 +450,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket_legacy)
|
||||
AddrInfo infoj = AddrInfo(
|
||||
CAddress(ResolveService("250.1.1.1"), NODE_NONE),
|
||||
ResolveIP("250." + ToString(p) + ".1.1"));
|
||||
int bucket = infoj.GetNewBucket(nKey1, asmap);
|
||||
int bucket = infoj.GetNewBucket(nKey1, EMPTY_NETGROUPMAN);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test: IP addresses in the different source groups should map to MORE
|
||||
@ -475,6 +471,9 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket_legacy)
|
||||
// 101.8.0.0/16 AS8
|
||||
BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
|
||||
{
|
||||
std::vector<bool> asmap = FromBytes(asmap_raw, sizeof(asmap_raw) * 8);
|
||||
NetGroupManager ngm_asmap{asmap};
|
||||
|
||||
CAddress addr1 = CAddress(ResolveService("250.1.1.1", 8333), NODE_NONE);
|
||||
CAddress addr2 = CAddress(ResolveService("250.1.1.1", 9999), NODE_NONE);
|
||||
|
||||
@ -486,27 +485,25 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
|
||||
uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
|
||||
uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();
|
||||
|
||||
std::vector<bool> asmap = FromBytes(asmap_raw, sizeof(asmap_raw) * 8);
|
||||
|
||||
BOOST_CHECK_EQUAL(info1.GetTriedBucket(nKey1, asmap), 236);
|
||||
BOOST_CHECK_EQUAL(info1.GetTriedBucket(nKey1, ngm_asmap), 236);
|
||||
|
||||
// Test: Make sure key actually randomizes bucket placement. A fail on
|
||||
// this test could be a security issue.
|
||||
BOOST_CHECK(info1.GetTriedBucket(nKey1, asmap) != info1.GetTriedBucket(nKey2, asmap));
|
||||
BOOST_CHECK(info1.GetTriedBucket(nKey1, ngm_asmap) != info1.GetTriedBucket(nKey2, ngm_asmap));
|
||||
|
||||
// Test: Two addresses with same IP but different ports can map to
|
||||
// different buckets because they have different keys.
|
||||
AddrInfo info2 = AddrInfo(addr2, source1);
|
||||
|
||||
BOOST_CHECK(info1.GetKey() != info2.GetKey());
|
||||
BOOST_CHECK(info1.GetTriedBucket(nKey1, asmap) != info2.GetTriedBucket(nKey1, asmap));
|
||||
BOOST_CHECK(info1.GetTriedBucket(nKey1, ngm_asmap) != info2.GetTriedBucket(nKey1, ngm_asmap));
|
||||
|
||||
std::set<int> buckets;
|
||||
for (int j = 0; j < 255; j++) {
|
||||
AddrInfo infoj = AddrInfo(
|
||||
CAddress(ResolveService("101." + ToString(j) + ".1.1"), NODE_NONE),
|
||||
ResolveIP("101." + ToString(j) + ".1.1"));
|
||||
int bucket = infoj.GetTriedBucket(nKey1, asmap);
|
||||
int bucket = infoj.GetTriedBucket(nKey1, ngm_asmap);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test: IP addresses in the different /16 prefix MAY map to more than
|
||||
@ -518,7 +515,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
|
||||
AddrInfo infoj = AddrInfo(
|
||||
CAddress(ResolveService("250." + ToString(j) + ".1.1"), NODE_NONE),
|
||||
ResolveIP("250." + ToString(j) + ".1.1"));
|
||||
int bucket = infoj.GetTriedBucket(nKey1, asmap);
|
||||
int bucket = infoj.GetTriedBucket(nKey1, ngm_asmap);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test: IP addresses in the different /16 prefix MAY NOT map to more than
|
||||
@ -528,6 +525,9 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
|
||||
{
|
||||
std::vector<bool> asmap = FromBytes(asmap_raw, sizeof(asmap_raw) * 8);
|
||||
NetGroupManager ngm_asmap{asmap};
|
||||
|
||||
CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
|
||||
CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE);
|
||||
|
||||
@ -538,27 +538,25 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
|
||||
uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
|
||||
uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();
|
||||
|
||||
std::vector<bool> asmap = FromBytes(asmap_raw, sizeof(asmap_raw) * 8);
|
||||
|
||||
// Test: Make sure the buckets are what we expect
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, asmap), 795);
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, source1, asmap), 795);
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, ngm_asmap), 795);
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, source1, ngm_asmap), 795);
|
||||
|
||||
// Test: Make sure key actually randomizes bucket placement. A fail on
|
||||
// this test could be a security issue.
|
||||
BOOST_CHECK(info1.GetNewBucket(nKey1, asmap) != info1.GetNewBucket(nKey2, asmap));
|
||||
BOOST_CHECK(info1.GetNewBucket(nKey1, ngm_asmap) != info1.GetNewBucket(nKey2, ngm_asmap));
|
||||
|
||||
// Test: Ports should not affect bucket placement in the addr
|
||||
AddrInfo info2 = AddrInfo(addr2, source1);
|
||||
BOOST_CHECK(info1.GetKey() != info2.GetKey());
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, asmap), info2.GetNewBucket(nKey1, asmap));
|
||||
BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, ngm_asmap), info2.GetNewBucket(nKey1, ngm_asmap));
|
||||
|
||||
std::set<int> buckets;
|
||||
for (int i = 0; i < 255; i++) {
|
||||
AddrInfo infoi = AddrInfo(
|
||||
CAddress(ResolveService("250.1.1." + ToString(i)), NODE_NONE),
|
||||
ResolveIP("250.1.1." + ToString(i)));
|
||||
int bucket = infoi.GetNewBucket(nKey1, asmap);
|
||||
int bucket = infoi.GetNewBucket(nKey1, ngm_asmap);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test: IP addresses in the same /16 prefix
|
||||
@ -571,7 +569,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
|
||||
ResolveService(
|
||||
ToString(250 + (j / 255)) + "." + ToString(j % 256) + ".1.1"), NODE_NONE),
|
||||
ResolveIP("251.4.1.1"));
|
||||
int bucket = infoj.GetNewBucket(nKey1, asmap);
|
||||
int bucket = infoj.GetNewBucket(nKey1, ngm_asmap);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test: IP addresses in the same source /16 prefix should not map to more
|
||||
@ -583,7 +581,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
|
||||
AddrInfo infoj = AddrInfo(
|
||||
CAddress(ResolveService("250.1.1.1"), NODE_NONE),
|
||||
ResolveIP("101." + ToString(p) + ".1.1"));
|
||||
int bucket = infoj.GetNewBucket(nKey1, asmap);
|
||||
int bucket = infoj.GetNewBucket(nKey1, ngm_asmap);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test: IP addresses in the different source /16 prefixes usually map to MORE
|
||||
@ -595,7 +593,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
|
||||
AddrInfo infoj = AddrInfo(
|
||||
CAddress(ResolveService("250.1.1.1"), NODE_NONE),
|
||||
ResolveIP("250." + ToString(p) + ".1.1"));
|
||||
int bucket = infoj.GetNewBucket(nKey1, asmap);
|
||||
int bucket = infoj.GetNewBucket(nKey1, ngm_asmap);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test: IP addresses in the different source /16 prefixes sometimes map to NO MORE
|
||||
|
@ -3,6 +3,7 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <netaddress.h>
|
||||
#include <netgroup.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
#include <util/asmap.h>
|
||||
|
||||
@ -56,5 +57,6 @@ FUZZ_TARGET(asmap)
|
||||
memcpy(&ipv4, addr_data, addr_size);
|
||||
net_addr.SetIP(CNetAddr{ipv4});
|
||||
}
|
||||
(void)net_addr.GetMappedAS(asmap);
|
||||
NetGroupManager netgroupman{asmap};
|
||||
(void)netgroupman.GetMappedAS(net_addr);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <net_permissions.h>
|
||||
#include <netaddress.h>
|
||||
#include <netbase.h>
|
||||
#include <netgroup.h>
|
||||
#include <protocol.h>
|
||||
#include <serialize.h>
|
||||
#include <streams.h>
|
||||
@ -315,22 +316,22 @@ BOOST_AUTO_TEST_CASE(subnet_test)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(netbase_getgroup)
|
||||
{
|
||||
std::vector<bool> asmap; // use /16
|
||||
BOOST_CHECK(ResolveIP("127.0.0.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // Local -> !Routable()
|
||||
BOOST_CHECK(ResolveIP("257.0.0.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // !Valid -> !Routable()
|
||||
BOOST_CHECK(ResolveIP("10.0.0.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // RFC1918 -> !Routable()
|
||||
BOOST_CHECK(ResolveIP("169.254.1.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // RFC3927 -> !Routable()
|
||||
BOOST_CHECK(ResolveIP("1.2.3.4").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // IPv4
|
||||
BOOST_CHECK(ResolveIP("::FFFF:0:102:304").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC6145
|
||||
BOOST_CHECK(ResolveIP("64:FF9B::102:304").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC6052
|
||||
BOOST_CHECK(ResolveIP("2002:102:304:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC3964
|
||||
BOOST_CHECK(ResolveIP("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC4380
|
||||
BOOST_CHECK(ResolveIP("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 4, 112, 175})); //he.net
|
||||
BOOST_CHECK(ResolveIP("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 32, 1})); //IPv6
|
||||
NetGroupManager netgroupman{std::vector<bool>()}; // use /16
|
||||
BOOST_CHECK(netgroupman.GetGroup(ResolveIP("127.0.0.1")) == std::vector<unsigned char>({0})); // Local -> !Routable()
|
||||
BOOST_CHECK(netgroupman.GetGroup(ResolveIP("257.0.0.1")) == std::vector<unsigned char>({0})); // !Valid -> !Routable()
|
||||
BOOST_CHECK(netgroupman.GetGroup(ResolveIP("10.0.0.1")) == std::vector<unsigned char>({0})); // RFC1918 -> !Routable()
|
||||
BOOST_CHECK(netgroupman.GetGroup(ResolveIP("169.254.1.1")) == std::vector<unsigned char>({0})); // RFC3927 -> !Routable()
|
||||
BOOST_CHECK(netgroupman.GetGroup(ResolveIP("1.2.3.4")) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // IPv4
|
||||
BOOST_CHECK(netgroupman.GetGroup(ResolveIP("::FFFF:0:102:304")) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC6145
|
||||
BOOST_CHECK(netgroupman.GetGroup(ResolveIP("64:FF9B::102:304")) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC6052
|
||||
BOOST_CHECK(netgroupman.GetGroup(ResolveIP("2002:102:304:9999:9999:9999:9999:9999")) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC3964
|
||||
BOOST_CHECK(netgroupman.GetGroup(ResolveIP("2001:0:9999:9999:9999:9999:FEFD:FCFB")) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC4380
|
||||
BOOST_CHECK(netgroupman.GetGroup(ResolveIP("2001:470:abcd:9999:9999:9999:9999:9999")) == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 4, 112, 175})); //he.net
|
||||
BOOST_CHECK(netgroupman.GetGroup(ResolveIP("2001:2001:9999:9999:9999:9999:9999:9999")) == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 32, 1})); //IPv6
|
||||
|
||||
// baz.net sha256 hash: 12929400eb4607c4ac075f087167e75286b179c693eb059a01774b864e8fe505
|
||||
std::vector<unsigned char> internal_group = {NET_INTERNAL, 0x12, 0x92, 0x94, 0x00, 0xeb, 0x46, 0x07, 0xc4, 0xac, 0x07};
|
||||
BOOST_CHECK(CreateInternal("baz.net").GetGroup(asmap) == internal_group);
|
||||
BOOST_CHECK(netgroupman.GetGroup(CreateInternal("baz.net")) == internal_group);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(netbase_parsenetwork)
|
||||
|
Loading…
x
Reference in New Issue
Block a user