diff --git a/src/net.cpp b/src/net.cpp index 4aab7bda1c0..36b4aa08486 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1466,6 +1466,12 @@ void ThreadOpenAddedConnections() } list > lservAddressesToAdd(0); + // Numeric (IP-literal) -addnode addresses that still need a connection. + // Such entries cost no DNS, so a resolution failure can never explain them + // being unconnected -- only a transient connect failure can -- and they + // should be retried promptly rather than after the full 2-minute + // name-resolution backoff. + std::vector vIpLiteralAddrs; BOOST_FOREACH(const std::string& strAddNode, lAddresses) { vector vservNode(0); if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) @@ -1476,6 +1482,19 @@ void ThreadOpenAddedConnections() BOOST_FOREACH(const CService& serv, vservNode) setservAddNodeAddresses.insert(serv); } + // Did this entry resolve with no DNS (a bare IP literal)? If so, + // track its addresses so we can shorten the retry backoff below. + CService servLiteral; + if (LookupNumeric(strAddNode.c_str(), servLiteral, Params().GetDefaultPort())) + BOOST_FOREACH(const CService& serv, vservNode) + vIpLiteralAddrs.push_back(serv); + } + else + { + // Previously skipped silently, leaving the user with no clue why an + // -addnode never connected. A name that fails to resolve here will + // be retried on the next loop iteration. + LogPrintf("ThreadOpenAddedConnections: could not resolve -addnode=%s; will retry\n", strAddNode); } } // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry @@ -1498,7 +1517,23 @@ void ThreadOpenAddedConnections() OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant); MilliSleep(500); } - MilliSleep(120000); // Retry every 2 minutes + // Is any IP-literal -addnode still not connected? If so, retry it quickly + // (no DNS to wait on); otherwise -- only name entries pending, or all + // connected -- keep the longer interval so we don't hammer DNS. + bool fHaveIpLiteralPending = false; + { + LOCK(cs_vNodes); + BOOST_FOREACH(const CService& addrLit, vIpLiteralAddrs) { + bool fConnected = false; + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->addr == addrLit) { fConnected = true; break; } + if (!fConnected) { fHaveIpLiteralPending = true; break; } + } + } + // IP-literal -addnode entries need no DNS, so retry them quickly instead of + // waiting the full 2-minute name-resolution backoff; name entries keep the + // longer interval so we don't hammer DNS. + MilliSleep(fHaveIpLiteralPending ? 15000 : 120000); } }