Skip to content

Commit 6170ec5

Browse files
committed
Do not query all DNS seed at once
Instead, when necessary, query 3. If that leads to a sufficient number of connects, stop. If not, query 3 more, and so on.
1 parent e5fdda6 commit 6170ec5

File tree

1 file changed

+34
-27
lines changed

1 file changed

+34
-27
lines changed

src/net.cpp

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed"
4949
// Dump addresses to peers.dat every 15 minutes (900s)
5050
static constexpr int DUMP_PEERS_INTERVAL = 15 * 60;
5151

52+
/** Number of DNS seeds to query when the number of connections is low. */
53+
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
54+
5255
// We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
5356
#define FEELER_SLEEP_WINDOW 1
5457

@@ -1508,35 +1511,41 @@ void StopMapPort()
15081511

15091512
void CConnman::ThreadDNSAddressSeed()
15101513
{
1511-
// goal: only query DNS seeds if address need is acute
1512-
// Avoiding DNS seeds when we don't need them improves user privacy by
1513-
// creating fewer identifying DNS requests, reduces trust by giving seeds
1514-
// less influence on the network topology, and reduces traffic to the seeds.
1515-
if ((addrman.size() > 0) &&
1516-
(!gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) {
1517-
if (!interruptNet.sleep_for(std::chrono::seconds(11)))
1518-
return;
1514+
FastRandomContext rng;
1515+
std::vector<std::string> seeds = Params().DNSSeeds();
1516+
Shuffle(seeds.begin(), seeds.end(), rng);
1517+
int seeds_right_now = 0; // Number of seeds left before testing if we have enough connections
1518+
int found = 0;
15191519

1520-
LOCK(cs_vNodes);
1521-
int nRelevant = 0;
1522-
for (const CNode* pnode : vNodes) {
1523-
nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
1524-
}
1525-
if (nRelevant >= 2) {
1526-
LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1527-
return;
1528-
}
1520+
if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
1521+
// When -forcednsseed is provided, query all.
1522+
seeds_right_now = seeds.size();
15291523
}
15301524

1531-
const std::vector<std::string> &vSeeds = Params().DNSSeeds();
1532-
int found = 0;
1525+
for (const std::string& seed : seeds) {
1526+
// goal: only query DNS seed if address need is acute
1527+
// Avoiding DNS seeds when we don't need them improves user privacy by
1528+
// creating fewer identifying DNS requests, reduces trust by giving seeds
1529+
// less influence on the network topology, and reduces traffic to the seeds.
1530+
if (addrman.size() > 0 && seeds_right_now == 0) {
1531+
if (!interruptNet.sleep_for(std::chrono::seconds(11))) return;
15331532

1534-
LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1533+
LOCK(cs_vNodes);
1534+
int nRelevant = 0;
1535+
for (const CNode* pnode : vNodes) {
1536+
nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
1537+
}
1538+
if (nRelevant >= 2) {
1539+
LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1540+
return;
1541+
}
1542+
seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
1543+
}
15351544

1536-
for (const std::string &seed : vSeeds) {
15371545
if (interruptNet) {
15381546
return;
15391547
}
1548+
LogPrintf("Loading addresses from DNS seed %s\n", seed);
15401549
if (HaveNameProxy()) {
15411550
AddOneShot(seed);
15421551
} else {
@@ -1549,13 +1558,11 @@ void CConnman::ThreadDNSAddressSeed()
15491558
continue;
15501559
}
15511560
unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed
1552-
if (LookupHost(host.c_str(), vIPs, nMaxIPs, true))
1553-
{
1554-
for (const CNetAddr& ip : vIPs)
1555-
{
1561+
if (LookupHost(host.c_str(), vIPs, nMaxIPs, true)) {
1562+
for (const CNetAddr& ip : vIPs) {
15561563
int nOneDay = 24*3600;
15571564
CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
1558-
addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1565+
addr.nTime = GetTime() - 3*nOneDay - rng.randrange(4*nOneDay); // use a random age between 3 and 7 days old
15591566
vAdd.push_back(addr);
15601567
found++;
15611568
}
@@ -1566,8 +1573,8 @@ void CConnman::ThreadDNSAddressSeed()
15661573
AddOneShot(seed);
15671574
}
15681575
}
1576+
--seeds_right_now;
15691577
}
1570-
15711578
LogPrintf("%d addresses found from DNS seeds\n", found);
15721579
}
15731580

0 commit comments

Comments
 (0)