Skip to content

Commit 321d0fc

Browse files
theuniTheBlueMatt
authored andcommitted
net: fix a few races. Credit @TheBlueMatt
These are (afaik) all long-standing races or concurrent accesses. Going forward, we can clean these up so that they're not all individual atomic accesses. - Reintroduce cs_vRecv to guard receive-specific vars - Lock vRecv/vSend for CNodeStats - Make some vars atomic. - Only set the connection time in CNode's constructor so that it doesn't change
1 parent 2447c10 commit 321d0fc

File tree

3 files changed

+22
-15
lines changed

3 files changed

+22
-15
lines changed

src/net.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,6 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
389389
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
390390
CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, pszDest ? pszDest : "", false);
391391
pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices);
392-
pnode->nTimeConnected = GetSystemTimeInSeconds();
393392
pnode->AddRef();
394393

395394
return pnode;
@@ -612,10 +611,16 @@ void CNode::copyStats(CNodeStats &stats)
612611
X(fInbound);
613612
X(fAddnode);
614613
X(nStartingHeight);
615-
X(nSendBytes);
616-
X(mapSendBytesPerMsgCmd);
617-
X(nRecvBytes);
618-
X(mapRecvBytesPerMsgCmd);
614+
{
615+
LOCK(cs_vSend);
616+
X(mapSendBytesPerMsgCmd);
617+
X(nSendBytes);
618+
}
619+
{
620+
LOCK(cs_vRecv);
621+
X(mapRecvBytesPerMsgCmd);
622+
X(nRecvBytes);
623+
}
619624
X(fWhitelisted);
620625

621626
// It is common for nodes with good ping times to suddenly become lagged,
@@ -643,6 +648,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete
643648
{
644649
complete = false;
645650
int64_t nTimeMicros = GetTimeMicros();
651+
LOCK(cs_vRecv);
646652
nLastRecv = nTimeMicros / 1000000;
647653
nRecvBytes += nBytes;
648654
while (nBytes > 0) {

src/net.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ class CNode
573573
std::deque<std::vector<unsigned char>> vSendMsg;
574574
CCriticalSection cs_vSend;
575575
CCriticalSection cs_hSocket;
576+
CCriticalSection cs_vRecv;
576577

577578
CCriticalSection cs_vProcessMsg;
578579
std::list<CNetMessage> vProcessMsg;
@@ -584,10 +585,10 @@ class CNode
584585
uint64_t nRecvBytes;
585586
std::atomic<int> nRecvVersion;
586587

587-
int64_t nLastSend;
588-
int64_t nLastRecv;
588+
std::atomic<int64_t> nLastSend;
589+
std::atomic<int64_t> nLastRecv;
589590
int64_t nTimeConnected;
590-
int64_t nTimeOffset;
591+
std::atomic<int64_t> nTimeOffset;
591592
const CAddress addr;
592593
std::string addrName;
593594
CService addrLocal;
@@ -614,7 +615,7 @@ class CNode
614615
CSemaphoreGrant grantOutbound;
615616
CCriticalSection cs_filter;
616617
CBloomFilter* pfilter;
617-
int nRefCount;
618+
std::atomic<int> nRefCount;
618619
const NodeId id;
619620

620621
const uint64_t nKeyedNetGroup;
@@ -665,15 +666,15 @@ class CNode
665666

666667
// Ping time measurement:
667668
// The pong reply we're expecting, or 0 if no pong expected.
668-
uint64_t nPingNonceSent;
669+
std::atomic<uint64_t> nPingNonceSent;
669670
// Time (in usec) the last ping was sent, or 0 if no ping was ever sent.
670-
int64_t nPingUsecStart;
671+
std::atomic<int64_t> nPingUsecStart;
671672
// Last measured round-trip time.
672-
int64_t nPingUsecTime;
673+
std::atomic<int64_t> nPingUsecTime;
673674
// Best measured round-trip time.
674-
int64_t nMinPingUsecTime;
675+
std::atomic<int64_t> nMinPingUsecTime;
675676
// Whether a ping is requested.
676-
bool fPingQueued;
677+
std::atomic<bool> fPingQueued;
677678
// Minimum fee rate with which to filter inv's to this node
678679
CAmount minFeeFilter;
679680
CCriticalSection cs_feeFilter;

src/net_processing.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2450,7 +2450,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
24502450
if (pingUsecTime > 0) {
24512451
// Successful ping time measurement, replace previous
24522452
pfrom->nPingUsecTime = pingUsecTime;
2453-
pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
2453+
pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime.load(), pingUsecTime);
24542454
} else {
24552455
// This should never happen
24562456
sProblem = "Timing mishap";

0 commit comments

Comments
 (0)