From f4ffebda75b0dbca78adc42623e7be26c1546737 Mon Sep 17 00:00:00 2001 From: Reactor Scram Date: Wed, 20 Dec 2023 14:17:55 -0600 Subject: [PATCH] fix(windows): make sure the worker thread for wintun shuts down cleanly (#2971) This thread will go away when I change it to non-blocking, but for now it was causing multiple sign ins during the same run of the client app to fail. --- .../tunnel/src/device_channel/tun_windows.rs | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/rust/connlib/tunnel/src/device_channel/tun_windows.rs b/rust/connlib/tunnel/src/device_channel/tun_windows.rs index 877e9fffb..df6d9310f 100644 --- a/rust/connlib/tunnel/src/device_channel/tun_windows.rs +++ b/rust/connlib/tunnel/src/device_channel/tun_windows.rs @@ -11,7 +11,7 @@ use std::{ }; use tokio::sync::mpsc; -// TODO: Make sure all these get dropped gracefully on disconnect +// TODO: Double-check that all these get dropped gracefully on disconnect pub struct Tun { _adapter: Arc, /// The index of our network adapter, we can use this when asking Windows to add / remove routes / DNS rules @@ -23,6 +23,14 @@ pub struct Tun { session: Arc, } +impl Drop for Tun { + fn drop(&mut self) { + if let Err(e) = self.session.shutdown() { + tracing::error!("wintun::Session::shutdown: {e:#?}"); + } + } +} + // Hides Powershell's console on Windows // const CREATE_NO_WINDOW: u32 = 0x08000000; @@ -170,9 +178,22 @@ fn start_recv_thread( session: Arc, ) -> std::thread::JoinHandle<()> { std::thread::spawn(move || { - while let Ok(pkt) = session.receive_blocking() { - // TODO: Don't allocate here if we can help it - packet_tx.blocking_send(pkt).unwrap(); + loop { + match session.receive_blocking() { + Ok(pkt) => { + // TODO: Don't allocate here if we can help it + if packet_tx.blocking_send(pkt).is_err() { + // Most likely the receiver was dropped and we're closing down the connlib session. + break; + } + } + // We get an Error::String when `Session::shutdown` is called + Err(wintun::Error::String(_)) => break, + Err(e) => { + tracing::error!("wintun::Session::receive_blocking: {e:#?}"); + break; + } + } } tracing::debug!("recv_task exiting gracefully"); })