aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2012-04-10 20:22:04 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2012-05-11 15:29:19 +0200
commit090e5b40f1b3ac9ac6209f8996da4d686686a2ac (patch)
treec26367aef8abd697b3f035e2340dcb407cd3424f
parentd32148567f5866a7cd2a77a2f44f846134011c9c (diff)
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.
-rw-r--r--src/main.cpp9
-rw-r--r--src/net.cpp14
-rw-r--r--src/net.h2
-rw-r--r--src/netbase.cpp25
-rw-r--r--src/netbase.h14
5 files changed, 60 insertions, 4 deletions
diff --git a/src/main.cpp b/src/main.cpp
index f9691a5d52..5f16378b41 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2418,6 +2418,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
// Store the new addresses
+ vector<CAddress> vAddrOk;
int64 nNow = GetAdjustedTime();
int64 nSince = nNow - 10 * 60;
BOOST_FOREACH(CAddress& addr, vAddr)
@@ -2427,6 +2428,7 @@ 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);
+ 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 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
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<uint256, CNode*>::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
index 75c8bbabaf..d407e66420 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -45,8 +45,9 @@ bool OpenNetworkConnection(const CAddress& addrConnect, const char *strDest = NU
bool fClient = false;
static bool fUseUPnP = false;
uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
-CCriticalSection cs_mapLocalHost;
-map<CNetAddr, int> mapLocalHost;
+static CCriticalSection cs_mapLocalHost;
+static map<CNetAddr, int> mapLocalHost;
+static bool vfReachable[NET_MAX] = {};
static CNode* pnodeLocalHost = NULL;
uint64 nLocalHostNonce = 0;
array<int, THREAD_MAX> vnThreadsRunning;
@@ -214,6 +215,9 @@ bool AddLocal(const CNetAddr& addr, int nScore)
{
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 @@ bool IsLocal(const CNetAddr& addr)
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
index a00dd1b8cc..63f8712040 100644
--- a/src/net.h
+++ b/src/net.h
@@ -58,8 +58,10 @@ bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
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
index 37e6120e7f..4c852f5eee 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -25,6 +25,14 @@ int nConnectTimeout = 5000;
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<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
{
vIP.clear();
@@ -688,6 +696,23 @@ bool CNetAddr::IsRoutable() const
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
index 1b6d8d59bb..998f8eaf14 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -17,6 +17,19 @@ extern int nConnectTimeout;
#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 @@ class CNetAddr
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;