-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix(identify): check actual port reuse instead of original intent #6096
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
fix(identify): check actual port reuse instead of original intent #6096
Conversation
When PortUse::Reuse fails and falls back to ephemeral ports, detect this by comparing observed ports with listening ports rather than tracking the original PortUse intent. Fixes libp2p#5820
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR and sorry for the (very) long delay!
Two nits, rest LGTM!
if observed_port_matches_listening_port(observed, &self.listen_addresses) { | ||
// If the observed port matches any of our listening ports, | ||
// then port reuse actually worked. Use the original observed address. | ||
self.events | ||
.push_back(ToSwarm::NewExternalAddrCandidate(observed.clone())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know that this is existing logic, but IMO we should only emit an event here if self.external_addresses
doesn't contain the address yet. Otherwise, we keep emitting events for the same addresses again and again.
for protocol in addr.iter() { | ||
match protocol { | ||
Tcp(port) | Udp(port) => return Some(port), | ||
_ => continue, | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should return the protocol
here so that below the type of protocol is also checked in the comparison. Theoretically, a port could be reachable for one protocol but not for the other.
#[test] | ||
fn test_address_translation_when_port_differs() { | ||
use libp2p_identity::Keypair; | ||
use libp2p_swarm::behaviour::FromSwarm; | ||
|
||
// Create a behavior with some listening addresses | ||
let keypair = Keypair::generate_ed25519(); | ||
let config = Config::new("test/1.0.0".to_string(), keypair.public()); | ||
let mut behaviour = Behaviour::new(config); | ||
|
||
// Add a listening address | ||
let listen_addr: Multiaddr = "/ip4/0.0.0.0/tcp/8080".parse().unwrap(); | ||
behaviour | ||
.listen_addresses | ||
.on_swarm_event(&FromSwarm::NewListenAddr( | ||
libp2p_swarm::behaviour::NewListenAddr { | ||
listener_id: libp2p_core::transport::ListenerId::next(), | ||
addr: &listen_addr, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests are very much appreciated, thanks!
When PortUse::Reuse fails and falls back to ephemeral ports, detect this by comparing observed ports with listening ports rather than tracking the original PortUse intent.
Fixes #5820
Description
Notes & open questions
Change checklist