From 237bd62b20b2f2ad73783822440ffdfcf082f59b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 7 Jul 2025 23:47:40 +0100 Subject: [PATCH] fix(snownet): don't generate candidates of mixed IP version (#9804) When we shipped the feature of optimistc server-reflexive candidates, we failed to add a check to only combine address and base such that they are the same IP version. This is not harmful but unnecessary noise. --- rust/connlib/snownet/src/node.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/rust/connlib/snownet/src/node.rs b/rust/connlib/snownet/src/node.rs index f6280416a..17dc4334f 100644 --- a/rust/connlib/snownet/src/node.rs +++ b/rust/connlib/snownet/src/node.rs @@ -1220,6 +1220,7 @@ fn generate_optimistic_candidates(agent: &mut IceAgent) { let optimistic_candidates = public_ips .cartesian_product(host_candidates) + .filter(|(ip, base)| ip.is_ipv4() == base.is_ipv4()) .filter_map(|(ip, base)| { let addr = SocketAddr::new(ip, base.port()); @@ -2394,7 +2395,7 @@ impl fmt::Display for SessionId { #[cfg(test)] mod tests { - use std::net::{IpAddr, Ipv4Addr, SocketAddrV4}; + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6}; use super::*; @@ -2487,4 +2488,33 @@ mod tests { assert!(agent.remote_candidates().contains(&expected_candidate)) } + + #[test] + fn skips_optimistic_candidates_of_different_base() { + let base1 = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(10, 0, 0, 1), 52625)); + let base2 = SocketAddr::V6(SocketAddrV6::new( + Ipv6Addr::new(10, 0, 0, 0, 0, 0, 0, 1), + 52625, + 0, + 0, + )); + let addr = IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)); + + let host1 = Candidate::host(base1, "udp").unwrap(); + let host2 = Candidate::host(base2, "udp").unwrap(); + let srvflx = + Candidate::server_reflexive(SocketAddr::new(addr, 40000), base1, "udp").unwrap(); + + let mut agent = IceAgent::new(); + agent.add_remote_candidate(host1); + agent.add_remote_candidate(host2); + agent.add_remote_candidate(srvflx); + + generate_optimistic_candidates(&mut agent); + + let unexpected_candidate = + Candidate::server_reflexive(SocketAddr::new(addr, 52625), base2, "udp").unwrap(); + + assert!(!agent.remote_candidates().contains(&unexpected_candidate)) + } }