Exemple #1
0
void CAddrMan::Good_(const CService& addr, int64_t nTime)
{
    int nId;

    nLastGood = nTime;

    CAddrInfo* pinfo = Find(addr, &nId);

    // if not found, bail out
    if (!pinfo)
        return;

    CAddrInfo& info = *pinfo;

    // check whether we are talking about the exact same CService (including same port)
    if (info != addr)
        return;

    // update info
    info.nLastSuccess = nTime;
    info.nLastTry = nTime;
    info.nAttempts = 0;
    // nTime is not updated here, to avoid leaking information about
    // currently-connected peers.

    // if it is already in the tried set, don't do anything else
    if (info.fInTried)
        return;

    // find a bucket it is in now
    int nRnd = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
    int nUBucket = -1;
    for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
        int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT;
        int nBpos = info.GetBucketPosition(nKey, true, nB);
        if (vvNew[nB][nBpos] == nId) {
            nUBucket = nB;
            break;
        }
    }

    // if no bucket is found, something bad happened;
    // TODO: maybe re-add the node, but for now, just bail out
    if (nUBucket == -1)
        return;

    LogPrint("addrman", "Moving %s to tried\n", addr.ToString());

    // move nId to the tried tables
    MakeTried(info, nId);
}
Exemple #2
0
void CAddrMan::Good_(const CService& addr, int64_t nTime)
{
    int nId;

    nLastGood = nTime;

    CAddrInfo* pinfo = Find(addr, &nId);

    if (!pinfo)
        return;

    CAddrInfo& info = *pinfo;

    if (info != addr)
        return;

    info.nLastSuccess = nTime;
    info.nLastTry = nTime;
    info.nAttempts = 0;

    if (info.fInTried)
        return;

    int nRnd = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
    int nUBucket = -1;
    for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
        int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT;
        int nBpos = info.GetBucketPosition(nKey, true, nB);
        if (vvNew[nB][nBpos] == nId) {
            nUBucket = nB;
            break;
        }
    }

    if (nUBucket == -1)
        return;

    LogPrint("addrman", "Moving %s to tried\n", addr.ToString());

    MakeTried(info, nId);
}
Exemple #3
0
void CAddrMan::Good_(const CService& addr, bool test_before_evict, int64_t nTime)
{
    int nId;

    nLastGood = nTime;

    CAddrInfo* pinfo = Find(addr, &nId);

    // if not found, bail out
    if (!pinfo)
        return;

    CAddrInfo& info = *pinfo;

    // check whether we are talking about the exact same CService (including same port)
    if (info != addr)
        return;

    // update info
    info.nLastSuccess = nTime;
    info.nLastTry = nTime;
    info.nAttempts = 0;
    // nTime is not updated here, to avoid leaking information about
    // currently-connected peers.

    // if it is already in the tried set, don't do anything else
    if (info.fInTried)
        return;

    // find a bucket it is in now
    int nRnd = insecure_rand.randrange(ADDRMAN_NEW_BUCKET_COUNT);
    int nUBucket = -1;
    for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
        int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT;
        int nBpos = info.GetBucketPosition(nKey, true, nB);
        if (vvNew[nB][nBpos] == nId) {
            nUBucket = nB;
            break;
        }
    }

    // if no bucket is found, something bad happened;
    // TODO: maybe re-add the node, but for now, just bail out
    if (nUBucket == -1)
        return;

    // which tried bucket to move the entry to
    int tried_bucket = info.GetTriedBucket(nKey);
    int tried_bucket_pos = info.GetBucketPosition(nKey, false, tried_bucket);

    // Will moving this address into tried evict another entry?
    if (test_before_evict && (vvTried[tried_bucket][tried_bucket_pos] != -1)) {
        // Output the entry we'd be colliding with, for debugging purposes
        auto colliding_entry = mapInfo.find(vvTried[tried_bucket][tried_bucket_pos]);
        LogPrint(BCLog::ADDRMAN, "Collision inserting element into tried table (%s), moving %s to m_tried_collisions=%d\n", colliding_entry != mapInfo.end() ? colliding_entry->second.ToString() : "", addr.ToString(), m_tried_collisions.size());
        if (m_tried_collisions.size() < ADDRMAN_SET_TRIED_COLLISION_SIZE) {
            m_tried_collisions.insert(nId);
        }
    } else {
        LogPrint(BCLog::ADDRMAN, "Moving %s to tried\n", addr.ToString());

        // move nId to the tried tables
        MakeTried(info, nId);
    }
}
/**
 * The only time good is called, is during the version message exchange, for inbound it was added first and any address problems
 * looked over and fixed.  For outbound, what we have, was likely what was used to make the connection, so it must have been good
 * or this would not have been called.
 * Still we may have services and port details incorrect in our database, and so any object differences can be corrected, if
 * a change is made to how this routine is called, from passing a CService to a CAddress object we can have the programmer fix
 * any problems before making this call, we'll look for, and fix the differences, if they show up here.
 */
void CAddrMan::Good_(const CAddress& addr, int64_t nTime)
{
    bool fChanged = false;
    int nId;
    CAddrInfo* pinfo = Find(addr, &nId);    // This matches on the CNetAddr portion of the object only aka the ip/i2p only

    // if not found, bail out
    if (!pinfo) {
        LogPrint( "addrman", "Marking as good failed, expected to find %s\n", addr.ToString() );
        return;
    }

    CAddrInfo& info = *pinfo;           // Only really for convenience, not really needed

    // check whether we are talking about the exact same CService (that includes the same port)
    if( (CService)info != (CService)addr) {
        assert( info.GetPort() != addr.GetPort() );     // The only reason which could cause a mismatch, or we have a serious programming problem
        LogPrint( "addrman", "While marking %s as good, it was found that port %d does not match our record, now updated.\n", info.ToString(), addr.GetPort() );
        info.SetPort( addr.GetPort() );
        fChanged = true;
    }

    // Ok so now we know that at least the CService details all match, lets check and fix the CAddress service bits for this peer, if its listed wrong, fix it.
    if( info.nServices != addr.nServices ) {
        LogPrint( "addrman", "While marking %s as good, the peer services was found to have changed from 0x%016x to 0x%016x, now updated.\n", info.ToString(), info.nServices, addr.nServices );
        info.nServices = addr.nServices;
        fChanged = true;
    }

    // update info
    info.nLastSuccess = nTime;
    info.nLastTry = nTime;
    info.nAttempts = 0;
    // info.nTime = nTime;
    // nTime is not updated here, to avoid leaking information about
    // currently-connected peers.

    // if it is already in the tried set, don't do anything else, except report we were here
    if(info.fInTried ) {
        if( !fChanged )
            LogPrint( "addrman", "Marked as good peer %s\n", info.ToString() );
        return;
    }


    // find a bucket it is in now
    int nRnd = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT);
    int nUBucket = -1;
    for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
    int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT;
    int nBpos = info.GetBucketPosition(nKey, true, nB);
    if (vvNew[nB][nBpos] == nId) {
            nUBucket = nB;
            break;
        }
    }

    // if no bucket is found, something bad happened;
    // TODO: maybe re-add the node, but for now, just bail out
    if( nUBucket == -1 ) {
        LogPrint( "addrman", "Fatal error while trying to add %s to tried, bucket not found\n", info.ToString() );
        return;
    }

    LogPrint("addrman", "Moving %s to tried\n", addr.ToString());

    // move nId to the tried tables
    MakeTried(info, nId);
}