Browse Source

bugfix + better handling of empty unk

pull/1/head
Pieter Wuille 13 years ago
parent
commit
6b68ff0a60
  1. 3
      bitcoin.cpp
  2. 35
      db.cpp
  3. 6
      db.h
  4. 5
      main.cpp

3
bitcoin.cpp

@ -204,7 +204,7 @@ class CNode {
} }
public: public:
CNode(const CIPPort& ip, vector<CAddress>& vAddrIn) : you(ip), nHeaderStart(-1), nMessageStart(-1), vAddr(&vAddrIn) { CNode(const CIPPort& ip, vector<CAddress>& vAddrIn) : you(ip), nHeaderStart(-1), nMessageStart(-1), vAddr(&vAddrIn), ban(0), doneAfter(0) {
vSend.SetType(SER_NETWORK); vSend.SetType(SER_NETWORK);
vSend.SetVersion(0); vSend.SetVersion(0);
vRecv.SetType(SER_NETWORK); vRecv.SetType(SER_NETWORK);
@ -251,6 +251,7 @@ public:
ProcessMessages(); ProcessMessages();
Send(); Send();
} }
if (sock == INVALID_SOCKET) res = false;
close(sock); close(sock);
sock = INVALID_SOCKET; sock = INVALID_SOCKET;
return (ban == 0) && res; return (ban == 0) && res;

35
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); 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; int cont = 0;
int64 now = time(NULL);
do { do {
cont = 0; cont = 0;
int tot = unkId.size() + ourId.size(); int tot = unkId.size();
if (tot == 0) return false; deque<int>::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; int rnd = rand() % tot;
if (rnd < unkId.size()) { if (rnd < unkId.size()) {
set<int>::iterator it = unkId.begin(); set<int>::iterator it = unkId.begin();
@ -31,12 +46,8 @@ bool CAddrDb::Get_(CIPPort &ip) {
printf("From UNK: %s\n", ip.ToString().c_str()); printf("From UNK: %s\n", ip.ToString().c_str());
} else { } else {
int ret = ourId.front(); int ret = ourId.front();
if (time(NULL) - idToInfo[ret].ourLastTry < MIN_RETRY) return false;
ourId.pop_front(); 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; ip = idToInfo[ret].ip;
printf("From OUR: %s (size = %i)\n", ip.ToString().c_str(), (int)ourId.size()); 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); uint32_t now = time(NULL);
if (info.IsTerrible()) { if (info.IsTerrible()) {
printf("%s: terrible\n", addr.ToString().c_str()); printf("%s: terrible\n", addr.ToString().c_str());
if (ban < 604800+now) ban = 604800+now; if (ban < 604800) ban = 604800;
} }
if (ban > now) { if (ban > 0) {
printf("%s: banned %lu seconds\n", addr.ToString().c_str(), (unsigned long)(ban-now)); printf("%s: ban %i seconds\n", addr.ToString().c_str(), ban);
banned[info.ip] = ban; banned[info.ip] = ban + now;
ipToId.erase(info.ip); ipToId.erase(info.ip);
goodId.erase(id); goodId.erase(id);
idToInfo.erase(id); idToInfo.erase(id);

6
db.h

@ -61,7 +61,7 @@ protected:
void Good_(const CIPPort &ip); void Good_(const CIPPort &ip);
void Bad_(const CIPPort &ip, int ban); void Bad_(const CIPPort &ip, int ban);
void Skipped_(const CIPPort &ip); void Skipped_(const CIPPort &ip);
bool Get_(CIPPort &ip); bool Get_(CIPPort &ip, int& wait);
int Lookup_(const CIPPort &ip); int Lookup_(const CIPPort &ip);
void GetIPs_(std::set<CIP>& ips, int max, bool fOnlyIPv4); void GetIPs_(std::set<CIP>& ips, int max, bool fOnlyIPv4);
@ -91,9 +91,9 @@ public:
CRITICAL_BLOCK(cs) CRITICAL_BLOCK(cs)
Bad_(addr, ban); Bad_(addr, ban);
} }
bool Get(CIPPort &ip) { bool Get(CIPPort &ip, int& wait) {
CRITICAL_BLOCK(cs) CRITICAL_BLOCK(cs)
return Get_(ip); return Get_(ip, wait);
} }
void GetIPs(std::set<CIP>& ips, int max, bool fOnlyIPv4 = true) { void GetIPs(std::set<CIP>& ips, int max, bool fOnlyIPv4 = true) {
CRITICAL_BLOCK(cs) CRITICAL_BLOCK(cs)

5
main.cpp

@ -15,8 +15,9 @@ extern "C" void* ThreadCrawler(void* data) {
do { do {
db.Stats(); db.Stats();
CIPPort ip; CIPPort ip;
if (!db.Get(ip)) { int wait = 5;
Sleep(5000); if (!db.Get(ip, wait)) {
Sleep(wait*1000);
continue; continue;
} }
int ban = 0; int ban = 0;

Loading…
Cancel
Save