diff --git a/src/main.cpp b/src/main.cpp index bc7613e10..8559372ca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7132,7 +7132,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) addr.nTime = nNow - 5 * 24 * 60 * 60; - pfrom->AddAddressKnown(addr); + pfrom->AddAddressIfNotAlreadyKnown(addr); + ++num_proc; bool fReachable = IsReachable(addr); if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) @@ -7988,9 +7989,8 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vAddr.reserve(pto->vAddrToSend.size()); BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend) { - if (!pto->addrKnown.contains(addr.GetKey())) + if (pto->AddAddressIfNotAlreadyKnown(addr)) { - pto->addrKnown.insert(addr.GetKey()); vAddr.push_back(addr); if (vAddr.size() >= MAX_ADDR_TO_SEND) diff --git a/src/net.cpp b/src/net.cpp index 0b38efc86..b460f3c37 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -556,6 +556,10 @@ void CNode::CloseSocketDisconnect() CloseSocket(hSocket); } } + { + LOCK(cs_addrKnown); + addrKnown.reset(); + } // in case this fails, we'll empty the recv buffer when the CNode is deleted TRY_LOCK(cs_vRecvMsg, lockRecv); diff --git a/src/net.h b/src/net.h index 53d8d376a..95e1c58f0 100644 --- a/src/net.h +++ b/src/net.h @@ -432,6 +432,8 @@ public: CCriticalSection cs_filter; CBloomFilter* pfilter; int nRefCount; + CRollingBloomFilter addrKnown; + mutable CCriticalSection cs_addrKnown; NodeId id; /** @@ -478,7 +480,6 @@ public: // flood relay std::vector vAddrToSend; - CRollingBloomFilter addrKnown; bool fGetAddr; std::set setKnown; @@ -561,11 +562,25 @@ public: nRefCount--; } - - - void AddAddressKnown(const CAddress& _addr) + bool AddAddressIfNotAlreadyKnown(const CAddress& addr) { - addrKnown.insert(_addr.GetKey()); + LOCK(cs_addrKnown); + // Avoid adding to addrKnown after it has been reset in CloseSocketDisconnect. + if (fDisconnect) { + return false; + } + if (!addrKnown.contains(addr.GetKey())) { + addrKnown.insert(addr.GetKey()); + return true; + } else { + return false; + } + } + + bool IsAddressKnown(const CAddress& addr) const + { + LOCK(cs_addrKnown); + return addrKnown.contains(addr.GetKey()); } void PushAddress(const CAddress& _addr) @@ -578,7 +593,8 @@ public: // Known checking here is only to save space from duplicates. // SendMessages will filter it again for knowns that were added // after addresses were pushed. - if (_addr.IsValid() && !addrKnown.contains(_addr.GetKey()) && addr_format_supported) { + if (_addr.IsValid() && !IsAddressKnown(addr) && addr_format_supported) { + if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) { vAddrToSend[insecure_rand() % vAddrToSend.size()] = _addr; } else {