Skip to content

Commit

Permalink
Scan network interfaces once at startup (#1704)
Browse files Browse the repository at this point in the history
* Retrieve network interfaces once in a lazy_static

* Fix non unix build
  • Loading branch information
OlivierHecart authored Jan 10, 2025
1 parent 32eab2e commit 573409f
Showing 1 changed file with 19 additions and 13 deletions.
32 changes: 19 additions & 13 deletions commons/zenoh-util/src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -24,6 +28,11 @@ zconfigurable! {
static ref WINDOWS_GET_ADAPTERS_ADDRESSES_MAX_RETRIES: u32 = 3;
}

#[cfg(unix)]
lazy_static! {
static ref IFACES: Vec<NetworkInterface> = pnet_datalink::interfaces();
}

#[cfg(windows)]
unsafe fn get_adapters_addresses(af_spec: i32) -> ZResult<Vec<u8>> {
use winapi::um::iptypes::IP_ADAPTER_ADDRESSES_LH;
Expand Down Expand Up @@ -59,7 +68,7 @@ unsafe fn get_adapters_addresses(af_spec: i32) -> ZResult<Vec<u8>> {
pub fn get_interface(name: &str) -> ZResult<Option<IpAddr>> {
#[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() {
Expand Down Expand Up @@ -122,7 +131,7 @@ pub fn get_interface(name: &str) -> ZResult<Option<IpAddr>> {
pub fn get_multicast_interfaces() -> Vec<IpAddr> {
#[cfg(unix)]
{
pnet_datalink::interfaces()
IFACES
.iter()
.filter_map(|iface| {
if iface.is_up() && iface.is_running() && iface.is_multicast() {
Expand All @@ -146,8 +155,8 @@ pub fn get_multicast_interfaces() -> Vec<IpAddr> {
pub fn get_local_addresses(interface: Option<&str>) -> ZResult<Vec<IpAddr>> {
#[cfg(unix)]
{
Ok(pnet_datalink::interfaces()
.into_iter()
Ok(IFACES
.iter()
.filter(|iface| {
if let Some(interface) = interface.as_ref() {
if iface.name != *interface {
Expand All @@ -156,7 +165,7 @@ pub fn get_local_addresses(interface: Option<&str>) -> ZResult<Vec<IpAddr>> {
}
iface.is_up() && iface.is_running()
})
.flat_map(|iface| iface.ips)
.flat_map(|iface| iface.ips.clone())
.map(|ipnet| ipnet.ip())
.collect())
}
Expand Down Expand Up @@ -196,7 +205,7 @@ pub fn get_local_addresses(interface: Option<&str>) -> ZResult<Vec<IpAddr>> {
pub fn get_unicast_addresses_of_multicast_interfaces() -> Vec<IpAddr> {
#[cfg(unix)]
{
pnet_datalink::interfaces()
IFACES
.iter()
.filter(|iface| iface.is_up() && iface.is_running() && iface.is_multicast())
.flat_map(|iface| {
Expand All @@ -219,10 +228,7 @@ pub fn get_unicast_addresses_of_multicast_interfaces() -> Vec<IpAddr> {
pub fn get_unicast_addresses_of_interface(name: &str) -> ZResult<Vec<IpAddr>> {
#[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");
Expand Down Expand Up @@ -276,7 +282,7 @@ pub fn get_unicast_addresses_of_interface(name: &str) -> ZResult<Vec<IpAddr>> {
pub fn get_index_of_interface(addr: IpAddr) -> ZResult<u32> {
#[cfg(unix)]
{
pnet_datalink::interfaces()
IFACES
.iter()
.find(|iface| iface.ips.iter().any(|ipnet| ipnet.ip() == addr))
.map(|iface| iface.index)
Expand Down Expand Up @@ -313,12 +319,12 @@ pub fn get_interface_names_by_addr(addr: IpAddr) -> ZResult<Vec<String>> {
#[cfg(unix)]
{
if addr.is_unspecified() {
Ok(pnet_datalink::interfaces()
Ok(IFACES
.iter()
.map(|iface| iface.name.clone())
.collect::<Vec<String>>())
} else {
Ok(pnet_datalink::interfaces()
Ok(IFACES
.iter()
.filter(|iface| iface.ips.iter().any(|ipnet| ipnet.ip() == addr))
.map(|iface| iface.name.clone())
Expand Down

0 comments on commit 573409f

Please sign in to comment.