From a80a87e5ca2780351b4b091f0074067143534090 Mon Sep 17 00:00:00 2001 From: nessi Date: Wed, 18 Mar 2026 14:34:17 +0100 Subject: [PATCH] feat: add macOS tunnel interface verification with retry logic after wg-quick up Add wait_for_macos_tunnel_running helper with 6-second polling loop checking tunnel_service_is_active after wg-quick up command. Retry up to 12 times with 500ms intervals before returning error if interface not verified. --- desktop-client/tunnel-helper/src/main.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/desktop-client/tunnel-helper/src/main.rs b/desktop-client/tunnel-helper/src/main.rs index 909a9bf..c9ffaa8 100644 --- a/desktop-client/tunnel-helper/src/main.rs +++ b/desktop-client/tunnel-helper/src/main.rs @@ -540,6 +540,7 @@ fn connect_direct(profile: &Path) -> Result<(), String> { if !status.success() { return Err(format!("macOS tunnel connect failed with status {status}")); } + wait_for_macos_tunnel_running(profile)?; return Ok(()); } @@ -704,6 +705,18 @@ fn tunnel_name(profile: &Path) -> Result<&str, String> { .ok_or_else(|| "invalid profile filename".to_string()) } +#[cfg(target_os = "macos")] +fn wait_for_macos_tunnel_running(profile: &Path) -> Result<(), String> { + for _ in 0..12 { + if tunnel_service_is_active(profile)? { + return Ok(()); + } + std::thread::sleep(std::time::Duration::from_millis(500)); + } + + Err("Tunnel was installed, but no active interface could be verified yet.".into()) +} + fn read_transfer_totals(profile: &Path) -> Result<(u64, u64), String> { let tunnel_name = tunnel_name(profile)?; let mut command = Command::new(find_wg_cli()?);