From 1e7f562f81fee2d850fb7de7acb082c083428515 Mon Sep 17 00:00:00 2001 From: ospab Date: Thu, 28 May 2026 16:32:59 +0300 Subject: [PATCH] Fix frontend ignoring tunnel errors & fix blocking wintun routines --- ostp-client/src/tunnel/native_handler.rs | 20 +++++++----- ostp-client/src/tunnel/wintun_handler.rs | 40 ++++++++++++++---------- ostp-gui/src-tauri/Cargo.lock | 4 +-- ostp-gui/src/main.js | 7 +++++ 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/ostp-client/src/tunnel/native_handler.rs b/ostp-client/src/tunnel/native_handler.rs index 6ab677b..76de492 100644 --- a/ostp-client/src/tunnel/native_handler.rs +++ b/ostp-client/src/tunnel/native_handler.rs @@ -70,18 +70,22 @@ pub async fn run_native_tunnel( New-NetRoute -DestinationPrefix '0.0.0.0/0' -InterfaceAlias 'ostp_tun' -NextHop '10.1.0.1' -RouteMetric 1 -ErrorAction SilentlyContinue\n", server_ip_str, current_exe ); - let _ = Command::new("powershell") - .creation_flags(CREATE_NO_WINDOW) - .args(["-NoProfile", "-Command", &setup_script]) - .output()?; + let _ = tokio::task::spawn_blocking(move || { + Command::new("powershell") + .creation_flags(CREATE_NO_WINDOW) + .args(["-NoProfile", "-Command", &setup_script]) + .output() + }).await.unwrap()?; if let Some(ref dns) = config.dns_server { if !dns.is_empty() { let net_setup = format!("netsh interface ipv4 set dnsservers name=\"ostp_tun\" static {} primary\n", dns); - let _ = Command::new("powershell") - .creation_flags(CREATE_NO_WINDOW) - .args(["-NoProfile", "-Command", &net_setup]) - .output()?; + let _ = tokio::task::spawn_blocking(move || { + Command::new("powershell") + .creation_flags(CREATE_NO_WINDOW) + .args(["-NoProfile", "-Command", &net_setup]) + .output() + }).await.unwrap()?; } } } diff --git a/ostp-client/src/tunnel/wintun_handler.rs b/ostp-client/src/tunnel/wintun_handler.rs index 493e434..b23d849 100644 --- a/ostp-client/src/tunnel/wintun_handler.rs +++ b/ostp-client/src/tunnel/wintun_handler.rs @@ -60,14 +60,16 @@ pub async fn run_wintun_tunnel( // 1. Delete stale TUN adapter if it exists from a previous run. // This prevents wintun from creating "ostp_tun 2", "ostp_tun 3", etc. tracing::info!("Cleaning up stale TUN adapter..."); - let _ = Command::new("powershell") - .creation_flags(CREATE_NO_WINDOW) - .args(["-NoProfile", "-Command", &format!( - "Get-NetAdapter -Name '{TUN_NAME}*' -ErrorAction SilentlyContinue | \ - Disable-NetAdapter -Confirm:$false -ErrorAction SilentlyContinue; \ - netsh interface set interface \"{TUN_NAME}\" admin=disable 2>$null" - )]) - .output(); + let _ = tokio::task::spawn_blocking(move || { + Command::new("powershell") + .creation_flags(CREATE_NO_WINDOW) + .args(["-NoProfile", "-Command", &format!( + "Get-NetAdapter -Name '{TUN_NAME}*' -ErrorAction SilentlyContinue | \ + Disable-NetAdapter -Confirm:$false -ErrorAction SilentlyContinue; \ + netsh interface set interface \"{TUN_NAME}\" admin=disable 2>$null" + )]) + .output() + }).await; // Brief pause to let the driver release the adapter tokio::time::sleep(std::time::Duration::from_millis(200)).await; @@ -138,11 +140,13 @@ pub async fn run_wintun_tunnel( let mut adapter_ready = false; while tokio::time::Instant::now() < adapter_deadline { tokio::time::sleep(std::time::Duration::from_millis(250)).await; - let check = Command::new("powershell") - .creation_flags(CREATE_NO_WINDOW) - .args(["-NoProfile", "-Command", - &format!("(Get-NetAdapter -Name '{TUN_NAME}' -ErrorAction SilentlyContinue).Status")]) - .output(); + let check = tokio::task::spawn_blocking(move || { + Command::new("powershell") + .creation_flags(CREATE_NO_WINDOW) + .args(["-NoProfile", "-Command", + &format!("(Get-NetAdapter -Name '{TUN_NAME}' -ErrorAction SilentlyContinue).Status")]) + .output() + }).await.unwrap(); if let Ok(out) = check { let status = String::from_utf8_lossy(&out.stdout).trim().to_string(); if debug { @@ -181,10 +185,12 @@ pub async fn run_wintun_tunnel( } } - let _ = Command::new("powershell") - .creation_flags(CREATE_NO_WINDOW) - .args(["-NoProfile", "-Command", &net_setup]) - .output()?; + let _ = tokio::task::spawn_blocking(move || { + Command::new("powershell") + .creation_flags(CREATE_NO_WINDOW) + .args(["-NoProfile", "-Command", &net_setup]) + .output() + }).await.unwrap()?; tracing::info!("TUN tunnel active. All traffic is routed through OSTP."); diff --git a/ostp-gui/src-tauri/Cargo.lock b/ostp-gui/src-tauri/Cargo.lock index 1484bc9..57eb0cd 100644 --- a/ostp-gui/src-tauri/Cargo.lock +++ b/ostp-gui/src-tauri/Cargo.lock @@ -2632,7 +2632,7 @@ dependencies = [ [[package]] name = "ostp-client" -version = "0.2.58" +version = "0.2.60" dependencies = [ "anyhow", "base64 0.22.1", @@ -2662,7 +2662,7 @@ dependencies = [ [[package]] name = "ostp-core" -version = "0.2.58" +version = "0.2.60" dependencies = [ "anyhow", "bytes", diff --git a/ostp-gui/src/main.js b/ostp-gui/src/main.js index eafca38..fc2b7ef 100644 --- a/ostp-gui/src/main.js +++ b/ostp-gui/src/main.js @@ -367,6 +367,13 @@ window.addEventListener('DOMContentLoaded', async () => { setState('disconnected'); // Event wiring + if (window.__TAURI__ && window.__TAURI__.event) { + window.__TAURI__.event.listen('tunnel-error', (evt) => { + setState('disconnected'); + showToast(String(evt.payload), 'error'); + }); + } + btnConnect.addEventListener('click', handleToggle); btnGoSettings.addEventListener('click', () => showScreen('settings')); btnBack.addEventListener('click', () => showScreen('home'));