Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions commons/zenoh-util/src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
// ZettaScale Zenoh Team, <[email protected]>
//
use std::net::{IpAddr, Ipv6Addr};
#[cfg(unix)]
use std::sync::{Arc, RwLock};
#[cfg(unix)]
use std::time::Duration;

#[cfg(unix)]
use lazy_static::lazy_static;
Expand All @@ -30,7 +34,23 @@ zconfigurable! {

#[cfg(unix)]
lazy_static! {
static ref IFACES: Vec<NetworkInterface> = pnet_datalink::interfaces();
static ref IFACES: Arc<RwLock<Vec<NetworkInterface>>> = {
let ifaces = Arc::new(RwLock::new(pnet_datalink::interfaces()));

let ifaces_clone = Arc::clone(&ifaces);
tokio::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_secs(10));
loop {
interval.tick().await;
let new_interfaces = pnet_datalink::interfaces();
if let Ok(mut guard) = ifaces_clone.write() {
*guard = new_interfaces;
}
}
});

ifaces
};
}

#[cfg(windows)]
Expand Down Expand Up @@ -68,7 +88,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 IFACES.iter() {
for iface in IFACES.read().unwrap().iter() {
if iface.name == name {
for ifaddr in &iface.ips {
if ifaddr.is_ipv4() {
Expand Down Expand Up @@ -132,6 +152,8 @@ pub fn get_multicast_interfaces() -> Vec<IpAddr> {
#[cfg(unix)]
{
IFACES
.read()
.unwrap()
.iter()
.filter_map(|iface| {
if iface.is_up() && iface.is_running() && iface.is_multicast() {
Expand All @@ -156,6 +178,8 @@ pub fn get_local_addresses(interface: Option<&str>) -> ZResult<Vec<IpAddr>> {
#[cfg(unix)]
{
Ok(IFACES
.read()
.unwrap()
.iter()
.filter(|iface| {
if let Some(interface) = interface.as_ref() {
Expand Down Expand Up @@ -206,6 +230,8 @@ pub fn get_unicast_addresses_of_multicast_interfaces() -> Vec<IpAddr> {
#[cfg(unix)]
{
IFACES
.read()
.unwrap()
.iter()
.filter(|iface| iface.is_up() && iface.is_running() && iface.is_multicast())
.flat_map(|iface| {
Expand All @@ -228,7 +254,12 @@ 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 IFACES.iter().find(|iface| iface.name == name) {
match IFACES
.read()
.unwrap()
.iter()
.find(|iface| iface.name == name)
{
Some(iface) => {
if !iface.is_up() {
bail!("Interface {name} is not up");
Expand Down Expand Up @@ -283,6 +314,8 @@ pub fn get_index_of_interface(addr: IpAddr) -> ZResult<u32> {
#[cfg(unix)]
{
IFACES
.read()
.unwrap()
.iter()
.find(|iface| iface.ips.iter().any(|ipnet| ipnet.ip() == addr))
.map(|iface| iface.index)
Expand Down Expand Up @@ -320,11 +353,15 @@ pub fn get_interface_names_by_addr(addr: IpAddr) -> ZResult<Vec<String>> {
{
if addr.is_unspecified() {
Ok(IFACES
.read()
.unwrap()
.iter()
.map(|iface| iface.name.clone())
.collect::<Vec<String>>())
} else {
Ok(IFACES
.read()
.unwrap()
.iter()
.filter(|iface| iface.ips.iter().any(|ipnet| ipnet.ip() == addr))
.map(|iface| iface.name.clone())
Expand Down
Loading