aboutsummaryrefslogtreecommitdiff
path: root/src/net.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net.cpp')
-rw-r--r--src/net.cpp241
1 files changed, 131 insertions, 110 deletions
diff --git a/src/net.cpp b/src/net.cpp
index ca9a173abe..ea3840a708 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -89,10 +89,6 @@ std::string strSubVersion;
limitedmap<uint256, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
-// Signals for message handling
-static CNodeSignals g_signals;
-CNodeSignals& GetNodeSignals() { return g_signals; }
-
void CConnman::AddOneShot(const std::string& strDest)
{
LOCK(cs_vOneShots);
@@ -101,7 +97,7 @@ void CConnman::AddOneShot(const std::string& strDest)
unsigned short GetListenPort()
{
- return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
+ return (unsigned short)(gArgs.GetArg("-port", Params().GetDefaultPort()));
}
// find 'best' local address for a particular peer
@@ -139,11 +135,10 @@ static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn
const int64_t nOneWeek = 7*24*60*60;
std::vector<CAddress> vSeedsOut;
vSeedsOut.reserve(vSeedsIn.size());
- for (std::vector<SeedSpec6>::const_iterator i(vSeedsIn.begin()); i != vSeedsIn.end(); ++i)
- {
+ for (const auto& seed_in : vSeedsIn) {
struct in6_addr ip;
- memcpy(&ip, i->addr, sizeof(ip));
- CAddress addr(CService(ip, i->port), NODE_NETWORK);
+ memcpy(&ip, seed_in.addr, sizeof(ip));
+ CAddress addr(CService(ip, seed_in.port), NODE_NETWORK);
addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
vSeedsOut.push_back(addr);
}
@@ -303,19 +298,23 @@ bool IsReachable(const CNetAddr& addr)
CNode* CConnman::FindNode(const CNetAddr& ip)
{
LOCK(cs_vNodes);
- for (CNode* pnode : vNodes)
- if ((CNetAddr)pnode->addr == ip)
- return (pnode);
- return NULL;
+ for (CNode* pnode : vNodes) {
+ if ((CNetAddr)pnode->addr == ip) {
+ return pnode;
+ }
+ }
+ return nullptr;
}
CNode* CConnman::FindNode(const CSubNet& subNet)
{
LOCK(cs_vNodes);
- for (CNode* pnode : vNodes)
- if (subNet.Match((CNetAddr)pnode->addr))
- return (pnode);
- return NULL;
+ for (CNode* pnode : vNodes) {
+ if (subNet.Match((CNetAddr)pnode->addr)) {
+ return pnode;
+ }
+ }
+ return nullptr;
}
CNode* CConnman::FindNode(const std::string& addrName)
@@ -323,19 +322,21 @@ CNode* CConnman::FindNode(const std::string& addrName)
LOCK(cs_vNodes);
for (CNode* pnode : vNodes) {
if (pnode->GetAddrName() == addrName) {
- return (pnode);
+ return pnode;
}
}
- return NULL;
+ return nullptr;
}
CNode* CConnman::FindNode(const CService& addr)
{
LOCK(cs_vNodes);
- for (CNode* pnode : vNodes)
- if ((CService)pnode->addr == addr)
- return (pnode);
- return NULL;
+ for (CNode* pnode : vNodes) {
+ if ((CService)pnode->addr == addr) {
+ return pnode;
+ }
+ }
+ return nullptr;
}
bool CConnman::CheckIncomingNonce(uint64_t nonce)
@@ -366,16 +367,16 @@ static CAddress GetBindAddress(SOCKET sock)
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure)
{
- if (pszDest == NULL) {
+ if (pszDest == nullptr) {
if (IsLocal(addrConnect))
- return NULL;
+ return nullptr;
// Look for an existing connection
CNode* pnode = FindNode((CService)addrConnect);
if (pnode)
{
LogPrintf("Failed to open new connection, already connected\n");
- return NULL;
+ return nullptr;
}
}
@@ -384,19 +385,16 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
pszDest ? pszDest : addrConnect.ToString(),
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
- // Connect
- SOCKET hSocket;
- bool proxyConnectionFailed = false;
- if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) :
- ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed))
- {
- if (!IsSelectableSocket(hSocket)) {
- LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
- CloseSocket(hSocket);
- return NULL;
- }
-
- if (pszDest && addrConnect.IsValid()) {
+ // Resolve
+ const int default_port = Params().GetDefaultPort();
+ if (pszDest) {
+ std::vector<CService> resolved;
+ if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
+ addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
+ if (!addrConnect.IsValid()) {
+ LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s", addrConnect.ToString(), pszDest);
+ return nullptr;
+ }
// It is possible that we already have a connection to the IP/port pszDest resolved to.
// In that case, drop the connection that was just created, and return the existing CNode instead.
// Also store the name we used to connect in that CNode, so that future FindNode() calls to that
@@ -406,13 +404,40 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
if (pnode)
{
pnode->MaybeSetAddrName(std::string(pszDest));
- CloseSocket(hSocket);
LogPrintf("Failed to open new connection, already connected\n");
- return NULL;
+ return nullptr;
}
}
+ }
- addrman.Attempt(addrConnect, fCountFailure);
+ // Connect
+ bool connected = false;
+ SOCKET hSocket;
+ proxyType proxy;
+ if (addrConnect.IsValid()) {
+ bool proxyConnectionFailed = false;
+
+ if (GetProxy(addrConnect.GetNetwork(), proxy))
+ connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, &proxyConnectionFailed);
+ else // no proxy needed (none set for target network)
+ connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout);
+ if (!proxyConnectionFailed) {
+ // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
+ // the proxy, mark this as an attempt.
+ addrman.Attempt(addrConnect, fCountFailure);
+ }
+ } else if (pszDest && GetNameProxy(proxy)) {
+ std::string host;
+ int port = default_port;
+ SplitHostPort(std::string(pszDest), port, host);
+ connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, nullptr);
+ }
+ if (connected) {
+ if (!IsSelectableSocket(hSocket)) {
+ LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
+ CloseSocket(hSocket);
+ return nullptr;
+ }
// Add node
NodeId id = GetNewNodeId();
@@ -423,13 +448,9 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
pnode->AddRef();
return pnode;
- } else if (!proxyConnectionFailed) {
- // If connecting to the node failed, and failure is not caused by a problem connecting to
- // the proxy, mark this as an attempt.
- addrman.Attempt(addrConnect, fCountFailure);
}
- return NULL;
+ return nullptr;
}
void CConnman::DumpBanlist()
@@ -478,10 +499,9 @@ void CConnman::ClearBanned()
bool CConnman::IsBanned(CNetAddr ip)
{
LOCK(cs_setBanned);
- for (banmap_t::iterator it = setBanned.begin(); it != setBanned.end(); it++)
- {
- CSubNet subNet = (*it).first;
- CBanEntry banEntry = (*it).second;
+ for (const auto& it : setBanned) {
+ CSubNet subNet = it.first;
+ CBanEntry banEntry = it.second;
if (subNet.Match(ip) && GetTime() < banEntry.nBanUntil) {
return true;
@@ -514,7 +534,7 @@ void CConnman::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t ba
banEntry.banReason = banReason;
if (bantimeoffset <= 0)
{
- bantimeoffset = GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME);
+ bantimeoffset = gArgs.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME);
sinceUnixEpoch = false;
}
banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset;
@@ -956,7 +976,7 @@ bool CConnman::AttemptToEvictConnection()
{
LOCK(cs_vNodes);
- for (CNode *node : vNodes) {
+ for (const CNode* node : vNodes) {
if (node->fWhitelisted)
continue;
if (!node->fInbound)
@@ -966,7 +986,7 @@ bool CConnman::AttemptToEvictConnection()
NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->nMinPingUsecTime,
node->nLastBlockTime, node->nLastTXTime,
(node->nServices & nRelevantServices) == nRelevantServices,
- node->fRelayTxes, node->pfilter != NULL, node->addr, node->nKeyedNetGroup};
+ node->fRelayTxes, node->pfilter != nullptr, node->addr, node->nKeyedNetGroup};
vEvictionCandidates.push_back(candidate);
}
}
@@ -1034,9 +1054,9 @@ bool CConnman::AttemptToEvictConnection()
// Disconnect from the network group with the most connections
NodeId evicted = vEvictionCandidates.front().id;
LOCK(cs_vNodes);
- for(std::vector<CNode*>::const_iterator it(vNodes.begin()); it != vNodes.end(); ++it) {
- if ((*it)->GetId() == evicted) {
- (*it)->fDisconnect = true;
+ for (CNode* pnode : vNodes) {
+ if (pnode->GetId() == evicted) {
+ pnode->fDisconnect = true;
return true;
}
}
@@ -1060,9 +1080,9 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
bool whitelisted = hListenSocket.whitelisted || IsWhitelistedRange(addr);
{
LOCK(cs_vNodes);
- for (CNode* pnode : vNodes)
- if (pnode->fInbound)
- nInbound++;
+ for (const CNode* pnode : vNodes) {
+ if (pnode->fInbound) nInbound++;
+ }
}
if (hSocket == INVALID_SOCKET)
@@ -1114,7 +1134,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", true);
pnode->AddRef();
pnode->fWhitelisted = whitelisted;
- GetNodeSignals().InitializeNode(pnode, *this);
+ m_msgproc->InitializeNode(pnode);
LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
@@ -1438,9 +1458,9 @@ void CConnman::WakeMessageHandler()
void ThreadMapPort()
{
std::string port = strprintf("%u", GetListenPort());
- const char * multicastif = 0;
- const char * minissdpdpath = 0;
- struct UPNPDev * devlist = 0;
+ const char * multicastif = nullptr;
+ const char * minissdpdpath = nullptr;
+ struct UPNPDev * devlist = nullptr;
char lanaddr[64];
#ifndef UPNPDISCOVER_SUCCESS
@@ -1510,13 +1530,13 @@ void ThreadMapPort()
{
r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
- freeUPNPDevlist(devlist); devlist = 0;
+ freeUPNPDevlist(devlist); devlist = nullptr;
FreeUPNPUrls(&urls);
throw;
}
} else {
LogPrintf("No valid UPnP IGDs found\n");
- freeUPNPDevlist(devlist); devlist = 0;
+ freeUPNPDevlist(devlist); devlist = nullptr;
if (r != 0)
FreeUPNPUrls(&urls);
}
@@ -1524,7 +1544,7 @@ void ThreadMapPort()
void MapPort(bool fUseUPnP)
{
- static boost::thread* upnp_thread = NULL;
+ static boost::thread* upnp_thread = nullptr;
if (fUseUPnP)
{
@@ -1539,7 +1559,7 @@ void MapPort(bool fUseUPnP)
upnp_thread->interrupt();
upnp_thread->join();
delete upnp_thread;
- upnp_thread = NULL;
+ upnp_thread = nullptr;
}
}
@@ -1575,7 +1595,7 @@ void CConnman::ThreadDNSAddressSeed()
// creating fewer identifying DNS requests, reduces trust by giving seeds
// less influence on the network topology, and reduces traffic to the seeds.
if ((addrman.size() > 0) &&
- (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) {
+ (!gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) {
if (!interruptNet.sleep_for(std::chrono::seconds(11)))
return;
@@ -1674,18 +1694,18 @@ void CConnman::ProcessOneShot()
}
}
-void CConnman::ThreadOpenConnections()
+void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
{
// Connect to specific addresses
- if (gArgs.IsArgSet("-connect"))
+ if (!connect.empty())
{
for (int64_t nLoop = 0;; nLoop++)
{
ProcessOneShot();
- for (const std::string& strAddr : gArgs.GetArgs("-connect"))
+ for (const std::string& strAddr : connect)
{
CAddress addr(CService(), NODE_NONE);
- OpenNetworkConnection(addr, false, NULL, strAddr.c_str());
+ OpenNetworkConnection(addr, false, nullptr, strAddr.c_str());
for (int i = 0; i < 10 && i < nLoop; i++)
{
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
@@ -1841,7 +1861,7 @@ void CConnman::ThreadOpenConnections()
LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
}
- OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, NULL, false, fFeeler);
+ OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, false, fFeeler);
}
}
}
@@ -1854,8 +1874,7 @@ std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo()
{
LOCK(cs_vAddedNodes);
ret.reserve(vAddedNodes.size());
- for (const std::string& strAddNode : vAddedNodes)
- lAddresses.push_back(strAddNode);
+ std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
}
@@ -1901,11 +1920,6 @@ std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo()
void CConnman::ThreadOpenAddedConnections()
{
- {
- LOCK(cs_vAddedNodes);
- vAddedNodes = gArgs.GetArgs("-addnode");
- }
-
while (true)
{
CSemaphoreGrant grant(*semAddnode);
@@ -1918,11 +1932,9 @@ void CConnman::ThreadOpenAddedConnections()
// the addednodeinfo state might change.
break;
}
- // If strAddedNode is an IP/port, decode it immediately, so
- // OpenNetworkConnection can detect existing connections to that IP/port.
tried = true;
- CService service(LookupNumeric(info.strAddedNode.c_str(), Params().GetDefaultPort()));
- OpenNetworkConnection(CAddress(service, NODE_NONE), false, &grant, info.strAddedNode.c_str(), false, false, true);
+ CAddress addr(CService(), NODE_NONE);
+ OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), false, false, true);
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
return;
}
@@ -1966,7 +1978,7 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
if (fAddnode)
pnode->fAddnode = true;
- GetNodeSignals().InitializeNode(pnode, *this);
+ m_msgproc->InitializeNode(pnode);
{
LOCK(cs_vNodes);
vNodes.push_back(pnode);
@@ -1996,16 +2008,16 @@ void CConnman::ThreadMessageHandler()
continue;
// Receive messages
- bool fMoreNodeWork = GetNodeSignals().ProcessMessages(pnode, *this, flagInterruptMsgProc);
+ bool fMoreNodeWork = m_msgproc->ProcessMessages(pnode, flagInterruptMsgProc);
fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
if (flagInterruptMsgProc)
return;
-
// Send messages
{
LOCK(pnode->cs_sendProcessing);
- GetNodeSignals().SendMessages(pnode, *this, flagInterruptMsgProc);
+ m_msgproc->SendMessages(pnode, flagInterruptMsgProc);
}
+
if (flagInterruptMsgProc)
return;
}
@@ -2153,9 +2165,9 @@ void Discover(boost::thread_group& threadGroup)
struct ifaddrs* myaddrs;
if (getifaddrs(&myaddrs) == 0)
{
- for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
+ for (struct ifaddrs* ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next)
{
- if (ifa->ifa_addr == NULL) continue;
+ if (ifa->ifa_addr == nullptr) continue;
if ((ifa->ifa_flags & IFF_UP) == 0) continue;
if (strcmp(ifa->ifa_name, "lo") == 0) continue;
if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
@@ -2208,8 +2220,8 @@ CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSe
nLastNodeId = 0;
nSendBufferMaxSize = 0;
nReceiveFloodSize = 0;
- semOutbound = NULL;
- semAddnode = NULL;
+ semOutbound = nullptr;
+ semAddnode = nullptr;
flagInterruptMsgProc = false;
Options connOptions;
@@ -2312,11 +2324,11 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
fAddressesInitialized = true;
- if (semOutbound == NULL) {
+ if (semOutbound == nullptr) {
// initialize semaphore
semOutbound = new CSemaphore(std::min((nMaxOutbound + nMaxFeeler), nMaxConnections));
}
- if (semAddnode == NULL) {
+ if (semAddnode == nullptr) {
// initialize semaphore
semAddnode = new CSemaphore(nMaxAddnode);
}
@@ -2324,6 +2336,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
//
// Start threads
//
+ assert(m_msgproc);
InterruptSocks5(false);
interruptNet.reset();
flagInterruptMsgProc = false;
@@ -2336,7 +2349,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
// Send and receive from sockets, accept connections
threadSocketHandler = std::thread(&TraceThread<std::function<void()> >, "net", std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this)));
- if (!GetBoolArg("-dnsseed", true))
+ if (!gArgs.GetBoolArg("-dnsseed", true))
LogPrintf("DNS seeding disabled\n");
else
threadDNSAddressSeed = std::thread(&TraceThread<std::function<void()> >, "dnsseed", std::function<void()>(std::bind(&CConnman::ThreadDNSAddressSeed, this)));
@@ -2344,9 +2357,16 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
// Initiate outbound connections from -addnode
threadOpenAddedConnections = std::thread(&TraceThread<std::function<void()> >, "addcon", std::function<void()>(std::bind(&CConnman::ThreadOpenAddedConnections, this)));
- // Initiate outbound connections unless connect=0
- if (!gArgs.IsArgSet("-connect") || gArgs.GetArgs("-connect").size() != 1 || gArgs.GetArgs("-connect")[0] != "0")
- threadOpenConnections = std::thread(&TraceThread<std::function<void()> >, "opencon", std::function<void()>(std::bind(&CConnman::ThreadOpenConnections, this)));
+ if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
+ if (clientInterface) {
+ clientInterface->ThreadSafeMessageBox(
+ _("Cannot provide specific connections and have addrman find outgoing connections at the same."),
+ "", CClientUIInterface::MSG_ERROR);
+ }
+ return false;
+ }
+ if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty())
+ threadOpenConnections = std::thread(&TraceThread<std::function<void()> >, "opencon", std::function<void()>(std::bind(&CConnman::ThreadOpenConnections, this, connOptions.m_specified_outgoing)));
// Process messages
threadMessageHandler = std::thread(&TraceThread<std::function<void()> >, "msghand", std::function<void()>(std::bind(&CConnman::ThreadMessageHandler, this)));
@@ -2434,18 +2454,19 @@ void CConnman::Stop()
vNodesDisconnected.clear();
vhListenSocket.clear();
delete semOutbound;
- semOutbound = NULL;
+ semOutbound = nullptr;
delete semAddnode;
- semAddnode = NULL;
+ semAddnode = nullptr;
}
void CConnman::DeleteNode(CNode* pnode)
{
assert(pnode);
bool fUpdateConnectionTime = false;
- GetNodeSignals().FinalizeNode(pnode->GetId(), fUpdateConnectionTime);
- if(fUpdateConnectionTime)
+ m_msgproc->FinalizeNode(pnode->GetId(), fUpdateConnectionTime);
+ if(fUpdateConnectionTime) {
addrman.Connected(pnode->addr);
+ }
delete pnode;
}
@@ -2483,9 +2504,8 @@ std::vector<CAddress> CConnman::GetAddresses()
bool CConnman::AddNode(const std::string& strNode)
{
LOCK(cs_vAddedNodes);
- for(std::vector<std::string>::const_iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
- if (strNode == *it)
- return false;
+ for (const std::string& it : vAddedNodes) {
+ if (strNode == it) return false;
}
vAddedNodes.push_back(strNode);
@@ -2511,9 +2531,11 @@ size_t CConnman::GetNodeCount(NumConnections flags)
return vNodes.size();
int nNum = 0;
- for(std::vector<CNode*>::const_iterator it = vNodes.begin(); it != vNodes.end(); ++it)
- if (flags & ((*it)->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT))
+ for (const auto& pnode : vNodes) {
+ if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
nNum++;
+ }
+ }
return nNum;
}
@@ -2523,8 +2545,7 @@ void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats)
vstats.clear();
LOCK(cs_vNodes);
vstats.reserve(vNodes.size());
- for(std::vector<CNode*>::iterator it = vNodes.begin(); it != vNodes.end(); ++it) {
- CNode* pnode = *it;
+ for (CNode* pnode : vNodes) {
vstats.emplace_back();
pnode->copyStats(vstats.back());
}