diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2014-06-21 13:34:36 +0200 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2014-07-09 20:40:14 +0200 |
commit | dc942e6f276b9fabc21f06d11cd16871d4054f82 (patch) | |
tree | 5ccbf11f0aec355fe115a606bb370125bb631d98 /src/init.cpp | |
parent | f3330b40a599615f15f585166ef08f00d06e9616 (diff) |
Introduce whitelisted peers.
This adds a -whitelist option to specify subnet ranges from which peers
that connect are whitelisted. In addition, there is a -whitebind option
which works like -bind, except peers connecting to it are also
whitelisted (allowing a separate listen port for trusted connections).
Being whitelisted has two effects (for now):
* They are immune to DoS disconnection/banning.
* Transactions they broadcast (which are valid) are always relayed,
even if they were already in the mempool. This means that a node
can function as a gateway for a local network, and that rebroadcasts
from the local network will work as expected.
Whitelisting replaces the magic exemption localhost had for DoS
disconnection (local addresses are still never banned, though), which
implied hidden service connects (from a localhost Tor node) were
incorrectly immune to DoS disconnection as well. This old
behaviour is removed for that reason, but can be restored using
-whitelist=127.0.0.1 or -whitelist=::1 can be specified. -whitebind
is safer to use in case non-trusted localhost connections are expected
(like hidden services).
Diffstat (limited to 'src/init.cpp')
-rw-r--r-- | src/init.cpp | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/src/init.cpp b/src/init.cpp index a1d75c9674..492070cbd9 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -58,7 +58,8 @@ CWallet* pwalletMain; enum BindFlags { BF_NONE = 0, BF_EXPLICIT = (1U << 0), - BF_REPORT_ERROR = (1U << 1) + BF_REPORT_ERROR = (1U << 1), + BF_WHITELIST = (1U << 2), }; static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; @@ -192,7 +193,7 @@ bool static Bind(const CService &addr, unsigned int flags) { if (!(flags & BF_EXPLICIT) && IsLimited(addr)) return false; std::string strError; - if (!BindListenPort(addr, strError)) { + if (!BindListenPort(addr, strError, flags & BF_WHITELIST)) { if (flags & BF_REPORT_ERROR) return InitError(strError); return false; @@ -253,6 +254,8 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 0)") + "\n"; #endif #endif + strUsage += " -whitebind=<addr> " + _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6") + "\n"; + strUsage += " -whitelist=<netmask> " + _("Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.") + "\n"; #ifdef ENABLE_WALLET strUsage += "\n" + _("Wallet options:") + "\n"; @@ -504,11 +507,11 @@ bool AppInit2(boost::thread_group& threadGroup) // ********************************************************* Step 2: parameter interactions - if (mapArgs.count("-bind")) { + if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) { // when specifying an explicit binding address, you want to listen on it // even when -connect or -proxy is specified if (SoftSetBoolArg("-listen", true)) - LogPrintf("AppInit2 : parameter interaction: -bind set -> setting -listen=1\n"); + LogPrintf("AppInit2 : parameter interaction: -bind or -whitebind set -> setting -listen=1\n"); } if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { @@ -552,7 +555,7 @@ bool AppInit2(boost::thread_group& threadGroup) } // Make sure enough file descriptors are available - int nBind = std::max((int)mapArgs.count("-bind"), 1); + int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1); nMaxConnections = GetArg("-maxconnections", 125); nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0); int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS); @@ -769,6 +772,15 @@ bool AppInit2(boost::thread_group& threadGroup) } } + if (mapArgs.count("-whitelist")) { + BOOST_FOREACH(const std::string& net, mapMultiArgs["-whitelist"]) { + CSubNet subnet(net); + if (!subnet.IsValid()) + return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net)); + CNode::AddWhitelistedRange(subnet); + } + } + CService addrProxy; bool fProxy = false; if (mapArgs.count("-proxy")) { @@ -805,13 +817,21 @@ bool AppInit2(boost::thread_group& threadGroup) bool fBound = false; if (fListen) { - if (mapArgs.count("-bind")) { + if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) { BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) { CService addrBind; if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind)); fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR)); } + BOOST_FOREACH(std::string strBind, mapMultiArgs["-whitebind"]) { + CService addrBind; + if (!Lookup(strBind.c_str(), addrBind, 0, false)) + return InitError(strprintf(_("Cannot resolve -whitebind address: '%s'"), strBind)); + if (addrBind.GetPort() == 0) + return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind)); + fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST)); + } } else { struct in_addr inaddr_any; |