Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13115379
D8198.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Subscribers
None
D8198.diff
View Options
diff --git a/src/init.cpp b/src/init.cpp
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -2787,8 +2787,8 @@
asmap_path));
return false;
}
- node.connman->SetAsmap(asmap);
const uint256 asmap_version = SerializeHash(asmap);
+ node.connman->SetAsmap(std::move(asmap));
LogPrintf("Using asmap version %s for IP bucketing.\n",
asmap_version.ToString());
} else {
diff --git a/src/net.h b/src/net.h
--- a/src/net.h
+++ b/src/net.h
@@ -357,7 +357,9 @@
*/
int64_t PoissonNextSendInbound(int64_t now, int average_interval_seconds);
- void SetAsmap(std::vector<bool> asmap) { addrman.m_asmap = asmap; }
+ void SetAsmap(std::vector<bool> asmap) {
+ addrman.m_asmap = std::move(asmap);
+ }
private:
struct ListenSocket {
@@ -971,7 +973,7 @@
void CloseSocketDisconnect();
- void copyStats(CNodeStats &stats, std::vector<bool> &m_asmap);
+ void copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap);
ServiceFlags GetLocalServices() const { return nLocalServices; }
diff --git a/src/net.cpp b/src/net.cpp
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -502,7 +502,7 @@
}
}
-void CNode::copyStats(CNodeStats &stats, std::vector<bool> &m_asmap) {
+void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap) {
stats.nodeid = this->GetId();
stats.nServices = nServices;
stats.addr = addr;
diff --git a/src/netaddress.h b/src/netaddress.h
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -100,6 +100,12 @@
bool GetInAddr(struct in_addr *pipv4Addr) const;
uint32_t GetNetClass() const;
+ //! For IPv4, mapped IPv4, SIIT translated IPv4, Teredo, 6to4 tunneled
+ //! addresses, return the relevant IPv4 address as a uint32.
+ uint32_t GetLinkedIPv4() const;
+ //! Whether this address has a linked IPv4 address (see GetLinkedIPv4()).
+ bool HasLinkedIPv4() const;
+
// The AS on the BGP path to the node we use to diversify
// peers in AddrMan bucketing based on the AS infrastructure.
// The ip->AS mapping depends on how asmap is constructed.
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
--- a/src/netaddress.cpp
+++ b/src/netaddress.cpp
@@ -404,6 +404,27 @@
return true;
}
+bool CNetAddr::HasLinkedIPv4() const {
+ return IsRoutable() && (IsIPv4() || IsRFC6145() || IsRFC6052() ||
+ IsRFC3964() || IsRFC4380());
+}
+
+uint32_t CNetAddr::GetLinkedIPv4() const {
+ if (IsIPv4() || IsRFC6145() || IsRFC6052()) {
+ // IPv4, mapped IPv4, SIIT translated IPv4: the IPv4 address is the last
+ // 4 bytes of the address
+ return ReadBE32(ip + 12);
+ } else if (IsRFC3964()) {
+ // 6to4 tunneled IPv4: the IPv4 address is in bytes 2-6
+ return ReadBE32(ip + 2);
+ } else if (IsRFC4380()) {
+ // Teredo tunneled IPv4: the IPv4 address is in the last 4 bytes of the
+ // address, but bitflipped
+ return ~ReadBE32(ip + 12);
+ }
+ assert(false);
+}
+
uint32_t CNetAddr::GetNetClass() const {
uint32_t net_class = NET_IPV6;
if (IsLocal()) {
@@ -413,8 +434,7 @@
net_class = NET_INTERNAL;
} else if (!IsRoutable()) {
net_class = NET_UNROUTABLE;
- } else if (IsIPv4() || IsRFC6145() || IsRFC6052() || IsRFC3964() ||
- IsRFC4380()) {
+ } else if (HasLinkedIPv4()) {
net_class = NET_IPV4;
} else if (IsTor()) {
net_class = NET_ONION;
@@ -429,10 +449,26 @@
// RFC7607.
}
std::vector<bool> ip_bits(128);
- for (int8_t byte_i = 0; byte_i < 16; ++byte_i) {
- uint8_t cur_byte = GetByte(15 - byte_i);
- for (uint8_t bit_i = 0; bit_i < 8; ++bit_i) {
- ip_bits[byte_i * 8 + bit_i] = (cur_byte >> (7 - bit_i)) & 1;
+ if (HasLinkedIPv4()) {
+ // For lookup, treat as if it was just an IPv4 address (pchIPv4 prefix +
+ // IPv4 bits)
+ for (int8_t byte_i = 0; byte_i < 12; ++byte_i) {
+ for (uint8_t bit_i = 0; bit_i < 8; ++bit_i) {
+ ip_bits[byte_i * 8 + bit_i] =
+ (pchIPv4[byte_i] >> (7 - bit_i)) & 1;
+ }
+ }
+ uint32_t ipv4 = GetLinkedIPv4();
+ for (int i = 0; i < 32; ++i) {
+ ip_bits[96 + i] = (ipv4 >> (31 - i)) & 1;
+ }
+ } else {
+ // Use all 128 bits of the IPv6 address otherwise
+ for (int8_t byte_i = 0; byte_i < 16; ++byte_i) {
+ uint8_t cur_byte = GetByte(15 - byte_i);
+ for (uint8_t bit_i = 0; bit_i < 8; ++bit_i) {
+ ip_bits[byte_i * 8 + bit_i] = (cur_byte >> (7 - bit_i)) & 1;
+ }
}
}
uint32_t mapped_as = Interpret(asmap, ip_bits);
@@ -469,30 +505,21 @@
int nStartByte = 0;
int nBits = 16;
- // all local addresses belong to the same group
if (IsLocal()) {
+ // all local addresses belong to the same group
nBits = 0;
- }
-
- if (IsInternal()) {
+ } else if (IsInternal()) {
// all internal-usage addresses get their own group
nStartByte = sizeof(g_internal_prefix);
nBits = (sizeof(ip) - sizeof(g_internal_prefix)) * 8;
} else if (!IsRoutable()) {
// all other unroutable addresses belong to the same group
nBits = 0;
- } else if (IsIPv4() || IsRFC6145() || IsRFC6052()) {
- // for IPv4 addresses, '1' + the 16 higher-order bits of the IP includes
- // mapped IPv4, SIIT translated IPv4, and the well-known prefix
- nStartByte = 12;
- } else if (IsRFC3964()) {
- // for 6to4 tunnelled addresses, use the encapsulated IPv4 address
- nStartByte = 2;
- } else if (IsRFC4380()) {
- // for Teredo-tunnelled IPv6 addresses, use the encapsulated IPv4
- // address
- vchRet.push_back(GetByte(3) ^ 0xFF);
- vchRet.push_back(GetByte(2) ^ 0xFF);
+ } else if (HasLinkedIPv4()) {
+ // IPv4 addresses (and mapped IPv4 addresses) use /16 groups
+ uint32_t ipv4 = GetLinkedIPv4();
+ vchRet.push_back((ipv4 >> 24) & 0xFF);
+ vchRet.push_back((ipv4 >> 16) & 0xFF);
return vchRet;
} else if (IsTor()) {
nStartByte = 6;
diff --git a/src/util/asmap.cpp b/src/util/asmap.cpp
--- a/src/util/asmap.cpp
+++ b/src/util/asmap.cpp
@@ -9,13 +9,17 @@
namespace {
-uint32_t DecodeBits(std::vector<bool>::const_iterator &bitpos, uint8_t minval,
- const std::vector<uint8_t> &bit_sizes) {
+uint32_t DecodeBits(std::vector<bool>::const_iterator &bitpos,
+ const std::vector<bool>::const_iterator &endpos,
+ uint8_t minval, const std::vector<uint8_t> &bit_sizes) {
uint32_t val = minval;
bool bit;
for (std::vector<uint8_t>::const_iterator bit_sizes_it = bit_sizes.begin();
bit_sizes_it != bit_sizes.end(); ++bit_sizes_it) {
if (bit_sizes_it + 1 != bit_sizes.end()) {
+ if (bitpos == endpos) {
+ break;
+ }
bit = *bitpos;
bitpos++;
} else {
@@ -25,6 +29,9 @@
val += (1 << *bit_sizes_it);
} else {
for (int b = 0; b < *bit_sizes_it; b++) {
+ if (bitpos == endpos) {
+ break;
+ }
bit = *bitpos;
bitpos++;
val += bit << (*bit_sizes_it - 1 - b);
@@ -36,26 +43,30 @@
}
const std::vector<uint8_t> TYPE_BIT_SIZES{0, 0, 1};
-uint32_t DecodeType(std::vector<bool>::const_iterator &bitpos) {
- return DecodeBits(bitpos, 0, TYPE_BIT_SIZES);
+uint32_t DecodeType(std::vector<bool>::const_iterator &bitpos,
+ const std::vector<bool>::const_iterator &endpos) {
+ return DecodeBits(bitpos, endpos, 0, TYPE_BIT_SIZES);
}
const std::vector<uint8_t> ASN_BIT_SIZES{15, 16, 17, 18, 19,
20, 21, 22, 23, 24};
-uint32_t DecodeASN(std::vector<bool>::const_iterator &bitpos) {
- return DecodeBits(bitpos, 1, ASN_BIT_SIZES);
+uint32_t DecodeASN(std::vector<bool>::const_iterator &bitpos,
+ const std::vector<bool>::const_iterator &endpos) {
+ return DecodeBits(bitpos, endpos, 1, ASN_BIT_SIZES);
}
const std::vector<uint8_t> MATCH_BIT_SIZES{1, 2, 3, 4, 5, 6, 7, 8};
-uint32_t DecodeMatch(std::vector<bool>::const_iterator &bitpos) {
- return DecodeBits(bitpos, 2, MATCH_BIT_SIZES);
+uint32_t DecodeMatch(std::vector<bool>::const_iterator &bitpos,
+ const std::vector<bool>::const_iterator &endpos) {
+ return DecodeBits(bitpos, endpos, 2, MATCH_BIT_SIZES);
}
const std::vector<uint8_t> JUMP_BIT_SIZES{5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30};
-uint32_t DecodeJump(std::vector<bool>::const_iterator &bitpos) {
- return DecodeBits(bitpos, 17, JUMP_BIT_SIZES);
+uint32_t DecodeJump(std::vector<bool>::const_iterator &bitpos,
+ const std::vector<bool>::const_iterator &endpos) {
+ return DecodeBits(bitpos, endpos, 17, JUMP_BIT_SIZES);
}
} // namespace
@@ -63,24 +74,33 @@
uint32_t Interpret(const std::vector<bool> &asmap,
const std::vector<bool> &ip) {
std::vector<bool>::const_iterator pos = asmap.begin();
+ const std::vector<bool>::const_iterator endpos = asmap.end();
uint8_t bits = ip.size();
- uint8_t default_asn = 0;
+ uint32_t default_asn = 0;
uint32_t opcode, jump, match, matchlen;
- while (1) {
- assert(pos != asmap.end());
- opcode = DecodeType(pos);
+ while (pos != endpos) {
+ opcode = DecodeType(pos, endpos);
if (opcode == 0) {
- return DecodeASN(pos);
+ return DecodeASN(pos, endpos);
} else if (opcode == 1) {
- jump = DecodeJump(pos);
+ jump = DecodeJump(pos, endpos);
+ if (bits == 0) {
+ break;
+ }
if (ip[ip.size() - bits]) {
+ if (jump >= endpos - pos) {
+ break;
+ }
pos += jump;
}
bits--;
} else if (opcode == 2) {
- match = DecodeMatch(pos);
+ match = DecodeMatch(pos, endpos);
matchlen = CountBits(match) - 1;
for (uint32_t bit = 0; bit < matchlen; bit++) {
+ if (bits == 0) {
+ break;
+ }
if ((ip[ip.size() - bits]) !=
((match >> (matchlen - 1 - bit)) & 1)) {
return default_asn;
@@ -88,9 +108,11 @@
bits--;
}
} else if (opcode == 3) {
- default_asn = DecodeASN(pos);
+ default_asn = DecodeASN(pos, endpos);
} else {
- assert(0);
+ break;
}
}
+ // 0 is not a valid ASN
+ return 0;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 1, 10:59 (15 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5185410
Default Alt Text
D8198.diff (10 KB)
Attached To
D8198: Fix some asmap issues
Event Timeline
Log In to Comment