Avoid recalculating vchKeyedNetGroup in eviction logic.

Lazy calculate vchKeyedNetGroup in CNode::GetKeyedNetGroup.
This commit is contained in:
Patrick Strateman 2016-05-23 00:21:05 -07:00 committed by Pieter Wuille
parent 22e0b35676
commit 053930ffc4
2 changed files with 29 additions and 34 deletions

View file

@ -14,6 +14,7 @@
#include "clientversion.h" #include "clientversion.h"
#include "consensus/consensus.h" #include "consensus/consensus.h"
#include "crypto/common.h" #include "crypto/common.h"
#include "crypto/sha256.h"
#include "hash.h" #include "hash.h"
#include "primitives/transaction.h" #include "primitives/transaction.h"
#include "scheduler.h" #include "scheduler.h"
@ -838,6 +839,7 @@ struct NodeEvictionCandidate
int64_t nTimeConnected; int64_t nTimeConnected;
int64_t nMinPingUsecTime; int64_t nMinPingUsecTime;
CAddress addr; CAddress addr;
std::vector<unsigned char> vchKeyedNetGroup;
}; };
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
@ -850,36 +852,8 @@ static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, cons
return a.nTimeConnected > b.nTimeConnected; return a.nTimeConnected > b.nTimeConnected;
} }
class CompareNetGroupKeyed static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) {
{ return a.vchKeyedNetGroup < b.vchKeyedNetGroup;
std::vector<unsigned char> vchSecretKey;
public:
CompareNetGroupKeyed()
{
vchSecretKey.resize(32, 0);
GetRandBytes(vchSecretKey.data(), vchSecretKey.size());
}
bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
{
std::vector<unsigned char> vchGroupA, vchGroupB;
CSHA256 hashA, hashB;
std::vector<unsigned char> vchA(32), vchB(32);
vchGroupA = a.addr.GetGroup();
vchGroupB = b.addr.GetGroup();
hashA.Write(begin_ptr(vchGroupA), vchGroupA.size());
hashB.Write(begin_ptr(vchGroupB), vchGroupB.size());
hashA.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
hashB.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
hashA.Finalize(begin_ptr(vchA));
hashB.Finalize(begin_ptr(vchB));
return vchA < vchB;
}
}; };
/** Try to find a connection to evict when the node is full. /** Try to find a connection to evict when the node is full.
@ -902,7 +876,7 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
continue; continue;
if (node->fDisconnect) if (node->fDisconnect)
continue; continue;
NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr}; NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr, node->vchKeyedNetGroup};
vEvictionCandidates.push_back(candidate); vEvictionCandidates.push_back(candidate);
} }
} }
@ -912,9 +886,8 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
// Protect connections with certain characteristics // Protect connections with certain characteristics
// Deterministically select 4 peers to protect by netgroup. // Deterministically select 4 peers to protect by netgroup.
// An attacker cannot predict which netgroups will be protected. // An attacker cannot predict which netgroups will be protected
static CompareNetGroupKeyed comparerNetGroupKeyed; std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNetGroupKeyed);
std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), comparerNetGroupKeyed);
vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end()); vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
if (vEvictionCandidates.empty()) return false; if (vEvictionCandidates.empty()) return false;
@ -2392,6 +2365,8 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
lastSentFeeFilter = 0; lastSentFeeFilter = 0;
nextSendTimeFeeFilter = 0; nextSendTimeFeeFilter = 0;
CalculateKeyedNetGroup();
BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes())
mapRecvBytesPerMsgCmd[msg] = 0; mapRecvBytesPerMsgCmd[msg] = 0;
mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;

View file

@ -9,6 +9,8 @@
#include "amount.h" #include "amount.h"
#include "bloom.h" #include "bloom.h"
#include "compat.h" #include "compat.h"
#include "crypto/common.h"
#include "crypto/sha256.h"
#include "limitedmap.h" #include "limitedmap.h"
#include "netbase.h" #include "netbase.h"
#include "protocol.h" #include "protocol.h"
@ -362,6 +364,8 @@ public:
CBloomFilter* pfilter; CBloomFilter* pfilter;
int nRefCount; int nRefCount;
NodeId id; NodeId id;
std::vector<unsigned char> vchKeyedNetGroup;
protected: protected:
// Denial-of-service detection/prevention // Denial-of-service detection/prevention
@ -450,6 +454,22 @@ private:
CNode(const CNode&); CNode(const CNode&);
void operator=(const CNode&); void operator=(const CNode&);
void CalculateKeyedNetGroup() {
static std::vector<unsigned char> vchSecretKey;
if (vchSecretKey.empty()) {
vchSecretKey.resize(32, 0);
GetRandBytes(vchSecretKey.data(), vchSecretKey.size());
}
std::vector<unsigned char> vchNetGroup(this->addr.GetGroup());
CSHA256 hash;
hash.Write(begin_ptr(vchNetGroup), vchNetGroup.size());
hash.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
vchKeyedNetGroup.resize(32, 0);
hash.Finalize(begin_ptr(vchKeyedNetGroup));
}
public: public:
NodeId GetId() const { NodeId GetId() const {