chore(gui-client/linux): poll for DNS changes every 5 seconds (#4875)

Closes #4819

There is a way to get them async with D-Bus. We can invest time in that
if we want. Polling works for now, it's just gonna be a slight battery
waste on laptops.
This commit is contained in:
Reactor Scram
2024-05-01 16:20:13 -05:00
committed by GitHub
parent 864908ea2f
commit 3eec350325
3 changed files with 40 additions and 15 deletions

View File

@@ -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() => {

View File

@@ -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<IpAddr>,
}
impl DnsListener {
pub(crate) fn new() -> Result<Self> {
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<Vec<IpAddr>> {
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
}

View File

@@ -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<Vec<IpAddr>> {
tokio::select! {
r = self.listener_4.notified() => r?,
r = self.listener_6.notified() => r?,
}
Ok(())
Ok(crate::client::resolvers::get().unwrap_or_default())
}
}