diff --git a/src/client/discovery.rs b/src/client/discovery.rs index c7e1516..98edff9 100644 --- a/src/client/discovery.rs +++ b/src/client/discovery.rs @@ -1,6 +1,7 @@ use crate::api::TypedDevice; use crate::discovery::{ - bind_socket, AlpacaPort, DEFAULT_DISCOVERY_PORT, DISCOVERY_ADDR_V6, DISCOVERY_MSG, + bind_socket, get_active_interfaces, AlpacaPort, DEFAULT_DISCOVERY_PORT, DISCOVERY_ADDR_V6, + DISCOVERY_MSG, }; use futures::StreamExt; use netdev::interface::InterfaceType; @@ -168,7 +169,7 @@ impl Client { #[tracing::instrument(level = "error")] pub async fn bind(self) -> eyre::Result { let socket = bind_socket((Ipv6Addr::UNSPECIFIED, 0)).await?; - let interfaces = tokio::task::spawn_blocking(netdev::get_interfaces).await?; + let interfaces = tokio::task::spawn_blocking(|| get_active_interfaces().collect()).await?; Ok(BoundClient { client: self, socket, diff --git a/src/discovery.rs b/src/discovery.rs index 3dd2d96..8ba035e 100644 --- a/src/discovery.rs +++ b/src/discovery.rs @@ -14,6 +14,12 @@ pub(crate) struct AlpacaPort { pub(crate) alpaca_port: u16, } +pub(crate) fn get_active_interfaces() -> impl Iterator { + netdev::get_interfaces() + .into_iter() + .filter(Interface::is_running) +} + #[tracing::instrument(level = "trace")] pub(crate) async fn bind_socket( addr: impl Into + std::fmt::Debug + Send, @@ -67,6 +73,7 @@ pub(crate) async fn bind_socket( pub use crate::client::{BoundDiscoveryClient, DiscoveryClient}; #[cfg(feature = "server")] pub use crate::server::{BoundDiscoveryServer, DiscoveryServer}; +use netdev::Interface; #[cfg(windows)] use std::os::windows::prelude::AsRawSocket; @@ -136,7 +143,7 @@ mod tests { .chain(DEFAULT_INTF.ipv6.iter().map(|net| (net.addr.into(), expected_addrs.default_intf_v6))); for (addr, expected) in expected_addrs { - eyre::ensure!(addrs.contains(&addr) == expected, "Address {addr} was{not} expected", addr = addr, not = if expected { "" } else { " not" }); + eyre::ensure!(addrs.contains(&addr) == expected, "Address {addr} was{not} expected", not = if expected { "" } else { " not" }); } Ok(()) diff --git a/src/server/discovery.rs b/src/server/discovery.rs index 2f339f4..9e001eb 100644 --- a/src/server/discovery.rs +++ b/src/server/discovery.rs @@ -1,5 +1,7 @@ use super::DEFAULT_DISCOVERY_PORT; -use crate::discovery::{bind_socket, AlpacaPort, DISCOVERY_ADDR_V6, DISCOVERY_MSG}; +use crate::discovery::{ + bind_socket, get_active_interfaces, AlpacaPort, DISCOVERY_ADDR_V6, DISCOVERY_MSG, +}; use netdev::Interface; use std::net::{IpAddr, Ipv6Addr, SocketAddr}; use tokio::net::UdpSocket; @@ -23,22 +25,20 @@ fn join_multicast_group(socket: &UdpSocket, intf: &Interface) { #[tracing::instrument(level = "debug", ret, skip(socket))] fn join_multicast_groups(socket: &UdpSocket, listen_addr: Ipv6Addr) { - let interfaces = netdev::get_interfaces(); if listen_addr.is_unspecified() { // If it's [::], join multicast on every available interface with IPv6 support. - for intf in interfaces { + for intf in get_active_interfaces() { if !intf.ipv6.is_empty() { join_multicast_group(socket, &intf); } } } else { // If it's a specific address, find corresponding interface and join multicast on it. - let intf = interfaces - .iter() + let intf = get_active_interfaces() .find(|intf| intf.ipv6.iter().any(|net| net.addr == listen_addr)) .expect("internal error: couldn't find the interface of an already bound socket"); - join_multicast_group(socket, intf); + join_multicast_group(socket, &intf); } }