From 33bfaffbea5a8cea060d249a8a20a23c52c332e5 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Tue, 21 Apr 2020 18:21:19 +0200 Subject: [PATCH] Don't return nodes with fDisconnect=true in FindNode FindNode is only interested in active connections, especially when called from OpenNetworkConnection. Connections which are about to get disconnected and removed should be treated as if they are not existent anymore, as otherwise there is a small race between disconnecting and reconnecting nodes, causing OpenNetworkConnection to return early. --- src/net.cpp | 20 ++++++++++++++++---- src/net.h | 8 ++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index babbdc6389..bd76bd390d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -323,10 +323,13 @@ bool IsReachable(const CNetAddr& addr) } -CNode* CConnman::FindNode(const CNetAddr& ip) +CNode* CConnman::FindNode(const CNetAddr& ip, bool fExcludeDisconnecting) { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { + if (fExcludeDisconnecting && pnode->fDisconnect) { + continue; + } if ((CNetAddr)pnode->addr == ip) { return pnode; } @@ -334,10 +337,13 @@ CNode* CConnman::FindNode(const CNetAddr& ip) return nullptr; } -CNode* CConnman::FindNode(const CSubNet& subNet) +CNode* CConnman::FindNode(const CSubNet& subNet, bool fExcludeDisconnecting) { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { + if (fExcludeDisconnecting && pnode->fDisconnect) { + continue; + } if (subNet.Match((CNetAddr)pnode->addr)) { return pnode; } @@ -345,10 +351,13 @@ CNode* CConnman::FindNode(const CSubNet& subNet) return nullptr; } -CNode* CConnman::FindNode(const std::string& addrName) +CNode* CConnman::FindNode(const std::string& addrName, bool fExcludeDisconnecting) { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { + if (fExcludeDisconnecting && pnode->fDisconnect) { + continue; + } if (pnode->GetAddrName() == addrName) { return pnode; } @@ -356,10 +365,13 @@ CNode* CConnman::FindNode(const std::string& addrName) return nullptr; } -CNode* CConnman::FindNode(const CService& addr) +CNode* CConnman::FindNode(const CService& addr, bool fExcludeDisconnecting) { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { + if (fExcludeDisconnecting && pnode->fDisconnect) { + continue; + } if ((CService)pnode->addr == addr) { return pnode; } diff --git a/src/net.h b/src/net.h index 6fc04d36e1..da9965dae6 100644 --- a/src/net.h +++ b/src/net.h @@ -497,10 +497,10 @@ private: uint64_t CalculateKeyedNetGroup(const CAddress& ad) const; - CNode* FindNode(const CNetAddr& ip); - CNode* FindNode(const CSubNet& subNet); - CNode* FindNode(const std::string& addrName); - CNode* FindNode(const CService& addr); + CNode* FindNode(const CNetAddr& ip, bool fExcludeDisconnecting = true); + CNode* FindNode(const CSubNet& subNet, bool fExcludeDisconnecting = true); + CNode* FindNode(const std::string& addrName, bool fExcludeDisconnecting = true); + CNode* FindNode(const CService& addr, bool fExcludeDisconnecting = true); bool AttemptToEvictConnection(); CNode* ConnectNode(CAddress addrConnect, const char *pszDest = nullptr, bool fCountFailure = false);