diff --git a/io/zenoh-links/zenoh-link-udp/src/lib.rs b/io/zenoh-links/zenoh-link-udp/src/lib.rs index ac7e766f05..935c802dcf 100644 --- a/io/zenoh-links/zenoh-link-udp/src/lib.rs +++ b/io/zenoh-links/zenoh-link-udp/src/lib.rs @@ -107,6 +107,7 @@ impl LocatorInspector for UdpLocatorInspector { pub mod config { pub const UDP_MULTICAST_IFACE: &str = "iface"; pub const UDP_MULTICAST_JOIN: &str = "join"; + pub const UDP_MULTICAST_TTL: &str = "ttl"; } pub async fn get_udp_addrs(address: Address<'_>) -> ZResult> { diff --git a/io/zenoh-links/zenoh-link-udp/src/multicast.rs b/io/zenoh-links/zenoh-link-udp/src/multicast.rs index f0b40efc5d..a82b37c8cd 100644 --- a/io/zenoh-links/zenoh-link-udp/src/multicast.rs +++ b/io/zenoh-links/zenoh-link-udp/src/multicast.rs @@ -272,7 +272,7 @@ impl LinkManagerMulticastUdp { .map_err(|e| zerror!("{}: {}", mcast_addr, e))?; } - // Bind the socket: let's bing to the unspecified address so we can join and read + // Bind the socket: let's bind to the unspecified address so we can join and read // from multiple multicast groups. let bind_mcast_addr = match mcast_addr.ip() { IpAddr::V4(_) => IpAddr::V4(Ipv4Addr::UNSPECIFIED), @@ -321,6 +321,28 @@ impl LinkManagerMulticastUdp { // https://docs.rs/tokio/latest/tokio/net/struct.UdpSocket.html#notes mcast_sock.set_nonblocking(true)?; + // If TTL is specified, add set the socket's TTL + if let Some(ttl_str) = config.get(UDP_MULTICAST_TTL) { + match &local_addr { + IpAddr::V4(_) => { + let ttl = match ttl_str.parse::() { + Ok(ttl) => ttl, + Err(e) => bail!("Can not parse TTL '{}' to a u32: {}", ttl_str, e), + }; + + ucast_sock.set_multicast_ttl_v4(ttl).map_err(|e| { + zerror!("Can not set multicast TTL {} on {}: {}", ttl, mcast_addr, e) + })?; + } + IpAddr::V6(_) => { + tracing::warn!( + "UDP multicast hop limit not supported for v6 socket: {}. See https://github.com/rust-lang/rust/pull/138744.", + mcast_addr + ); + } + } + } + // Build the tokio multicast UdpSocket let mcast_sock = UdpSocket::from_std(mcast_sock.into())?;