Endpoint EndpointPool::getCandidate(const set<unsigned int>& not_in, int64_t start_time) { // // Choose an address to connect to based on most recently seen // Endpoint candidate; int64_t now = GetAdjustedTime(); vector<Endpoint> endpoints = queryColRow<Endpoint(unsigned int, unsigned short, unsigned int, unsigned int)>("SELECT ip, port, time, lasttry FROM Endpoints WHERE lasttry < ? ORDER BY time DESC", now-60*60); // iterate until we get an address not in not_in or in the same class-B network: for (vector<Endpoint>::const_iterator e = endpoints.begin(); e != endpoints.end(); ++e) { bool skip = false; for (set<unsigned int>::const_iterator ep = not_in.begin(); ep != not_in.end(); ++ep) { if (e->getIP() == (*ep)) { skip = true; break; } } if (skip) continue; Endpoint candidate = *e; if (!candidate.isIPv4() || !candidate.isValid()) continue; return candidate; } return Endpoint(); /* BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, Endpoint)& item, _endpoints) { const Endpoint& ep = item.second; if (!ep.isIPv4() || !ep.isValid() || not_in.count(ep.getIP() & 0x0000ffff)) continue; int64_t sinceLastSeen = GetAdjustedTime() - ep.getTime(); int64_t sinceLastTry = GetAdjustedTime() - ep.getLastTry(); // Randomize the order in a deterministic way, putting the standard port first int64_t randomizer = (uint64_t)(start_time * 4951 + ep.getLastTry() * 9567851 + ep.getIP() * 7789) % (2 * 60 * 60); if (ep.getPort() != htons(_defaultPort)) randomizer += 2 * 60 * 60; // Last seen Base retry frequency // <1 hour 10 min // 1 hour 1 hour // 4 hours 2 hours // 24 hours 5 hours // 48 hours 7 hours // 7 days 13 hours // 30 days 27 hours // 90 days 46 hours // 365 days 93 hours int64_t delay = (int64_t)(3600.0 * sqrt(fabs((double)sinceLastSeen) / 3600.0) + randomizer); // Fast reconnect for one hour after last seen if (sinceLastSeen < 60 * 60) delay = 10 * 60; // Limit retry frequency if (sinceLastTry < delay) continue; // If we have IRC, we'll be notified when they first come online, // and again every 24 hours by the refresh broadcast. // if (vNodes.size() >= 2 && sinceLastSeen > 24 * 60 * 60) // continue; // Only try the old stuff if we don't have enough connections //if (vNodes.size() >= 8 && sinceLastSeen > 24 * 60 * 60) // continue; if (start_time > 0 && sinceLastSeen > 24 * 60 * 60) continue; // If multiple addresses are ready, prioritize by time since // last seen and time since last tried. int64_t score = min(sinceLastTry, (int64_t)24 * 60 * 60) - sinceLastSeen - randomizer; if (score > best) { best = score; candidate = ep; } } return candidate; */ }