From 337665dff1e549e74386ce501ce6e4c849f36bc6 Mon Sep 17 00:00:00 2001 From: Erin Power Date: Mon, 21 Oct 2024 14:14:10 +0200 Subject: [PATCH] feat: Add UDP GRO option --- src/sys/unix.rs | 38 ++++++++++++++++++++++++++++++++++++++ tests/socket.rs | 6 ++++++ 2 files changed, 44 insertions(+) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 3a898bc3..5f8b9e0c 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -896,6 +896,44 @@ impl SockAddr { #[cfg(not(any(target_os = "linux", target_os = "android")))] None } + + /// Get the value of the `UDP_GRO` option on this socket. + /// + /// For more information about this option, see [`set_udp_gro`]. + /// + /// [`set_udp_gro`]: Socket::set_udp_gro + #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + #[cfg_attr( + docsrs, + doc(cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))) + )] + pub fn udp_gro(&self) -> io::Result { + unsafe { + getsockopt::(self.as_raw(), libc::SOL_UDP, libc::UDP_GRO) + .map(|reuse| reuse != 0) + } + } + + /// Set value for the `UDP_GRO` option on this socket. + /// + /// This indicates that the kernel can combine multiple datagrams into a + /// single buffer, this needs to be used in combination with [`Self::recvmsg`] + /// to get the number of segments in the buffer from the [`MsgHdr`]. + #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + #[cfg_attr( + docsrs, + doc(cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))) + )] + pub fn set_udp_gro(&self, reuse: bool) -> io::Result<()> { + unsafe { + setsockopt( + self.as_raw(), + sys::SOL_UDP, + sys::UDP_GRO, + reuse as c_int, + ) + } + } } pub(crate) type Socket = c_int; diff --git a/tests/socket.rs b/tests/socket.rs index 2300f0ed..4b3ca73c 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1355,6 +1355,12 @@ test!(reuse_address, set_reuse_address(true)); not(any(windows, target_os = "solaris", target_os = "illumos")) ))] test!(reuse_port, set_reuse_port(true)); +#[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] +#[cfg_attr( + docsrs, + doc(cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))) +)] +test!(udp_gro, set_udp_gro(true)); #[cfg(all(feature = "all", target_os = "freebsd"))] test!(reuse_port_lb, set_reuse_port_lb(true)); #[cfg(all(feature = "all", unix, not(target_os = "redox")))]