diff --git a/resources/client_row.ui b/resources/client_row.ui index 317006d..7ef7219 100644 --- a/resources/client_row.ui +++ b/resources/client_row.ui @@ -44,6 +44,7 @@ + 5 GTK_INPUT_PURPOSE_NUMBER 0.5 center diff --git a/resources/window.ui b/resources/window.ui index bb10b69..7c96036 100644 --- a/resources/window.ui +++ b/resources/window.ui @@ -124,6 +124,7 @@ port + 5 diff --git a/src/client.rs b/src/client.rs index 240114e..2ce6d5c 100644 --- a/src/client.rs +++ b/src/client.rs @@ -119,6 +119,8 @@ pub struct ClientState { pub active_addr: Option, /// tracks whether or not the client is responding to pings pub alive: bool, + /// ips from dns + pub dns_ips: Vec, /// all ip addresses associated with a particular client /// e.g. Laptops usually have at least an ethernet and a wifi port /// which have different ip addresses diff --git a/src/dns.rs b/src/dns.rs index 430b954..c33fc39 100644 --- a/src/dns.rs +++ b/src/dns.rs @@ -1,8 +1,8 @@ use anyhow::Result; -use std::{collections::HashSet, error::Error, net::IpAddr}; +use std::net::IpAddr; use tokio::sync::mpsc::{channel, Receiver, Sender}; -use hickory_resolver::TokioAsyncResolver; +use hickory_resolver::{error::ResolveError, TokioAsyncResolver}; use crate::{client::ClientHandle, server::Server}; @@ -24,7 +24,7 @@ impl DnsResolver { )) } - async fn resolve(&self, host: &str) -> Result, Box> { + async fn resolve(&self, host: &str) -> Result, ResolveError> { let response = self.resolver.lookup_ip(host).await?; for ip in response.iter() { log::info!("{host}: adding ip {ip}"); @@ -44,21 +44,14 @@ impl DnsResolver { let handle = self.dns_request.recv().await.expect("channel closed"); /* update resolving status */ - let hostname = if let Some((c, s)) = server.client_manager.borrow_mut().get_mut(handle) - { - s.resolving = true; - c.hostname.clone() - } else { - continue; + let hostname = match server.get_hostname(handle) { + Some(hostname) => hostname, + None => continue, }; - let Some(hostname) = hostname else { - continue; - }; - - /* FIXME race -> need some other event */ - server.client_resolved(handle); log::info!("resolving ({handle}) `{hostname}` ..."); + server.set_resolving(handle, true); + let ips = match self.resolve(&hostname).await { Ok(ips) => ips, Err(e) => { @@ -67,16 +60,8 @@ impl DnsResolver { } }; - /* update ips and resolving state */ - if let Some((c, s)) = server.client_manager.borrow_mut().get_mut(handle) { - let mut addrs = HashSet::from_iter(c.fix_ips.iter().cloned()); - for ip in ips { - addrs.insert(ip); - } - s.ips = addrs; - s.resolving = false; - } - server.client_resolved(handle); + server.update_dns_ips(handle, ips); + server.set_resolving(handle, false); } } } diff --git a/src/frontend/gtk/window.rs b/src/frontend/gtk/window.rs index b69855e..7ba5ab7 100644 --- a/src/frontend/gtk/window.rs +++ b/src/frontend/gtk/window.rs @@ -207,12 +207,15 @@ impl Window { } pub fn request_port_change(&self) { - let port = self.imp().port_entry.get().text().to_string(); - if let Ok(port) = port.as_str().parse::() { - self.request(FrontendRequest::ChangePort(port)); - } else { - self.request(FrontendRequest::ChangePort(DEFAULT_PORT)); - } + let port = self + .imp() + .port_entry + .get() + .text() + .as_str() + .parse::() + .unwrap_or(DEFAULT_PORT); + self.request(FrontendRequest::ChangePort(port)); } pub fn request_capture(&self) { @@ -224,20 +227,15 @@ impl Window { } pub fn request_client_state(&self, client: &ClientObject) { - let handle = client.handle(); - let event = FrontendRequest::GetState(handle); - self.request(event); + self.request(FrontendRequest::GetState(client.handle())); } pub fn request_client_create(&self) { - let event = FrontendRequest::Create; - self.request(event); + self.request(FrontendRequest::Create); } pub fn request_dns(&self, client: &ClientObject) { - let data = client.get_data(); - let event = FrontendRequest::ResolveDns(data.handle); - self.request(event); + self.request(FrontendRequest::ResolveDns(client.get_data().handle)); } pub fn request_client_update(&self, client: &ClientObject) { @@ -257,15 +255,11 @@ impl Window { } pub fn request_client_activate(&self, client: &ClientObject, active: bool) { - let handle = client.handle(); - let event = FrontendRequest::Activate(handle, active); - self.request(event); + self.request(FrontendRequest::Activate(client.handle(), active)); } pub fn request_client_delete(&self, client: &ClientObject) { - let handle = client.handle(); - let event = FrontendRequest::Delete(handle); - self.request(event); + self.request(FrontendRequest::Delete(client.handle())); } pub fn request(&self, event: FrontendRequest) { diff --git a/src/server.rs b/src/server.rs index d7a60ab..b97178a 100644 --- a/src/server.rs +++ b/src/server.rs @@ -285,7 +285,7 @@ impl Server { self.notify_frontend(FrontendEvent::PortChanged(port, msg)); } - pub(crate) fn client_resolved(&self, handle: ClientHandle) { + pub(crate) fn client_updated(&self, handle: ClientHandle) { let state = self.client_manager.borrow().get(handle).cloned(); if let Some((config, state)) = state { self.notify_frontend(FrontendEvent::State(handle, config, state)); @@ -296,7 +296,8 @@ impl Server { self.client_manager .borrow() .get_client_states() - .filter_map(|(h, (_, s))| if s.active { Some(h) } else { None }) + .filter(|(_, (_, s))| s.active) + .map(|(h, _)| h) .collect() } @@ -443,12 +444,28 @@ impl Server { } fn update_fix_ips(&self, handle: ClientHandle, fix_ips: Vec) { - let mut client_manager = self.client_manager.borrow_mut(); - let Some((c, _)) = client_manager.get_mut(handle) else { - return; + if let Some((c, _)) = self.client_manager.borrow_mut().get_mut(handle) { + c.fix_ips = fix_ips; }; + self.update_ips(handle); + } - c.fix_ips = fix_ips; + pub(crate) fn update_dns_ips(&self, handle: ClientHandle, dns_ips: Vec) { + if let Some((_, s)) = self.client_manager.borrow_mut().get_mut(handle) { + s.dns_ips = dns_ips; + }; + self.update_ips(handle); + } + + fn update_ips(&self, handle: ClientHandle) { + if let Some((c, s)) = self.client_manager.borrow_mut().get_mut(handle) { + s.ips = c + .fix_ips + .iter() + .cloned() + .chain(s.dns_ips.iter().cloned()) + .collect::>(); + } } fn update_hostname(&self, handle: ClientHandle, hostname: Option) { @@ -528,6 +545,20 @@ impl Server { let status = FrontendEvent::CaptureStatus(status); self.notify_frontend(status); } + + pub(crate) fn set_resolving(&self, handle: ClientHandle, status: bool) { + if let Some((_, s)) = self.client_manager.borrow_mut().get_mut(handle) { + s.resolving = status; + } + self.client_updated(handle); + } + + pub(crate) fn get_hostname(&self, handle: u64) -> Option { + self.client_manager + .borrow_mut() + .get_mut(handle) + .and_then(|(c, _)| c.hostname.clone()) + } } async fn listen_frontend(