From 0582c9b858ed1170736ac4f3b563e7ab2a9b8251 Mon Sep 17 00:00:00 2001 From: Benno Zeeman Date: Wed, 5 Jul 2023 16:39:10 +0200 Subject: [PATCH] swarm: translate external address candidate The `NewExternalAddrCandidate` event is yielded both before and after address translation. This will cause, in the case of TCP, ephemeral ports to be added as candidate. In turn, that will cause protocols like AutoNAT to fail as these candidates are not actually reachable/external. We will now only yield the original candidate if translation did not apply. Fixes #4153 --- swarm/src/lib.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 9b739f337806..17e3c3df517d 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1062,14 +1062,8 @@ where self.pending_event = Some((peer_id, handler, event)); } ToSwarm::NewExternalAddrCandidate(addr) => { - self.behaviour - .on_swarm_event(FromSwarm::NewExternalAddrCandidate( - NewExternalAddrCandidate { addr: &addr }, - )); - - // Generate more candidates based on address translation. + // Apply address translation to the candidate address. // For TCP without port-reuse, the observed address contains an ephemeral port which needs to be replaced by the port of a listen address. - let translated_addresses = { let mut addrs: Vec<_> = self .listened_addrs @@ -1083,6 +1077,15 @@ where addrs.dedup(); addrs }; + + // If address translation yielded nothing, broacast the original candidate address. + if translated_addresses.is_empty() { + self.behaviour + .on_swarm_event(FromSwarm::NewExternalAddrCandidate( + NewExternalAddrCandidate { addr: &addr }, + )); + } + for addr in translated_addresses { self.behaviour .on_swarm_event(FromSwarm::NewExternalAddrCandidate(