Merge #9050: net: make a few values immutable, and use deterministic randomness for the localnonce

59ac5c5 net: Use deterministic randomness for CNode's nonce, and make it const (Cory Fields)
aff6584 net: constify a few CNode vars to indicate that they're threadsafe (Cory Fields)
This commit is contained in:
Wladimir J. van der Laan 2016-11-03 10:45:11 +01:00
commit fcf61b80fa
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
4 changed files with 33 additions and 23 deletions

View File

@ -64,6 +64,7 @@
const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8] static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL; // SHA256("localhostnonce")[0:8]
// //
// Global state variables // Global state variables
// //
@ -389,7 +390,10 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
addrman.Attempt(addrConnect, fCountFailure); addrman.Attempt(addrConnect, fCountFailure);
// Add node // Add node
CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), pszDest ? pszDest : "", false); NodeId id = GetNewNodeId();
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, pszDest ? pszDest : "", false);
GetNodeSignals().InitializeNode(pnode->GetId(), pnode); GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef(); pnode->AddRef();
@ -1024,7 +1028,10 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
} }
} }
CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), "", true); NodeId id = GetNewNodeId();
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, "", true);
GetNodeSignals().InitializeNode(pnode->GetId(), pnode); GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef(); pnode->AddRef();
pnode->fWhitelisted = whitelisted; pnode->fWhitelisted = whitelisted;
@ -2118,7 +2125,11 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
if (pnodeLocalHost == NULL) { if (pnodeLocalHost == NULL) {
CNetAddr local; CNetAddr local;
LookupHost("127.0.0.1", local, false); LookupHost("127.0.0.1", local, false);
pnodeLocalHost = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices), 0);
NodeId id = GetNewNodeId();
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
pnodeLocalHost = new CNode(id, nLocalServices, GetBestHeight(), INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices), 0, nonce);
GetNodeSignals().InitializeNode(pnodeLocalHost->GetId(), pnodeLocalHost); GetNodeSignals().InitializeNode(pnodeLocalHost->GetId(), pnodeLocalHost);
} }
@ -2509,12 +2520,17 @@ void CNode::Fuzz(int nChance)
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; } unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize; } unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize; }
CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, const std::string& addrNameIn, bool fInboundIn) : CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const std::string& addrNameIn, bool fInboundIn) :
ssSend(SER_NETWORK, INIT_PROTO_VERSION), ssSend(SER_NETWORK, INIT_PROTO_VERSION),
addr(addrIn), addr(addrIn),
fInbound(fInboundIn),
id(idIn),
nKeyedNetGroup(nKeyedNetGroupIn), nKeyedNetGroup(nKeyedNetGroupIn),
addrKnown(5000, 0.001), addrKnown(5000, 0.001),
filterInventoryKnown(50000, 0.000001) filterInventoryKnown(50000, 0.000001),
nLocalHostNonce(nLocalHostNonceIn),
nLocalServices(nLocalServicesIn),
nMyStartingHeight(nMyStartingHeightIn)
{ {
nServices = NODE_NONE; nServices = NODE_NONE;
nServicesExpected = NODE_NONE; nServicesExpected = NODE_NONE;
@ -2533,7 +2549,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
fOneShot = false; fOneShot = false;
fClient = false; // set by version message fClient = false; // set by version message
fFeeler = false; fFeeler = false;
fInbound = fInboundIn;
fNetworkNode = false; fNetworkNode = false;
fSuccessfullyConnected = false; fSuccessfullyConnected = false;
fDisconnect = false; fDisconnect = false;
@ -2562,12 +2577,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
minFeeFilter = 0; minFeeFilter = 0;
lastSentFeeFilter = 0; lastSentFeeFilter = 0;
nextSendTimeFeeFilter = 0; nextSendTimeFeeFilter = 0;
id = idIn;
nOptimisticBytesWritten = 0; nOptimisticBytesWritten = 0;
nLocalServices = nLocalServicesIn;
GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
nMyStartingHeight = nMyStartingHeightIn;
BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes())
mapRecvBytesPerMsgCmd[msg] = 0; mapRecvBytesPerMsgCmd[msg] = 0;

View File

@ -589,7 +589,7 @@ public:
bool fFeeler; // If true this node is being used as a short lived feeler. bool fFeeler; // If true this node is being used as a short lived feeler.
bool fOneShot; bool fOneShot;
bool fClient; bool fClient;
bool fInbound; const bool fInbound;
bool fNetworkNode; bool fNetworkNode;
bool fSuccessfullyConnected; bool fSuccessfullyConnected;
bool fDisconnect; bool fDisconnect;
@ -603,7 +603,7 @@ public:
CCriticalSection cs_filter; CCriticalSection cs_filter;
CBloomFilter* pfilter; CBloomFilter* pfilter;
int nRefCount; int nRefCount;
NodeId id; const NodeId id;
const uint64_t nKeyedNetGroup; const uint64_t nKeyedNetGroup;
protected: protected:
@ -669,7 +669,7 @@ public:
CAmount lastSentFeeFilter; CAmount lastSentFeeFilter;
int64_t nextSendTimeFeeFilter; int64_t nextSendTimeFeeFilter;
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, const std::string &addrNameIn = "", bool fInboundIn = false); CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const std::string &addrNameIn = "", bool fInboundIn = false);
~CNode(); ~CNode();
private: private:
@ -677,10 +677,10 @@ private:
void operator=(const CNode&); void operator=(const CNode&);
uint64_t nLocalHostNonce; const uint64_t nLocalHostNonce;
// Services offered to this peer // Services offered to this peer
ServiceFlags nLocalServices; const ServiceFlags nLocalServices;
int nMyStartingHeight; const int nMyStartingHeight;
public: public:
NodeId GetId() const { NodeId GetId() const {

View File

@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
{ {
connman->ClearBanned(); connman->ClearBanned();
CAddress addr1(ip(0xa0b0c001), NODE_NONE); CAddress addr1(ip(0xa0b0c001), NODE_NONE);
CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, "", true); CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, 0, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1); GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1; dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100); // Should get banned Misbehaving(dummyNode1.GetId(), 100); // Should get banned
@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
CAddress addr2(ip(0xa0b0c002), NODE_NONE); CAddress addr2(ip(0xa0b0c002), NODE_NONE);
CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, "", true); CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, 1, "", true);
GetNodeSignals().InitializeNode(dummyNode2.GetId(), &dummyNode2); GetNodeSignals().InitializeNode(dummyNode2.GetId(), &dummyNode2);
dummyNode2.nVersion = 1; dummyNode2.nVersion = 1;
Misbehaving(dummyNode2.GetId(), 50); Misbehaving(dummyNode2.GetId(), 50);
@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
connman->ClearBanned(); connman->ClearBanned();
mapArgs["-banscore"] = "111"; // because 11 is my favorite number mapArgs["-banscore"] = "111"; // because 11 is my favorite number
CAddress addr1(ip(0xa0b0c001), NODE_NONE); CAddress addr1(ip(0xa0b0c001), NODE_NONE);
CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, "", true); CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, 1, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1); GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1; dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100); Misbehaving(dummyNode1.GetId(), 100);
@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
SetMockTime(nStartTime); // Overrides future calls to GetTime() SetMockTime(nStartTime); // Overrides future calls to GetTime()
CAddress addr(ip(0xa0b0c001), NODE_NONE); CAddress addr(ip(0xa0b0c001), NODE_NONE);
CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, "", true); CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, 4, "", true);
GetNodeSignals().InitializeNode(dummyNode.GetId(), &dummyNode); GetNodeSignals().InitializeNode(dummyNode.GetId(), &dummyNode);
dummyNode.nVersion = 1; dummyNode.nVersion = 1;

View File

@ -164,12 +164,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
bool fInboundIn = false; bool fInboundIn = false;
// Test that fFeeler is false by default. // Test that fFeeler is false by default.
CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, pszDest, fInboundIn); CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, pszDest, fInboundIn);
BOOST_CHECK(pnode1->fInbound == false); BOOST_CHECK(pnode1->fInbound == false);
BOOST_CHECK(pnode1->fFeeler == false); BOOST_CHECK(pnode1->fFeeler == false);
fInboundIn = true; fInboundIn = true;
CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, pszDest, fInboundIn); CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, pszDest, fInboundIn);
BOOST_CHECK(pnode2->fInbound == true); BOOST_CHECK(pnode2->fInbound == true);
BOOST_CHECK(pnode2->fFeeler == false); BOOST_CHECK(pnode2->fFeeler == false);
} }