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); }
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); }
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); }