use std::net::IpAddr;
pub fn zenoh_endpoint_is_loopback(endpoint: &str) -> bool {
let Ok(endpoint) = endpoint.parse::<zenoh_protocol::core::EndPoint>() else {
return false;
};
let address = endpoint.address().as_str();
let host = match address.strip_prefix('[') {
Some(rest) => rest.split(']').next().unwrap_or_default(),
None => address
.rsplit_once(':')
.map_or(address, |(host, _port)| host),
};
host.parse::<IpAddr>()
.map_or(host == "localhost", |ip| ip.to_canonical().is_loopback())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn loopback_endpoints_are_recognized_in_every_spelling() {
for endpoint in [
"tcp/127.0.0.1:5456",
"tcp/127.0.0.1:5456?prio=high#iface=lo",
"tcp/127.0.0.1:5456#iface=lo",
"tcp/[::1]:5456",
"tcp/[::1]",
"tcp/[::1]:5456?prio=high#iface=lo",
"tcp/[::ffff:127.0.0.1]:5456",
"tcp/localhost:5456",
"udp/127.1.2.3:1",
] {
assert!(zenoh_endpoint_is_loopback(endpoint), "{endpoint}");
}
for endpoint in [
"tcp/10.0.2.100:5456",
"tcp/[fd7a:1::2]:5456",
"tcp/robot-01.local:5456",
"tcp/0.0.0.0:5456",
"not-an-endpoint",
"",
] {
assert!(!zenoh_endpoint_is_loopback(endpoint), "{endpoint}");
}
}
}