From dbcfdb1fb6ff2db5977d07fb3d93046cf72bb421 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Mon, 30 Mar 2026 00:03:46 +0000 Subject: [PATCH] fix(client): wait for the connection task to shut down cleanly before disconnecting and increase test timeout --- changelog.md | 6 ++++++ package.json | 2 +- rust/src/client.rs | 12 +++++++++++- ts/00_commitinfo_data.ts | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index 8905058..cfaed1f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # Changelog +## 2026-03-30 - 1.10.2 - fix(client) +wait for the connection task to shut down cleanly before disconnecting and increase test timeout + +- store the spawned client connection task handle and await it during disconnect with a 5 second timeout so the disconnect frame can be sent before closing +- increase the test script timeout from 60 seconds to 90 seconds to reduce flaky test runs + ## 2026-03-29 - 1.10.1 - fix(test, docs, scripts) correct test command verbosity, shorten load test timings, and document forwarding modes diff --git a/package.json b/package.json index 51d38b2..d66326a 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "scripts": { "build": "(tsbuild tsfolders) && (tsrust)", "test:before": "(tsrust)", - "test": "tstest test/ --verbose --logfile --timeout 60", + "test": "tstest test/ --verbose --logfile --timeout 90", "buildDocs": "tsdoc" }, "repository": { diff --git a/rust/src/client.rs b/rust/src/client.rs index 96da678..4129fa1 100644 --- a/rust/src/client.rs +++ b/rust/src/client.rs @@ -81,6 +81,7 @@ pub struct VpnClient { connected_since: Arc>>, quality_rx: Option>, link_health: Arc>, + connection_handle: Option>, } impl VpnClient { @@ -93,6 +94,7 @@ impl VpnClient { connected_since: Arc::new(RwLock::new(None)), quality_rx: None, link_health: Arc::new(RwLock::new(LinkHealth::Degraded)), + connection_handle: None, } } @@ -280,7 +282,7 @@ impl VpnClient { // Spawn packet forwarding loop let assigned_ip_clone = assigned_ip.clone(); - tokio::spawn(client_loop( + let join_handle = tokio::spawn(client_loop( sink, stream, noise_transport, @@ -294,6 +296,7 @@ impl VpnClient { tun_writer, tun_subnet, )); + self.connection_handle = Some(join_handle); Ok(assigned_ip_clone) } @@ -303,6 +306,13 @@ impl VpnClient { if let Some(tx) = self.shutdown_tx.take() { let _ = tx.send(()).await; } + // Wait for the connection task to send the Disconnect frame and close + if let Some(handle) = self.connection_handle.take() { + let _ = tokio::time::timeout( + std::time::Duration::from_secs(5), + handle, + ).await; + } *self.assigned_ip.write().await = None; *self.connected_since.write().await = None; *self.state.write().await = ClientState::Disconnected; diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 3ef89e1..187d2b3 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartvpn', - version: '1.10.1', + version: '1.10.2', description: 'A VPN solution with TypeScript control plane and Rust data plane daemon' }