From 573409fb641e465c8d77056447b2c9974091062e Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Fri, 10 Jan 2025 18:08:17 +0100 Subject: [PATCH] Scan network interfaces once at startup (#1704) * Retrieve network interfaces once in a lazy_static * Fix non unix build --- commons/zenoh-util/src/net/mod.rs | 32 ++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/commons/zenoh-util/src/net/mod.rs b/commons/zenoh-util/src/net/mod.rs index 65577ac61d..777dc886c6 100644 --- a/commons/zenoh-util/src/net/mod.rs +++ b/commons/zenoh-util/src/net/mod.rs @@ -13,6 +13,10 @@ // use std::net::{IpAddr, Ipv6Addr}; +#[cfg(unix)] +use lazy_static::lazy_static; +#[cfg(unix)] +use pnet_datalink::NetworkInterface; use tokio::net::{TcpSocket, UdpSocket}; use zenoh_core::zconfigurable; #[cfg(unix)] @@ -24,6 +28,11 @@ zconfigurable! { static ref WINDOWS_GET_ADAPTERS_ADDRESSES_MAX_RETRIES: u32 = 3; } +#[cfg(unix)] +lazy_static! { + static ref IFACES: Vec = pnet_datalink::interfaces(); +} + #[cfg(windows)] unsafe fn get_adapters_addresses(af_spec: i32) -> ZResult> { use winapi::um::iptypes::IP_ADAPTER_ADDRESSES_LH; @@ -59,7 +68,7 @@ unsafe fn get_adapters_addresses(af_spec: i32) -> ZResult> { pub fn get_interface(name: &str) -> ZResult> { #[cfg(unix)] { - for iface in pnet_datalink::interfaces() { + for iface in IFACES.iter() { if iface.name == name { for ifaddr in &iface.ips { if ifaddr.is_ipv4() { @@ -122,7 +131,7 @@ pub fn get_interface(name: &str) -> ZResult> { pub fn get_multicast_interfaces() -> Vec { #[cfg(unix)] { - pnet_datalink::interfaces() + IFACES .iter() .filter_map(|iface| { if iface.is_up() && iface.is_running() && iface.is_multicast() { @@ -146,8 +155,8 @@ pub fn get_multicast_interfaces() -> Vec { pub fn get_local_addresses(interface: Option<&str>) -> ZResult> { #[cfg(unix)] { - Ok(pnet_datalink::interfaces() - .into_iter() + Ok(IFACES + .iter() .filter(|iface| { if let Some(interface) = interface.as_ref() { if iface.name != *interface { @@ -156,7 +165,7 @@ pub fn get_local_addresses(interface: Option<&str>) -> ZResult> { } iface.is_up() && iface.is_running() }) - .flat_map(|iface| iface.ips) + .flat_map(|iface| iface.ips.clone()) .map(|ipnet| ipnet.ip()) .collect()) } @@ -196,7 +205,7 @@ pub fn get_local_addresses(interface: Option<&str>) -> ZResult> { pub fn get_unicast_addresses_of_multicast_interfaces() -> Vec { #[cfg(unix)] { - pnet_datalink::interfaces() + IFACES .iter() .filter(|iface| iface.is_up() && iface.is_running() && iface.is_multicast()) .flat_map(|iface| { @@ -219,10 +228,7 @@ pub fn get_unicast_addresses_of_multicast_interfaces() -> Vec { pub fn get_unicast_addresses_of_interface(name: &str) -> ZResult> { #[cfg(unix)] { - match pnet_datalink::interfaces() - .into_iter() - .find(|iface| iface.name == name) - { + match IFACES.iter().find(|iface| iface.name == name) { Some(iface) => { if !iface.is_up() { bail!("Interface {name} is not up"); @@ -276,7 +282,7 @@ pub fn get_unicast_addresses_of_interface(name: &str) -> ZResult> { pub fn get_index_of_interface(addr: IpAddr) -> ZResult { #[cfg(unix)] { - pnet_datalink::interfaces() + IFACES .iter() .find(|iface| iface.ips.iter().any(|ipnet| ipnet.ip() == addr)) .map(|iface| iface.index) @@ -313,12 +319,12 @@ pub fn get_interface_names_by_addr(addr: IpAddr) -> ZResult> { #[cfg(unix)] { if addr.is_unspecified() { - Ok(pnet_datalink::interfaces() + Ok(IFACES .iter() .map(|iface| iface.name.clone()) .collect::>()) } else { - Ok(pnet_datalink::interfaces() + Ok(IFACES .iter() .filter(|iface| iface.ips.iter().any(|ipnet| ipnet.ip() == addr)) .map(|iface| iface.name.clone())