Skip to content

Commit c31b24f

Browse files
committed
Use 64-bit SipHash of netgroups in eviction
1 parent 9bf156b commit c31b24f

File tree

2 files changed

+29
-32
lines changed

2 files changed

+29
-32
lines changed

src/net.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ struct NodeEvictionCandidate
839839
int64_t nTimeConnected;
840840
int64_t nMinPingUsecTime;
841841
CAddress addr;
842-
std::vector<unsigned char> vchKeyedNetGroup;
842+
uint64_t nKeyedNetGroup;
843843
};
844844

845845
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
@@ -853,7 +853,7 @@ static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, cons
853853
}
854854

855855
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) {
856-
return a.vchKeyedNetGroup < b.vchKeyedNetGroup;
856+
return a.nKeyedNetGroup < b.nKeyedNetGroup;
857857
};
858858

859859
/** Try to find a connection to evict when the node is full.
@@ -876,7 +876,7 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
876876
continue;
877877
if (node->fDisconnect)
878878
continue;
879-
NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr, node->vchKeyedNetGroup};
879+
NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr, node->nKeyedNetGroup};
880880
vEvictionCandidates.push_back(candidate);
881881
}
882882
}
@@ -908,24 +908,24 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
908908

909909
// Identify the network group with the most connections and youngest member.
910910
// (vEvictionCandidates is already sorted by reverse connect time)
911-
std::vector<unsigned char> naMostConnections;
911+
uint64_t naMostConnections;
912912
unsigned int nMostConnections = 0;
913913
int64_t nMostConnectionsTime = 0;
914-
std::map<std::vector<unsigned char>, std::vector<NodeEvictionCandidate> > mapAddrCounts;
914+
std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapAddrCounts;
915915
BOOST_FOREACH(const NodeEvictionCandidate &node, vEvictionCandidates) {
916-
mapAddrCounts[node.addr.GetGroup()].push_back(node);
917-
int64_t grouptime = mapAddrCounts[node.addr.GetGroup()][0].nTimeConnected;
918-
size_t groupsize = mapAddrCounts[node.addr.GetGroup()].size();
916+
mapAddrCounts[node.nKeyedNetGroup].push_back(node);
917+
int64_t grouptime = mapAddrCounts[node.nKeyedNetGroup][0].nTimeConnected;
918+
size_t groupsize = mapAddrCounts[node.nKeyedNetGroup].size();
919919

920920
if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
921921
nMostConnections = groupsize;
922922
nMostConnectionsTime = grouptime;
923-
naMostConnections = node.addr.GetGroup();
923+
naMostConnections = node.nKeyedNetGroup;
924924
}
925925
}
926926

927927
// Reduce to the network group with the most connections
928-
vEvictionCandidates = mapAddrCounts[naMostConnections];
928+
vEvictionCandidates = std::move(mapAddrCounts[naMostConnections]);
929929

930930
// Do not disconnect peers if there is only one unprotected connection from their network group.
931931
// This step excessively favors netgroup diversity, and should be removed once more protective criteria are established.
@@ -2318,6 +2318,8 @@ unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAX
23182318

23192319
CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) :
23202320
ssSend(SER_NETWORK, INIT_PROTO_VERSION),
2321+
addr(addrIn),
2322+
nKeyedNetGroup(CalculateKeyedNetGroup(addrIn)),
23212323
addrKnown(5000, 0.001),
23222324
filterInventoryKnown(50000, 0.000001)
23232325
{
@@ -2330,7 +2332,6 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
23302332
nRecvBytes = 0;
23312333
nTimeConnected = GetTime();
23322334
nTimeOffset = 0;
2333-
addr = addrIn;
23342335
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
23352336
nVersion = 0;
23362337
strSubVer = "";
@@ -2365,8 +2366,6 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
23652366
lastSentFeeFilter = 0;
23662367
nextSendTimeFeeFilter = 0;
23672368

2368-
CalculateKeyedNetGroup();
2369-
23702369
BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes())
23712370
mapRecvBytesPerMsgCmd[msg] = 0;
23722371
mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
@@ -2599,3 +2598,17 @@ bool CBanDB::Read(banmap_t& banSet)
25992598
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
26002599
return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
26012600
}
2601+
2602+
/* static */ uint64_t CNode::CalculateKeyedNetGroup(const CAddress& ad)
2603+
{
2604+
static uint64_t k0 = 0, k1 = 0;
2605+
while (k0 == 0 && k1 == 0) {
2606+
// Make sure this only runs on the first invocation.
2607+
GetRandBytes((unsigned char*)&k0, sizeof(k0));
2608+
GetRandBytes((unsigned char*)&k1, sizeof(k1));
2609+
}
2610+
2611+
std::vector<unsigned char> vchNetGroup(ad.GetGroup());
2612+
2613+
return CSipHasher(k0, k1).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize();
2614+
}

src/net.h

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
#include "amount.h"
1010
#include "bloom.h"
1111
#include "compat.h"
12-
#include "crypto/common.h"
13-
#include "crypto/sha256.h"
1412
#include "limitedmap.h"
1513
#include "netbase.h"
1614
#include "protocol.h"
@@ -337,7 +335,7 @@ class CNode
337335
int64_t nLastRecv;
338336
int64_t nTimeConnected;
339337
int64_t nTimeOffset;
340-
CAddress addr;
338+
const CAddress addr;
341339
std::string addrName;
342340
CService addrLocal;
343341
int nVersion;
@@ -365,7 +363,7 @@ class CNode
365363
int nRefCount;
366364
NodeId id;
367365

368-
std::vector<unsigned char> vchKeyedNetGroup;
366+
const uint64_t nKeyedNetGroup;
369367
protected:
370368

371369
// Denial-of-service detection/prevention
@@ -454,22 +452,8 @@ class CNode
454452
CNode(const CNode&);
455453
void operator=(const CNode&);
456454

457-
void CalculateKeyedNetGroup() {
458-
static std::vector<unsigned char> vchSecretKey;
459-
if (vchSecretKey.empty()) {
460-
vchSecretKey.resize(32, 0);
461-
GetRandBytes(vchSecretKey.data(), vchSecretKey.size());
462-
}
463-
464-
std::vector<unsigned char> vchNetGroup(this->addr.GetGroup());
455+
static uint64_t CalculateKeyedNetGroup(const CAddress& ad);
465456

466-
CSHA256 hash;
467-
hash.Write(begin_ptr(vchNetGroup), vchNetGroup.size());
468-
hash.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
469-
470-
vchKeyedNetGroup.resize(32, 0);
471-
hash.Finalize(begin_ptr(vchKeyedNetGroup));
472-
}
473457
public:
474458

475459
NodeId GetId() const {

0 commit comments

Comments
 (0)