aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/net.cpp61
1 files changed, 34 insertions, 27 deletions
diff --git a/src/net.cpp b/src/net.cpp
index 7d6eb31a7c..35a85fad7a 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -49,6 +49,9 @@ static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed"
// Dump addresses to peers.dat every 15 minutes (900s)
static constexpr int DUMP_PEERS_INTERVAL = 15 * 60;
+/** Number of DNS seeds to query when the number of connections is low. */
+static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
+
// We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
#define FEELER_SLEEP_WINDOW 1
@@ -1508,35 +1511,41 @@ void StopMapPort()
void CConnman::ThreadDNSAddressSeed()
{
- // goal: only query DNS seeds if address need is acute
- // Avoiding DNS seeds when we don't need them improves user privacy by
- // 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) &&
- (!gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) {
- if (!interruptNet.sleep_for(std::chrono::seconds(11)))
- return;
+ FastRandomContext rng;
+ std::vector<std::string> seeds = Params().DNSSeeds();
+ Shuffle(seeds.begin(), seeds.end(), rng);
+ int seeds_right_now = 0; // Number of seeds left before testing if we have enough connections
+ int found = 0;
- LOCK(cs_vNodes);
- int nRelevant = 0;
- for (const CNode* pnode : vNodes) {
- nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
- }
- if (nRelevant >= 2) {
- LogPrintf("P2P peers available. Skipped DNS seeding.\n");
- return;
- }
+ if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
+ // When -forcednsseed is provided, query all.
+ seeds_right_now = seeds.size();
}
- const std::vector<std::string> &vSeeds = Params().DNSSeeds();
- int found = 0;
+ for (const std::string& seed : seeds) {
+ // goal: only query DNS seed if address need is acute
+ // Avoiding DNS seeds when we don't need them improves user privacy by
+ // 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 && seeds_right_now == 0) {
+ if (!interruptNet.sleep_for(std::chrono::seconds(11))) return;
- LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
+ LOCK(cs_vNodes);
+ int nRelevant = 0;
+ for (const CNode* pnode : vNodes) {
+ nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
+ }
+ if (nRelevant >= 2) {
+ LogPrintf("P2P peers available. Skipped DNS seeding.\n");
+ return;
+ }
+ seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
+ }
- for (const std::string &seed : vSeeds) {
if (interruptNet) {
return;
}
+ LogPrintf("Loading addresses from DNS seed %s\n", seed);
if (HaveNameProxy()) {
AddOneShot(seed);
} else {
@@ -1549,13 +1558,11 @@ void CConnman::ThreadDNSAddressSeed()
continue;
}
unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed
- if (LookupHost(host.c_str(), vIPs, nMaxIPs, true))
- {
- for (const CNetAddr& ip : vIPs)
- {
+ if (LookupHost(host.c_str(), vIPs, nMaxIPs, true)) {
+ for (const CNetAddr& ip : vIPs) {
int nOneDay = 24*3600;
CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
- addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
+ addr.nTime = GetTime() - 3*nOneDay - rng.randrange(4*nOneDay); // use a random age between 3 and 7 days old
vAdd.push_back(addr);
found++;
}
@@ -1566,8 +1573,8 @@ void CConnman::ThreadDNSAddressSeed()
AddOneShot(seed);
}
}
+ --seeds_right_now;
}
-
LogPrintf("%d addresses found from DNS seeds\n", found);
}