aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init.cpp109
-rw-r--r--src/net.cpp62
-rw-r--r--src/net.h11
3 files changed, 103 insertions, 79 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 1f3a58e53b..88084cbeec 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -88,14 +88,6 @@ static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
#define MIN_CORE_FILEDESCRIPTORS 150
#endif
-/** Used to pass flags to the Bind() function */
-enum BindFlags {
- BF_NONE = 0,
- BF_EXPLICIT = (1U << 0),
- BF_REPORT_ERROR = (1U << 1),
- BF_WHITELIST = (1U << 2),
-};
-
static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat";
//////////////////////////////////////////////////////////////////////////////
@@ -296,17 +288,6 @@ static void registerSignalHandler(int signal, void(*handler)(int))
}
#endif
-bool static Bind(CConnman& connman, const CService &addr, unsigned int flags) {
- if (!(flags & BF_EXPLICIT) && IsLimited(addr))
- return false;
- std::string strError;
- if (!connman.BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) {
- if (flags & BF_REPORT_ERROR)
- return InitError(strError);
- return false;
- }
- return true;
-}
void OnRPCStarted()
{
uiInterface.NotifyBlockTip.connect(&RPCNotifyBlockChange);
@@ -898,10 +879,16 @@ bool AppInitParameterInteraction()
return InitError(_("Prune mode is incompatible with -txindex."));
}
+ // -bind and -whitebind can't be set when not listening
+ size_t nUserBind =
+ (gArgs.IsArgSet("-bind") ? gArgs.GetArgs("-bind").size() : 0) +
+ (gArgs.IsArgSet("-whitebind") ? gArgs.GetArgs("-whitebind").size() : 0);
+ if (nUserBind != 0 && !gArgs.GetBoolArg("-listen", DEFAULT_LISTEN)) {
+ return InitError("Cannot set -bind or -whitebind together with -listen=0");
+ }
+
// Make sure enough file descriptors are available
- int nBind = std::max(
- (gArgs.IsArgSet("-bind") ? gArgs.GetArgs("-bind").size() : 0) +
- (gArgs.IsArgSet("-whitebind") ? gArgs.GetArgs("-whitebind").size() : 0), size_t(1));
+ int nBind = std::max(nUserBind, size_t(1));
nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
nMaxConnections = std::max(nUserMaxConnections, 0);
@@ -1280,16 +1267,6 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
}
}
- if (gArgs.IsArgSet("-whitelist")) {
- for (const std::string& net : gArgs.GetArgs("-whitelist")) {
- CSubNet subnet;
- LookupSubNet(net.c_str(), subnet);
- if (!subnet.IsValid())
- return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net));
- connman.AddWhitelistedRange(subnet);
- }
- }
-
// Check for host lookup allowed before parsing any network related parameters
fNameLookup = GetBoolArg("-dns", DEFAULT_NAME_LOOKUP);
@@ -1340,36 +1317,6 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
fDiscover = GetBoolArg("-discover", true);
fRelayTxes = !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY);
- if (fListen) {
- bool fBound = false;
- if (gArgs.IsArgSet("-bind")) {
- for (const std::string& strBind : gArgs.GetArgs("-bind")) {
- CService addrBind;
- if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
- return InitError(ResolveErrMsg("bind", strBind));
- fBound |= Bind(connman, addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
- }
- }
- if (gArgs.IsArgSet("-whitebind")) {
- for (const std::string& strBind : gArgs.GetArgs("-whitebind")) {
- CService addrBind;
- if (!Lookup(strBind.c_str(), addrBind, 0, false))
- return InitError(ResolveErrMsg("whitebind", strBind));
- if (addrBind.GetPort() == 0)
- return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind));
- fBound |= Bind(connman, addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST));
- }
- }
- if (!gArgs.IsArgSet("-bind") && !gArgs.IsArgSet("-whitebind")) {
- struct in_addr inaddr_any;
- inaddr_any.s_addr = INADDR_ANY;
- fBound |= Bind(connman, CService(in6addr_any, GetListenPort()), BF_NONE);
- fBound |= Bind(connman, CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
- }
- if (!fBound)
- return InitError(_("Failed to listen on any port. Use -listen=0 if you want this."));
- }
-
if (gArgs.IsArgSet("-externalip")) {
for (const std::string& strAddr : gArgs.GetArgs("-externalip")) {
CService addrLocal;
@@ -1636,7 +1583,6 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
// Map ports with UPnP
MapPort(GetBoolArg("-upnp", DEFAULT_UPNP));
- std::string strNodeError;
CConnman::Options connOptions;
connOptions.nLocalServices = nLocalServices;
connOptions.nRelevantServices = nRelevantServices;
@@ -1652,12 +1598,45 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
connOptions.nMaxOutboundTimeframe = nMaxOutboundTimeframe;
connOptions.nMaxOutboundLimit = nMaxOutboundLimit;
+ if (gArgs.IsArgSet("-bind")) {
+ for (const std::string& strBind : gArgs.GetArgs("-bind")) {
+ CService addrBind;
+ if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) {
+ return InitError(ResolveErrMsg("bind", strBind));
+ }
+ connOptions.vBinds.push_back(addrBind);
+ }
+ }
+ if (gArgs.IsArgSet("-whitebind")) {
+ for (const std::string& strBind : gArgs.GetArgs("-whitebind")) {
+ CService addrBind;
+ if (!Lookup(strBind.c_str(), addrBind, 0, false)) {
+ return InitError(ResolveErrMsg("whitebind", strBind));
+ }
+ if (addrBind.GetPort() == 0) {
+ return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind));
+ }
+ connOptions.vWhiteBinds.push_back(addrBind);
+ }
+ }
+
+ if (gArgs.IsArgSet("-whitelist")) {
+ for (const auto& net : gArgs.GetArgs("-whitelist")) {
+ CSubNet subnet;
+ LookupSubNet(net.c_str(), subnet);
+ if (!subnet.IsValid())
+ return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net));
+ connOptions.vWhitelistedRange.push_back(subnet);
+ }
+ }
+
if (gArgs.IsArgSet("-seednode")) {
connOptions.vSeedNodes = gArgs.GetArgs("-seednode");
}
- if (!connman.Start(scheduler, strNodeError, connOptions))
- return InitError(strNodeError);
+ if (!connman.Start(scheduler, connOptions)) {
+ return false;
+ }
// ********************************************************* Step 12: finished
diff --git a/src/net.cpp b/src/net.cpp
index 43bd0eb0d5..91a62626a2 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -64,6 +64,14 @@
#endif
#endif
+/** Used to pass flags to the Bind() function */
+enum BindFlags {
+ BF_NONE = 0,
+ BF_EXPLICIT = (1U << 0),
+ BF_REPORT_ERROR = (1U << 1),
+ BF_WHITELIST = (1U << 2),
+};
+
const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
@@ -601,7 +609,6 @@ void CConnman::SetBannedSetDirty(bool dirty)
bool CConnman::IsWhitelistedRange(const CNetAddr &addr) {
- LOCK(cs_vWhitelistedRange);
for (const CSubNet& subnet : vWhitelistedRange) {
if (subnet.Match(addr))
return true;
@@ -609,12 +616,6 @@ bool CConnman::IsWhitelistedRange(const CNetAddr &addr) {
return false;
}
-void CConnman::AddWhitelistedRange(const CSubNet &subnet) {
- LOCK(cs_vWhitelistedRange);
- vWhitelistedRange.push_back(subnet);
-}
-
-
std::string CNode::GetAddrName() const {
LOCK(cs_addrName);
return addrName;
@@ -2220,7 +2221,38 @@ NodeId CConnman::GetNewNodeId()
return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
}
-bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options connOptions)
+
+bool CConnman::Bind(const CService &addr, unsigned int flags) {
+ if (!(flags & BF_EXPLICIT) && IsLimited(addr))
+ return false;
+ std::string strError;
+ if (!BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) {
+ if ((flags & BF_REPORT_ERROR) && clientInterface) {
+ clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
+ }
+ return false;
+ }
+ return true;
+}
+
+bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<CService>& whiteBinds) {
+ bool fBound = false;
+ for (const auto& addrBind : binds) {
+ fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
+ }
+ for (const auto& addrBind : whiteBinds) {
+ fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST));
+ }
+ if (binds.empty() && whiteBinds.empty()) {
+ struct in_addr inaddr_any;
+ inaddr_any.s_addr = INADDR_ANY;
+ fBound |= Bind(CService(in6addr_any, GetListenPort()), BF_NONE);
+ fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
+ }
+ return fBound;
+}
+
+bool CConnman::Start(CScheduler& scheduler, Options connOptions)
{
nTotalBytesRecv = 0;
nTotalBytesSent = 0;
@@ -2242,11 +2274,23 @@ bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options c
SetBestHeight(connOptions.nBestHeight);
+ clientInterface = connOptions.uiInterface;
+
+ if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) {
+ if (clientInterface) {
+ clientInterface->ThreadSafeMessageBox(
+ _("Failed to listen on any port. Use -listen=0 if you want this."),
+ "", CClientUIInterface::MSG_ERROR);
+ }
+ return false;
+ }
+
+ vWhitelistedRange = connOptions.vWhitelistedRange;
+
for (const auto& strDest : connOptions.vSeedNodes) {
AddOneShot(strDest);
}
- clientInterface = connOptions.uiInterface;
if (clientInterface) {
clientInterface->InitMessage(_("Loading P2P addresses..."));
}
diff --git a/src/net.h b/src/net.h
index a6aea189f9..dc25e7a5dd 100644
--- a/src/net.h
+++ b/src/net.h
@@ -144,13 +144,14 @@ public:
uint64_t nMaxOutboundTimeframe = 0;
uint64_t nMaxOutboundLimit = 0;
std::vector<std::string> vSeedNodes;
+ std::vector<CSubNet> vWhitelistedRange;
+ std::vector<CService> vBinds, vWhiteBinds;
};
CConnman(uint64_t seed0, uint64_t seed1);
~CConnman();
- bool Start(CScheduler& scheduler, std::string& strNodeError, Options options);
+ bool Start(CScheduler& scheduler, Options options);
void Stop();
void Interrupt();
- bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
bool GetNetworkActive() const { return fNetworkActive; };
void SetNetworkActive(bool active);
bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false, bool fFeeler = false, bool fAddnode = false);
@@ -244,8 +245,6 @@ public:
unsigned int GetSendBufferSize() const;
- void AddWhitelistedRange(const CSubNet &subnet);
-
ServiceFlags GetLocalServices() const;
//!set the max outbound target in bytes
@@ -289,6 +288,9 @@ private:
ListenSocket(SOCKET socket_, bool whitelisted_) : socket(socket_), whitelisted(whitelisted_) {}
};
+ bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
+ bool Bind(const CService &addr, unsigned int flags);
+ bool InitBinds(const std::vector<CService>& binds, const std::vector<CService>& whiteBinds);
void ThreadOpenAddedConnections();
void AddOneShot(const std::string& strDest);
void ProcessOneShot();
@@ -346,7 +348,6 @@ private:
// Whitelisted ranges. Any node connecting from these is automatically
// whitelisted (as well as those connecting to whitelisted binds).
std::vector<CSubNet> vWhitelistedRange;
- CCriticalSection cs_vWhitelistedRange;
unsigned int nSendBufferMaxSize;
unsigned int nReceiveFloodSize;