38 int *nThreads = (
int *)data;
40 std::vector<CServiceResult> ips;
45 5000 + std::rand() % (500 * *nThreads)));
49 std::vector<CAddress> addr;
50 for (
size_t i = 0; i < ips.size(); i++) {
60 bool ret =
node.Run();
74 }
catch (std::ios_base::failure &e) {
86extern "C" uint32_t
GetIPList(
void *thread,
char *requestedHostname,
87 addr_t *addr, uint32_t max, uint32_t ipv4,
106 void cacheHit(uint64_t requestedFlags,
bool force =
false) {
107 static bool nets[
NET_MAX] = {};
117 (thisflag.
cache.size() * thisflag.
cache.size()) ||
119 thisflag.
cache.size() &&
121 std::set<CNetAddr> ips;
122 db.
GetIPs(ips, requestedFlags, 1000, nets);
124 thisflag.
cache.clear();
127 thisflag.
cache.reserve(ips.size());
128 for (
auto &ip : ips) {
130 struct in6_addr addr6;
131 if (ip.GetInAddr(&addr)) {
134 memcpy(&a.
data.
v4, &addr, 4);
135 thisflag.
cache.push_back(a);
137 }
else if (ip.GetIn6Addr(&addr6)) {
140 memcpy(&a.
data.
v6, &addr6, 16);
141 thisflag.
cache.push_back(a);
169 uint32_t max, uint32_t ipv4, uint32_t ipv6) {
172 uint64_t requestedFlags = 0;
173 int hostlen = strlen(requestedHostname);
174 if (hostlen > 1 && requestedHostname[0] ==
'x' &&
175 requestedHostname[1] !=
'0') {
177 uint64_t
flags = (uint64_t)strtoull(requestedHostname + 1, &pEnd, 16);
178 if (*pEnd ==
'.' && pEnd <= requestedHostname + 17 &&
182 requestedFlags =
flags;
186 }
else if (strcasecmp(requestedHostname, thread->
dns_opt.
host)) {
190 auto &thisflag = thread->
perflag[requestedFlags];
191 uint32_t size = thisflag.cache.size();
192 uint32_t maxmax = (ipv4 ? thisflag.nIPv4 : 0) + (ipv6 ? thisflag.nIPv6 : 0);
201 uint32_t j = i + (rand() % (size - i));
203 bool ok = (ipv4 && thisflag.cache[j].v == 4) ||
204 (ipv6 && thisflag.cache[j].v == 6);
213 addr[i] = thisflag.cache[j];
214 thisflag.cache[j] = thisflag.cache[i];
215 thisflag.cache[i] = addr[i];
243 const auto dumpInterval(*(
const std::chrono::seconds *)data);
250 std::vector<CAddrReport> v =
db.
GetAll();
258 rename(
"dnsseed.dat.new",
"dnsseed.dat");
260 std::ofstream d{
"dnsseed.dump"};
263 "lastSuccess %%(2h) %%(8h) %%(1d) %%(7d) "
264 "%%(30d) blocks svcs version\n");
265 double stat[5] = {0, 0, 0, 0, 0};
269 "%-47s %4d %11" PRId64
270 " %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6i %08" PRIx64
274 rep.lastSuccess, 100.0 * rep.uptime[0],
275 100.0 * rep.uptime[1], 100.0 * rep.uptime[2],
276 100.0 * rep.uptime[3], 100.0 * rep.uptime[4], rep.blocks,
277 rep.services, rep.clientVersion, rep.clientSubVersion);
278 stat[0] += rep.uptime[0];
279 stat[1] += rep.uptime[1];
280 stat[2] += rep.uptime[2];
281 stat[3] += rep.uptime[3];
282 stat[4] += rep.uptime[4];
284 std::ofstream ff{
"dnsstats.log", std::ios_base::app};
286 stat[1], stat[2], stat[3], stat[4]);
299 time_t tim = time(
nullptr);
300 struct tm *tmp = localtime(&tim);
301 strftime(c, 256,
"[%y-%m-%d %H:%M:%S]", tmp);
311 uint64_t requests = 0;
312 uint64_t queries = 0;
313 for (
unsigned int i = 0; i <
dnsThread.size(); i++) {
314 requests +=
dnsThread[i]->dns_opt.nRequests;
319 "%s %i/%i available (%i tried in %is, %i new, %i active), %i "
320 "banned; %llu DNS requests, %llu db queries\n",
323 stats.
nBanned, (
unsigned long long)requests,
324 (
unsigned long long)queries);
335 std::vector<CNetAddr> ips;
337 for (
auto &ip : ips) {
347int main(
int argc,
char **argv) {
351 signal(SIGPIPE, SIG_IGN);
352 setbuf(stdout,
nullptr);
361 tfm::format(std::cout,
"Supporting whitelisted filters: ");
367 tfm::format(std::cout,
"0x%lx", (
unsigned long)*it);
370 if (!opts.
tor.empty()) {
396 if (opts.
ns.empty()) {
397 tfm::format(std::cout,
"No nameserver set. Not starting DNS server.\n");
400 if (fDNS && opts.
host.empty()) {
401 tfm::format(std::cerr,
"No hostname set. Please use -h.\n");
404 if (fDNS && opts.
mbox.empty()) {
405 tfm::format(std::cerr,
"No e-mail address set. Please use -m.\n");
423 pthread_t threadDns, threadSeed, threadDump, threadStats;
426 "Starting %i DNS threads for %s on %s (port %i)...",
433 if (threadStatus != 0) {
434 tfm::format(std::cerr,
"Failed to create DNS thread (%i)\n",
446 pthread_create(&threadSeed,
nullptr,
ThreadSeeder,
nullptr);
447 if (threadStatus != 0) {
448 tfm::format(std::cerr,
"Failed to create seeder thread (%i)\n",
455 pthread_attr_t attr_crawler;
456 pthread_attr_init(&attr_crawler);
457 pthread_attr_setstacksize(&attr_crawler, 0x40000);
458 for (
int i = 0; i < opts.
nThreads; i++) {
460 int threadStatus = pthread_create(&thread, &attr_crawler,
ThreadCrawler,
462 if (threadStatus != 0) {
463 tfm::format(std::cerr,
"Failed to create crawler thread (%i)\n",
468 pthread_attr_destroy(&attr_crawler);
472 pthread_create(&threadStats,
nullptr,
ThreadStats,
nullptr);
473 if (threadStatus != 0) {
474 tfm::format(std::cerr,
"Failed to create stats thread (%i)\n",
480 int threadStatus = pthread_create(&threadDump,
nullptr,
ThreadDumper,
482 if (threadStatus != 0) {
483 tfm::format(std::cerr,
"Failed to create dump thread (%i)\n",
489 pthread_join(threadDump, &res);
const CChainParams & Params()
Return the currently selected parameters.
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
void Add(const CAddress &addr, bool fForce=false)
void GetMany(std::vector< CServiceResult > &ips, int max)
void ResultMany(const std::vector< CServiceResult > &ips)
void GetStats(CAddrDbStats &stats) const
std::vector< CAddrReport > GetAll()
void GetIPs(std::set< CNetAddr > &ips, uint64_t requestedFlags, uint32_t max, const bool *nets)
std::map< CService, int64_t > banned
A CService with information about it as peer.
std::atomic< uint64_t > dbQueries
std::set< uint64_t > filterWhitelist
std::map< uint64_t, FlagSpecificData > perflag
CDnsThread(seeder::CDnsSeedOpts *opts, int idIn)
void cacheHit(uint64_t requestedFlags, bool force=false)
A combination of a network address (CNetAddr) and a (TCP) port.
std::string ToStringIPPort() const
std::chrono::seconds dumpInterval
int ParseCommandLine(int argc, const char **argv)
std::set< uint64_t > filter_whitelist
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
int dnsserver(dns_opt_t *opt)
const std::vector< std::string > GetRandomizedDNSSeeds(const CChainParams ¶ms)
Return the list of hostnames to look up for DNS seeds.
BCLog::Logger & LogInstance()
FILE * fopen(const fs::path &p, const char *mode)
static const int CONTINUE_EXECUTION
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
@ NET_ONION
TOR (v2 or v3)
CService LookupNumeric(const std::string &name, uint16_t portDefault, DNSLookupFn dns_lookup_function)
Resolve a service string with a numeric IP to its first corresponding service.
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Resolve a host string to its corresponding network addresses.
bool SetProxy(enum Network net, const proxyType &addrProxy)
ServiceFlags
nServices flags.
int main(int argc, char *argv[])
const std::function< std::string(const char *)> G_TRANSLATION_FUN
Translate string to current locale using Qt.
static uint16_t GetDefaultPort()
int StatCompare(const CAddrReport &a, const CAddrReport &b)
void * ThreadDNS(void *arg)
void * ThreadDumper(void *data)
std::vector< CDnsThread * > dnsThread
void * ThreadStats(void *)
uint32_t GetIPList(void *thread, char *requestedHostname, addr_t *addr, uint32_t max, uint32_t ipv4, uint32_t ipv6)
static const unsigned int MAX_HOSTS_PER_SEED
void * ThreadSeeder(void *)
void * ThreadCrawler(void *data)
std::vector< addr_t > cache
uint32_t(* cb)(void *opt, char *requested_hostname, addr_t *addr, uint32_t max, uint32_t ipv4, uint32_t ipv6)
void UninterruptibleSleep(const std::chrono::microseconds &n)
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.