diff --git a/rust/gui-client/src-tauri/src/client/gui.rs b/rust/gui-client/src-tauri/src/client/gui.rs index f4c1387ed..017e8487f 100644 --- a/rust/gui-client/src-tauri/src/client/gui.rs +++ b/rust/gui-client/src-tauri/src/client/gui.rs @@ -821,11 +821,11 @@ async fn run_controller( } } }, - r = dns_listener.notified() => { - r?; + resolvers = dns_listener.notified() => { + let resolvers = resolvers?; if let Some(session) = controller.session.as_mut() { - tracing::debug!("New DNS resolvers, calling `Session::set_dns`"); - session.connlib.set_dns(client::resolvers::get().unwrap_or_default()).await?; + tracing::debug!(?resolvers, "New DNS resolvers, calling `Session::set_dns`"); + session.connlib.set_dns(resolvers).await?; } }, req = rx.recv() => { diff --git a/rust/gui-client/src-tauri/src/client/network_changes/linux.rs b/rust/gui-client/src-tauri/src/client/network_changes/linux.rs index f11a21a69..933015e54 100644 --- a/rust/gui-client/src-tauri/src/client/network_changes/linux.rs +++ b/rust/gui-client/src-tauri/src/client/network_changes/linux.rs @@ -1,6 +1,8 @@ //! Not implemented for Linux yet use anyhow::Result; +use std::net::IpAddr; +use tokio::time::Interval; pub(crate) fn run_dns_debug() -> Result<()> { tracing::warn!("network_changes not implemented yet on Linux"); @@ -28,18 +30,42 @@ impl Worker { Ok(()) } - pub(crate) async fn notified(&self) { + /// Not implemented on Linux + /// + /// On Windows this returns when we gain or lose Internet. + pub(crate) async fn notified(&mut self) { futures::future::pending().await } } -pub(crate) struct DnsListener {} +pub(crate) struct DnsListener { + interval: Interval, + last_seen: Vec, +} impl DnsListener { pub(crate) fn new() -> Result { - Ok(Self {}) + Ok(Self { + interval: create_interval(), + last_seen: crate::client::resolvers::get().unwrap_or_default(), + }) } - pub(crate) async fn notified(&mut self) -> Result<()> { - futures::future::pending().await + + pub(crate) async fn notified(&mut self) -> Result> { + loop { + self.interval.tick().await; + tracing::trace!("Checking for DNS changes"); + let new = crate::client::resolvers::get().unwrap_or_default(); + if new != self.last_seen { + self.last_seen = new.clone(); + return Ok(new); + } + } } } + +fn create_interval() -> Interval { + let mut interval = tokio::time::interval(std::time::Duration::from_secs(5)); + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay); + interval +} diff --git a/rust/gui-client/src-tauri/src/client/network_changes/windows.rs b/rust/gui-client/src-tauri/src/client/network_changes/windows.rs index 89c62d2ea..e455d6dd1 100644 --- a/rust/gui-client/src-tauri/src/client/network_changes/windows.rs +++ b/rust/gui-client/src-tauri/src/client/network_changes/windows.rs @@ -406,7 +406,7 @@ fn get_apartment_type() -> WinResult<(Com::APTTYPE, Com::APTTYPEQUALIFIER)> { mod async_dns { use anyhow::{Context, Result}; - use std::{ffi::c_void, ops::Deref, path::Path}; + use std::{ffi::c_void, net::IpAddr, ops::Deref, path::Path}; use tokio::sync::mpsc; use windows::Win32::{ Foundation::{CloseHandle, BOOLEAN, HANDLE, INVALID_HANDLE_VALUE}, @@ -450,12 +450,11 @@ mod async_dns { rt.block_on(async move { loop { - tokio::select! { + let resolvers = tokio::select! { _r = tokio::signal::ctrl_c() => break, r = listener.notified() => r?, - } + }; - let resolvers = crate::client::resolvers::get()?; tracing::info!(?resolvers); } @@ -482,12 +481,12 @@ mod async_dns { }) } - pub(crate) async fn notified(&mut self) -> Result<()> { + pub(crate) async fn notified(&mut self) -> Result> { tokio::select! { r = self.listener_4.notified() => r?, r = self.listener_6.notified() => r?, } - Ok(()) + Ok(crate::client::resolvers::get().unwrap_or_default()) } }