7
7
#include < stdio.h>
8
8
#include < stdlib.h>
9
9
#include < getopt.h>
10
+ #include < atomic>
10
11
11
12
#include " bitcoin.h"
12
13
#include " db.h"
@@ -188,19 +189,25 @@ extern "C" void* ThreadCrawler(void* data) {
188
189
db.ResultMany (ips);
189
190
db.Add (addr);
190
191
} while (1 );
192
+ return nullptr ;
191
193
}
192
194
193
195
extern " C" int GetIPList (void *thread, char *requestedHostname, addr_t *addr, int max, int ipv4, int ipv6);
194
196
195
197
class CDnsThread {
196
198
public:
199
+ struct FlagSpecificData {
200
+ int nIPv4, nIPv6;
201
+ std::vector<addr_t > cache;
202
+ time_t cacheTime;
203
+ unsigned int cacheHits;
204
+ FlagSpecificData () : nIPv4(0 ), nIPv6(0 ), cacheTime(0 ), cacheHits(0 ) {}
205
+ };
206
+
197
207
dns_opt_t dns_opt; // must be first
198
208
const int id;
199
- std::map<uint64_t , vector<addr_t > > cache;
200
- int nIPv4, nIPv6;
201
- std::map<uint64_t , time_t > cacheTime;
202
- unsigned int cacheHits;
203
- uint64_t dbQueries;
209
+ std::map<uint64_t , FlagSpecificData> perflag;
210
+ std::atomic<uint64_t > dbQueries;
204
211
std::set<uint64_t > filterWhitelist;
205
212
206
213
void cacheHit (uint64_t requestedFlags, bool force = false ) {
@@ -210,34 +217,35 @@ class CDnsThread {
210
217
nets[NET_IPV6] = true ;
211
218
}
212
219
time_t now = time (NULL );
213
- cacheHits++;
214
- if (force || cacheHits > (cache[requestedFlags].size ()*cache[requestedFlags].size ()/400 ) || (cacheHits*cacheHits > cache[requestedFlags].size () / 20 && (now - cacheTime[requestedFlags] > 5 ))) {
220
+ FlagSpecificData thisflag = perflag[requestedFlags];
221
+ thisflag.cacheHits ++;
222
+ if (force || thisflag.cacheHits * 400 > (thisflag.cache .size ()*thisflag.cache .size ()) || (thisflag.cacheHits *thisflag.cacheHits * 20 > thisflag.cache .size () && (now - thisflag.cacheTime > 5 ))) {
215
223
set<CNetAddr> ips;
216
224
db.GetIPs (ips, requestedFlags, 1000 , nets);
217
225
dbQueries++;
218
- cache[requestedFlags] .clear ();
219
- nIPv4 = 0 ;
220
- nIPv6 = 0 ;
221
- cache[requestedFlags] .reserve (ips.size ());
226
+ thisflag. cache .clear ();
227
+ thisflag. nIPv4 = 0 ;
228
+ thisflag. nIPv6 = 0 ;
229
+ thisflag. cache .reserve (ips.size ());
222
230
for (set<CNetAddr>::iterator it = ips.begin (); it != ips.end (); it++) {
223
231
struct in_addr addr;
224
232
struct in6_addr addr6;
225
233
if ((*it).GetInAddr (&addr)) {
226
234
addr_t a;
227
235
a.v = 4 ;
228
236
memcpy (&a.data .v4 , &addr, 4 );
229
- cache[requestedFlags] .push_back (a);
230
- nIPv4++;
237
+ thisflag. cache .push_back (a);
238
+ thisflag. nIPv4 ++;
231
239
} else if ((*it).GetIn6Addr (&addr6)) {
232
240
addr_t a;
233
241
a.v = 6 ;
234
242
memcpy (&a.data .v6 , &addr6, 16 );
235
- cache[requestedFlags] .push_back (a);
236
- nIPv6++;
243
+ thisflag. cache .push_back (a);
244
+ thisflag. nIPv6 ++;
237
245
}
238
246
}
239
- cacheHits = 0 ;
240
- cacheTime[requestedFlags] = now;
247
+ thisflag. cacheHits = 0 ;
248
+ thisflag. cacheTime = now;
241
249
}
242
250
}
243
251
@@ -250,12 +258,8 @@ class CDnsThread {
250
258
dns_opt.cb = GetIPList;
251
259
dns_opt.port = opts->nPort ;
252
260
dns_opt.nRequests = 0 ;
253
- cache.clear ();
254
- cacheTime.clear ();
255
- cacheHits = 0 ;
256
261
dbQueries = 0 ;
257
- nIPv4 = 0 ;
258
- nIPv6 = 0 ;
262
+ perflag.clear ();
259
263
filterWhitelist = opts->filter_whitelist ;
260
264
}
261
265
@@ -280,8 +284,9 @@ extern "C" int GetIPList(void *data, char *requestedHostname, addr_t* addr, int
280
284
else if (strcasecmp (requestedHostname, thread->dns_opt .host ))
281
285
return 0 ;
282
286
thread->cacheHit (requestedFlags);
283
- unsigned int size = thread->cache [requestedFlags].size ();
284
- unsigned int maxmax = (ipv4 ? thread->nIPv4 : 0 ) + (ipv6 ? thread->nIPv6 : 0 );
287
+ auto & thisflag = thread->perflag [requestedFlags];
288
+ unsigned int size = thisflag.cache .size ();
289
+ unsigned int maxmax = (ipv4 ? thisflag.nIPv4 : 0 ) + (ipv6 ? thisflag.nIPv6 : 0 );
285
290
if (max > size)
286
291
max = size;
287
292
if (max > maxmax)
@@ -290,16 +295,16 @@ extern "C" int GetIPList(void *data, char *requestedHostname, addr_t* addr, int
290
295
while (i<max) {
291
296
int j = i + (rand () % (size - i));
292
297
do {
293
- bool ok = (ipv4 && thread-> cache [requestedFlags] [j].v == 4 ) ||
294
- (ipv6 && thread-> cache [requestedFlags] [j].v == 6 );
298
+ bool ok = (ipv4 && thisflag. cache [j].v == 4 ) ||
299
+ (ipv6 && thisflag. cache [j].v == 6 );
295
300
if (ok) break ;
296
301
j++;
297
302
if (j==size)
298
303
j=i;
299
304
} while (1 );
300
- addr[i] = thread-> cache [requestedFlags] [j];
301
- thread-> cache [requestedFlags][ j] = thread-> cache [requestedFlags] [i];
302
- thread-> cache [requestedFlags] [i] = addr[i];
305
+ addr[i] = thisflag. cache [j];
306
+ thisflag. cache [j] = thisflag. cache [i];
307
+ thisflag. cache [i] = addr[i];
303
308
i++;
304
309
}
305
310
return max;
@@ -310,6 +315,7 @@ vector<CDnsThread*> dnsThread;
310
315
extern " C" void * ThreadDNS (void * arg) {
311
316
CDnsThread *thread = (CDnsThread*)arg;
312
317
thread->run ();
318
+ return nullptr ;
313
319
}
314
320
315
321
int StatCompare (const CAddrReport& a, const CAddrReport& b) {
@@ -346,7 +352,7 @@ extern "C" void* ThreadDumper(void*) {
346
352
double stat[5 ]={0 ,0 ,0 ,0 ,0 };
347
353
for (vector<CAddrReport>::const_iterator it = v.begin (); it < v.end (); it++) {
348
354
CAddrReport rep = *it;
349
- fprintf (d, " %-47s %4d %11" PRId64" %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6i %08" PRIx64" %5i \" %s\"\n " , rep.ip .ToString ().c_str (), (int )rep.fGood , rep.lastSuccess , 100.0 *rep.uptime [0 ], 100.0 *rep.uptime [1 ], 100.0 *rep.uptime [2 ], 100.0 *rep.uptime [3 ], 100.0 *rep.uptime [4 ], rep.blocks , rep.services , rep.clientVersion , rep.clientSubVersion .c_str ());
355
+ fprintf (d, " %-47s %4d %11" PRId64 " %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6i %08" PRIx64 " %5i \" %s\"\n " , rep.ip .ToString ().c_str (), (int )rep.fGood , rep.lastSuccess , 100.0 *rep.uptime [0 ], 100.0 *rep.uptime [1 ], 100.0 *rep.uptime [2 ], 100.0 *rep.uptime [3 ], 100.0 *rep.uptime [4 ], rep.blocks , rep.services , rep.clientVersion , rep.clientSubVersion .c_str ());
350
356
stat[0 ] += rep.uptime [0 ];
351
357
stat[1 ] += rep.uptime [1 ];
352
358
stat[2 ] += rep.uptime [2 ];
@@ -359,6 +365,7 @@ extern "C" void* ThreadDumper(void*) {
359
365
fclose (ff);
360
366
}
361
367
} while (1 );
368
+ return nullptr ;
362
369
}
363
370
364
371
extern " C" void * ThreadStats (void *) {
@@ -387,6 +394,7 @@ extern "C" void* ThreadStats(void*) {
387
394
printf (" %s %i/%i available (%i tried in %is, %i new, %i active), %i banned; %llu DNS requests, %llu db queries" , c, stats.nGood , stats.nAvail , stats.nTracked , stats.nAge , stats.nNew , stats.nAvail - stats.nTracked - stats.nNew , stats.nBanned , (unsigned long long )requests, (unsigned long long )queries);
388
395
Sleep (1000 );
389
396
} while (1 );
397
+ return nullptr ;
390
398
}
391
399
392
400
static const string mainnet_seeds[] = {" dnsseed.bluematt.me" , " bitseed.xf2.org" , " dnsseed.bitcoin.dashjr.org" , " seed.bitcoin.sipa.be" , " " };
@@ -411,6 +419,7 @@ extern "C" void* ThreadSeeder(void*) {
411
419
}
412
420
Sleep (1800000 );
413
421
} while (1 );
422
+ return nullptr ;
414
423
}
415
424
416
425
int main (int argc, char **argv) {
0 commit comments