Skip to content

Commit 960cf2e

Browse files
committed
net: move nLocalHostNonce to CConnman
This behavior seems to have been quite racy and broken. Move nLocalHostNonce into CNode, and check received nonces against all non-fully-connected nodes. If there's a match, assume we've connected to ourself.
1 parent 551e088 commit 960cf2e

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5025,7 +5025,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
50255025
}
50265026

50275027
// Disconnect if we connected to ourself
5028-
if (nNonce == nLocalHostNonce && nNonce > 1)
5028+
if (pfrom->fInbound && !connman.CheckIncomingNonce(nNonce))
50295029
{
50305030
LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
50315031
pfrom->fDisconnect = true;

src/net.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ CCriticalSection cs_mapLocalHost;
8383
std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
8484
static bool vfLimited[NET_MAX] = {};
8585
static CNode* pnodeLocalHost = NULL;
86-
uint64_t nLocalHostNonce = 0;
8786
int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS;
8887
std::string strSubVersion;
8988

@@ -346,6 +345,16 @@ CNode* CConnman::FindNode(const CService& addr)
346345
return NULL;
347346
}
348347

348+
bool CConnman::CheckIncomingNonce(uint64_t nonce)
349+
{
350+
LOCK(cs_vNodes);
351+
BOOST_FOREACH(CNode* pnode, vNodes) {
352+
if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce)
353+
return false;
354+
}
355+
return true;
356+
}
357+
349358
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure)
350359
{
351360
if (pszDest == NULL) {
@@ -465,7 +474,6 @@ void CNode::PushVersion()
465474
int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
466475
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService(), addr.nServices));
467476
CAddress addrMe = GetLocalAddress(&addr);
468-
GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
469477
if (fLogIPs)
470478
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id);
471479
else
@@ -2535,6 +2543,8 @@ CNode::CNode(NodeId idIn, SOCKET hSocketIn, const CAddress& addrIn, const std::s
25352543
nextSendTimeFeeFilter = 0;
25362544
id = idIn;
25372545

2546+
GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
2547+
25382548
BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes())
25392549
mapRecvBytesPerMsgCmd[msg] = 0;
25402550
mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;

src/net.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class CConnman
114114
void Stop();
115115
bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
116116
bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false, bool fFeeler = false);
117+
bool CheckIncomingNonce(uint64_t nonce);
117118

118119
bool ForNode(NodeId id, std::function<bool(CNode* pnode)> func);
119120
bool ForEachNode(std::function<bool(CNode* pnode)> func);
@@ -297,7 +298,6 @@ extern bool fListen;
297298
extern ServiceFlags nLocalServices;
298299
extern ServiceFlags nRelevantServices;
299300
extern bool fRelayTxes;
300-
extern uint64_t nLocalHostNonce;
301301

302302
/** Maximum number of connections to simultaneously allow (aka connection slots) */
303303
extern int nMaxConnections;
@@ -523,12 +523,17 @@ class CNode
523523

524524
static uint64_t CalculateKeyedNetGroup(const CAddress& ad);
525525

526+
uint64_t nLocalHostNonce;
526527
public:
527528

528529
NodeId GetId() const {
529530
return id;
530531
}
531532

533+
uint64_t GetLocalNonce() const {
534+
return nLocalHostNonce;
535+
}
536+
532537
int GetRefCount()
533538
{
534539
assert(nRefCount >= 0);

0 commit comments

Comments
 (0)