# HG changeset patch # User Pieter Wuille # Date 1334082124 -7200 # Node ID 3513aef58df1111f140c691c6a453d7ec34af160 # Parent f8e75c9db98ac46d4bfe4653ac01f6bc339389a6 Limited relaying/storing of foreign addresses Introduce a boolean variable for each "network" (ipv4, ipv6, tor, i2p), and track whether we are likely to able to connect to it. Addresses in "addr" messages outside of our network get limited relaying and are not stored in addrman. diff --git a/src/main.cpp b/src/main.cpp --- a/src/main.cpp +++ b/src/main.cpp @@ -2418,6 +2418,7 @@ } // Store the new addresses + vector vAddrOk; int64 nNow = GetAdjustedTime(); int64 nSince = nNow - 10 * 60; BOOST_FOREACH(CAddress& addr, vAddr) @@ -2427,6 +2428,7 @@ if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) addr.nTime = nNow - 5 * 24 * 60 * 60; pfrom->AddAddressKnown(addr); + bool fReachable = IsReachable(addr); if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) { // Relay to a limited number of other nodes @@ -2451,13 +2453,16 @@ hashKey = Hash(BEGIN(hashKey), END(hashKey)); mapMix.insert(make_pair(hashKey, pnode)); } - int nRelayNodes = 2; + int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s) for (multimap::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) ((*mi).second)->PushAddress(addr); } } + // Do not store addresses outside our network + if (fReachable) + vAddrOk.push_back(addr); } - addrman.Add(vAddr, pfrom->addr, 2 * 60 * 60); + addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60); if (vAddr.size() < 1000) pfrom->fGetAddr = false; if (pfrom->fOneShot) diff --git a/src/net.cpp b/src/net.cpp --- a/src/net.cpp +++ b/src/net.cpp @@ -45,8 +45,9 @@ bool fClient = false; static bool fUseUPnP = false; uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); -CCriticalSection cs_mapLocalHost; -map mapLocalHost; +static CCriticalSection cs_mapLocalHost; +static map mapLocalHost; +static bool vfReachable[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; uint64 nLocalHostNonce = 0; array vnThreadsRunning; @@ -214,6 +215,9 @@ { LOCK(cs_mapLocalHost); mapLocalHost[addr] = std::max(nScore, mapLocalHost[addr]) + (mapLocalHost.count(addr) ? 1 : 0); + enum Network net = addr.GetNetwork(); + vfReachable[net] = true; + if (net == NET_IPV6) vfReachable[NET_IPV4] = true; } AdvertizeLocal(); @@ -243,6 +247,12 @@ return mapLocalHost.count(addr) > 0; } +// check whether a given address is in a network we can probably connect to +bool IsReachable(const CNetAddr& addr) +{ + LOCK(cs_mapLocalHost); + return vfReachable[addr.GetNetwork()]; +} bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet) { diff --git a/src/net.h b/src/net.h --- a/src/net.h +++ b/src/net.h @@ -58,8 +58,10 @@ bool SeenLocal(const CNetAddr& addr); bool IsLocal(const CNetAddr& addr); bool GetLocal(CNetAddr &addr, const CNetAddr *paddrPeer = NULL); +bool IsReachable(const CNetAddr &addr); CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); + enum { MSG_TX = 1, diff --git a/src/netbase.cpp b/src/netbase.cpp --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -25,6 +25,14 @@ static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; +enum Network ParseNetwork(std::string net) { + if (net == "ipv4") return NET_IPV4; + if (net == "ipv6") return NET_IPV6; + if (net == "tor") return NET_TOR; + if (net == "i2p") return NET_I2P; + return NET_UNROUTABLE; +} + bool static LookupIntern(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup) { vIP.clear(); @@ -688,6 +696,23 @@ return IsValid() && !(IsRFC1918() || IsRFC3927() || IsRFC4862() || (IsRFC4193() && !IsOnionCat() && !IsGarliCat()) || IsRFC4843() || IsLocal()); } +enum Network CNetAddr::GetNetwork() const +{ + if (!IsRoutable()) + return NET_UNROUTABLE; + + if (IsIPv4()) + return NET_IPV4; + + if (IsOnionCat()) + return NET_TOR; + + if (IsGarliCat()) + return NET_I2P; + + return NET_IPV6; +} + std::string CNetAddr::ToStringIP() const { if (IsIPv4()) diff --git a/src/netbase.h b/src/netbase.h --- a/src/netbase.h +++ b/src/netbase.h @@ -17,6 +17,19 @@ #undef SetPort #endif +enum Network +{ + NET_UNROUTABLE, + NET_IPV4, + NET_IPV6, + NET_TOR, + NET_I2P, + + NET_MAX +}; + +enum Network ParseNetwork(std::string net); + /** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */ class CNetAddr { @@ -48,6 +61,7 @@ bool IsRoutable() const; bool IsValid() const; bool IsMulticast() const; + enum Network GetNetwork() const; std::string ToString() const; std::string ToStringIP() const; int GetByte(int n) const;