Skip to content

Commit b1e43cf

Browse files
authored
Merge pull request #2561 from Pythonix/split-dns-resolve
net: Turn net structures into dumb storage classes (backport)
2 parents 3611fce + 402bb7f commit b1e43cf

16 files changed

+2043
-1009
lines changed

Diff for: src/Makefile.am

+2
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ GRIDCOIN_CORE_H = \
153153
miner.h \
154154
mruset.h \
155155
netbase.h \
156+
netaddress.h \
156157
net.h \
157158
node/blockstorage.h \
158159
pbkdf2.h \
@@ -265,6 +266,7 @@ GRIDCOIN_CORE_CPP = addrdb.cpp \
265266
main.cpp \
266267
miner.cpp \
267268
netbase.cpp \
269+
netaddress.cpp \
268270
net.cpp \
269271
node/blockstorage.cpp \
270272
node/ui_interface.cpp \

Diff for: src/Makefile.test.include

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ GRIDCOIN_TESTS =\
3232
test/checkpoints_tests.cpp \
3333
test/dos_tests.cpp \
3434
test/accounting_tests.cpp \
35+
test/addrman_tests.cpp \
3536
test/allocator_tests.cpp \
3637
test/base32_tests.cpp \
3738
test/base58_tests.cpp \
@@ -59,6 +60,7 @@ GRIDCOIN_TESTS =\
5960
test/mruset_tests.cpp \
6061
test/multisig_tests.cpp \
6162
test/netbase_tests.cpp \
63+
test/net_tests.cpp \
6264
test/random_tests.cpp \
6365
test/rpc_tests.cpp \
6466
test/sanity_tests.cpp \

Diff for: src/addrman.cpp

+43-13
Original file line numberDiff line numberDiff line change
@@ -330,39 +330,47 @@ void CAddrMan::Attempt_(const CService &addr, int64_t nTime)
330330
info.nAttempts++;
331331
}
332332

333-
CAddress CAddrMan::Select_()
333+
CAddrInfo CAddrMan::Select_(bool newOnly)
334334
{
335335
if (size() == 0)
336-
return CAddress();
336+
return CAddrInfo();
337+
338+
if (newOnly && nNew == 0)
339+
return CAddrInfo();
337340

338341
// Use a 50% chance for choosing between tried and new table entries.
339-
if (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0)) {
342+
if (!newOnly &&
343+
(nTried > 0 && (nNew == 0 || RandomInt(2) == 0))) {
340344
// use a tried node
341345
double fChanceFactor = 1.0;
342346
while (1) {
343-
int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT);
344-
int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
345-
if (vvTried[nKBucket][nKBucketPos] == -1)
346-
continue;
347+
int nKBucket = RandomInt(ADDRMAN_TRIED_BUCKET_COUNT);
348+
int nKBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
349+
while (vvTried[nKBucket][nKBucketPos] == -1) {
350+
nKBucket = (nKBucket + insecure_rand()) % ADDRMAN_TRIED_BUCKET_COUNT;
351+
nKBucketPos = (nKBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE;
352+
}
347353
int nId = vvTried[nKBucket][nKBucketPos];
348354
assert(mapInfo.count(nId) == 1);
349355
CAddrInfo& info = mapInfo[nId];
350-
if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
356+
if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
351357
return info;
352358
fChanceFactor *= 1.2;
353359
}
354360
} else {
355361
// use a new node
356362
double fChanceFactor = 1.0;
357363
while (1) {
358-
int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT);
359-
int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
360-
if (vvNew[nUBucket][nUBucketPos] == -1)
361-
continue;
364+
int nUBucket = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
365+
int nUBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
366+
while (vvNew[nUBucket][nUBucketPos] == -1) {
367+
nUBucket = (nUBucket + insecure_rand()) % ADDRMAN_NEW_BUCKET_COUNT;
368+
nUBucketPos = (nUBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE;
369+
}
362370
int nId = vvNew[nUBucket][nUBucketPos];
363371
assert(mapInfo.count(nId) == 1);
364372
CAddrInfo& info = mapInfo[nId];
365-
if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
373+
if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
366374
return info;
367375
fChanceFactor *= 1.2;
368376
}
@@ -488,3 +496,25 @@ void CAddrMan::Connected_(const CService &addr, int64_t nTime)
488496
if (nTime - info.nTime > nUpdateInterval)
489497
info.nTime = nTime;
490498
}
499+
500+
void CAddrMan::SetServices_(const CService& addr, ServiceFlags nServices)
501+
{
502+
CAddrInfo* pinfo = Find(addr);
503+
504+
// if not found, bail out
505+
if (!pinfo)
506+
return;
507+
508+
CAddrInfo& info = *pinfo;
509+
510+
// check whether we are talking about the exact same CService (including same port)
511+
if (info != addr)
512+
return;
513+
514+
// update info
515+
info.nServices = nServices;
516+
}
517+
518+
int CAddrMan::RandomInt(int nMax){
519+
return GetRandInt(nMax);
520+
}

Diff for: src/addrman.h

+29-10
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,6 @@ class CAddrMan
171171
// critical section to protect the inner data structures
172172
mutable CCriticalSection cs;
173173

174-
//! secret key to randomize bucket select with
175-
uint256 nKey;
176-
177174
//! last used nId
178175
int nIdCount;
179176

@@ -200,6 +197,12 @@ class CAddrMan
200197

201198
protected:
202199

200+
//! secret key to randomize bucket select with
201+
uint256 nKey;
202+
203+
//! Source of random numbers for randomization in inner loops
204+
FastRandomContext insecure_rand;
205+
203206
// Find an entry.
204207
CAddrInfo* Find(const CNetAddr& addr, int* pnId = nullptr);
205208

@@ -228,8 +231,11 @@ class CAddrMan
228231
// Mark an entry as attempted to connect.
229232
void Attempt_(const CService &addr, int64_t nTime);
230233

231-
//! Select an address to connect to.
232-
CAddress Select_();
234+
//! Select an address to connect to, if newOnly is set to true, only the new table is selected from.
235+
CAddrInfo Select_(bool newOnly);
236+
237+
//! Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic.
238+
virtual int RandomInt(int nMax);
233239

234240
#ifdef DEBUG_ADDRMAN
235241
// Perform consistency check. Returns an error code or zero.
@@ -242,6 +248,9 @@ class CAddrMan
242248
// Mark an entry as currently-connected-to.
243249
void Connected_(const CService &addr, int64_t nTime);
244250

251+
//! Update an entry's service bits.
252+
void SetServices_(const CService &addr, ServiceFlags nServices);
253+
245254
public:
246255
/**
247256
* serialized format:
@@ -458,7 +467,7 @@ class CAddrMan
458467
}
459468

460469
//! Return the number of (unique) addresses in all tables.
461-
int size()
470+
size_t size()
462471
{
463472
LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead
464473
return vRandom.size();
@@ -522,14 +531,16 @@ class CAddrMan
522531
Check();
523532
}
524533

525-
//! Choose an address to connect to.
526-
CAddress Select()
534+
/**
535+
* Choose an address to connect to.
536+
*/
537+
CAddrInfo Select(bool newOnly = false)
527538
{
528-
CAddress addrRet;
539+
CAddrInfo addrRet;
529540
{
530541
LOCK(cs);
531542
Check();
532-
addrRet = Select_();
543+
addrRet = Select_(newOnly);
533544
Check();
534545
}
535546
return addrRet;
@@ -557,6 +568,14 @@ class CAddrMan
557568
Check();
558569
}
559570

571+
void SetServices(const CService &addr, ServiceFlags nServices)
572+
{
573+
LOCK(cs);
574+
Check();
575+
SetServices_(addr, nServices);
576+
Check();
577+
}
578+
560579
};
561580

562581
#endif // BITCOIN_ADDRMAN_H

Diff for: src/init.cpp

+10-9
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ bool AppInit2(ThreadHandlerPtr threads)
10821082
CService addrProxy;
10831083
bool fProxy = false;
10841084
if (gArgs.IsArgSet("-proxy")) {
1085-
addrProxy = CService(gArgs.GetArg("-proxy", ""), 9050);
1085+
CService addrProxy(LookupNumeric(gArgs.GetArg("-proxy", "").c_str(), 9050));
10861086
if (!addrProxy.IsValid())
10871087
return InitError(strprintf(_("Invalid -proxy address: '%s'"), gArgs.GetArg("-proxy", "")));
10881088

@@ -1091,17 +1091,17 @@ bool AppInit2(ThreadHandlerPtr threads)
10911091
if (!IsLimited(NET_IPV6))
10921092
SetProxy(NET_IPV6, addrProxy);
10931093
SetNameProxy(addrProxy);
1094-
10951094
fProxy = true;
10961095
}
10971096

10981097
// -tor can override normal proxy, -notor disables Tor entirely
10991098
if (gArgs.IsArgSet("-tor") && (fProxy || gArgs.IsArgSet("-tor"))) {
1100-
CService addrOnion;
1101-
if (!gArgs.IsArgSet("-tor"))
1099+
proxyType addrOnion;
1100+
if (!gArgs.IsArgSet("-tor")) {
11021101
addrOnion = addrProxy;
1103-
else
1104-
addrOnion = CService(gArgs.GetArg("-tor", ""), 9050);
1102+
} else {
1103+
CService addrProxy(LookupNumeric(gArgs.GetArg("-tor", "").c_str(), 9050));
1104+
}
11051105
if (!addrOnion.IsValid())
11061106
return InitError(strprintf(_("Invalid -tor address: '%s'"), gArgs.GetArg("-tor", "")));
11071107
SetProxy(NET_TOR, addrOnion);
@@ -1144,10 +1144,11 @@ bool AppInit2(ThreadHandlerPtr threads)
11441144
{
11451145
for (auto const& strAddr : gArgs.GetArgs("-externalip"))
11461146
{
1147-
CService addrLocal(strAddr, GetListenPort(), fNameLookup);
1148-
if (!addrLocal.IsValid())
1147+
CService addrLocal;
1148+
if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid())
1149+
AddLocal(addrLocal, LOCAL_MANUAL);
1150+
else
11491151
return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr));
1150-
AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL);
11511152
}
11521153
}
11531154

Diff for: src/net.cpp

+25-18
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ CCriticalSection cs_mapLocalHost;
6464
std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
6565
static bool vfLimited[NET_MAX] GUARDED_BY(cs_mapLocalHost) = {};
6666
static CNode* pnodeLocalHost = nullptr;
67-
CAddress addrSeenByPeer(CService("0.0.0.0", 0), nLocalServices);
67+
CAddress addrSeenByPeer(LookupNumeric("0.0.0.0", 0), nLocalServices);
6868
uint64_t nLocalHostNonce = 0;
6969

7070

@@ -484,7 +484,7 @@ bool CNode::DisconnectNode(NodeId id)
484484
void CNode::PushVersion()
485485
{
486486
int64_t nTime = GetAdjustedTime();
487-
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
487+
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(LookupNumeric("0.0.0.0", 0)));
488488
CAddress addrMe = CAddress(CService(), nLocalServices);
489489
GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
490490
LogPrint(BCLog::LogFlags::NET, "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s",
@@ -1179,8 +1179,11 @@ void ThreadMapPort2(void* parg)
11791179
{
11801180
if(externalIPAddress[0])
11811181
{
1182-
LogPrintf("UPnP: ExternalIPAddress = %s", externalIPAddress);
1183-
AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1182+
CNetAddr resolved;
1183+
if(LookupHost(externalIPAddress, resolved, false)) {
1184+
LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString().c_str());
1185+
AddLocal(resolved, LOCAL_UPNP);
1186+
}
11841187
}
11851188
else
11861189
LogPrintf("UPnP: GetExternalIPAddress not successful.");
@@ -1311,11 +1314,11 @@ void ThreadDNSAddressSeed2(void* parg)
13111314
if (HaveNameProxy()) {
13121315
AddOneShot(seed[1]);
13131316
} else {
1314-
vector<CNetAddr> vaddr;
1317+
vector<CNetAddr> vIPs;
13151318
vector<CAddress> vAdd;
1316-
if (LookupHost(seed[1], vaddr))
1319+
if (LookupHost(seed[1], vIPs, 0, true))
13171320
{
1318-
for (auto const& ip : vaddr)
1321+
for (auto const& ip : vIPs)
13191322
{
13201323
int nOneDay = 24*3600;
13211324
CAddress addr = CAddress(CService(ip, GetDefaultPort()));
@@ -1324,20 +1327,22 @@ void ThreadDNSAddressSeed2(void* parg)
13241327
found++;
13251328
}
13261329
}
1327-
addrman.Add(vAdd, CNetAddr(seed[0], true));
1330+
// TODO: The seed name resolve may fail, yielding an IP of [::], which results in
1331+
// addrman assigning the same source to results from different seeds.
1332+
// This should switch to a hard-coded stable dummy IP for each seed name, so that the
1333+
// resolve is not required at all.
1334+
if (!vIPs.empty()) {
1335+
CService seedSource;
1336+
Lookup(seed[0], seedSource, 0, true);
1337+
addrman.Add(vAdd, seedSource);
1338+
}
13281339
}
13291340
}
13301341
}
13311342

13321343
LogPrint(BCLog::LogFlags::NET, "%d addresses found from DNS seeds", found);
13331344
}
13341345

1335-
1336-
1337-
1338-
1339-
1340-
13411346
unsigned int pnSeed[] =
13421347
{
13431348
0xdf4bd379, 0x7934d29b, 0x26bc02ad, 0x7ab743ad, 0x0ab3a7bc,
@@ -1527,7 +1532,7 @@ void ThreadOpenConnections2(void* parg)
15271532
return;
15281533

15291534
// Add seed nodes
1530-
if (addrman.size()==0 && (GetAdjustedTime() - nStart > 60) && !fTestNet)
1535+
if (addrman.size() == 0 && (GetAdjustedTime() - nStart > 60) && !fTestNet)
15311536
{
15321537
std::vector<CAddress> vAdd;
15331538
for (const auto& seed : pnSeed)
@@ -1543,7 +1548,9 @@ void ThreadOpenConnections2(void* parg)
15431548
addr.nTime = GetAdjustedTime() - GetRand(nOneWeek) - nOneWeek;
15441549
vAdd.push_back(addr);
15451550
}
1546-
addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1551+
CNetAddr local;
1552+
LookupHost("127.0.0.1", local, false);
1553+
addrman.Add(vAdd, local);
15471554
}
15481555

15491556
//
@@ -1952,7 +1959,7 @@ void static Discover()
19521959
if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
19531960
{
19541961
vector<CNetAddr> vaddr;
1955-
if (LookupHost(pszHostName, vaddr))
1962+
if (LookupHost(pszHostName, vaddr, 0, true))
19561963
{
19571964
for (auto const& addr : vaddr)
19581965
{
@@ -2010,7 +2017,7 @@ void StartNode(void* parg)
20102017
nMaxOutbound, max_connections);
20112018

20122019
if (pnodeLocalHost == nullptr)
2013-
pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
2020+
pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(LookupNumeric("127.0.0.1", 0), nLocalServices));
20142021

20152022
Discover();
20162023

0 commit comments

Comments
 (0)