6 void CAddrInfo::Update(bool good) {
7 uint32_t now = time(NULL);
9 ourLastTry = now - MIN_RETRY;
10 int age = now - ourLastTry;
15 stat2H.Update(good, age, 3600*2);
16 stat8H.Update(good, age, 3600*8);
17 stat1D.Update(good, age, 3600*24);
18 stat1W.Update(good, age, 3600*24*7);
19 stat1M.Update(good, age, 3600*24*30);
20 int ign = GetIgnoreTime();
21 if (ign && (ignoreTill==0 || ignoreTill < ign+now)) ignoreTill = ign+now;
22 // 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,
23 // 100.0 * stat2H.reliability, 100.0 * (stat2H.reliability + 1.0 - stat2H.weight), stat2H.count,
24 // 100.0 * stat8H.reliability, 100.0 * (stat8H.reliability + 1.0 - stat8H.weight), stat8H.count,
25 // 100.0 * stat1D.reliability, 100.0 * (stat1D.reliability + 1.0 - stat1D.weight), stat1D.count,
26 // 100.0 * stat1W.reliability, 100.0 * (stat1W.reliability + 1.0 - stat1W.weight), stat1W.count);
29 bool CAddrDb::Get_(CService &ip, int &wait) {
30 int64 now = time(NULL);
32 int tot = unkId.size();
34 deque<int>::iterator it = ourId.begin();
35 while (it < ourId.end()) {
36 if (now - idToInfo[*it].ourLastTry > MIN_RETRY) {
44 if (ourId.size() > 0) {
45 wait = MIN_RETRY - (now - idToInfo[ourId.front()].ourLastTry);
51 int rnd = rand() % tot;
53 if (rnd < unkId.size()) {
54 if (rnd*10 < unkId.size()) {
55 // once every 10 attempts, restart with the oldest unknown IP
56 set<int>::iterator it = unkId.begin();
59 // 90% of the time try the last learned IP
60 set<int>::reverse_iterator it = unkId.rbegin();
66 if (time(NULL) - idToInfo[ret].ourLastTry < MIN_RETRY) return false;
69 if (idToInfo[ret].ignoreTill && idToInfo[ret].ignoreTill < now) {
71 idToInfo[ret].ourLastTry = now;
73 ip = idToInfo[ret].ip;
81 int CAddrDb::Lookup_(const CService &ip) {
87 void CAddrDb::Good_(const CService &addr, int clientV, std::string clientSV, int blocks) {
88 int id = Lookup_(addr);
92 CAddrInfo &info = idToInfo[id];
93 info.clientVersion = clientV;
94 info.clientSubVersion = clientSV;
97 if (info.IsGood() && goodId.count(id)==0) {
99 // printf("%s: good; %i good nodes now\n", ToString(addr).c_str(), (int)goodId.size());
105 void CAddrDb::Bad_(const CService &addr, int ban)
107 int id = Lookup_(addr);
108 if (id == -1) return;
110 CAddrInfo &info = idToInfo[id];
112 uint32_t now = time(NULL);
113 int ter = info.GetBanTime();
115 // printf("%s: terrible\n", ToString(addr).c_str());
116 if (ban < ter) ban = ter;
119 // printf("%s: ban for %i seconds\n", ToString(addr).c_str(), ban);
120 banned[info.ip] = ban + now;
121 ipToId.erase(info.ip);
125 if (/*!info.IsGood() && */ goodId.count(id)==1) {
127 // printf("%s: not good; %i good nodes left\n", ToString(addr).c_str(), (int)goodId.size());
134 void CAddrDb::Skipped_(const CService &addr)
136 int id = Lookup_(addr);
137 if (id == -1) return;
140 // printf("%s: skipped\n", ToString(addr).c_str());
145 void CAddrDb::Add_(const CAddress &addr, bool force) {
146 if (!force && !addr.IsRoutable())
149 if (banned.count(ipp)) {
150 time_t bantime = banned[ipp];
151 if (force || (bantime < time(NULL) && addr.nTime > bantime))
156 if (ipToId.count(ipp)) {
157 CAddrInfo &ai = idToInfo[ipToId[ipp]];
158 if (addr.nTime > ai.lastTry || ai.services != addr.nServices)
160 ai.lastTry = addr.nTime;
161 ai.services |= addr.nServices;
162 // printf("%s: updated\n", ToString(addr).c_str());
171 ai.services = addr.nServices;
172 ai.lastTry = addr.nTime;
179 // printf("%s: added\n", ToString(ipp).c_str(), ipToId[ipp]);
184 void CAddrDb::GetIPs_(set<CNetAddr>& ips, int max, const bool* nets) {
185 if (goodId.size() == 0) {
187 if (ourId.size() == 0) {
188 if (unkId.size() == 0) return;
194 ips.insert(idToInfo[id].ip);
198 if (max > goodId.size() / 2)
199 max = goodId.size() / 2;
202 int low = *goodId.begin();
203 int high = *goodId.rbegin();
205 while (ids.size() < max) {
206 int range = high-low+1;
207 int pos = low + (rand() % range);
208 int id = *(goodId.lower_bound(pos));
211 for (set<int>::const_iterator it = ids.begin(); it != ids.end(); it++) {
212 CService &ip = idToInfo[*it].ip;
213 if (nets[ip.GetNetwork()])