monthly stats, subversion, better dump
This commit is contained in:
parent
eceeda1eec
commit
f4aa8699b4
5 changed files with 64 additions and 19 deletions
|
@ -81,7 +81,7 @@ class CNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GotVersion() {
|
void GotVersion() {
|
||||||
// printf("%s: version %i\n", ToString(you).c_str(), nVersion);
|
// printf("\n%s: version %i\n", ToString(you).c_str(), nVersion);
|
||||||
BeginMessage("getaddr");
|
BeginMessage("getaddr");
|
||||||
EndMessage();
|
EndMessage();
|
||||||
doneAfter = time(NULL) + 10;
|
doneAfter = time(NULL) + 10;
|
||||||
|
@ -256,9 +256,13 @@ public:
|
||||||
int GetClientVersion() {
|
int GetClientVersion() {
|
||||||
return nVersion;
|
return nVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GetClientSubVersion() {
|
||||||
|
return strSubVer;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TestNode(const CIPPort &cip, int &ban, int &clientV, vector<CAddress>& vAddr) {
|
bool TestNode(const CIPPort &cip, int &ban, int &clientV, std::string &clientSV, vector<CAddress>& vAddr) {
|
||||||
try {
|
try {
|
||||||
CNode node(cip, vAddr);
|
CNode node(cip, vAddr);
|
||||||
bool ret = node.Run();
|
bool ret = node.Run();
|
||||||
|
@ -268,6 +272,7 @@ bool TestNode(const CIPPort &cip, int &ban, int &clientV, vector<CAddress>& vAdd
|
||||||
ban = 0;
|
ban = 0;
|
||||||
}
|
}
|
||||||
clientV = node.GetClientVersion();
|
clientV = node.GetClientVersion();
|
||||||
|
clientSV = node.GetClientSubVersion();
|
||||||
// printf("%s: %s!!!\n", cip.ToString().c_str(), ret ? "GOOD" : "BAD");
|
// printf("%s: %s!!!\n", cip.ToString().c_str(), ret ? "GOOD" : "BAD");
|
||||||
return ret;
|
return ret;
|
||||||
} catch(std::ios_base::failure& e) {
|
} catch(std::ios_base::failure& e) {
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
bool TestNode(const CIPPort &cip, int &ban, int &client, std::vector<CAddress>& vAddr);
|
bool TestNode(const CIPPort &cip, int &ban, int &client, std::string &clientSV, std::vector<CAddress>& vAddr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
4
db.cpp
4
db.cpp
|
@ -16,6 +16,7 @@ void CAddrInfo::Update(bool good) {
|
||||||
stat8H.Update(good, age, 3600*8);
|
stat8H.Update(good, age, 3600*8);
|
||||||
stat1D.Update(good, age, 3600*24);
|
stat1D.Update(good, age, 3600*24);
|
||||||
stat1W.Update(good, age, 3600*24*7);
|
stat1W.Update(good, age, 3600*24*7);
|
||||||
|
stat1M.Update(good, age, 3600*24*30);
|
||||||
int ign = GetIgnoreTime();
|
int ign = GetIgnoreTime();
|
||||||
if (ign && (ignoreTill==0 || ignoreTill < ign+now)) ignoreTill = ign+now;
|
if (ign && (ignoreTill==0 || ignoreTill < ign+now)) ignoreTill = ign+now;
|
||||||
// printf("%s: got %s result: success=%i/%i; 2H:%.2f%%-%.2f%%(%.2f) 8H:%.2f%%-%.2f%%(%.2f) 1D:%.2f%%-%.2f%%(%.2f) 1W:%.2f%%-%.2f%%(%.2f) \n", ToString(ip).c_str(), good ? "good" : "bad", success, total,
|
// printf("%s: got %s result: success=%i/%i; 2H:%.2f%%-%.2f%%(%.2f) 8H:%.2f%%-%.2f%%(%.2f) 1D:%.2f%%-%.2f%%(%.2f) 1W:%.2f%%-%.2f%%(%.2f) \n", ToString(ip).c_str(), good ? "good" : "bad", success, total,
|
||||||
|
@ -83,13 +84,14 @@ int CAddrDb::Lookup_(const CIPPort &ip) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAddrDb::Good_(const CIPPort &addr, int clientV) {
|
void CAddrDb::Good_(const CIPPort &addr, int clientV, std::string clientSV) {
|
||||||
int id = Lookup_(addr);
|
int id = Lookup_(addr);
|
||||||
if (id == -1) return;
|
if (id == -1) return;
|
||||||
unkId.erase(id);
|
unkId.erase(id);
|
||||||
banned.erase(addr);
|
banned.erase(addr);
|
||||||
CAddrInfo &info = idToInfo[id];
|
CAddrInfo &info = idToInfo[id];
|
||||||
info.clientVersion = clientV;
|
info.clientVersion = clientV;
|
||||||
|
info.clientSubVersion = clientSV;
|
||||||
info.Update(true);
|
info.Update(true);
|
||||||
if (info.IsGood() && goodId.count(id)==0) {
|
if (info.IsGood() && goodId.count(id)==0) {
|
||||||
goodId.insert(id);
|
goodId.insert(id);
|
||||||
|
|
27
db.h
27
db.h
|
@ -46,6 +46,8 @@ class CAddrReport {
|
||||||
public:
|
public:
|
||||||
CIPPort ip;
|
CIPPort ip;
|
||||||
int clientVersion;
|
int clientVersion;
|
||||||
|
double uptime[5];
|
||||||
|
std::string clientSubVersion;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,9 +62,11 @@ private:
|
||||||
CAddrStat stat8H;
|
CAddrStat stat8H;
|
||||||
CAddrStat stat1D;
|
CAddrStat stat1D;
|
||||||
CAddrStat stat1W;
|
CAddrStat stat1W;
|
||||||
|
CAddrStat stat1M;
|
||||||
int clientVersion;
|
int clientVersion;
|
||||||
int total;
|
int total;
|
||||||
int success;
|
int success;
|
||||||
|
std::string clientSubVersion;
|
||||||
public:
|
public:
|
||||||
CAddrInfo() : services(0), lastTry(0), ourLastTry(0), ignoreTill(0), clientVersion(0), total(0), success(0) {}
|
CAddrInfo() : services(0), lastTry(0), ourLastTry(0), ignoreTill(0), clientVersion(0), total(0), success(0) {}
|
||||||
|
|
||||||
|
@ -70,6 +74,12 @@ public:
|
||||||
CAddrReport ret;
|
CAddrReport ret;
|
||||||
ret.ip = ip;
|
ret.ip = ip;
|
||||||
ret.clientVersion = clientVersion;
|
ret.clientVersion = clientVersion;
|
||||||
|
ret.clientSubVersion = clientSubVersion;
|
||||||
|
ret.uptime[0] = stat2H.reliability;
|
||||||
|
ret.uptime[1] = stat8H.reliability;
|
||||||
|
ret.uptime[2] = stat1D.reliability;
|
||||||
|
ret.uptime[3] = stat1W.reliability;
|
||||||
|
ret.uptime[4] = stat1M.reliability;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +119,7 @@ public:
|
||||||
friend class CAddrDb;
|
friend class CAddrDb;
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE (
|
IMPLEMENT_SERIALIZE (
|
||||||
unsigned char version = 0;
|
unsigned char version = 2;
|
||||||
READWRITE(version);
|
READWRITE(version);
|
||||||
READWRITE(ip);
|
READWRITE(ip);
|
||||||
READWRITE(services);
|
READWRITE(services);
|
||||||
|
@ -123,9 +133,16 @@ public:
|
||||||
READWRITE(stat8H);
|
READWRITE(stat8H);
|
||||||
READWRITE(stat1D);
|
READWRITE(stat1D);
|
||||||
READWRITE(stat1W);
|
READWRITE(stat1W);
|
||||||
|
if (version >= 1)
|
||||||
|
READWRITE(stat1M);
|
||||||
|
else
|
||||||
|
if (!fWrite)
|
||||||
|
*((CAddrStat*)(&stat1M)) = stat1W;
|
||||||
READWRITE(total);
|
READWRITE(total);
|
||||||
READWRITE(success);
|
READWRITE(success);
|
||||||
READWRITE(clientVersion);
|
READWRITE(clientVersion);
|
||||||
|
if (version >= 2)
|
||||||
|
READWRITE(clientSubVersion);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -157,20 +174,20 @@ private:
|
||||||
std::deque<int> ourId; // sequence of tried nodes, in order we have tried connecting to them (c,d)
|
std::deque<int> ourId; // sequence of tried nodes, in order we have tried connecting to them (c,d)
|
||||||
std::set<int> unkId; // set of nodes not yet tried (b)
|
std::set<int> unkId; // set of nodes not yet tried (b)
|
||||||
std::set<int> goodId; // set of good nodes (d, good e)
|
std::set<int> goodId; // set of good nodes (d, good e)
|
||||||
std::map<CIPPort, time_t> banned; // nodes that are banned, with their unban time (a)
|
|
||||||
int nDirty;
|
int nDirty;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// internal routines that assume proper locks are acquired
|
// internal routines that assume proper locks are acquired
|
||||||
void Add_(const CAddress &addr, bool force); // 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)
|
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 Good_(const CIPPort &ip, int clientV, std::string clientSV); // 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 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_)
|
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
|
int Lookup_(const CIPPort &ip); // look up id of an IP
|
||||||
void GetIPs_(std::set<CIP>& ips, int max, bool fOnlyIPv4); // get a random set of IPs (shared lock only)
|
void GetIPs_(std::set<CIP>& ips, int max, bool fOnlyIPv4); // get a random set of IPs (shared lock only)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
std::map<CIPPort, time_t> banned; // nodes that are banned, with their unban time (a)
|
||||||
|
|
||||||
void GetStats(CAddrDbStats &stats) {
|
void GetStats(CAddrDbStats &stats) {
|
||||||
SHARED_CRITICAL_BLOCK(cs) {
|
SHARED_CRITICAL_BLOCK(cs) {
|
||||||
|
@ -255,9 +272,9 @@ public:
|
||||||
for (int i=0; i<vAddr.size(); i++)
|
for (int i=0; i<vAddr.size(); i++)
|
||||||
Add_(vAddr[i], fForce);
|
Add_(vAddr[i], fForce);
|
||||||
}
|
}
|
||||||
void Good(const CIPPort &addr, int clientVersion) {
|
void Good(const CIPPort &addr, int clientVersion, std::string clientSubVersion) {
|
||||||
CRITICAL_BLOCK(cs)
|
CRITICAL_BLOCK(cs)
|
||||||
Good_(addr, clientVersion);
|
Good_(addr, clientVersion, clientSubVersion);
|
||||||
}
|
}
|
||||||
void Skipped(const CIPPort &addr) {
|
void Skipped(const CIPPort &addr) {
|
||||||
CRITICAL_BLOCK(cs)
|
CRITICAL_BLOCK(cs)
|
||||||
|
|
41
main.cpp
41
main.cpp
|
@ -1,3 +1,5 @@
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -105,10 +107,11 @@ extern "C" void* ThreadCrawler(void* data) {
|
||||||
int ban = 0;
|
int ban = 0;
|
||||||
vector<CAddress> addr;
|
vector<CAddress> addr;
|
||||||
int clientV = 0;
|
int clientV = 0;
|
||||||
bool ret = TestNode(ip,ban,clientV,addr);
|
std::string clientSV;
|
||||||
|
bool ret = TestNode(ip,ban,clientV,clientSV,addr);
|
||||||
db.Add(addr);
|
db.Add(addr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
db.Good(ip, clientV);
|
db.Good(ip, clientV, clientSV);
|
||||||
} else {
|
} else {
|
||||||
db.Bad(ip, ban);
|
db.Bad(ip, ban);
|
||||||
}
|
}
|
||||||
|
@ -150,6 +153,18 @@ extern "C" void* ThreadDNS(void* arg) {
|
||||||
dnsserver(&dns_opt);
|
dnsserver(&dns_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int StatCompare(const CAddrReport& a, const CAddrReport& b) {
|
||||||
|
if (a.uptime[4] == b.uptime[4]) {
|
||||||
|
if (a.uptime[3] == b.uptime[3]) {
|
||||||
|
return a.clientVersion > b.clientVersion;
|
||||||
|
} else {
|
||||||
|
return a.uptime[3] > b.uptime[3];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return a.uptime[4] > b.uptime[4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void* ThreadDumper(void*) {
|
extern "C" void* ThreadDumper(void*) {
|
||||||
do {
|
do {
|
||||||
Sleep(100000);
|
Sleep(100000);
|
||||||
|
@ -159,16 +174,28 @@ extern "C" void* ThreadDumper(void*) {
|
||||||
CAutoFile cf(f);
|
CAutoFile cf(f);
|
||||||
cf << db;
|
cf << db;
|
||||||
}
|
}
|
||||||
|
FILE *d = fopen("dnsseed.dump", "w");
|
||||||
|
vector<CAddrReport> v = db.GetAll();
|
||||||
|
sort(v.begin(), v.end(), StatCompare);
|
||||||
|
for (vector<CAddrReport>::const_iterator it = v.begin(); it < v.end(); it++) {
|
||||||
|
CAddrReport rep = *it;
|
||||||
|
fprintf(d, "%s\t%.2f%%\t%.2f%%\t%.2f%%\t%.2f%%\t%.2f%%\t%i \"%s\"\n", rep.ip.ToString().c_str(), 100.0*rep.uptime[0], 100.0*rep.uptime[1], 100.0*rep.uptime[2], 100.0*rep.uptime[3], 100.0*rep.uptime[4], rep.clientVersion, rep.clientSubVersion.c_str());
|
||||||
|
}
|
||||||
|
fclose(d);
|
||||||
}
|
}
|
||||||
} while(1);
|
} while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void* ThreadStats(void*) {
|
extern "C" void* ThreadStats(void*) {
|
||||||
do {
|
do {
|
||||||
|
char c[256];
|
||||||
|
time_t tim = time(NULL);
|
||||||
|
struct tm *tmp = localtime(&tim);
|
||||||
|
strftime(c, 256, "[%y-%m-%d %H:%M:%S]", tmp);
|
||||||
CAddrDbStats stats;
|
CAddrDbStats stats;
|
||||||
db.GetStats(stats);
|
db.GetStats(stats);
|
||||||
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
|
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
|
||||||
printf("*** %i/%i available (%i tried in %is, %i new, %i active), %i banned; %llu DNS requests", stats.nGood, stats.nAvail, stats.nTracked, stats.nAge, stats.nNew, stats.nAvail - stats.nTracked - stats.nNew, stats.nBanned, (unsigned long long)dns_opt.nRequests);
|
printf("%s %i/%i available (%i tried in %is, %i new, %i active), %i banned; %llu DNS requests", c, stats.nGood, stats.nAvail, stats.nTracked, stats.nAge, stats.nNew, stats.nAvail - stats.nTracked - stats.nNew, stats.nBanned, (unsigned long long)dns_opt.nRequests);
|
||||||
Sleep(1000);
|
Sleep(1000);
|
||||||
} while(1);
|
} while(1);
|
||||||
}
|
}
|
||||||
|
@ -205,13 +232,7 @@ int main(int argc, char **argv) {
|
||||||
printf("Loading dnsseed.dat...");
|
printf("Loading dnsseed.dat...");
|
||||||
CAutoFile cf(f);
|
CAutoFile cf(f);
|
||||||
cf >> db;
|
cf >> db;
|
||||||
// FILE *d = fopen("dnsseed.dump", "w");
|
// db.banned.clear();
|
||||||
// vector<CAddrReport> v = db.GetAll();
|
|
||||||
// for (vector<CAddrReport>::const_iterator it = v.begin(); it < v.end(); it++) {
|
|
||||||
// CAddrReport rep = *it;
|
|
||||||
// fprintf(d, "%s %i\n", rep.ip.ToString().c_str(), rep.clientVersion);
|
|
||||||
// }
|
|
||||||
// fclose(d);
|
|
||||||
printf("done\n");
|
printf("done\n");
|
||||||
}
|
}
|
||||||
pthread_t threadDns, threadSeed, threadDump, threadStats;
|
pthread_t threadDns, threadSeed, threadDump, threadStats;
|
||||||
|
|
Loading…
Reference in a new issue