diff --git a/db.cpp b/db.cpp index 55277c0..2313f40 100644 --- a/db.cpp +++ b/db.cpp @@ -138,13 +138,13 @@ void CAddrDb::Skipped_(const CIPPort &addr) } -void CAddrDb::Add_(const CAddress &addr) { - if (!addr.IsRoutable()) +void CAddrDb::Add_(const CAddress &addr, bool force) { + if (!force && !addr.IsRoutable()) return; CIPPort ipp(addr); if (banned.count(ipp)) { time_t bantime = banned[ipp]; - if (bantime < time(NULL) && addr.nTime > bantime) + if (force || (bantime < time(NULL) && addr.nTime > bantime)) banned.erase(ipp); else return; @@ -157,6 +157,9 @@ void CAddrDb::Add_(const CAddress &addr) { ai.services |= addr.nServices; // printf("%s: updated\n", ToString(addr).c_str()); } + if (force) { + ai.ignoreTill = 0; + } return; } CAddrInfo ai; diff --git a/db.h b/db.h index f590274..ff39139 100644 --- a/db.h +++ b/db.h @@ -68,10 +68,10 @@ public: if (total <= 3 && success * 2 >= total) return true; - if (stat2H.reliability > 0.7 && stat2H.count > 3) return true; - if (stat8H.reliability > 0.6 && stat8H.count > 6) return true; - if (stat1D.reliability > 0.5 && stat1D.count > 12) return true; - if (stat1W.reliability > 0.4 && stat1W.count > 24) return true; + if (stat2H.reliability > 0.7 && stat2H.count > 1) return true; + if (stat8H.reliability > 0.6 && stat8H.count > 2) return true; + if (stat1D.reliability > 0.5 && stat1D.count > 4) return true; + if (stat1W.reliability > 0.4 && stat1W.count > 8) return true; return false; } @@ -116,6 +116,15 @@ public: ) }; +class CAddrDbStats { +public: + int nBanned; + int nAvail; + int nTracked; + int nNew; + int nGood; +}; + // seen nodes // / \ // (a) banned nodes available nodes-------------- @@ -138,7 +147,7 @@ private: protected: // internal routines that assume proper locks are acquired - void Add_(const CAddress &addr); // add an address + void Add_(const CAddress &addr, bool force); // add an address bool Get_(CIPPort &ip, int& wait); // get an IP to test (must call Good_, Bad_, or Skipped_ on result afterwards) void Good_(const CIPPort &ip, int clientV); // mark an IP as good (must have been returned by Get_) void Bad_(const CIPPort &ip, int ban); // mark an IP as bad (and optionally ban it) (must have been returned by Get_) @@ -148,6 +157,16 @@ protected: public: + void GetStats(CAddrDbStats &stats) { + SHARED_CRITICAL_BLOCK(cs) { + stats.nBanned = banned.size(); + stats.nAvail = idToInfo.size(); + stats.nTracked = ourId.size(); + stats.nGood = goodId.size(); + stats.nNew = unkId.size(); + } + } + // serialization code // format: // nVersion (0 for now) @@ -197,30 +216,15 @@ public: READWRITE(banned); } });) - - // print statistics - void Stats() { - SHARED_CRITICAL_BLOCK(cs) { - if (nDirty > 50) { - printf("**** %i available (%i tracked, %i new, %i active), %i banned; %i good\n", - (int)idToInfo.size(), - (int)ourId.size(), - (int)unkId.size(), - (int)idToInfo.size() - (int)ourId.size() - (int)unkId.size(), - (int)banned.size(), - (int)goodId.size()); - nDirty = 0; // hopefully atomic - } - } - } - void Add(const CAddress &addr) { + + void Add(const CAddress &addr, bool fForce = false) { CRITICAL_BLOCK(cs) - Add_(addr); + Add_(addr, fForce); } - void Add(const std::vector &vAddr) { + void Add(const std::vector &vAddr, bool fForce = false) { CRITICAL_BLOCK(cs) for (int i=0; inRequests), addr[0], addr[1], addr[2], addr[3], ntohs(si_other.sin_port), (int)insize); if (insize > 0) { ssize_t ret = dnshandle(opt, inbuf, insize, outbuf); if (ret > 0) diff --git a/main.cpp b/main.cpp index 5e1216f..614c25c 100644 --- a/main.cpp +++ b/main.cpp @@ -3,7 +3,7 @@ #include "bitcoin.h" #include "db.h" -#define NTHREADS 16 +#define NTHREADS 32 using namespace std; @@ -15,7 +15,6 @@ CAddrDb db; extern "C" void* ThreadCrawler(void* data) { do { - db.Stats(); CIPPort ip; int wait = 5; if (!db.Get(ip, wait)) { @@ -57,16 +56,18 @@ extern "C" int GetIPList(struct in_addr *addr, int max, int ipv4only) { return n; } +static dns_opt_t dns_opt; + extern "C" void* ThreadDNS(void*) { - dns_opt_t opt; - opt.host = "seed.bitcoin.sipa.be"; - opt.ns = "vps.sipa.be"; - opt.mbox = "sipa.ulyssis.org"; - opt.datattl = 60; - opt.nsttl = 40000; - opt.cb = GetIPList; - opt.port = 53; - dnsserver(&opt); + dns_opt.host = "seed.bitcoin.sipa.be"; + dns_opt.ns = "vps.sipa.be"; + dns_opt.mbox = "sipa.ulyssis.org"; + dns_opt.datattl = 60; + dns_opt.nsttl = 40000; + dns_opt.cb = GetIPList; + dns_opt.port = 53; + dns_opt.nRequests = 0; + dnsserver(&dns_opt); } extern "C" void* ThreadDumper(void*) { @@ -82,24 +83,45 @@ extern "C" void* ThreadDumper(void*) { } while(1); } +extern "C" void* ThreadStats(void*) { + do { + CAddrDbStats stats; + db.GetStats(stats); + printf("*** %i available (%i tracked, %i new, %i active), %i banned; %i good; %llu DNS requests\n", stats.nAvail, stats.nTracked, stats.nNew, stats.nAvail - stats.nTracked - stats.nNew, stats.nBanned, stats.nGood, (unsigned long long)dns_opt.nRequests); + Sleep(10000); + } while(1); +} + +static const string seeds[] = {"dnsseed.bluematt.me", "bitseed.xf2.org", "dnsseed.bitcoin.dashjr.org", "seed.bitcoin.sipa.be"}; + +extern "C" void* ThreadSeeder(void*) { + do { + for (int i=0; i ips; + LookupHost(seeds[i].c_str(), ips); + for (vector::iterator it = ips.begin(); it != ips.end(); it++) { + db.Add(CIPPort(*it, 8333), true); + } + } + Sleep(1800000); + } while(1); +} + int main(void) { FILE *f = fopen("dnsseed.dat","r"); if (f) { CAutoFile cf(f); cf >> db; } - vector ips; - LookupHost("dnsseed.bluematt.me", ips); - for (vector::iterator it = ips.begin(); it != ips.end(); it++) { - db.Add(CIPPort(*it, 8333)); - } - pthread_t thread[NTHREADS+2]; + pthread_t thread[NTHREADS+4]; for (int i=0; i