@@ -15,6 +15,17 @@ using namespace std;
15
15
16
16
bool fTestNet = false ;
17
17
18
+ uint64_t filter_whitelist[] = {
19
+ 0x0000000000000001 ,
20
+ 0x0000000000000003 ,
21
+ 0x0000000000000005 ,
22
+ 0x0000000000000007 ,
23
+ 0x0000000000000009 ,
24
+ 0x000000000000000B ,
25
+ 0x000000000000000D ,
26
+ 0x000000000000000F ,
27
+ };
28
+
18
29
class CDnsSeedOpts {
19
30
public:
20
31
int nThreads;
@@ -167,53 +178,54 @@ extern "C" void* ThreadCrawler(void* data) {
167
178
} while (1 );
168
179
}
169
180
170
- extern " C" int GetIPList (void *thread, addr_t *addr, int max, int ipv4, int ipv6);
181
+ extern " C" int GetIPList (void *thread, char *requestedHostname, addr_t *addr, int max, int ipv4, int ipv6);
171
182
172
183
class CDnsThread {
173
184
public:
174
185
dns_opt_t dns_opt; // must be first
175
186
const int id;
176
- vector<addr_t > cache;
187
+ std::map< uint64_t , vector<addr_t > > cache;
177
188
int nIPv4, nIPv6;
178
- time_t cacheTime;
189
+ std::map< uint64_t , time_t > cacheTime;
179
190
unsigned int cacheHits;
180
191
uint64_t dbQueries;
192
+ std::vector<uint64_t > filterWhitelist;
181
193
182
- void cacheHit (bool force = false ) {
194
+ void cacheHit (uint64_t requestedFlags, bool force = false ) {
183
195
static bool nets[NET_MAX] = {};
184
196
if (!nets[NET_IPV4]) {
185
197
nets[NET_IPV4] = true ;
186
198
nets[NET_IPV6] = true ;
187
199
}
188
200
time_t now = time (NULL );
189
201
cacheHits++;
190
- if (force || cacheHits > (cache.size ()*cache.size ()/400 ) || (cacheHits*cacheHits > cache.size () / 20 && (now - cacheTime > 5 ))) {
202
+ if (force || cacheHits > (cache[requestedFlags] .size ()*cache[requestedFlags] .size ()/400 ) || (cacheHits*cacheHits > cache[requestedFlags] .size () / 20 && (now - cacheTime[requestedFlags] > 5 ))) {
191
203
set<CNetAddr> ips;
192
- db.GetIPs (ips, 1000 , nets);
204
+ db.GetIPs (ips, requestedFlags, 1000 , nets);
193
205
dbQueries++;
194
- cache.clear ();
206
+ cache[requestedFlags] .clear ();
195
207
nIPv4 = 0 ;
196
208
nIPv6 = 0 ;
197
- cache.reserve (ips.size ());
209
+ cache[requestedFlags] .reserve (ips.size ());
198
210
for (set<CNetAddr>::iterator it = ips.begin (); it != ips.end (); it++) {
199
211
struct in_addr addr;
200
212
struct in6_addr addr6;
201
213
if ((*it).GetInAddr (&addr)) {
202
214
addr_t a;
203
215
a.v = 4 ;
204
216
memcpy (&a.data .v4 , &addr, 4 );
205
- cache.push_back (a);
217
+ cache[requestedFlags] .push_back (a);
206
218
nIPv4++;
207
219
} else if ((*it).GetIn6Addr (&addr6)) {
208
220
addr_t a;
209
221
a.v = 6 ;
210
222
memcpy (&a.data .v6 , &addr6, 16 );
211
- cache.push_back (a);
223
+ cache[requestedFlags] .push_back (a);
212
224
nIPv6++;
213
225
}
214
226
}
215
227
cacheHits = 0 ;
216
- cacheTime = now;
228
+ cacheTime[requestedFlags] = now;
217
229
}
218
230
}
219
231
@@ -227,24 +239,36 @@ class CDnsThread {
227
239
dns_opt.port = opts->nPort ;
228
240
dns_opt.nRequests = 0 ;
229
241
cache.clear ();
230
- cache.reserve (1000 );
231
- cacheTime = 0 ;
242
+ cacheTime.clear ();
232
243
cacheHits = 0 ;
233
244
dbQueries = 0 ;
234
245
nIPv4 = 0 ;
235
246
nIPv6 = 0 ;
236
- cacheHit ( true );
247
+ filterWhitelist = std::vector< uint64_t >(filter_whitelist, filter_whitelist + ( sizeof filter_whitelist / sizeof filter_whitelist[ 0 ]) );
237
248
}
238
249
239
250
void run () {
240
251
dnsserver (&dns_opt);
241
252
}
242
253
};
243
254
244
- extern " C" int GetIPList (void *data, addr_t * addr, int max, int ipv4, int ipv6) {
255
+ extern " C" int GetIPList (void *data, char *requestedHostname, addr_t * addr, int max, int ipv4, int ipv6) {
245
256
CDnsThread *thread = (CDnsThread*)data;
246
- thread->cacheHit ();
247
- unsigned int size = thread->cache .size ();
257
+
258
+ uint64_t requestedFlags = 0 ;
259
+ int hostlen = strlen (requestedHostname);
260
+ if (hostlen > 1 && requestedHostname[0 ] == ' x' && requestedHostname[1 ] != ' 0' ) {
261
+ char *pEnd;
262
+ uint64_t flags = (uint64_t )strtoull (requestedHostname+1 , &pEnd, 16 );
263
+ if (*pEnd == ' .' && pEnd <= requestedHostname+17 && std::find (thread->filterWhitelist .begin (), thread->filterWhitelist .end (), flags) != thread->filterWhitelist .end ())
264
+ requestedFlags = flags;
265
+ else
266
+ return 0 ;
267
+ }
268
+ else if (strcasecmp (requestedHostname, thread->dns_opt .host ))
269
+ return 0 ;
270
+ thread->cacheHit (requestedFlags);
271
+ unsigned int size = thread->cache [requestedFlags].size ();
248
272
unsigned int maxmax = (ipv4 ? thread->nIPv4 : 0 ) + (ipv6 ? thread->nIPv6 : 0 );
249
273
if (max > size)
250
274
max = size;
@@ -254,16 +278,16 @@ extern "C" int GetIPList(void *data, addr_t* addr, int max, int ipv4, int ipv6)
254
278
while (i<max) {
255
279
int j = i + (rand () % (size - i));
256
280
do {
257
- bool ok = (ipv4 && thread->cache [j].v == 4 ) ||
258
- (ipv6 && thread->cache [j].v == 6 );
281
+ bool ok = (ipv4 && thread->cache [requestedFlags][ j].v == 4 ) ||
282
+ (ipv6 && thread->cache [requestedFlags][ j].v == 6 );
259
283
if (ok) break ;
260
284
j++;
261
285
if (j==size)
262
286
j=i;
263
287
} while (1 );
264
- addr[i] = thread->cache [j];
265
- thread->cache [j] = thread->cache [i];
266
- thread->cache [i] = addr[i];
288
+ addr[i] = thread->cache [requestedFlags][ j];
289
+ thread->cache [requestedFlags][ j] = thread->cache [requestedFlags] [i];
290
+ thread->cache [requestedFlags][ i] = addr[i];
267
291
i++;
268
292
}
269
293
return max;
@@ -306,11 +330,11 @@ extern "C" void* ThreadDumper(void*) {
306
330
rename (" dnsseed.dat.new" , " dnsseed.dat" );
307
331
}
308
332
FILE *d = fopen (" dnsseed.dump" , " w" );
309
- fprintf (d, " # address good lastSuccess %%(2h) %%(8h) %%(1d) %%(7d) %%(30d) blocks svcs version\n " );
333
+ fprintf (d, " # address servicebits good lastSuccess %%(2h) %%(8h) %%(1d) %%(7d) %%(30d) blocks svcs version\n " );
310
334
double stat[5 ]={0 ,0 ,0 ,0 ,0 };
311
335
for (vector<CAddrReport>::const_iterator it = v.begin (); it < v.end (); it++) {
312
336
CAddrReport rep = *it;
313
- 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 ());
337
+ fprintf (d, " %-47s %8lld % 4d %11" PRId64" %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6i %08" PRIx64" %5i \" %s\"\n " , rep.ip .ToString ().c_str (), ( uint64_t )rep. services , (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 ());
314
338
stat[0 ] += rep.uptime [0 ];
315
339
stat[1 ] += rep.uptime [1 ];
316
340
stat[2 ] += rep.uptime [2 ];
0 commit comments