diff options
author | Cory Fields <cory-nospam-@coryfields.com> | 2016-04-17 20:21:58 -0400 |
---|---|---|
committer | Cory Fields <cory-nospam-@coryfields.com> | 2016-09-08 12:24:06 -0400 |
commit | 960cf2e4058a9c195bf64e1aecb46024f9ef022a (patch) | |
tree | 4f1400221f79419d8942fe48961c4ef24886c0e3 /src | |
parent | 551e0887db9034b1e6490a267ba864b1d26ff469 (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | src/net.cpp | 14 | ||||
-rw-r--r-- | src/net.h | 7 |
3 files changed, 19 insertions, 4 deletions
diff --git a/src/main.cpp b/src/main.cpp index af598d4873..43ccb6374c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5025,7 +5025,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // Disconnect if we connected to ourself - if (nNonce == nLocalHostNonce && nNonce > 1) + if (pfrom->fInbound && !connman.CheckIncomingNonce(nNonce)) { LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString()); pfrom->fDisconnect = true; diff --git a/src/net.cpp b/src/net.cpp index 8bc8ecc436..71b4b01688 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -83,7 +83,6 @@ CCriticalSection cs_mapLocalHost; std::map<CNetAddr, LocalServiceInfo> mapLocalHost; static bool vfLimited[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; -uint64_t nLocalHostNonce = 0; int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS; std::string strSubVersion; @@ -346,6 +345,16 @@ CNode* CConnman::FindNode(const CService& addr) return NULL; } +bool CConnman::CheckIncomingNonce(uint64_t nonce) +{ + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) { + if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce) + return false; + } + return true; +} + CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure) { if (pszDest == NULL) { @@ -465,7 +474,6 @@ void CNode::PushVersion() int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService(), addr.nServices)); CAddress addrMe = GetLocalAddress(&addr); - GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); if (fLogIPs) LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id); else @@ -2535,6 +2543,8 @@ CNode::CNode(NodeId idIn, SOCKET hSocketIn, const CAddress& addrIn, const std::s nextSendTimeFeeFilter = 0; id = idIn; + GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); + BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) mapRecvBytesPerMsgCmd[msg] = 0; mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; @@ -114,6 +114,7 @@ public: void Stop(); bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false); bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false, bool fFeeler = false); + bool CheckIncomingNonce(uint64_t nonce); bool ForNode(NodeId id, std::function<bool(CNode* pnode)> func); bool ForEachNode(std::function<bool(CNode* pnode)> func); @@ -297,7 +298,6 @@ extern bool fListen; extern ServiceFlags nLocalServices; extern ServiceFlags nRelevantServices; extern bool fRelayTxes; -extern uint64_t nLocalHostNonce; /** Maximum number of connections to simultaneously allow (aka connection slots) */ extern int nMaxConnections; @@ -523,12 +523,17 @@ private: static uint64_t CalculateKeyedNetGroup(const CAddress& ad); + uint64_t nLocalHostNonce; public: NodeId GetId() const { return id; } + uint64_t GetLocalNonce() const { + return nLocalHostNonce; + } + int GetRefCount() { assert(nRefCount >= 0); |