diff --git a/main.cpp b/main.cpp index aef68838cb..13b7828dd5 100644 --- a/main.cpp +++ b/main.cpp @@ -1926,7 +1926,9 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { vector vAddr; vRecv >> vAddr; - if (vAddr.size() > 50000) // lower this to 1000 later + if (pfrom->nVersion < 200) // don't want addresses from 0.1.5 + return true; + if (vAddr.size() > 1000) return error("message addr size() = %d", vAddr.size()); // Store the new addresses @@ -2311,6 +2313,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) if (pto->setAddrKnown.insert(addr).second) { vAddr.push_back(addr); + // receiver rejects addr messages larger than 1000 if (vAddr.size() >= 1000) { pto->PushMessage("addr", vAddr); diff --git a/net.cpp b/net.cpp index c5659dc923..59d40dc121 100644 --- a/net.cpp +++ b/net.cpp @@ -968,9 +968,9 @@ bool OpenNetworkConnection(const CAddress& addrConnect) if (addrLocalHost.IsRoutable() && !fUseProxy) { // Advertise our address - vector vAddrToSend; - vAddrToSend.push_back(addrLocalHost); - pnode->PushMessage("addr", vAddrToSend); + vector vAddr; + vAddr.push_back(addrLocalHost); + pnode->PushMessage("addr", vAddr); } // Get as many addresses as we can diff --git a/net.h b/net.h index 9ce848f636..11197cc429 100644 --- a/net.h +++ b/net.h @@ -289,16 +289,24 @@ public: bool IsRoutable() const { - return !(GetByte(3) == 10 || - (GetByte(3) == 192 && GetByte(2) == 168) || - GetByte(3) == 127 || - GetByte(3) == 0 || - ip == 0 || - ip == INADDR_NONE); + return IsValid() && + !(GetByte(3) == 10 || + (GetByte(3) == 192 && GetByte(2) == 168) || + GetByte(3) == 127 || + GetByte(3) == 0); } bool IsValid() const { + // Clean up 3-byte shifted addresses caused by garbage in size field + // of addr messages from versions before 0.2.9 checksum. + // Two consecutive addr messages look like this: + // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26... + // so if the first length field is garbled, it reads the second batch + // of addr misaligned by 3 bytes. + if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0) + return false; + return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX)); } @@ -619,7 +627,7 @@ 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 (!setAddrKnown.count(addr)) + if (addr.IsValid() && !setAddrKnown.count(addr)) vAddrToSend.push_back(addr); } diff --git a/serialize.h b/serialize.h index 25dcfb4746..f2d368986a 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 210; +static const int VERSION = 211; static const char* pszSubVer = ".0";