From 040769b0d844754148634503d30effaef4c00412 Mon Sep 17 00:00:00 2001 From: Jonathan Nilsson Date: Tue, 26 Apr 2022 11:57:37 +0200 Subject: [PATCH] Add Socket::(set_)recv_tos Gets or set the IP_RECVTOS option. --- src/socket.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/sys/unix.rs | 8 ++++++++ tests/socket.rs | 11 +++++++++++ 3 files changed, 65 insertions(+) diff --git a/src/socket.rs b/src/socket.rs index 0491e109..591a4b2d 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1388,6 +1388,52 @@ impl Socket { getsockopt::(self.as_raw(), sys::IPPROTO_IP, sys::IP_TOS).map(|tos| tos as u32) } } + + /// Set the value of the `IP_RECVTOS` option for this socket. + /// + /// If enabled, the IP_TOS ancillary message is passed with + /// incoming packets. It contains a byte which specifies the + /// Type of Service/Precedence field of the packet header. + #[cfg(not(any( + target_os = "fuschia", + target_os = "illumos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + target_os = "windows", + )))] + pub fn set_recv_tos(&self, recv_tos: bool) -> io::Result<()> { + let recv_tos = if recv_tos { 1 } else { 0 }; + + unsafe { + setsockopt( + self.as_raw(), + sys::IPPROTO_IP, + sys::IP_RECVTOS, + recv_tos as c_int, + ) + } + } + + /// Get the value of the `IP_RECVTOS` option for this socket. + /// + /// For more information about this option, see [`set_recv_tos`]. + /// + /// [`set_recv_tos`]: Socket::set_recv_tos + #[cfg(not(any( + target_os = "fuschia", + target_os = "illumos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + target_os = "windows", + )))] + pub fn recv_tos(&self) -> io::Result { + unsafe { + getsockopt::(self.as_raw(), sys::IPPROTO_IP, sys::IP_RECVTOS) + .map(|recv_tos| recv_tos > 0) + } + } } /// Socket options for IPv6 sockets, get/set using `IPPROTO_IPV6`. diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 58b48ecd..d4624a6c 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -77,6 +77,14 @@ pub(crate) use libc::{MSG_TRUNC, SO_OOBINLINE}; // Used in `Socket`. #[cfg(all(feature = "all", not(target_os = "redox")))] pub(crate) use libc::IP_HDRINCL; +#[cfg(not(any( + target_os = "fuschia", + target_os = "illumos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub(crate) use libc::IP_RECVTOS; #[cfg(not(any( target_os = "fuschia", target_os = "redox", diff --git a/tests/socket.rs b/tests/socket.rs index c6e3ad33..6653608f 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1172,6 +1172,17 @@ test!(IPv4 ttl, set_ttl(40)); target_os = "illumos", )))] test!(IPv4 tos, set_tos(96)); + +#[cfg(not(any( + target_os = "fuschia", + target_os = "illumos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + target_os = "windows", +)))] +test!(IPv4 recv_tos, set_recv_tos(true)); + #[cfg(not(windows))] // TODO: returns `WSAENOPROTOOPT` (10042) on Windows. test!(IPv4 broadcast, set_broadcast(true));