diff --git a/Makefile b/Makefile index ff4641e..d1fed9d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,14 @@ -dnsseed: dns.o bitcoin.cpp netbase.cpp protocol.cpp db.cpp main.cpp bitcoin.h netbase.h protocol.h db.h serialize.h uint256.h util.h - g++ -pthread -lssl -O3 -ggdb3 -march=nocona -Wno-invalid-offsetof -o dnsseed bitcoin.cpp netbase.cpp protocol.cpp db.cpp main.cpp dns.o +dnsseed: dns.o bitcoin.o netbase.o protocol.o db.o main.o + g++ -pthread -lssl -o dnsseed dns.o bitcoin.o netbase.o protocol.o db.o main.o + strip -s dnsseed + +dnsseed.dbg: dns.o bitcoin.o netbase.o protocol.o db.o main.o + g++ -pthread -lssl -o dnsseed.dbg dns.o bitcoin.o netbase.o protocol.o db.o main.o + +%.o: %.cpp bitcoin.h netbase.h protocol.h db.h serialize.h uint256.h util.h + g++ -pthread -O3 -ggdb3 -march=nocona -Wno-invalid-offsetof -c -o $@ $< dns.o: dns.c - gcc -std=c99 -O3 -g0 -march=nocona dns.c -c -o dns.o + gcc -pthread -std=c99 -O3 -g0 -march=nocona dns.c -c -o dns.o +%.o: %.cpp diff --git a/bitcoin.cpp b/bitcoin.cpp index ab57aef..28debf9 100644 --- a/bitcoin.cpp +++ b/bitcoin.cpp @@ -32,7 +32,7 @@ class CNode { nHeaderStart = vSend.size(); vSend << CMessageHeader(pszCommand, 0); nMessageStart = vSend.size(); - printf("%s: SEND %s\n", you.ToString().c_str(), pszCommand); +// printf("%s: SEND %s\n", ToString(you).c_str(), pszCommand); } void AbortMessage() { @@ -83,18 +83,18 @@ class CNode { void GotVersion() { if (nVersion < MIN_VERSION) { - printf("%s: BAD (version %i is below %i)\n", you.ToString().c_str(), nVersion, MIN_VERSION); + printf("%s: BAD (version %i is below %i)\n", ToString(you).c_str(), nVersion, MIN_VERSION); ban = 1000000; return; } - printf("%s: version %i\n", you.ToString().c_str(), nVersion); + printf("%s: version %i\n", ToString(you).c_str(), nVersion); BeginMessage("getaddr"); EndMessage(); doneAfter = time(NULL) + 10; } bool ProcessMessage(string strCommand, CDataStream& vRecv) { - printf("%s: RECV %s\n", you.ToString().c_str(), strCommand.c_str()); +// printf("%s: RECV %s\n", ToString(you).c_str(), strCommand.c_str()); if (strCommand == "version") { int64 nTime; CAddress addrMe; @@ -110,7 +110,7 @@ class CNode { vRecv >> nStartingHeight; if (!(you.nServices & NODE_NETWORK)) { - printf("%s: BAD (no NODE_NETWORK)\n", you.ToString().c_str()); + printf("%s: BAD (no NODE_NETWORK)\n", ToString(you).c_str()); ban = 1000000; return true; } @@ -136,20 +136,20 @@ class CNode { if (strCommand == "addr") { vector vAddrNew; vRecv >> vAddrNew; - printf("%s: got %i addresses\n", you.ToString().c_str(), (int)vAddrNew.size()); + printf("%s: got %i addresses\n", ToString(you).c_str(), (int)vAddrNew.size()); int64 now = time(NULL); vector::iterator it = vAddrNew.begin(); if (doneAfter == 0 || doneAfter > now + 1) doneAfter = now + 1; while (it != vAddrNew.end()) { CAddress &addr = *it; -// printf("%s: got address %s\n", you.ToString().c_str(), addr.ToString().c_str(), (int)(vAddr->size())); +// printf("%s: got address %s\n", ToString(you).c_str(), addr.ToString().c_str(), (int)(vAddr->size())); it++; if (!addr.IsIPv4()) continue; if (addr.nTime <= 100000000 || addr.nTime > now + 600) addr.nTime = now - 5 * 86400; vAddr->push_back(addr); -// printf("%s: added address %s (#%i)\n", you.ToString().c_str(), addr.ToString().c_str(), (int)(vAddr->size())); +// printf("%s: added address %s (#%i)\n", ToString(you).c_str(), addr.ToString().c_str(), (int)(vAddr->size())); if (vAddr->size() > 1000) {doneAfter = 1; return true; } } return false; @@ -174,13 +174,13 @@ class CNode { CMessageHeader hdr; vRecv >> hdr; if (!hdr.IsValid()) { - printf("%s: BAD (invalid header)\n", you.ToString().c_str()); + printf("%s: BAD (invalid header)\n", ToString(you).c_str()); ban = 100000; return true; } string strCommand = hdr.GetCommand(); unsigned int nMessageSize = hdr.nMessageSize; if (nMessageSize > MAX_SIZE) { - printf("%s: BAD (message too large)\n", you.ToString().c_str()); + printf("%s: BAD (message too large)\n", ToString(you).c_str()); ban = 100000; return true; } @@ -198,7 +198,7 @@ class CNode { vRecv.ignore(nMessageSize); if (ProcessMessage(strCommand, vMsg)) return true; - printf("%s: done processing %s\n", you.ToString().c_str(), strCommand.c_str()); +// printf("%s: done processing %s\n", ToString(you).c_str(), strCommand.c_str()); } while(1); return false; } @@ -244,8 +244,12 @@ public: vRecv.resize(nPos + nBytes); memcpy(&vRecv[nPos], pchBuf, nBytes); } else if (nBytes == 0) { - Sleep(127); + printf("%s: BAD (connection closed prematurely)\n", ToString(you).c_str()); + res = false; + break; } else { + printf("%s: BAD (connection error)\n", ToString(you).c_str()); + res = false; break; } ProcessMessages(); @@ -270,7 +274,7 @@ bool TestNode(const CIPPort &cip, int &ban, vector& vAddr) { } else { ban = 0; } - printf("%s: %s!!!\n", cip.ToString().c_str(), ret ? "GOOD" : "BAD"); +// printf("%s: %s!!!\n", cip.ToString().c_str(), ret ? "GOOD" : "BAD"); return ret; } @@ -284,3 +288,4 @@ int main(void) { printf("ret=%s ban=%i vAddr.size()=%i\n", ret ? "good" : "bad", ban, (int)vAddr.size()); } */ + diff --git a/db.cpp b/db.cpp index 65e7296..1d9ca15 100644 --- a/db.cpp +++ b/db.cpp @@ -5,6 +5,8 @@ using namespace std; void CAddrInfo::Update(bool good) { uint32_t now = time(NULL); + if (ourLastTry == 0) + ourLastTry = now - MIN_RETRY; double f = exp(-(now-ourLastTry)/TAU); reliability = reliability * f + (good ? (1.0-f) : 0); timing = (timing + (now-ourLastTry) * weight) * f; @@ -14,44 +16,41 @@ void CAddrInfo::Update(bool good) { ourLastTry = now; total++; if (good) success++; - printf("%s: got %s result: weight=%g reliability=%g avgage=%g count=%g success=%i/%i\n", ip.ToString().c_str(), good ? "good" : "bad", weight, reliability/weight, timing/weight, count/weight, success, total); + printf("%s: got %s result: weight=%g reliability=%g avgage=%g count=%g success=%i/%i\n", ToString(ip).c_str(), good ? "good" : "bad", weight, GetReliability(), GetAvgAge(), GetCount(), success, total); } bool CAddrDb::Get_(CIPPort &ip, int &wait) { - int cont = 0; int64 now = time(NULL); - do { - cont = 0; - int tot = unkId.size(); - deque::iterator it = ourId.begin(); - while (it < ourId.end()) { - if (now - idToInfo[*it].ourLastTry > MIN_RETRY) { - tot++; - it++; - } else { - break; - } - } - if (tot == 0) { - if (ourId.size() > 0) { - wait = MIN_RETRY - (now - idToInfo[ourId.front()].ourLastTry); - } - return false; - } - int rnd = rand() % tot; - if (rnd < unkId.size()) { - set::iterator it = unkId.begin(); - ip = idToInfo[*it].ip; - unkId.erase(it); - printf("From UNK: %s\n", ip.ToString().c_str()); + int tot = unkId.size(); + deque::iterator it = ourId.begin(); + while (it < ourId.end()) { + if (now - idToInfo[*it].ourLastTry > MIN_RETRY) { + tot++; + it++; } else { - int ret = ourId.front(); - if (time(NULL) - idToInfo[ret].ourLastTry < MIN_RETRY) return false; - ourId.pop_front(); - ip = idToInfo[ret].ip; - printf("From OUR: %s (size = %i)\n", ip.ToString().c_str(), (int)ourId.size()); + break; + } + } + if (tot == 0) { + if (ourId.size() > 0) { + wait = MIN_RETRY - (now - idToInfo[ourId.front()].ourLastTry); } - } while(cont); + return false; + } + int rnd = rand() % tot; + if (rnd < unkId.size()) { + set::reverse_iterator it = unkId.rbegin(); + ip = idToInfo[*it].ip; + unkId.erase(*it); + printf("%s: new node\n", ToString(ip).c_str()); + } else { + int ret = ourId.front(); + if (time(NULL) - idToInfo[ret].ourLastTry < MIN_RETRY) return false; + ourId.pop_front(); + ip = idToInfo[ret].ip; + printf("%s: old node\n", ToString(ip).c_str()); + } + fDirty = true; return true; } @@ -62,18 +61,17 @@ int CAddrDb::Lookup_(const CIPPort &ip) { } void CAddrDb::Good_(const CIPPort &addr) { - printf("%s: good!\n", addr.ToString().c_str()); int id = Lookup_(addr); - printf("%s: good (id=%i)!\n", addr.ToString().c_str(), id); if (id == -1) return; unkId.erase(id); banned.erase(addr); CAddrInfo &info = idToInfo[id]; info.Update(true); - if (info.IsGood()) { + if (info.IsGood() && goodId.count(id)==0) { goodId.insert(id); - printf("%s: good; %i good nodes now\n", addr.ToString().c_str(), (int)goodId.size()); + printf("%s: good; %i good nodes now\n", ToString(addr).c_str(), (int)goodId.size()); } + fDirty = true; ourId.push_back(id); } @@ -86,22 +84,23 @@ void CAddrDb::Bad_(const CIPPort &addr, int ban) info.Update(false); uint32_t now = time(NULL); if (info.IsTerrible()) { - printf("%s: terrible\n", addr.ToString().c_str()); + printf("%s: terrible\n", ToString(addr).c_str()); if (ban < 604800) ban = 604800; } if (ban > 0) { - printf("%s: ban %i seconds\n", addr.ToString().c_str(), ban); + printf("%s: ban for %i seconds\n", ToString(addr).c_str(), ban); banned[info.ip] = ban + now; ipToId.erase(info.ip); goodId.erase(id); idToInfo.erase(id); } else { - if (!info.IsGood()) { + if (!info.IsGood() && goodId.count(id)==1) { goodId.erase(id); - printf("%s: not good; %i good nodes left\n", addr.ToString().c_str(), (int)goodId.size()); + printf("%s: not good; %i good nodes left\n", ToString(addr).c_str(), (int)goodId.size()); } ourId.push_back(id); } + fDirty = true; } void CAddrDb::Skipped_(const CIPPort &addr) @@ -110,7 +109,8 @@ void CAddrDb::Skipped_(const CIPPort &addr) if (id == -1) return; unkId.erase(id); ourId.push_back(id); - printf("%s: skipped\n", addr.ToString().c_str()); + printf("%s: skipped\n", ToString(addr).c_str()); + fDirty = true; } @@ -127,10 +127,12 @@ void CAddrDb::Add_(const CAddress &addr) { } if (ipToId.count(ipp)) { CAddrInfo &ai = idToInfo[ipToId[ipp]]; - if (addr.nTime > ai.lastTry) + if (addr.nTime > ai.lastTry || ai.services != addr.nServices) + { ai.lastTry = addr.nTime; - ai.services |= addr.nServices; - printf("%s: updated\n", addr.ToString().c_str()); + ai.services |= addr.nServices; +// printf("%s: updated\n", ToString(addr).c_str()); + } return; } CAddrInfo ai; @@ -145,8 +147,9 @@ void CAddrDb::Add_(const CAddress &addr) { int id = nId++; idToInfo[id] = ai; ipToId[ipp] = id; - printf("%s: added as id %i\n", ipp.ToString().c_str(), ipToId[ipp]); + printf("%s: added\n", ToString(ipp).c_str(), ipToId[ipp]); unkId.insert(id); + fDirty = true; } void CAddrDb::GetIPs_(set& ips, int max, bool fOnlyIPv4) { diff --git a/db.h b/db.h index 2e78d2e..e3ee55d 100644 --- a/db.h +++ b/db.h @@ -13,6 +13,12 @@ #define TAU 86400.0 #define MIN_RETRY 1000 +std::string static inline ToString(const CIPPort &ip) { + std::string str = ip.ToString(); + while (str.size() < 22) str += ' '; + return str; +} + class CAddrInfo { private: CIPPort ip; @@ -26,11 +32,14 @@ private: int total; int success; public: + double GetCount() const { return count; } + double GetAvgAge() const { return timing/weight; } + double GetReliability() const { return reliability/weight; } bool IsGood() { - return (weight > 0 && reliability/weight > 0.8 && timing/weight < 86400) && ip.GetPort() == 8333; + return (weight > 0 && GetReliability() > 0.8 && GetAvgAge() < 86400 && ip.GetPort() == 8333 && ip.IsRoutable()); } bool IsTerrible() { - return (weight > 0.5 & reliability/weight < 0.2 && timing/weight < 86400 && count/weight > 2.0); + return ((weight > 0.1 && GetCount() > 5 && GetReliability() < 0.05) || (weight > 0.5 && GetReliability() < 0.2 && GetAvgAge() > 7200 && GetCount() > 5)); } void Update(bool good); @@ -54,9 +63,9 @@ public: // seen nodes // / \ -// (a) banned nodes tracked nodes -// / \ -// tried nodes (b) unknown nodes +// (a) banned nodes available nodes-------------- +// / | \ +// tracked nodes (b) unknown nodes (e) active nodes // / \ // (d) good nodes (c) non-good nodes @@ -64,24 +73,36 @@ class CAddrDb { private: mutable CCriticalSection cs; int nId; // number of address id's - std::map idToInfo; // map address id to address info (b,c,d) - std::map ipToId; // map ip to id (b,c,d) + std::map idToInfo; // map address id to address info (b,c,d,e) + std::map ipToId; // map ip to id (b,c,d,e) std::deque ourId; // sequence of tried nodes, in order we have tried connecting to them (c,d) std::set unkId; // set of nodes not yet tried (b) - std::set goodId; // set of good nodes (d) + std::set goodId; // set of good nodes (d, good e) std::map banned; // nodes that are banned, with their unban time (a) + bool fDirty; protected: - void Add_(const CAddress &addr); - void Good_(const CIPPort &ip); - void Bad_(const CIPPort &ip, int ban); - void Skipped_(const CIPPort &ip); - bool Get_(CIPPort &ip, int& wait); - int Lookup_(const CIPPort &ip); - void GetIPs_(std::set& ips, int max, bool fOnlyIPv4); + // internal routines that assume proper locks are acquired + void Add_(const CAddress &addr); // 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); // 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_) + void Skipped_(const CIPPort &ip); // mark an IP as skipped (must have been returned by Get_) + int Lookup_(const CIPPort &ip); // look up id of an IP + void GetIPs_(std::set& ips, int max, bool fOnlyIPv4); // get a random set of IPs (shared lock only) public: + // seriazlization code + // format: + // nVersion (0 for now) + // nOur (number of ips in (c,d)) + // nUnk (number of ips in (b)) + // CAddrInfo[nOur] + // CAddrInfo[nUnk] + // banned + // acquires a shared lock (this does not suffice for read mode, but we assume that only happens at startup, single-threaded) + // this way, dumping does not interfere with GetIPs_, which is called from the DNS thread IMPLEMENT_SERIALIZE (({ int nVersion = 0; READWRITE(nVersion); @@ -109,28 +130,44 @@ public: for (int i=0; inId++; - db->idToInfo[id] = info; - db->ipToId[info.ip] = id; - db->ourId.push_back(id); - if (info.IsGood()) db->goodId.insert(id); + if (!info.IsTerrible()) { + int id = db->nId++; + db->idToInfo[id] = info; + db->ipToId[info.ip] = id; + db->ourId.push_back(id); + if (info.IsGood()) db->goodId.insert(id); + } } for (int i=0; inId++; - db->idToInfo[id] = info; - db->ipToId[info.ip] = id; - db->unkId.insert(id); + if (!info.IsTerrible()) { + int id = db->nId++; + db->idToInfo[id] = info; + db->ipToId[info.ip] = id; + db->unkId.insert(id); + } } + db->fDirty = true; } READWRITE(banned); } });) + // print statistics void Stats() { - CRITICAL_BLOCK(cs) - printf("**** %i good, %lu our, %i unk, %i banned; %i known ips\n", (int)goodId.size(), (unsigned long)ourId.size(), (int)unkId.size(), (int)banned.size(), (int)ipToId.size()); + SHARED_CRITICAL_BLOCK(cs) { + if (fDirty) { + 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()); + fDirty = false; // hopefully atomic + } + } } void Add(const CAddress &addr) { CRITICAL_BLOCK(cs) diff --git a/dns.c b/dns.c index 09fe31f..2298841 100644 --- a/dns.c +++ b/dns.c @@ -9,16 +9,9 @@ #include #include -#define BUFLEN 512 - -int port = 53; -int datattl = 60; -int nsttl = 30583; -char *host = "seedtest.bitcoin.sipa.be"; -char *ns = "vps.sipa.be"; -char *mbox = "sipa.ulyssis.org"; +#include "dns.h" -extern int GetIPList(struct in_addr *addr, int max, int ipv4only); +#define BUFLEN 512 typedef enum { CLASS_IN = 1, @@ -88,10 +81,10 @@ int static parse_name(const unsigned char **inpos, const unsigned char *inend, c // -1: component > 63 characters // -2: insufficent space in output // -3: two subsequent dots -int static write_name(unsigned char** outpos, unsigned char *outend, char *name, int offset) { +int static write_name(unsigned char** outpos, const unsigned char *outend, const char *name, int offset) { while (*name != 0) { char *dot = strchr(name, '.'); - char *fin = dot; + const char *fin = dot; if (!dot) fin = name + strlen(name); if (fin - name > 63) return -1; if (fin == name) return -3; @@ -114,7 +107,7 @@ int static write_name(unsigned char** outpos, unsigned char *outend, char *name, return 0; } -int static write_record(unsigned char** outpos, unsigned char *outend, char *name, int offset, dns_type typ, dns_class cls, int ttl) { +int static write_record(unsigned char** outpos, const unsigned char *outend, const char *name, int offset, dns_type typ, dns_class cls, int ttl) { unsigned char *oldpos = *outpos; int error = 0; // name @@ -134,7 +127,7 @@ error: } -int static write_record_a(unsigned char** outpos, unsigned char *outend, char *name, int offset, dns_class cls, int ttl, const struct in_addr *ip) { +int static write_record_a(unsigned char** outpos, const unsigned char *outend, const char *name, int offset, dns_class cls, int ttl, const struct in_addr *ip) { unsigned char *oldpos = *outpos; int error = 0; int ret = write_record(outpos, outend, name, offset, TYPE_A, cls, ttl); @@ -152,7 +145,7 @@ error: return error; } -int static write_record_aaaa(unsigned char** outpos, unsigned char *outend, char *name, int offset, dns_class cls, int ttl, const struct in6_addr *ip) { +int static write_record_aaaa(unsigned char** outpos, const unsigned char *outend, const char *name, int offset, dns_class cls, int ttl, const struct in6_addr *ip) { unsigned char *oldpos = *outpos; int error = 0; int ret = write_record(outpos, outend, name, offset, TYPE_AAAA, cls, ttl); @@ -170,7 +163,7 @@ error: return error; } -int static write_record_ns(unsigned char** outpos, unsigned char *outend, char *name, int offset, dns_class cls, int ttl, char *ns) { +int static write_record_ns(unsigned char** outpos, const unsigned char *outend, char *name, int offset, dns_class cls, int ttl, const char *ns) { unsigned char *oldpos = *outpos; int ret = write_record(outpos, outend, name, offset, TYPE_NS, cls, ttl); if (ret) return ret; @@ -188,7 +181,7 @@ error: return error; } -int static write_record_soa(unsigned char** outpos, unsigned char *outend, char *name, int offset, dns_class cls, int ttl, char* mname, char *rname, +int static write_record_soa(unsigned char** outpos, const unsigned char *outend, char *name, int offset, dns_class cls, int ttl, const char* mname, const char *rname, uint32_t serial, uint32_t refresh, uint32_t retry, uint32_t expire, uint32_t minimum) { unsigned char *oldpos = *outpos; int ret = write_record(outpos, outend, name, offset, TYPE_SOA, cls, ttl); @@ -215,7 +208,7 @@ error: return error; } -ssize_t static dnshandle(const unsigned char *inbuf, size_t insize, unsigned char* outbuf) { +ssize_t static dnshandle(dns_opt_t *opt, const unsigned char *inbuf, size_t insize, unsigned char* outbuf) { int error = 0; if (insize < 12) // DNS header return -1; @@ -248,8 +241,8 @@ ssize_t static dnshandle(const unsigned char *inbuf, size_t insize, unsigned cha int ret = parse_name(&inpos, inend, inbuf, name, 256); if (ret == -1) { error = 1; goto error; } if (ret == -2) { error = 5; goto error; } - int namel = strlen(name), hostl = strlen(host); - if (strcmp(name, host) && (namelhost); + if (strcmp(name, opt->host) && (namelhost))) { error = 5; goto error; } if (inend - inpos < 4) { error = 1; goto error; } // copy question to output memcpy(outbuf+12, inbuf+12, inpos+4 - (inbuf+12)); @@ -268,7 +261,7 @@ ssize_t static dnshandle(const unsigned char *inbuf, size_t insize, unsigned cha unsigned char *outpos = outbuf+(inpos-inbuf); unsigned char *outend = outbuf + BUFLEN; - printf("Request host='%s' type=%i class=%i\n", name, typ, cls); + printf("DNS: Request host='%s' type=%i class=%i\n", name, typ, cls); // calculate size of authority section @@ -277,7 +270,7 @@ ssize_t static dnshandle(const unsigned char *inbuf, size_t insize, unsigned cha if (!((typ == TYPE_NS || typ == QTYPE_ANY) && (cls == CLASS_IN || cls == QCLASS_ANY))) { // authority section will be necessary unsigned char *oldpos = outpos; - write_record_ns(&oldpos, outend, "", offset, CLASS_IN, 0, ns); + write_record_ns(&oldpos, outend, "", offset, CLASS_IN, 0, opt->ns); auth_size = oldpos - outpos; // printf("Authority section will claim %i bytes\n", auth_size); } @@ -288,14 +281,14 @@ ssize_t static dnshandle(const unsigned char *inbuf, size_t insize, unsigned cha // NS records if ((typ == TYPE_NS || typ == QTYPE_ANY) && (cls == CLASS_IN || cls == QCLASS_ANY)) { - int ret2 = write_record_ns(&outpos, outend - auth_size, "", offset, CLASS_IN, nsttl, ns); + int ret2 = write_record_ns(&outpos, outend - auth_size, "", offset, CLASS_IN, opt->nsttl, opt->ns); // printf("wrote NS record: %i\n", ret2); if (!ret2) { outbuf[7]++; have_ns++; } } // SOA records if ((typ == TYPE_SOA || typ == QTYPE_ANY) && (cls == CLASS_IN || cls == QCLASS_ANY)) { - int ret2 = write_record_soa(&outpos, outend - auth_size, "", offset, CLASS_IN, nsttl, ns, mbox, time(NULL), 604800, 86400, 2592000, 604800); + int ret2 = write_record_soa(&outpos, outend - auth_size, "", offset, CLASS_IN, opt->nsttl, opt->ns, opt->mbox, time(NULL), 604800, 86400, 2592000, 604800); // printf("wrote SOA record: %i\n", ret2); if (!ret2) { outbuf[7]++; } } @@ -303,10 +296,10 @@ ssize_t static dnshandle(const unsigned char *inbuf, size_t insize, unsigned cha // A records if ((typ == TYPE_A || typ == QTYPE_ANY) && (cls == CLASS_IN || cls == QCLASS_ANY)) { struct in_addr addr[20]; - int naddr = GetIPList(addr, 20, 1); + int naddr = opt->cb(addr, 20, 1); int n = 0; while (n < naddr) { - int ret = write_record_a(&outpos, outend - auth_size, "", offset, CLASS_IN, datattl, &addr[n]); + int ret = write_record_a(&outpos, outend - auth_size, "", offset, CLASS_IN, opt->datattl, &addr[n]); // printf("wrote A record: %i\n", ret); if (!ret) { n++; @@ -318,7 +311,7 @@ ssize_t static dnshandle(const unsigned char *inbuf, size_t insize, unsigned cha // Authority section if (!have_ns) { - int ret2 = write_record_ns(&outpos, outend, "", offset, CLASS_IN, nsttl, ns); + int ret2 = write_record_ns(&outpos, outend, "", offset, CLASS_IN, opt->nsttl, opt->ns); // printf("wrote NS record: %i\n", ret2); if (!ret2) { outbuf[9]++; @@ -340,7 +333,7 @@ error: return 12; } -int dnsserver(void) { +int dnsserver(dns_opt_t *opt) { struct sockaddr_in si_me, si_other; socklen_t s, slen=sizeof(si_other); unsigned char inbuf[BUFLEN], outbuf[BUFLEN]; @@ -348,16 +341,16 @@ int dnsserver(void) { return -1; memset((char *) &si_me, 0, sizeof(si_me)); si_me.sin_family = AF_INET; - si_me.sin_port = htons(port); + si_me.sin_port = htons(opt->port); si_me.sin_addr.s_addr = INADDR_ANY; if (bind(s, (struct sockaddr*)&si_me, sizeof(si_me))==-1) return -2; do { ssize_t insize = recvfrom(s, inbuf, BUFLEN, 0, (struct sockaddr*)&si_other, &slen); unsigned char *addr = (unsigned char*)&si_other.sin_addr.s_addr; - printf("Request from %i.%i.%i.%i:%i of %i bytes\n", addr[0], addr[1], addr[2], addr[3], ntohs(si_other.sin_port), (int)insize); + printf("DNS: Request from %i.%i.%i.%i:%i of %i bytes\n", addr[0], addr[1], addr[2], addr[3], ntohs(si_other.sin_port), (int)insize); if (insize > 0) { - ssize_t ret = dnshandle(inbuf, insize, outbuf); + ssize_t ret = dnshandle(opt, inbuf, insize, outbuf); if (ret > 0) sendto(s, outbuf, ret, 0, (struct sockaddr*)&si_other, slen); } diff --git a/main.cpp b/main.cpp index 46f1c94..df2f9e2 100644 --- a/main.cpp +++ b/main.cpp @@ -8,7 +8,7 @@ using namespace std; extern "C" { -// #include "dns.h" +#include "dns.h" } CAddrDb db; @@ -47,10 +47,16 @@ extern "C" int GetIPList(struct in_addr *addr, int max, int ipv4only) { return n; } -extern "C" int dnsserver(void); - extern "C" void* ThreadDNS(void*) { - dnsserver(); + dns_opt_t opt; + opt.host = "seedtest.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); } extern "C" void* ThreadDumper(void*) { diff --git a/netbase.cpp b/netbase.cpp index 904af3c..b8680df 100644 --- a/netbase.cpp +++ b/netbase.cpp @@ -274,7 +274,6 @@ bool CIPPort::ConnectSocket(SOCKET& hSocketRet, int nTimeout) const return false; } - printf("%s: connected\n", ToString().c_str()); hSocketRet = hSocket; return true; }