| 397 | } |
| 398 | |
| 399 | bool ProcessAddrMessage(CNode *pFrom, CDataStream &vRecv) { |
| 400 | vector<CAddress> vAddr; |
| 401 | vRecv >> vAddr; |
| 402 | |
| 403 | // Don't want addr from older versions unless seeding |
| 404 | // if (pFrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000) |
| 405 | // return true; |
| 406 | if (vAddr.size() > 1000) { |
| 407 | Misbehaving(pFrom->GetId(), 20); |
| 408 | return ERRORMSG("message addr size() = %u", vAddr.size()); |
| 409 | } |
| 410 | |
| 411 | // Store the new addresses |
| 412 | vector<CAddress> vAddrOk; |
| 413 | int64_t nNow = GetAdjustedTime(); |
| 414 | int64_t nSince = nNow - 10 * 60; |
| 415 | for (auto &addr : vAddr) { |
| 416 | boost::this_thread::interruption_point(); |
| 417 | |
| 418 | if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) |
| 419 | addr.nTime = nNow - 5 * 24 * 60 * 60; |
| 420 | |
| 421 | pFrom->AddAddressKnown(addr); |
| 422 | bool fReachable = IsReachable(addr); |
| 423 | if (addr.nTime > nSince && !pFrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) { |
| 424 | // Relay to a limited number of other nodes |
| 425 | { |
| 426 | LOCK(cs_vNodes); |
| 427 | // Use deterministic randomness to send to the same nodes for 24 hours |
| 428 | // at a time so the setAddrKnowns of the chosen nodes prevent repeats |
| 429 | static uint256 hashSalt; |
| 430 | if (hashSalt.IsNull()) hashSalt = GetRandHash(); |
| 431 | uint64_t hashAddr = addr.GetHash(); |
| 432 | uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr << 32) ^ |
| 433 | ((GetTime() + hashAddr) / (24 * 60 * 60))); |
| 434 | hashRand = Hash(BEGIN(hashRand), END(hashRand)); |
| 435 | multimap<uint256, CNode *> mapMix; |
| 436 | for (auto pNode : vNodes) { |
| 437 | // if (pNode->nVersion < CADDR_TIME_VERSION) |
| 438 | // continue; |
| 439 | uint32_t nPointer; |
| 440 | memcpy(&nPointer, &pNode, sizeof(nPointer)); |
| 441 | uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer); |
| 442 | hashKey = Hash(BEGIN(hashKey), END(hashKey)); |
| 443 | mapMix.insert(make_pair(hashKey, pNode)); |
| 444 | } |
| 445 | int32_t nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s) |
| 446 | for (auto mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) |
| 447 | ((*mi).second)->PushAddress(addr); |
| 448 | } |
| 449 | } |
| 450 | // Do not store addresses outside our network |
| 451 | if (fReachable) |
| 452 | vAddrOk.push_back(addr); |
| 453 | } |
| 454 | addrman.Add(vAddrOk, pFrom->addr, 2 * 60 * 60); |
| 455 | if (vAddr.size() < 1000) |
| 456 | pFrom->fGetAddr = false; |
no test coverage detected