| 4499 | } |
| 4500 | |
| 4501 | void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::microseconds current_time) |
| 4502 | { |
| 4503 | // Nothing to do for non-address-relay peers |
| 4504 | if (!peer.m_addr_relay_enabled) return; |
| 4505 | |
| 4506 | LOCK(peer.m_addr_send_times_mutex); |
| 4507 | // Periodically advertise our local address to the peer. |
| 4508 | if (fListen && !m_chainman.ActiveChainstate().IsInitialBlockDownload() && |
| 4509 | peer.m_next_local_addr_send < current_time) { |
| 4510 | // If we've sent before, clear the bloom filter for the peer, so that our |
| 4511 | // self-announcement will actually go out. |
| 4512 | // This might be unnecessary if the bloom filter has already rolled |
| 4513 | // over since our last self-announcement, but there is only a small |
| 4514 | // bandwidth cost that we can incur by doing this (which happens |
| 4515 | // once a day on average). |
| 4516 | if (peer.m_next_local_addr_send != 0us) { |
| 4517 | peer.m_addr_known->reset(); |
| 4518 | } |
| 4519 | if (std::optional<CAddress> local_addr = GetLocalAddrForPeer(&node)) { |
| 4520 | FastRandomContext insecure_rand; |
| 4521 | PushAddress(peer, *local_addr, insecure_rand); |
| 4522 | } |
| 4523 | peer.m_next_local_addr_send = GetExponentialRand(current_time, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL); |
| 4524 | } |
| 4525 | |
| 4526 | // We sent an `addr` message to this peer recently. Nothing more to do. |
| 4527 | if (current_time <= peer.m_next_addr_send) return; |
| 4528 | |
| 4529 | peer.m_next_addr_send = GetExponentialRand(current_time, AVG_ADDRESS_BROADCAST_INTERVAL); |
| 4530 | |
| 4531 | if (!Assume(peer.m_addrs_to_send.size() <= MAX_ADDR_TO_SEND)) { |
| 4532 | // Should be impossible since we always check size before adding to |
| 4533 | // m_addrs_to_send. Recover by trimming the vector. |
| 4534 | peer.m_addrs_to_send.resize(MAX_ADDR_TO_SEND); |
| 4535 | } |
| 4536 | |
| 4537 | // Remove addr records that the peer already knows about, and add new |
| 4538 | // addrs to the m_addr_known filter on the same pass. |
| 4539 | auto addr_already_known = [&peer](const CAddress& addr) { |
| 4540 | bool ret = peer.m_addr_known->contains(addr.GetKey()); |
| 4541 | if (!ret) peer.m_addr_known->insert(addr.GetKey()); |
| 4542 | return ret; |
| 4543 | }; |
| 4544 | peer.m_addrs_to_send.erase(std::remove_if(peer.m_addrs_to_send.begin(), peer.m_addrs_to_send.end(), addr_already_known), |
| 4545 | peer.m_addrs_to_send.end()); |
| 4546 | |
| 4547 | // No addr messages to send |
| 4548 | if (peer.m_addrs_to_send.empty()) return; |
| 4549 | |
| 4550 | const char* msg_type; |
| 4551 | int make_flags; |
| 4552 | if (peer.m_wants_addrv2) { |
| 4553 | msg_type = NetMsgType::ADDRV2; |
| 4554 | make_flags = ADDRV2_FORMAT; |
| 4555 | } else { |
| 4556 | msg_type = NetMsgType::ADDR; |
| 4557 | make_flags = 0; |
| 4558 | } |
nothing calls this directly
no test coverage detected