Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5328,7 +5328,20 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::micros
}
if (std::optional<CService> local_service = GetLocalAddrForPeer(node)) {
CAddress local_addr{*local_service, peer.m_our_services, Now<NodeSeconds>()};
PushAddress(peer, local_addr);
if (peer.m_next_local_addr_send == 0us) {
// Send the initial self-announcement in its own message. This makes sure
// rate-limiting with limited start-tokens doesn't ignore it if the first
// message ends up containing multiple addresses.
std::vector<CAddress> self_announcement {local_addr};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

micro-nit: could drop space

Suggested change
std::vector<CAddress> self_announcement {local_addr};
std::vector<CAddress> self_announcement{local_addr};

if (peer.m_wants_addrv2) {
MakeAndPushMessage(node, NetMsgType::ADDRV2, CAddress::V2_NETWORK(self_announcement));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new direct-send path bypasses the addr.IsValid() and IsAddrCompatible(peer, addr) checks performed by PushAddress().
Could this be an issue?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that those two checks might still be needed to ensure the address we’re about to relay is valid and compatible with the peer, even if GetLocalAddrForPeer() succeeded.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but haven't had the time to investigate closer

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but haven't had the time to investigate closer

} else {
MakeAndPushMessage(node, NetMsgType::ADDR, CAddress::V1_NETWORK(self_announcement));
}
} else {
// All later self-announcements are sent together with the other addresses.
PushAddress(peer, local_addr);
}
}
peer.m_next_local_addr_send = current_time + m_rng.rand_exp_duration(AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
}
Expand Down
16 changes: 13 additions & 3 deletions test/functional/p2p_addr_selfannouncement.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"""
Test that a node sends a self-announcement with its external IP to
in- and outbound peers after connection open and again sometime later.

Additionally, this checks that the first self-announcement arrives
in its own message and that this message is the first we receive.
"""

import time
Expand Down Expand Up @@ -42,6 +45,13 @@ def handle_addr_message(self, message):
self.addresses_received += 1
if addr == self.expected:
self.self_announcements_received += 1
if self.self_announcements_received == 1:
# If it's the first self-announcement, check that it is
# in the first addr message we receive, and that this message
# only contains one address. This also implies that it is
# the first address we receive.
assert_equal(self.addr_messages_received, 1)
assert_equal(len(message.addrs), 1)

Comment thread
0xB10C marked this conversation as resolved.
def on_addrv2(self, message):
assert (self.addrv2_test)
Expand Down Expand Up @@ -69,10 +79,10 @@ def run_test(self):
self.self_announcement_test(outbound=True, addrv2=True)

def inbound_connection_open_assertions(self, addr_receiver):
# We expect one self-announcement and multiple other addresses in
# response to a GETADDR in a single addr / addrv2 message.
# In response to a GETADDR, we expect a message with the self-announcement
# and an addr message containing the GETADDR response.
assert_equal(addr_receiver.self_announcements_received, 1)
assert_equal(addr_receiver.addr_messages_received, 1)
assert_equal(addr_receiver.addr_messages_received, 2)
assert_greater_than(addr_receiver.addresses_received, 1)

def outbound_connection_open_assertions(self, addr_receiver):
Expand Down
Loading