From 6b68ff0a6096cb25f67413da01fd4e2514b1ce2c Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 20 Dec 2011 06:42:48 +0100 Subject: [PATCH] bugfix + better handling of empty unk --- bitcoin.cpp | 3 ++- db.cpp | 35 +++++++++++++++++++++++------------ db.h | 6 +++--- main.cpp | 5 +++-- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/bitcoin.cpp b/bitcoin.cpp index 2a16026..ab57aef 100644 --- a/bitcoin.cpp +++ b/bitcoin.cpp @@ -204,7 +204,7 @@ class CNode { } public: - CNode(const CIPPort& ip, vector& vAddrIn) : you(ip), nHeaderStart(-1), nMessageStart(-1), vAddr(&vAddrIn) { + CNode(const CIPPort& ip, vector& vAddrIn) : you(ip), nHeaderStart(-1), nMessageStart(-1), vAddr(&vAddrIn), ban(0), doneAfter(0) { vSend.SetType(SER_NETWORK); vSend.SetVersion(0); vRecv.SetType(SER_NETWORK); @@ -251,6 +251,7 @@ public: ProcessMessages(); Send(); } + if (sock == INVALID_SOCKET) res = false; close(sock); sock = INVALID_SOCKET; return (ban == 0) && res; diff --git a/db.cpp b/db.cpp index faa78d8..65e7296 100644 --- a/db.cpp +++ b/db.cpp @@ -17,12 +17,27 @@ void CAddrInfo::Update(bool good) { 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); } -bool CAddrDb::Get_(CIPPort &ip) { +bool CAddrDb::Get_(CIPPort &ip, int &wait) { int cont = 0; + int64 now = time(NULL); do { cont = 0; - int tot = unkId.size() + ourId.size(); - if (tot == 0) return false; + 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(); @@ -31,12 +46,8 @@ bool CAddrDb::Get_(CIPPort &ip) { printf("From UNK: %s\n", ip.ToString().c_str()); } else { int ret = ourId.front(); + if (time(NULL) - idToInfo[ret].ourLastTry < MIN_RETRY) return false; ourId.pop_front(); - if (unkId.size() > 0 && time(NULL) - idToInfo[ret].ourLastTry < MIN_RETRY) { - ourId.push_back(ret); - cont=1; - continue; - } ip = idToInfo[ret].ip; printf("From OUR: %s (size = %i)\n", ip.ToString().c_str(), (int)ourId.size()); } @@ -76,11 +87,11 @@ void CAddrDb::Bad_(const CIPPort &addr, int ban) uint32_t now = time(NULL); if (info.IsTerrible()) { printf("%s: terrible\n", addr.ToString().c_str()); - if (ban < 604800+now) ban = 604800+now; + if (ban < 604800) ban = 604800; } - if (ban > now) { - printf("%s: banned %lu seconds\n", addr.ToString().c_str(), (unsigned long)(ban-now)); - banned[info.ip] = ban; + if (ban > 0) { + printf("%s: ban %i seconds\n", addr.ToString().c_str(), ban); + banned[info.ip] = ban + now; ipToId.erase(info.ip); goodId.erase(id); idToInfo.erase(id); diff --git a/db.h b/db.h index 929bae8..2602b00 100644 --- a/db.h +++ b/db.h @@ -61,7 +61,7 @@ protected: void Good_(const CIPPort &ip); void Bad_(const CIPPort &ip, int ban); void Skipped_(const CIPPort &ip); - bool Get_(CIPPort &ip); + bool Get_(CIPPort &ip, int& wait); int Lookup_(const CIPPort &ip); void GetIPs_(std::set& ips, int max, bool fOnlyIPv4); @@ -91,9 +91,9 @@ public: CRITICAL_BLOCK(cs) Bad_(addr, ban); } - bool Get(CIPPort &ip) { + bool Get(CIPPort &ip, int& wait) { CRITICAL_BLOCK(cs) - return Get_(ip); + return Get_(ip, wait); } void GetIPs(std::set& ips, int max, bool fOnlyIPv4 = true) { CRITICAL_BLOCK(cs) diff --git a/main.cpp b/main.cpp index 314aafe..d47cc1e 100644 --- a/main.cpp +++ b/main.cpp @@ -15,8 +15,9 @@ extern "C" void* ThreadCrawler(void* data) { do { db.Stats(); CIPPort ip; - if (!db.Get(ip)) { - Sleep(5000); + int wait = 5; + if (!db.Get(ip, wait)) { + Sleep(wait*1000); continue; } int ban = 0;