From 2d802edf6aba3e00e826a96548f385fb9a4322d4 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 5 May 2025 11:11:28 +1000 Subject: [PATCH] fix(connlib): _always_ use one IP stack for relayed connections (#9018) At the moment, Firezone already attempts to prefer the same IP stack across relayed connections all the way through to the Gateway. This is achieved with a feature in str0m implemented in https://github.com/algesten/str0m/pull/640 where the `IceAgent` computes the local preference of an added candidate such that an IPv4 candidate allocated over an IPv4 network has a higher preference than an IPv6 candidate allocated over an IPv4 network. If a candidate gets accepted by the local agent, it is signaled to the remote via our control protocol. The remote peer then adds the candidate as a remote candidate and the ICE process starts by pairing them with local ones and testing connectivity. Currently, str0m's API consumes the candidate and only returns a `bool` whether it should be sent signaled to the remote. This means the local preference computed as part of `add_local_candidate` **is not** reflected in the priority of the candidate sent to the remote. As a result, if the controlled agent (i.e. the Gateway) is behind symmetric NAT and therefore only has relay candidates available, the preference of IPv4 over IPv6 candidates on an IPv4 network is lost. This is what we are seeing in #8998. This changes with https://github.com/algesten/str0m/pull/650 being merged to `main` which we are updating to with this PR. Now, `add_local_candidate` returns an `Option<&Candidate>` which has been modified with the local preference of the `IceAgent` around the preferred IP stack of relay candidates. As such, the priority calculated and signaled to the remote embeds this information and will be taken into account by the controlling agent (i.e. the Client) when nominating a pair. Resolves: #8998 --- rust/Cargo.lock | 2 +- rust/Cargo.toml | 2 +- rust/connlib/snownet/src/node.rs | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 33363aac6..9c12554b1 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -6597,7 +6597,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "str0m" version = "0.8.0" -source = "git+https://github.com/firezone/str0m?branch=main#8401a07556ee930866768d3993514fedb455b0b3" +source = "git+https://github.com/algesten/str0m?branch=main#6025dfde2e48905539255ec88f1350ab50428d50" dependencies = [ "combine", "crc", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index f8cfd59a9..8b8b966b4 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -215,7 +215,7 @@ ip_network = { git = "https://github.com/JakubOnderka/ip_network", branch = "mas ip_network_table = { git = "https://github.com/edmonds/ip_network_table", branch = "some-useful-traits" } # For `Debug` and `Clone` tracing-stackdriver = { git = "https://github.com/thomaseizinger/tracing-stackdriver", branch = "bump-otel-0.26" } # Waiting for release. softbuffer = { git = "https://github.com/rust-windowing/softbuffer" } # Waiting for release. -str0m = { git = "https://github.com/firezone/str0m", branch = "main" } +str0m = { git = "https://github.com/algesten/str0m", branch = "main" } # Enforce `tracing-macros` to have released `tracing` version. [patch.'https://github.com/tokio-rs/tracing'] diff --git a/rust/connlib/snownet/src/node.rs b/rust/connlib/snownet/src/node.rs index 8bdfd60c5..0bb24aef8 100644 --- a/rust/connlib/snownet/src/node.rs +++ b/rust/connlib/snownet/src/node.rs @@ -1387,14 +1387,14 @@ fn add_local_candidate( return; } - let is_new = agent.add_local_candidate(candidate.clone()); + let Some(candidate) = agent.add_local_candidate(candidate) else { + return; + }; - if is_new { - pending_events.push_back(Event::NewIceCandidate { - connection: id, - candidate: candidate.to_sdp_string(), - }) - } + pending_events.push_back(Event::NewIceCandidate { + connection: id, + candidate: candidate.to_sdp_string(), + }) } fn invalidate_allocation_candidates(