From 36555364c255fd35e095ab7f235640fafee0196a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristaps=20Skujin=CC=A7s=CC=8C?= Date: Tue, 11 Aug 2026 17:45:10 +0200 Subject: [PATCH 1/2] fix(transport/ttl): use libc constants for IP_TTL/IP_MULTICAST_TTL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hardcoded Linux values (2, 33) caused ENOPROTOOPT on macOS/BSD where they are 4 and 10; libc constants resolve correctly per-platform. Signed-off-by: Kristaps Skujiņš --- crates/hdds/src/transport/ttl.rs | 36 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/crates/hdds/src/transport/ttl.rs b/crates/hdds/src/transport/ttl.rs index 921e1dc..58a0f29 100644 --- a/crates/hdds/src/transport/ttl.rs +++ b/crates/hdds/src/transport/ttl.rs @@ -173,9 +173,9 @@ pub fn set_socket2_multicast_ttl(socket: &Socket, ttl: u8) -> io::Result<()> { /// Set multicast TTL on a raw file descriptor. #[cfg(unix)] fn set_multicast_ttl_fd(fd: i32, ttl: u8) -> io::Result<()> { - // IP_MULTICAST_TTL = 33 on Linux - const IP_MULTICAST_TTL: i32 = 33; - const IPPROTO_IP: i32 = 0; + // Use libc constants: value differs per-OS (Linux=33, macOS/BSD=10) + let ip_multicast_ttl: i32 = libc::IP_MULTICAST_TTL; + let ipproto_ip: i32 = libc::IPPROTO_IP; let ttl_val = i32::from(ttl); // SAFETY: @@ -187,8 +187,8 @@ fn set_multicast_ttl_fd(fd: i32, ttl: u8) -> io::Result<()> { let result = unsafe { libc::setsockopt( fd, - IPPROTO_IP, - IP_MULTICAST_TTL, + ipproto_ip, + ip_multicast_ttl, &ttl_val as *const i32 as *const libc::c_void, std::mem::size_of::() as libc::socklen_t, ) @@ -232,9 +232,9 @@ pub fn set_socket2_unicast_ttl(socket: &Socket, ttl: u8) -> io::Result<()> { /// Set unicast TTL on a raw file descriptor. #[cfg(unix)] fn set_unicast_ttl_fd(fd: i32, ttl: u8) -> io::Result<()> { - // IP_TTL = 2 on Linux - const IP_TTL: i32 = 2; - const IPPROTO_IP: i32 = 0; + // Use libc constants: value differs per-OS (Linux=2, macOS/BSD=4) + let ip_ttl: i32 = libc::IP_TTL; + let ipproto_ip: i32 = libc::IPPROTO_IP; let ttl_val = i32::from(ttl); // SAFETY: @@ -246,8 +246,8 @@ fn set_unicast_ttl_fd(fd: i32, ttl: u8) -> io::Result<()> { let result = unsafe { libc::setsockopt( fd, - IPPROTO_IP, - IP_TTL, + ipproto_ip, + ip_ttl, &ttl_val as *const i32 as *const libc::c_void, std::mem::size_of::() as libc::socklen_t, ) @@ -279,8 +279,8 @@ pub fn get_multicast_ttl(socket: &UdpSocket) -> Option { /// Get multicast TTL from a raw file descriptor. #[cfg(unix)] fn get_multicast_ttl_fd(fd: i32) -> Option { - const IP_MULTICAST_TTL: i32 = 33; - const IPPROTO_IP: i32 = 0; + let ip_multicast_ttl: i32 = libc::IP_MULTICAST_TTL; + let ipproto_ip: i32 = libc::IPPROTO_IP; let mut ttl_val: i32 = 0; let mut len: libc::socklen_t = std::mem::size_of::() as libc::socklen_t; @@ -294,8 +294,8 @@ fn get_multicast_ttl_fd(fd: i32) -> Option { let result = unsafe { libc::getsockopt( fd, - IPPROTO_IP, - IP_MULTICAST_TTL, + ipproto_ip, + ip_multicast_ttl, &mut ttl_val as *mut i32 as *mut libc::c_void, &mut len, ) @@ -319,8 +319,8 @@ pub fn get_unicast_ttl(socket: &UdpSocket) -> Option { /// Get unicast TTL from a raw file descriptor. #[cfg(unix)] fn get_unicast_ttl_fd(fd: i32) -> Option { - const IP_TTL: i32 = 2; - const IPPROTO_IP: i32 = 0; + let ip_ttl: i32 = libc::IP_TTL; + let ipproto_ip: i32 = libc::IPPROTO_IP; let mut ttl_val: i32 = 0; let mut len: libc::socklen_t = std::mem::size_of::() as libc::socklen_t; @@ -334,8 +334,8 @@ fn get_unicast_ttl_fd(fd: i32) -> Option { let result = unsafe { libc::getsockopt( fd, - IPPROTO_IP, - IP_TTL, + ipproto_ip, + ip_ttl, &mut ttl_val as *mut i32 as *mut libc::c_void, &mut len, ) From fcecd9554c7d0cc1152d01d7bc8df755be27f148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristaps=20Skujin=CC=A7s=CC=8C?= Date: Tue, 11 Aug 2026 17:45:10 +0200 Subject: [PATCH 2/2] fix(transport/dscp): use libc constants for IP_TOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hardcoded IP_TOS=1 (Linux) returned ENOPROTOOPT on macOS/BSD where it is 3; libc::IP_TOS resolves correctly per-platform. Signed-off-by: Kristaps Skujiņš --- crates/hdds/src/transport/dscp.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/crates/hdds/src/transport/dscp.rs b/crates/hdds/src/transport/dscp.rs index 5efe3e9..cbf1700 100644 --- a/crates/hdds/src/transport/dscp.rs +++ b/crates/hdds/src/transport/dscp.rs @@ -252,23 +252,22 @@ fn set_socket2_tos_raw(socket: &Socket, tos: u8) -> io::Result<()> { /// Set TOS on a raw file descriptor. #[cfg(unix)] fn set_tos_fd(fd: i32, tos: u8) -> io::Result<()> { - // IP_TOS = 1 on Linux - const IP_TOS: i32 = 1; - // IPPROTO_IP = 0 - const IPPROTO_IP: i32 = 0; + // Use libc constants: IP_TOS differs per-OS (Linux=1, macOS/BSD=3) + let ip_tos: i32 = libc::IP_TOS; + let ipproto_ip: i32 = libc::IPPROTO_IP; let tos_val = i32::from(tos); // SAFETY: // - fd is a valid socket descriptor (caller responsibility, obtained from UdpSocket::as_raw_fd()) - // - IPPROTO_IP (0) and IP_TOS (1) are valid socket option constants + // - IPPROTO_IP and IP_TOS are valid socket option constants // - tos_val is a stack-allocated i32, properly aligned // - size_of::() correctly represents the option value size // - setsockopt only modifies kernel socket state, no memory corruption possible let result = unsafe { libc::setsockopt( fd, - IPPROTO_IP, - IP_TOS, + ipproto_ip, + ip_tos, &tos_val as *const i32 as *const libc::c_void, std::mem::size_of::() as libc::socklen_t, ) @@ -295,23 +294,23 @@ pub fn get_socket_dscp(socket: &UdpSocket) -> Option { /// Get TOS from a raw file descriptor. #[cfg(unix)] fn get_tos_fd(fd: i32) -> Option { - const IP_TOS: i32 = 1; - const IPPROTO_IP: i32 = 0; + let ip_tos: i32 = libc::IP_TOS; + let ipproto_ip: i32 = libc::IPPROTO_IP; let mut tos_val: i32 = 0; let mut len: libc::socklen_t = std::mem::size_of::() as libc::socklen_t; // SAFETY: // - fd is a valid socket descriptor (caller responsibility) - // - IPPROTO_IP (0) and IP_TOS (1) are valid socket option constants + // - IPPROTO_IP and IP_TOS are valid socket option constants // - tos_val is a mutable stack-allocated i32, properly aligned // - len is initialized to size_of::() and passed by mutable reference // - getsockopt writes at most len bytes to tos_val, which has sufficient space let result = unsafe { libc::getsockopt( fd, - IPPROTO_IP, - IP_TOS, + ipproto_ip, + ip_tos, &mut tos_val as *mut i32 as *mut libc::c_void, &mut len, )