aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;