diff options
Diffstat (limited to 'src/net.cpp')
-rw-r--r-- | src/net.cpp | 164 |
1 files changed, 86 insertions, 78 deletions
diff --git a/src/net.cpp b/src/net.cpp index 682f47bff2..f7e6c300b1 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -136,7 +136,7 @@ static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn for (const auto& seed_in : vSeedsIn) { struct in6_addr ip; memcpy(&ip, seed_in.addr, sizeof(ip)); - CAddress addr(CService(ip, seed_in.port), NODE_NETWORK); + CAddress addr(CService(ip, seed_in.port), GetDesirableServiceFlags(NODE_NONE)); addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek; vSeedsOut.push_back(addr); } @@ -181,6 +181,10 @@ void AdvertiseLocal(CNode *pnode) if (fListen && pnode->fSuccessfullyConnected) { CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices()); + if (gArgs.GetBoolArg("-addrmantest", false)) { + // use IPv4 loopback during addrmantest + addrLocal = CAddress(CService(LookupNumeric("127.0.0.1", GetListenPort())), pnode->GetLocalServices()); + } // If discovery is enabled, sometimes give our peer the address it // tells us that it sees us as in case it has a better idea of our // address than we do. @@ -189,7 +193,7 @@ void AdvertiseLocal(CNode *pnode) { addrLocal.SetIP(pnode->GetAddrLocal()); } - if (addrLocal.IsRoutable()) + if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false)) { LogPrint(BCLog::NET, "AdvertiseLocal: advertising address %s\n", addrLocal.ToString()); FastRandomContext insecure_rand; @@ -297,7 +301,7 @@ CNode* CConnman::FindNode(const CNetAddr& ip) { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { - if ((CNetAddr)pnode->addr == ip) { + if (static_cast<CNetAddr>(pnode->addr) == ip) { return pnode; } } @@ -308,7 +312,7 @@ CNode* CConnman::FindNode(const CSubNet& subNet) { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { - if (subNet.Match((CNetAddr)pnode->addr)) { + if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) { return pnode; } } @@ -330,7 +334,7 @@ CNode* CConnman::FindNode(const CService& addr) { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { - if ((CService)pnode->addr == addr) { + if (static_cast<CService>(pnode->addr) == addr) { return pnode; } } @@ -370,7 +374,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo return nullptr; // Look for an existing connection - CNode* pnode = FindNode((CService)addrConnect); + CNode* pnode = FindNode(static_cast<CService>(addrConnect)); if (pnode) { LogPrintf("Failed to open new connection, already connected\n"); @@ -398,7 +402,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo // Also store the name we used to connect in that CNode, so that future FindNode() calls to that // name catch this early. LOCK(cs_vNodes); - CNode* pnode = FindNode((CService)addrConnect); + CNode* pnode = FindNode(static_cast<CService>(addrConnect)); if (pnode) { pnode->MaybeSetAddrName(std::string(pszDest)); @@ -410,7 +414,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo // Connect bool connected = false; - SOCKET hSocket; + SOCKET hSocket = INVALID_SOCKET; proxyType proxy; if (addrConnect.IsValid()) { bool proxyConnectionFailed = false; @@ -559,7 +563,7 @@ void CConnman::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t ba { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { - if (subNet.Match((CNetAddr)pnode->addr)) + if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) pnode->fDisconnect = true; } } @@ -1431,7 +1435,7 @@ void CConnman::ThreadSocketHandler() } else if (!pnode->fSuccessfullyConnected) { - LogPrintf("version handshake timeout from %d\n", pnode->GetId()); + LogPrint(BCLog::NET, "version handshake timeout from %d\n", pnode->GetId()); pnode->fDisconnect = true; } } @@ -1459,6 +1463,8 @@ void CConnman::WakeMessageHandler() #ifdef USE_UPNP +static CThreadInterrupt g_upnp_interrupt; +static std::thread g_upnp_thread; void ThreadMapPort() { std::string port = strprintf("%u", GetListenPort()); @@ -1509,35 +1515,29 @@ void ThreadMapPort() std::string strDesc = "Bitcoin " + FormatFullVersion(); - try { - while (true) { + do { #ifndef UPNPDISCOVER_SUCCESS - /* miniupnpc 1.5 */ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); + /* miniupnpc 1.5 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); #else - /* miniupnpc 1.6 */ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); + /* miniupnpc 1.6 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); #endif - if(r!=UPNPCOMMAND_SUCCESS) - LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - port, port, lanaddr, r, strupnperror(r)); - else - LogPrintf("UPnP Port Mapping successful.\n"); - - MilliSleep(20*60*1000); // Refresh every 20 minutes - } - } - catch (const boost::thread_interrupted&) - { - r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); - LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r); - freeUPNPDevlist(devlist); devlist = nullptr; - FreeUPNPUrls(&urls); - throw; + if(r!=UPNPCOMMAND_SUCCESS) + LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", + port, port, lanaddr, r, strupnperror(r)); + else + LogPrintf("UPnP Port Mapping successful.\n"); } + while(g_upnp_interrupt.sleep_for(std::chrono::minutes(20))); + + r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); + LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r); + freeUPNPDevlist(devlist); devlist = nullptr; + FreeUPNPUrls(&urls); } else { LogPrintf("No valid UPnP IGDs found\n"); freeUPNPDevlist(devlist); devlist = nullptr; @@ -1546,27 +1546,39 @@ void ThreadMapPort() } } -void MapPort(bool fUseUPnP) +void StartMapPort() { - static std::unique_ptr<boost::thread> upnp_thread; + if (!g_upnp_thread.joinable()) { + assert(!g_upnp_interrupt); + g_upnp_thread = std::thread((std::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort))); + } +} - if (fUseUPnP) - { - if (upnp_thread) { - upnp_thread->interrupt(); - upnp_thread->join(); - } - upnp_thread.reset(new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort))); +void InterruptMapPort() +{ + if(g_upnp_thread.joinable()) { + g_upnp_interrupt(); } - else if (upnp_thread) { - upnp_thread->interrupt(); - upnp_thread->join(); - upnp_thread.reset(); +} + +void StopMapPort() +{ + if(g_upnp_thread.joinable()) { + g_upnp_thread.join(); + g_upnp_interrupt.reset(); } } #else -void MapPort(bool) +void StartMapPort() +{ + // Intentionally left blank. +} +void InterruptMapPort() +{ + // Intentionally left blank. +} +void StopMapPort() { // Intentionally left blank. } @@ -1577,19 +1589,6 @@ void MapPort(bool) -static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredServiceBits) -{ - //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK) - if (!data.supportsServiceBitsFiltering || *requiredServiceBits == NODE_NETWORK) { - *requiredServiceBits = NODE_NETWORK; - return data.host; - } - - // See chainparams.cpp, most dnsseeds only support one or two possible servicebits hostnames - return strprintf("x%x.%s", *requiredServiceBits, data.host); -} - - void CConnman::ThreadDNSAddressSeed() { // goal: only query DNS seeds if address need is acute @@ -1612,22 +1611,22 @@ void CConnman::ThreadDNSAddressSeed() } } - const std::vector<CDNSSeedData> &vSeeds = Params().DNSSeeds(); + const std::vector<std::string> &vSeeds = Params().DNSSeeds(); int found = 0; LogPrintf("Loading addresses from DNS seeds (could take a while)\n"); - for (const CDNSSeedData &seed : vSeeds) { + for (const std::string &seed : vSeeds) { if (interruptNet) { return; } if (HaveNameProxy()) { - AddOneShot(seed.host); + AddOneShot(seed); } else { std::vector<CNetAddr> vIPs; std::vector<CAddress> vAdd; ServiceFlags requiredServiceBits = GetDesirableServiceFlags(NODE_NONE); - std::string host = GetDNSHost(seed, &requiredServiceBits); + std::string host = strprintf("x%x.%s", requiredServiceBits, seed); CNetAddr resolveSource; if (!resolveSource.SetInternal(host)) { continue; @@ -1643,6 +1642,10 @@ void CConnman::ThreadDNSAddressSeed() found++; } addrman.Add(vAdd, resolveSource); + } else { + // We now avoid directly using results from DNS Seeds which do not support service bit filtering, + // instead using them as a oneshot to get nodes with our desired service bits. + AddOneShot(seed); } } } @@ -1691,8 +1694,7 @@ void CConnman::ProcessOneShot() CAddress addr; CSemaphoreGrant grant(*semOutbound, true); if (grant) { - if (!OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true)) - AddOneShot(strDest); + OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true); } } @@ -1826,11 +1828,18 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect) } } + addrman.ResolveCollisions(); + int64_t nANow = GetAdjustedTime(); int nTries = 0; while (!interruptNet) { - CAddrInfo addr = addrman.Select(fFeeler); + CAddrInfo addr = addrman.SelectTriedCollision(); + + // SelectTriedCollision returns an invalid address if it is empty. + if (!fFeeler || !addr.IsValid()) { + addr = addrman.Select(fFeeler); + } // if we selected an invalid address, restart if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr)) @@ -1962,29 +1971,29 @@ void CConnman::ThreadOpenAddedConnections() } // if successful, this moves the passed grant to the constructed node -bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler, bool manual_connection) +void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler, bool manual_connection) { // // Initiate outbound network connection // if (interruptNet) { - return false; + return; } if (!fNetworkActive) { - return false; + return; } if (!pszDest) { if (IsLocal(addrConnect) || - FindNode((CNetAddr)addrConnect) || IsBanned(addrConnect) || + FindNode(static_cast<CNetAddr>(addrConnect)) || IsBanned(addrConnect) || FindNode(addrConnect.ToStringIPPort())) - return false; + return; } else if (FindNode(std::string(pszDest))) - return false; + return; CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure); if (!pnode) - return false; + return; if (grantOutbound) grantOutbound->MoveTo(pnode->grantOutbound); if (fOneShot) @@ -1999,8 +2008,6 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai LOCK(cs_vNodes); vNodes.push_back(pnode); } - - return true; } void CConnman::ThreadMessageHandler() @@ -2133,7 +2140,7 @@ bool CConnman::BindListenPort(const CService &addrBind, std::string& strError, b return true; } -void Discover(boost::thread_group& threadGroup) +void Discover() { if (!fDiscover) return; @@ -2722,6 +2729,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn fOneShot = false; m_manual_connection = false; fClient = false; // set by version message + m_limited_node = false; // set by version message fFeeler = false; fSuccessfullyConnected = false; fDisconnect = false; |