From 2ebb62614db79b1e242fcf6384b3096413eb4149 Mon Sep 17 00:00:00 2001 From: Sachymetsu Date: Thu, 8 Jan 2026 17:34:33 +0100 Subject: [PATCH] No authoritative, use A/AAAA records for ip, Home view keybinds --- src/net.rs | 53 +++++++++++++++++++++++++++-------------------- src/views/home.rs | 14 ++++++++++--- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/net.rs b/src/net.rs index 5cf789f..322db51 100644 --- a/src/net.rs +++ b/src/net.rs @@ -15,7 +15,11 @@ use futures_concurrency::future::Race; use sachy_mdns::{ GROUP_SOCK_V4, MDNS_PORT, client::query_service, - dns::{records::Record, reqres::Response, traits::DnsParse}, + dns::{ + records::{QType, Record}, + reqres::Response, + traits::DnsParse, + }, }; use socket2::{Domain, Protocol, Socket, Type}; @@ -56,6 +60,7 @@ pub fn setup_mdns_task(mut commands: Commands) -> Result { while signal_rx.recv().await.is_ok() { let send_fut = async { + // Retry three times in case packets get lost coz UDP things for _ in 0..3 { udp_socket.send_to(query, GROUP_SOCK_V4).await.ok(); Timer::after(Duration::from_millis(250)).await; @@ -63,34 +68,36 @@ pub fn setup_mdns_task(mut commands: Commands) -> Result { }; let recv_fut = async { - while let Ok((read, socket)) = udp_socket.recv_from(&mut buf).await { + while let Ok((read, _)) = udp_socket.recv_from(&mut buf).await { let input = &buf[..read]; let Ok(resp) = Response::parse(&mut &*input, input) else { continue; }; - if resp.flags.is_authoritative() - && resp.answers.iter().any(|answer| { - if let Record::PTR(_) = &answer.record { - answer.name == "_picostrike._tcp.local" - } else { - false - } - }) - && let Some(instance) = resp.additional.iter().find_map(|answer| { - if let Record::SRV(srv) = &answer.record { - Some(InstanceDetails { - host: answer.name.to_string(), - address: srv.target.to_string(), - port: srv.port, - ip: socket.ip(), - }) - } else { - None - } - }) + if resp.answers.iter().any(|answer| { + answer.atype == QType::PTR && answer.name == "_picostrike._tcp.local" + }) && let Some(ip) = resp.additional.iter().find_map(|answer| match &answer + .record { - resp_tx.send(instance).await.ok(); + Record::A(a) => Some(IpAddr::V4(a.address)), + Record::AAAA(aaaa) => Some(IpAddr::V6(aaaa.address)), + _ => None, + }) && let Some((name, srv)) = resp.additional.iter().find_map(|answer| { + if let Record::SRV(srv) = &answer.record { + Some((answer.name, srv)) + } else { + None + } + }) { + resp_tx + .send(InstanceDetails { + host: name.to_string(), + address: srv.target.to_string(), + port: srv.port, + ip, + }) + .await + .ok(); } } }; diff --git a/src/views/home.rs b/src/views/home.rs index b7bb4d6..81ff5c9 100644 --- a/src/views/home.rs +++ b/src/views/home.rs @@ -96,8 +96,8 @@ pub fn home_view( q_devices: Query<(&Name, &DeviceSocket), With>, ) -> Result { context.draw(|frame| { - let [top, bottom] = - Layout::vertical([Constraint::Length(3), Constraint::Fill(1)]).areas(frame.area()); + let [top, mid, bottom] = + Layout::vertical([Constraint::Length(3), Constraint::Fill(1), Constraint::Length(3)]).areas(frame.area()); let searching = if is_searching.searching.is_some() { "Searching..." @@ -119,18 +119,26 @@ pub fn home_view( )) }); + let help = Paragraph::new("Keys: 'q'/ESC Quit, 's' Toggle Search, UP/DOWN Choose Device(s), ENTER/SPACE Connect to Device").block( + Block::bordered() + .padding(Padding::horizontal(2)) + .border_style(Color::LightBlue), + ); + let list = List::new(items) .highlight_symbol(">> ") .direction(ListDirection::TopToBottom) .block( Block::bordered() .title("Devices") + .title_alignment(HorizontalAlignment::Center) .padding(Padding::new(2, 2, 1, 1)) .border_style(Color::LightBlue), ); frame.render_widget(paragraph, top); - frame.render_stateful_widget(list, bottom, &mut list_state.0); + frame.render_stateful_widget(list, mid, &mut list_state.0); + frame.render_widget(help, bottom); })?; Ok(()) -- 2.51.2