Пример #1
0
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;
 */
}