Skip to content

Commit

Permalink
Ignore inactive network interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
RReverser committed Aug 27, 2024
1 parent 00b99e2 commit f486767
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 9 deletions.
5 changes: 3 additions & 2 deletions src/client/discovery.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -168,7 +169,7 @@ impl Client {
#[tracing::instrument(level = "error")]
pub async fn bind(self) -> eyre::Result<BoundClient> {
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,
Expand Down
9 changes: 8 additions & 1 deletion src/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ pub(crate) struct AlpacaPort {
pub(crate) alpaca_port: u16,
}

pub(crate) fn get_active_interfaces() -> impl Iterator<Item = Interface> {
netdev::get_interfaces()
.into_iter()
.filter(Interface::is_running)
}

#[tracing::instrument(level = "trace")]
pub(crate) async fn bind_socket(
addr: impl Into<SocketAddr> + std::fmt::Debug + Send,
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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(())
Expand Down
12 changes: 6 additions & 6 deletions src/server/discovery.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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);
}
}

Expand Down

0 comments on commit f486767

Please sign in to comment.