diff --git a/rust/connlib/snownet/src/node.rs b/rust/connlib/snownet/src/node.rs index b2258dfa9..fa46cea40 100644 --- a/rust/connlib/snownet/src/node.rs +++ b/rust/connlib/snownet/src/node.rs @@ -1292,7 +1292,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(|(ip, base)| ip.is_ipv4() && base.is_ipv4()) .filter_map(|(ip, base)| { let addr = SocketAddr::new(ip, base.port()); @@ -1303,6 +1303,7 @@ fn generate_optimistic_candidates(agent: &mut IceAgent) { .ok() }) .filter(|c| !remote_candidates.contains(c)) + .take(2) .collect::>(); for c in optimistic_candidates { @@ -2649,7 +2650,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::*; @@ -2691,4 +2692,65 @@ mod tests { assert!(agent.remote_candidates().contains(&expected_candidate)) } + + #[test] + fn skips_optimistic_candidates_for_ipv6() { + let base = SocketAddr::V6(SocketAddrV6::new( + Ipv6Addr::new(10, 0, 0, 0, 0, 0, 0, 1), + 52625, + 0, + 0, + )); + let addr = IpAddr::V6(Ipv6Addr::new(1, 1, 1, 1, 1, 1, 1, 1)); + + let host = Candidate::host(base, "udp").unwrap(); + let srvflx = + Candidate::server_reflexive(SocketAddr::new(addr, 40000), base, "udp").unwrap(); + + let mut agent = IceAgent::new(); + agent.add_remote_candidate(host); + agent.add_remote_candidate(srvflx); + + generate_optimistic_candidates(&mut agent); + + let unexpected_candidate = + Candidate::server_reflexive(SocketAddr::new(addr, 52625), base, "udp").unwrap(); + + assert!(!agent.remote_candidates().contains(&unexpected_candidate)) + } + + #[test] + fn limits_optimistic_ipv4_candidates_to_2() { + let base = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(10, 0, 0, 1), 52625)); + let addr1 = IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)); + let addr2 = IpAddr::V4(Ipv4Addr::new(1, 1, 1, 2)); + let addr3 = IpAddr::V4(Ipv4Addr::new(1, 1, 1, 3)); + + let host = Candidate::host(base, "udp").unwrap(); + let srflx1 = + Candidate::server_reflexive(SocketAddr::new(addr1, 40000), base, "udp").unwrap(); + let srflx2 = + Candidate::server_reflexive(SocketAddr::new(addr2, 40000), base, "udp").unwrap(); + let srflx3 = + Candidate::server_reflexive(SocketAddr::new(addr3, 40000), base, "udp").unwrap(); + + let mut agent = IceAgent::new(); + agent.add_remote_candidate(host); + agent.add_remote_candidate(srflx1); + agent.add_remote_candidate(srflx2); + agent.add_remote_candidate(srflx3); + + generate_optimistic_candidates(&mut agent); + + let expected_candidate1 = + Candidate::server_reflexive(SocketAddr::new(addr1, 52625), base, "udp").unwrap(); + let expected_candidate2 = + Candidate::server_reflexive(SocketAddr::new(addr2, 52625), base, "udp").unwrap(); + let unexpected_candidate3 = + Candidate::server_reflexive(SocketAddr::new(addr3, 52625), base, "udp").unwrap(); + + assert!(agent.remote_candidates().contains(&expected_candidate1)); + assert!(agent.remote_candidates().contains(&expected_candidate2)); + assert!(!agent.remote_candidates().contains(&unexpected_candidate3)); + } } diff --git a/website/src/components/Changelog/Gateway.tsx b/website/src/components/Changelog/Gateway.tsx index 99589af52..2b669b817 100644 --- a/website/src/components/Changelog/Gateway.tsx +++ b/website/src/components/Changelog/Gateway.tsx @@ -22,7 +22,12 @@ export default function Gateway() { return ( - + + + Fixes a rare CPU-spike issue in case a Client connected with many + possible IPv6 addresses. + + Remove the FIREZONE_NUM_TUN_THREADS env variable. The Gateway will now