Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a7b9fd9
refactor: Use uint16_t instead of unsigned short
furszy Jun 2, 2021
d2a8baf
addrman.h: CAddrInfo inline members default values, plus several typo…
furszy Jun 2, 2021
e986ed0
CAddrMan::Deserialize handle corrupt serializations better.
pstratem Apr 24, 2016
8d01cbd
Add asmap utility which queries a mapping
naumenkogs Dec 18, 2019
fd51941
Tests: address placement should be deterministic by default
ReneNyffenegger Jul 13, 2017
718f1df
CAddrManTest: remove redundant MakeDeterministic call.
furszy Jun 2, 2021
4c3ae7d
Integrate ASN bucketing in Addrman and add tests
naumenkogs Jun 2, 2021
ce7aa15
scripted-diff: Replace NET_TOR with NET_ONION
wodry Jul 2, 2018
2fe5a05
Return mapped AS in RPC call getpeerinfo
naumenkogs Dec 24, 2019
cb698fb
Add extra logging of asmap use and bucketing
naumenkogs Jan 10, 2020
868a6ed
Avoid asmap copies in initialization
sipa Jan 29, 2020
9a28bc0
Mark asmap const in statistics code
sipa Jan 29, 2020
e527e04
Use ASNs for mapped IPv4 addresses correctly
sipa Jan 29, 2020
4290d3f
Make asmap Interpret tolerant of malicious map data
sipa Jan 31, 2020
de39fab
test: add feature_asmap functional tests
jonatack Dec 28, 2019
8c7bdbe
config: use default value in -asmap config
jonatack Jun 3, 2021
618b8d1
config: enable passing -asmap an absolute file path
jonatack Dec 29, 2019
6545656
config: separate the asmap finding and parsing checks
jonatack Dec 29, 2019
0c9efb8
test: add functional test for an empty, unparsable asmap
jonatack Dec 29, 2019
2fc1f37
logging: asmap logging and #include fixups
jonatack Dec 29, 2019
65cd143
net: extract conditional to bool CNetAddr::IsHeNet
jonatack Feb 5, 2020
672d9a2
init: move asmap code earlier in init process
jonatack Jun 3, 2021
16791f2
CMakeLists tests: add raw files generation.
furszy Jun 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ set(UTIL_SOURCES
./src/threadinterrupt.cpp
./src/arith_uint256.cpp
./src/uint256.cpp
./src/util/asmap.cpp
./src/util/threadnames.cpp
./src/util/blockstatecatcher.h
./src/util/system.cpp
Expand Down
File renamed without changes.
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ BITCOIN_CORE_H = \
guiinterfaceutil.h \
uint256.h \
undo.h \
util/asmap.h \
util/blockstatecatcher.h \
util/system.h \
util/macros.h \
Expand Down Expand Up @@ -561,6 +562,7 @@ libbitcoin_util_a_SOURCES = \
support/lockedpool.cpp \
sync.cpp \
threadinterrupt.cpp \
util/asmap.cpp \
uint256.cpp \
util/system.cpp \
utilmoneystr.cpp \
Expand Down
12 changes: 11 additions & 1 deletion src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ JSON_TEST_FILES = \
test/data/merkle_commitments_sapling.json \
test/data/sapling_key_components.json

RAW_TEST_FILES =
RAW_TEST_FILES = \
test/data/asmap.raw

GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)

Expand Down Expand Up @@ -423,3 +424,12 @@ check-local: check-sapling check-standard
echo "};};"; \
} > "$@.new" && mv -f "$@.new" "$@"
@echo "Generated $@"

%.raw.h: %.raw
@$(MKDIR_P) $(@D)
@{ \
echo "static unsigned const char $(*F)_raw[] = {" && \
$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' && \
echo "};"; \
} > "$@.new" && mv -f "$@.new" "$@"
@echo "Generated $@"
4 changes: 3 additions & 1 deletion src/addrdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "tinyformat.h"
#include "util/system.h"

#include <cstdint>

namespace {

template <typename Stream, typename Data>
Expand All @@ -37,7 +39,7 @@ template <typename Data>
bool SerializeFileDB(const std::string& prefix, const fs::path& path, const Data& data)
{
// Generate random temporary filename
unsigned short randv = 0;
uint16_t randv = 0;
GetRandBytes((unsigned char*)&randv, sizeof(randv));
std::string tmpfn = strprintf("%s.%04x", prefix, randv);

Expand Down
76 changes: 53 additions & 23 deletions src/addrman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,30 @@
#include "addrman.h"

#include "hash.h"
#include "serialize.h"
#include "streams.h"
#include "logging.h"
#include "serialize.h"


int CAddrInfo::GetTriedBucket(const uint256& nKey) const
int CAddrInfo::GetTriedBucket(const uint256& nKey, const std::vector<bool> &asmap) const
{
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey()).GetHash().GetCheapHash();
uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP)).GetHash().GetCheapHash();
return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup(asmap) << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP)).GetHash().GetCheapHash();
int tried_bucket = hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
uint32_t mapped_as = GetMappedAS(asmap);
LogPrint(BCLog::NET, "IP %s mapped to AS%i belongs to tried bucket %i\n", ToStringIP(), mapped_as, tried_bucket);
return tried_bucket;
}

int CAddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src) const
int CAddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src, const std::vector<bool> &asmap) const
{
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << vchSourceGroupKey).GetHash().GetCheapHash();
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup(asmap);
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup(asmap) << vchSourceGroupKey).GetHash().GetCheapHash();
uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP)).GetHash().GetCheapHash();
return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
int new_bucket = hash2 % ADDRMAN_NEW_BUCKET_COUNT;
uint32_t mapped_as = GetMappedAS(asmap);
LogPrint(BCLog::NET, "IP %s mapped to AS%i belongs to new bucket %i\n", ToStringIP(), mapped_as, new_bucket);
return new_bucket;
}

int CAddrInfo::GetBucketPosition(const uint256& nKey, bool fNew, int nBucket) const
Expand Down Expand Up @@ -156,7 +163,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId)
assert(info.nRefCount == 0);

// which tried bucket to move the entry to
int nKBucket = info.GetTriedBucket(nKey);
int nKBucket = info.GetTriedBucket(nKey, m_asmap);
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).
Expand All @@ -172,7 +179,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId)
nTried--;

// find which new bucket it belongs to
int nUBucket = infoOld.GetNewBucket(nKey);
int nUBucket = infoOld.GetNewBucket(nKey, m_asmap);
int nUBucketPos = infoOld.GetBucketPosition(nKey, true, nUBucket);
ClearNew(nUBucket, nUBucketPos);
assert(vvNew[nUBucket][nUBucketPos] == -1);
Expand Down Expand Up @@ -236,7 +243,7 @@ void CAddrMan::Good_(const CService& addr, bool test_before_evict, int64_t nTime
return;

// which tried bucket to move the entry to
int tried_bucket = info.GetTriedBucket(nKey);
int tried_bucket = info.GetTriedBucket(nKey, m_asmap);
int tried_bucket_pos = info.GetBucketPosition(nKey, false, tried_bucket);

// Will moving this address into tried evict another entry?
Expand Down Expand Up @@ -304,7 +311,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP
fNew = true;
}

int nUBucket = pinfo->GetNewBucket(nKey, source);
int nUBucket = pinfo->GetNewBucket(nKey, source, m_asmap);
int nUBucketPos = pinfo->GetBucketPosition(nKey, true, nUBucket);
if (vvNew[nUBucket][nUBucketPos] != nId) {
bool fInsert = vvNew[nUBucket][nUBucketPos] == -1;
Expand Down Expand Up @@ -438,15 +445,15 @@ int CAddrMan::Check_()

for (int n = 0; n < ADDRMAN_TRIED_BUCKET_COUNT; n++) {
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
if (vvTried[n][i] != -1) {
if (!setTried.count(vvTried[n][i]))
return -11;
if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey) != n)
return -17;
if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i)
return -18;
setTried.erase(vvTried[n][i]);
}
if (vvTried[n][i] != -1) {
if (!setTried.count(vvTried[n][i]))
return -11;
if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey, m_asmap) != n)
return -17;
if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i)
return -18;
setTried.erase(vvTried[n][i]);
}
}
}

Expand Down Expand Up @@ -547,7 +554,7 @@ void CAddrMan::ResolveCollisions_()
CAddrInfo& info_new = mapInfo[id_new];

// Which tried bucket to move the entry to.
int tried_bucket = info_new.GetTriedBucket(nKey);
int tried_bucket = info_new.GetTriedBucket(nKey, m_asmap);
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;
Expand Down Expand Up @@ -611,10 +618,33 @@ CAddrInfo CAddrMan::SelectTriedCollision_()
CAddrInfo& newInfo = mapInfo[id_new];

// which tried bucket to move the entry to
int tried_bucket = newInfo.GetTriedBucket(nKey);
int tried_bucket = newInfo.GetTriedBucket(nKey, m_asmap);
int tried_bucket_pos = newInfo.GetBucketPosition(nKey, false, tried_bucket);

int id_old = vvTried[tried_bucket][tried_bucket_pos];

return mapInfo[id_old];
}

std::vector<bool> CAddrMan::DecodeAsmap(fs::path path)
{
std::vector<bool> bits;
FILE *filestr = fsbridge::fopen(path, "rb");
CAutoFile file(filestr, SER_DISK, CLIENT_VERSION);
if (file.IsNull()) {
LogPrintf("Failed to open asmap file from disk\n");
return bits;
}
fseek(filestr, 0, SEEK_END);
int length = ftell(filestr);
LogPrintf("Opened asmap file %s (%d bytes) from disk\n", path, length);
fseek(filestr, 0, SEEK_SET);
char cur_byte;
for (int i = 0; i < length; ++i) {
file >> cur_byte;
for (int bit = 0; bit < 8; ++bit) {
bits.push_back((cur_byte >> bit) & 1);
}
}
return bits;
}
Loading