diff --git a/src/init.cpp b/src/init.cpp index 03b47b3ef..202d51367 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -189,6 +189,7 @@ bool AppInit2(int argc, char* argv[]) " -connect= \t\t " + _("Connect only to the specified node") + "\n" + " -seednode= \t\t " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" + " -externalip= \t " + _("Specify your own public address") + "\n" + + " -blocknet= \t " + _("Do not connect to addresses in network net (ipv4, ipv6)") + "\n" + " -discover \t " + _("Try to discover public IP address (default: 1)") + "\n" + " -irc \t " + _("Find peers using internet relay chat (default: 0)") + "\n" + " -listen \t " + _("Accept connections from outside (default: 1)") + "\n" + @@ -560,6 +561,17 @@ bool AppInit2(int argc, char* argv[]) SoftSetBoolArg("-discover", false); } + if (mapArgs.count("-blocknet")) { + BOOST_FOREACH(std::string snet, mapMultiArgs["-blocknet"]) { + enum Network net = ParseNetwork(snet); + if (net == NET_UNROUTABLE) { + ThreadSafeMessageBox(_("Unknown network specified in -blocknet"), _("Bitcoin"), wxOK | wxMODAL); + return false; + } + SetLimited(net); + } + } + fNameLookup = GetBoolArg("-dns"); fProxyNameLookup = GetBoolArg("-proxydns"); if (fProxyNameLookup) diff --git a/src/net.cpp b/src/net.cpp index d407e6642..79d0a8ddb 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -48,6 +48,7 @@ uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); static CCriticalSection cs_mapLocalHost; static map mapLocalHost; static bool vfReachable[NET_MAX] = {}; +static bool vfLimited[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; uint64 nLocalHostNonce = 0; array vnThreadsRunning; @@ -225,7 +226,20 @@ bool AddLocal(const CNetAddr& addr, int nScore) return true; } -// vote for a local address +/** Make a particular network entirely off-limits (no automatic connects to it) */ +void SetLimited(enum Network net, bool fLimited) +{ + LOCK(cs_mapLocalHost); + vfLimited[net] = fLimited; +} + +bool IsLimited(const CNetAddr& addr) +{ + LOCK(cs_mapLocalHost); + return vfLimited[addr.GetNetwork()]; +} + +/** vote for a local address */ bool SeenLocal(const CNetAddr& addr) { { @@ -240,18 +254,19 @@ bool SeenLocal(const CNetAddr& addr) return true; } -// check whether a given address is potentially local +/** check whether a given address is potentially local */ bool IsLocal(const CNetAddr& addr) { LOCK(cs_mapLocalHost); return mapLocalHost.count(addr) > 0; } -// check whether a given address is in a network we can probably connect to +/** 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()]; + enum Network net = addr.GetNetwork(); + return vfReachable[net] && !vfLimited[net]; } bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet) @@ -1409,6 +1424,9 @@ void ThreadOpenConnections2(void* parg) nTries++; + if (IsLimited(addr)) + continue; + // only consider very recently tried nodes after 30 failed attempts if (nANow - addr.nLastTry < 600 && nTries < 30) continue; diff --git a/src/net.h b/src/net.h index 63f871204..be167b001 100644 --- a/src/net.h +++ b/src/net.h @@ -54,6 +54,8 @@ enum LOCAL_MAX }; +void SetLimited(enum Network net, bool fLimited = true); +bool IsLimited(const CNetAddr& addr); bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE); bool SeenLocal(const CNetAddr& addr); bool IsLocal(const CNetAddr& addr);