From f2ae3fb7cfaab738b171af13b1405a7284849f1e Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Fri, 28 Aug 2026 10:55:38 -0600 Subject: [PATCH] Add SO_DONTROUTE support to {get,set}sockopt --- src/backend/libc/net/sockopt.rs | 10 ++++++++++ src/backend/linux_raw/c.rs | 2 +- src/backend/linux_raw/net/sockopt.rs | 10 ++++++++++ src/net/sockopt.rs | 22 ++++++++++++++++++++++ tests/net/sockopt.rs | 5 +++++ 5 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/backend/libc/net/sockopt.rs b/src/backend/libc/net/sockopt.rs index 0f2e67b99..5873d848c 100644 --- a/src/backend/libc/net/sockopt.rs +++ b/src/backend/libc/net/sockopt.rs @@ -462,6 +462,16 @@ pub(crate) fn socket_cookie(fd: BorrowedFd<'_>) -> io::Result { getsockopt(fd, c::SOL_SOCKET, c::SO_COOKIE) } +#[inline] +pub(crate) fn socket_dont_route(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_DONTROUTE).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_dont_route(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_DONTROUTE, from_bool(value)) +} + #[cfg(target_os = "linux")] #[inline] pub(crate) fn socket_incoming_cpu(fd: BorrowedFd<'_>) -> io::Result { diff --git a/src/backend/linux_raw/c.rs b/src/backend/linux_raw/c.rs index 762cdd479..53e8e37bc 100644 --- a/src/backend/linux_raw/c.rs +++ b/src/backend/linux_raw/c.rs @@ -97,7 +97,7 @@ pub(crate) use linux_raw_sys::{ MSG_EOR, MSG_ERRQUEUE, MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, SCM_CREDENTIALS, SCM_RIGHTS, SHUT_RD, SHUT_RDWR, SHUT_WR, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SOL_XDP, SO_ACCEPTCONN, SO_BROADCAST, SO_COOKIE, - SO_DOMAIN, SO_ERROR, SO_INCOMING_CPU, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, + SO_DOMAIN, SO_DONTROUTE, SO_ERROR, SO_INCOMING_CPU, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_ORIGINAL_DST, SO_PASSCRED, SO_PROTOCOL, SO_RCVBUF, SO_RCVBUFFORCE, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO, SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_REUSEPORT, SO_SNDBUF, SO_SNDBUFFORCE, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, SO_SNDTIMEO_OLD, SO_TYPE, diff --git a/src/backend/linux_raw/net/sockopt.rs b/src/backend/linux_raw/net/sockopt.rs index 85c65b085..af366c240 100644 --- a/src/backend/linux_raw/net/sockopt.rs +++ b/src/backend/linux_raw/net/sockopt.rs @@ -428,6 +428,16 @@ pub(crate) fn socket_cookie(fd: BorrowedFd<'_>) -> io::Result { getsockopt(fd, c::SOL_SOCKET, c::SO_COOKIE) } +#[inline] +pub(crate) fn socket_dont_route(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_DONTROUTE).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_dont_route(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_DONTROUTE, from_bool(value)) +} + #[inline] pub(crate) fn socket_incoming_cpu(fd: BorrowedFd<'_>) -> io::Result { getsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU) diff --git a/src/net/sockopt.rs b/src/net/sockopt.rs index 9536e175d..1a04841f8 100644 --- a/src/net/sockopt.rs +++ b/src/net/sockopt.rs @@ -702,6 +702,28 @@ pub fn socket_cookie(fd: Fd) -> io::Result { backend::net::sockopt::socket_cookie(fd.as_fd()) } +/// `getsockopt(fd, SOL_SOCKET, SO_DONTROUTE)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[inline] +#[doc(alias = "SO_DONTROUTE")] +pub fn socket_dont_route(fd: Fd) -> io::Result { + backend::net::sockopt::socket_dont_route(fd.as_fd()) +} + +/// `setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[inline] +#[doc(alias = "SO_DONTROUTE")] +pub fn set_socket_dont_route(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_socket_dont_route(fd.as_fd(), value) +} + /// `getsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU)` /// /// See the [module-level documentation] for more. diff --git a/tests/net/sockopt.rs b/tests/net/sockopt.rs index d139d9a5c..c47bad5ca 100644 --- a/tests/net/sockopt.rs +++ b/tests/net/sockopt.rs @@ -166,6 +166,11 @@ fn test_sockopts_socket(s: &OwnedFd) { ); } + // Check the initial value of `SO_DONTROUTE`, set it, and check it. + assert_eq!(sockopt::socket_dont_route(s).unwrap(), false); + sockopt::set_socket_dont_route(s, true).unwrap(); + assert_eq!(sockopt::socket_dont_route(s).unwrap(), true); + // Check the initial value of `SO_INCOMING_CPU`, set it, and check it. #[cfg(target_os = "linux")] {