@@ -167,48 +167,48 @@ extern "C" void* ThreadCrawler(void* data) {
167167 } while (1 );
168168}
169169
170- extern " C" int GetIPList (void *thread, addr_t *addr, int max, int ipv4, int ipv6);
170+ extern " C" int GetIPList (void *thread, char *requestedHostname, addr_t *addr, int max, int ipv4, int ipv6);
171171
172172class CDnsThread {
173173public:
174174 dns_opt_t dns_opt; // must be first
175175 const int id;
176- vector<addr_t > cache;
176+ std::map< uint64_t , vector<addr_t > > cache;
177177 int nIPv4, nIPv6;
178178 time_t cacheTime;
179179 unsigned int cacheHits;
180180 uint64_t dbQueries;
181181
182- void cacheHit (bool force = false ) {
182+ void cacheHit (uint64_t requestedFlags, bool force = false ) {
183183 static bool nets[NET_MAX] = {};
184184 if (!nets[NET_IPV4]) {
185185 nets[NET_IPV4] = true ;
186186 nets[NET_IPV6] = true ;
187187 }
188188 time_t now = time (NULL );
189189 cacheHits++;
190- if (force || cacheHits > (cache.size ()*cache.size ()/400 ) || (cacheHits*cacheHits > cache.size () / 20 && (now - cacheTime > 5 ))) {
190+ if (force || cacheHits > (cache[requestedFlags] .size ()*cache[requestedFlags] .size ()/400 ) || (cacheHits*cacheHits > cache[requestedFlags] .size () / 20 && (now - cacheTime > 5 ))) {
191191 set<CNetAddr> ips;
192- db.GetIPs (ips, 1000 , nets);
192+ db.GetIPs (ips, requestedFlags, 1000 , nets);
193193 dbQueries++;
194- cache.clear ();
194+ cache[requestedFlags] .clear ();
195195 nIPv4 = 0 ;
196196 nIPv6 = 0 ;
197- cache.reserve (ips.size ());
197+ cache[requestedFlags] .reserve (ips.size ());
198198 for (set<CNetAddr>::iterator it = ips.begin (); it != ips.end (); it++) {
199199 struct in_addr addr;
200200 struct in6_addr addr6;
201201 if ((*it).GetInAddr (&addr)) {
202202 addr_t a;
203203 a.v = 4 ;
204204 memcpy (&a.data .v4 , &addr, 4 );
205- cache.push_back (a);
205+ cache[requestedFlags] .push_back (a);
206206 nIPv4++;
207207 } else if ((*it).GetIn6Addr (&addr6)) {
208208 addr_t a;
209209 a.v = 6 ;
210210 memcpy (&a.data .v6 , &addr6, 16 );
211- cache.push_back (a);
211+ cache[requestedFlags] .push_back (a);
212212 nIPv6++;
213213 }
214214 }
@@ -227,24 +227,31 @@ class CDnsThread {
227227 dns_opt.port = opts->nPort ;
228228 dns_opt.nRequests = 0 ;
229229 cache.clear ();
230- cache.reserve (1000 );
231230 cacheTime = 0 ;
232231 cacheHits = 0 ;
233232 dbQueries = 0 ;
234233 nIPv4 = 0 ;
235234 nIPv6 = 0 ;
236- cacheHit (true );
237235 }
238236
239237 void run () {
240238 dnsserver (&dns_opt);
241239 }
242240};
243241
244- extern " C" int GetIPList (void *data, addr_t * addr, int max, int ipv4, int ipv6) {
242+ extern " C" int GetIPList (void *data, char *requestedHostname, addr_t * addr, int max, int ipv4, int ipv6) {
245243 CDnsThread *thread = (CDnsThread*)data;
246- thread->cacheHit ();
247- unsigned int size = thread->cache .size ();
244+
245+ uint64_t requestedFlags = 0 ;
246+ int hostlen = strlen (requestedHostname);
247+ if (hostlen > 1 && requestedHostname[0 ] == ' x' && requestedHostname[1 ] != ' 0' ) {
248+ char *pEnd;
249+ uint64_t flags = (uint64_t )strtoull (requestedHostname+1 , &pEnd, 16 );
250+ if (*pEnd == ' .' && pEnd <= requestedHostname+17 )
251+ requestedFlags = flags;
252+ }
253+ thread->cacheHit (requestedFlags);
254+ unsigned int size = thread->cache [requestedFlags].size ();
248255 unsigned int maxmax = (ipv4 ? thread->nIPv4 : 0 ) + (ipv6 ? thread->nIPv6 : 0 );
249256 if (max > size)
250257 max = size;
@@ -254,16 +261,16 @@ extern "C" int GetIPList(void *data, addr_t* addr, int max, int ipv4, int ipv6)
254261 while (i<max) {
255262 int j = i + (rand () % (size - i));
256263 do {
257- bool ok = (ipv4 && thread->cache [j].v == 4 ) ||
258- (ipv6 && thread->cache [j].v == 6 );
264+ bool ok = (ipv4 && thread->cache [requestedFlags][ j].v == 4 ) ||
265+ (ipv6 && thread->cache [requestedFlags][ j].v == 6 );
259266 if (ok) break ;
260267 j++;
261268 if (j==size)
262269 j=i;
263270 } while (1 );
264- addr[i] = thread->cache [j];
265- thread->cache [j] = thread->cache [i];
266- thread->cache [i] = addr[i];
271+ addr[i] = thread->cache [requestedFlags][ j];
272+ thread->cache [requestedFlags][ j] = thread->cache [requestedFlags] [i];
273+ thread->cache [requestedFlags][ i] = addr[i];
267274 i++;
268275 }
269276 return max;
@@ -306,11 +313,11 @@ extern "C" void* ThreadDumper(void*) {
306313 rename (" dnsseed.dat.new" , " dnsseed.dat" );
307314 }
308315 FILE *d = fopen (" dnsseed.dump" , " w" );
309- fprintf (d, " # address good lastSuccess %%(2h) %%(8h) %%(1d) %%(7d) %%(30d) blocks svcs version\n " );
316+ fprintf (d, " # address servicebits good lastSuccess %%(2h) %%(8h) %%(1d) %%(7d) %%(30d) blocks svcs version\n " );
310317 double stat[5 ]={0 ,0 ,0 ,0 ,0 };
311318 for (vector<CAddrReport>::const_iterator it = v.begin (); it < v.end (); it++) {
312319 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 ());
320+ 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 ());
314321 stat[0 ] += rep.uptime [0 ];
315322 stat[1 ] += rep.uptime [1 ];
316323 stat[2 ] += rep.uptime [2 ];
0 commit comments