From 028dd3f2760a8724f85c5f45d9ac03a748e548ee Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 26 Sep 2023 22:59:11 -0700 Subject: [PATCH 01/15] Reduce duplicate documentation in the sockopt module. Instead of copying all the Reference URLs for each sockopt function, factor common links out into the module-level documentation. --- src/net/sockopt.rs | 1962 ++++++++------------------------------------ 1 file changed, 344 insertions(+), 1618 deletions(-) diff --git a/src/net/sockopt.rs b/src/net/sockopt.rs index 1939155d9..c718aed20 100644 --- a/src/net/sockopt.rs +++ b/src/net/sockopt.rs @@ -2,6 +2,143 @@ //! //! In the rustix API, there is a separate function for each option, so that //! it can be given an option-specific type signature. +//! +//! # References for all `get_*` functions: +//! +//! - [POSIX `getsockopt`] +//! - [Linux `getsockopt`] +//! - [Winsock2 `getsockopt`] +//! - [Apple `getsockopt`] +//! - [FreeBSD `getsockopt`] +//! - [NetBSD `getsockopt`] +//! - [OpenBSD `getsockopt`] +//! - [DragonFly BSD `getsockopt`] +//! - [illumos `getsockopt`] +//! - [glibc `getsockopt`] +//! +//! [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html +//! [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html +//! [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt +//! [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html +//! [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 +//! [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 +//! [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 +//! [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 +//! [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt +//! [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html +//! +//! # References for all `set_*` functions: +//! +//! - [POSIX `setsockopt`] +//! - [Linux `setsockopt`] +//! - [Winsock2 `setsockopt`] +//! - [Apple `setsockopt`] +//! - [FreeBSD `setsockopt`] +//! - [NetBSD `setsockopt`] +//! - [OpenBSD `setsockopt`] +//! - [DragonFly BSD `setsockopt`] +//! - [illumos `setsockopt`] +//! - [glibc `setsockopt`] +//! +//! [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html +//! [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html +//! [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt +//! [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html +//! [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 +//! [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 +//! [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 +//! [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 +//! [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt +//! [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html +//! +//! # References for `get_socket_*` and `set_socket_*` functions: +//! +//! - [References for all `get_*` functions] +//! - [References for all `set_*` functions] +//! - [POSIX `sys/socket.h`] +//! - [Linux `socket`] +//! - [Winsock2 `SOL_SOCKET` options] +//! - [glibc `SOL_SOCKET` Options] +//! +//! [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html +//! [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html +//! [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options +//! [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +//! +//! # References for `get_ip_*` and `set_ip_*` functions: +//! +//! - [References for all `get_*` functions] +//! - [References for all `set_*` functions] +//! - [POSIX `netinet/in.h`] +//! - [Linux `ip`] +//! - [Winsock2 `IPPROTO_IP` options] +//! - [Apple `ip`] +//! - [FreeBSD `ip`] +//! - [NetBSD `ip`] +//! - [OpenBSD `ip`] +//! - [DragonFly BSD `ip`] +//! - [illumos `ip`] +//! +//! [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html +//! [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html +//! [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options +//! [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html +//! [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 +//! [NetBSD `ip`]: https://man.netbsd.org/ip.4 +//! [OpenBSD `ip`]: https://man.openbsd.org/ip.4 +//! [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 +//! [illumos `ip`]: https://illumos.org/man/4P/ip +//! +//! # References for `get_ipv6_*` and `set_ipv6_*` functions: +//! +//! - [References for all `get_*` functions] +//! - [References for all `set_*` functions] +//! - [POSIX `netinet/in.h`] +//! - [Linux `ipv6`] +//! - [Winsock2 `IPPROTO_IPV6` options] +//! - [Apple `ip6`] +//! - [FreeBSD `ip6`] +//! - [NetBSD `ip6`] +//! - [OpenBSD `ip6`] +//! - [DragonFly BSD `ip6`] +//! - [illumos `ip6`] +//! +//! [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html +//! [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html +//! [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options +//! [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html +//! [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 +//! [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 +//! [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 +//! [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 +//! [illumos `ip6`]: https://illumos.org/man/4P/ip6 +//! +//! # References for `get_tcp_*` and `set_tcp_*` functions: +//! +//! - [References for all `get_*` functions] +//! - [References for all `set_*` functions] +//! - [POSIX `netinet/tcp.h`] +//! - [Linux `tcp`] +//! - [Winsock2 `IPPROTO_TCP` options] +//! - [Apple `tcp`] +//! - [FreeBSD `tcp`] +//! - [NetBSD `tcp`] +//! - [OpenBSD `tcp`] +//! - [DragonFly BSD `tcp`] +//! - [illumos `tcp`] +//! +//! [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html +//! [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html +//! [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options +//! [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html +//! [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 +//! [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 +//! [OpenBSD `tcp`]: https://man.openbsd.org/tcp.4 +//! [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 +//! [illumos `tcp`]: https://illumos.org/man/4P/tcp +//! +//! [References for all `get_*` functions]: #references-for-all-get_-functions +//! [References for all `set_*` functions]: #references-for-all-set_-functions #![doc(alias = "getsockopt")] #![doc(alias = "setsockopt")] @@ -26,9 +163,6 @@ use core::time::Duration; /// Timeout identifier for use with [`set_socket_timeout`] and /// [`get_socket_timeout`]. -/// -/// [`set_socket_timeout`]: crate::net::sockopt::set_socket_timeout. -/// [`get_socket_timeout`]: crate::net::sockopt::get_socket_timeout. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] #[repr(u32)] pub enum Timeout { @@ -41,74 +175,21 @@ pub enum Timeout { /// `getsockopt(fd, SOL_SOCKET, SO_TYPE)`—Returns the type of a socket. /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_TYPE")] pub fn get_socket_type(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_socket_type(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, value)` -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// `setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, value)`—Set whether local +/// addresses may be reused in `bind`. +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_REUSEADDR")] pub fn set_socket_reuseaddr(fd: Fd, value: bool) -> io::Result<()> { @@ -117,36 +198,9 @@ pub fn set_socket_reuseaddr(fd: Fd, value: bool) -> io::Result<()> { /// `getsockopt(fd, SOL_SOCKET, SO_REUSEADDR)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_REUSEADDR")] pub fn get_socket_reuseaddr(fd: Fd) -> io::Result { @@ -155,179 +209,65 @@ pub fn get_socket_reuseaddr(fd: Fd) -> io::Result { /// `setsockopt(fd, SOL_SOCKET, SO_BROADCAST, broadcast)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_BROADCAST")] -pub fn set_socket_broadcast(fd: Fd, broadcast: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_broadcast(fd.as_fd(), broadcast) +pub fn set_socket_broadcast(fd: Fd, value: bool) -> io::Result<()> { + backend::net::syscalls::sockopt::set_socket_broadcast(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_BROADCAST)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_BROADCAST")] pub fn get_socket_broadcast(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_socket_broadcast(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_LINGER, linger)` -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// `setsockopt(fd, SOL_SOCKET, SO_LINGER, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_LINGER")] -pub fn set_socket_linger(fd: Fd, linger: Option) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_linger(fd.as_fd(), linger) +pub fn set_socket_linger(fd: Fd, value: Option) -> io::Result<()> { + backend::net::syscalls::sockopt::set_socket_linger(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_LINGER)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_LINGER")] pub fn get_socket_linger(fd: Fd) -> io::Result> { backend::net::syscalls::sockopt::get_socket_linger(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_PASSCRED, passcred)` +/// `setsockopt(fd, SOL_SOCKET, SO_PASSCRED, value)` /// -/// # References -/// - [Linux `setsockopt`] -/// - [Linux `socket`] +/// See the [module-level documentation] for more. /// -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[cfg(linux_kernel)] #[inline] #[doc(alias = "SO_PASSCRED")] -pub fn set_socket_passcred(fd: Fd, passcred: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_passcred(fd.as_fd(), passcred) +pub fn set_socket_passcred(fd: Fd, value: bool) -> io::Result<()> { + backend::net::syscalls::sockopt::set_socket_passcred(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_PASSCRED)` /// -/// # References -/// - [Linux `getsockopt`] -/// - [Linux `socket`] +/// See the [module-level documentation] for more. /// -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[cfg(linux_kernel)] #[inline] #[doc(alias = "SO_PASSCRED")] @@ -338,36 +278,9 @@ pub fn get_socket_passcred(fd: Fd) -> io::Result { /// `setsockopt(fd, SOL_SOCKET, id, timeout)`—Set the sending or receiving /// timeout. /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_RCVTIMEO")] #[doc(alias = "SO_SNDTIMEO")] @@ -381,36 +294,9 @@ pub fn set_socket_timeout( /// `getsockopt(fd, SOL_SOCKET, id)`—Get the sending or receiving timeout. /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_RCVTIMEO")] #[doc(alias = "SO_SNDTIMEO")] @@ -420,36 +306,9 @@ pub fn get_socket_timeout(fd: Fd, id: Timeout) -> io::Result(fd: Fd) -> io::Result> { @@ -458,36 +317,9 @@ pub fn get_socket_error(fd: Fd) -> io::Result> { /// `getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[cfg(any(apple, target_os = "freebsd"))] #[doc(alias = "SO_NOSIGPIPE")] #[inline] @@ -495,267 +327,78 @@ pub fn get_socket_nosigpipe(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_socket_nosigpipe(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, val)` -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// `setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[cfg(any(apple, target_os = "freebsd"))] #[doc(alias = "SO_NOSIGPIPE")] #[inline] -pub fn set_socket_nosigpipe(fd: Fd, val: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_nosigpipe(fd.as_fd(), val) +pub fn set_socket_nosigpipe(fd: Fd, value: bool) -> io::Result<()> { + backend::net::syscalls::sockopt::set_socket_nosigpipe(fd.as_fd(), value) } -/// `setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, keepalive)` -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// `setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_KEEPALIVE")] -pub fn set_socket_keepalive(fd: Fd, keepalive: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_keepalive(fd.as_fd(), keepalive) +pub fn set_socket_keepalive(fd: Fd, value: bool) -> io::Result<()> { + backend::net::syscalls::sockopt::set_socket_keepalive(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_KEEPALIVE")] pub fn get_socket_keepalive(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_socket_keepalive(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_RCVBUF, size)` -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// `setsockopt(fd, SOL_SOCKET, SO_RCVBUF, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_RCVBUF")] -pub fn set_socket_recv_buffer_size(fd: Fd, size: usize) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_recv_buffer_size(fd.as_fd(), size) +pub fn set_socket_recv_buffer_size(fd: Fd, value: usize) -> io::Result<()> { + backend::net::syscalls::sockopt::set_socket_recv_buffer_size(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_RCVBUF)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_RCVBUF")] pub fn get_socket_recv_buffer_size(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_socket_recv_buffer_size(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_SNDBUF, size)` -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// `setsockopt(fd, SOL_SOCKET, SO_SNDBUF, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_SNDBUF")] -pub fn set_socket_send_buffer_size(fd: Fd, size: usize) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_send_buffer_size(fd.as_fd(), size) +pub fn set_socket_send_buffer_size(fd: Fd, value: usize) -> io::Result<()> { + backend::net::syscalls::sockopt::set_socket_send_buffer_size(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_SNDBUF)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_SNDBUF")] pub fn get_socket_send_buffer_size(fd: Fd) -> io::Result { @@ -764,36 +407,9 @@ pub fn get_socket_send_buffer_size(fd: Fd) -> io::Result { /// `getsockopt(fd, SOL_SOCKET, SO_DOMAIN)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[cfg(not(any( apple, windows, @@ -813,34 +429,9 @@ pub fn get_socket_domain(fd: Fd) -> io::Result { /// `getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it. #[inline] #[doc(alias = "SO_ACCEPTCONN")] @@ -848,91 +439,22 @@ pub fn get_socket_acceptconn(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_socket_acceptconn(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_IP, IP_TTL, ttl)` -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `setsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// `setsockopt(fd, IPPROTO_IP, IP_TTL, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "IP_TTL")] -pub fn set_ip_ttl(fd: Fd, ttl: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_ttl(fd.as_fd(), ttl) +pub fn set_ip_ttl(fd: Fd, value: u32) -> io::Result<()> { + backend::net::syscalls::sockopt::set_ip_ttl(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IP, IP_TTL)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `getsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_TTL")] pub fn get_ip_ttl(fd: Fd) -> io::Result { @@ -941,342 +463,86 @@ pub fn get_ip_ttl(fd: Fd) -> io::Result { /// `setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, only_v6)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_V6ONLY")] -pub fn set_ipv6_v6only(fd: Fd, only_v6: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_v6only(fd.as_fd(), only_v6) +pub fn set_ipv6_v6only(fd: Fd, value: bool) -> io::Result<()> { + backend::net::syscalls::sockopt::set_ipv6_v6only(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `getsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_V6ONLY")] pub fn get_ipv6_v6only(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_ipv6_v6only(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, multicast_loop)` -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `setsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_MULTICAST_LOOP")] -pub fn set_ip_multicast_loop(fd: Fd, multicast_loop: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_multicast_loop(fd.as_fd(), multicast_loop) +pub fn set_ip_multicast_loop(fd: Fd, value: bool) -> io::Result<()> { + backend::net::syscalls::sockopt::set_ip_multicast_loop(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `getsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_MULTICAST_LOOP")] pub fn get_ip_multicast_loop(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_ip_multicast_loop(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, multicast_ttl)` -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `setsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_MULTICAST_TTL")] -pub fn set_ip_multicast_ttl(fd: Fd, multicast_ttl: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_multicast_ttl(fd.as_fd(), multicast_ttl) +pub fn set_ip_multicast_ttl(fd: Fd, value: u32) -> io::Result<()> { + backend::net::syscalls::sockopt::set_ip_multicast_ttl(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `getsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_MULTICAST_TTL")] pub fn get_ip_multicast_ttl(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_ip_multicast_ttl(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, multicast_loop)` -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_MULTICAST_LOOP")] -pub fn set_ipv6_multicast_loop(fd: Fd, multicast_loop: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_multicast_loop(fd.as_fd(), multicast_loop) +pub fn set_ipv6_multicast_loop(fd: Fd, value: bool) -> io::Result<()> { + backend::net::syscalls::sockopt::set_ipv6_multicast_loop(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `getsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_MULTICAST_LOOP")] pub fn get_ipv6_multicast_loop(fd: Fd) -> io::Result { @@ -1285,90 +551,20 @@ pub fn get_ipv6_multicast_loop(fd: Fd) -> io::Result { /// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, multicast_hops)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IP_MULTICAST_TTL")] -pub fn set_ipv6_multicast_hops(fd: Fd, multicast_hops: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_multicast_hops(fd.as_fd(), multicast_hops) +pub fn set_ipv6_multicast_hops(fd: Fd, value: u32) -> io::Result<()> { + backend::net::syscalls::sockopt::set_ipv6_multicast_hops(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `getsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_UNICAST_HOPS")] pub fn get_ipv6_unicast_hops(fd: Fd) -> io::Result { @@ -1377,90 +573,20 @@ pub fn get_ipv6_unicast_hops(fd: Fd) -> io::Result { /// `setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, unicast_hops)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_UNICAST_HOPS")] -pub fn set_ipv6_unicast_hops(fd: Fd, unicast_hops: Option) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_unicast_hops(fd.as_fd(), unicast_hops) +pub fn set_ipv6_unicast_hops(fd: Fd, value: Option) -> io::Result<()> { + backend::net::syscalls::sockopt::set_ipv6_unicast_hops(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `getsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IP_MULTICAST_TTL")] pub fn get_ipv6_multicast_hops(fd: Fd) -> io::Result { @@ -1469,44 +595,9 @@ pub fn get_ipv6_multicast_hops(fd: Fd) -> io::Result { /// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, interface)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `setsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_ADD_MEMBERSHIP")] pub fn set_ip_add_membership( @@ -1519,46 +610,9 @@ pub fn set_ip_add_membership( /// `setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, multiaddr, interface)` /// -/// `IPV6_ADD_MEMBERSHIP` is the same as `IPV6_JOIN_GROUP` in POSIX. -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_JOIN_GROUP")] #[doc(alias = "IPV6_ADD_MEMBERSHIP")] @@ -1572,44 +626,9 @@ pub fn set_ipv6_add_membership( /// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `setsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_DROP_MEMBERSHIP")] pub fn set_ip_drop_membership( @@ -1622,46 +641,9 @@ pub fn set_ip_drop_membership( /// `setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, multiaddr, interface)` /// -/// `IPV6_DROP_MEMBERSHIP` is the same as `IPV6_LEAVE_GROUP` in POSIX. -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_LEAVE_GROUP")] #[doc(alias = "IPV6_DROP_MEMBERSHIP")] @@ -1673,177 +655,45 @@ pub fn set_ipv6_drop_membership( backend::net::syscalls::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface) } -/// `setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, nodelay)` -/// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `setsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `setsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `tcp`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `tcp`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `setsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `tcp`]: https://man.openbsd.org/tcp.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp +/// `setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[inline] #[doc(alias = "TCP_NODELAY")] -pub fn set_tcp_nodelay(fd: Fd, nodelay: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_nodelay(fd.as_fd(), nodelay) +pub fn set_tcp_nodelay(fd: Fd, value: bool) -> io::Result<()> { + backend::net::syscalls::sockopt::set_tcp_nodelay(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_NODELAY)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 -/// [OpenBSD `tcp`]: https://man.openbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[inline] #[doc(alias = "TCP_NODELAY")] pub fn get_tcp_nodelay(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_tcp_nodelay(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, count)` -/// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp +/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[inline] #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPCNT")] -pub fn set_tcp_keepcnt(fd: Fd, count: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_keepcnt(fd.as_fd(), count) +pub fn set_tcp_keepcnt(fd: Fd, value: u32) -> io::Result<()> { + backend::net::syscalls::sockopt::set_tcp_keepcnt(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[inline] #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPCNT")] @@ -1851,89 +701,27 @@ pub fn get_tcp_keepcnt(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_tcp_keepcnt(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, duration)` +/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, value)` /// /// `TCP_KEEPALIVE` on Apple platforms. /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[inline] #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPIDLE")] -pub fn set_tcp_keepidle(fd: Fd, duration: Duration) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_keepidle(fd.as_fd(), duration) +pub fn set_tcp_keepidle(fd: Fd, value: Duration) -> io::Result<()> { + backend::net::syscalls::sockopt::set_tcp_keepidle(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE)` /// /// `TCP_KEEPALIVE` on Apple platforms. /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[inline] #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPIDLE")] @@ -1941,85 +729,23 @@ pub fn get_tcp_keepidle(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_tcp_keepidle(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, duration)` -/// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp +/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[inline] #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPINTVL")] -pub fn set_tcp_keepintvl(fd: Fd, duration: Duration) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_keepintvl(fd.as_fd(), duration) +pub fn set_tcp_keepintvl(fd: Fd, value: Duration) -> io::Result<()> { + backend::net::syscalls::sockopt::set_tcp_keepintvl(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[inline] #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPINTVL")] From 70b80e98db446354736a161f61261432ab9c6a59 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 26 Sep 2023 23:27:22 -0700 Subject: [PATCH 02/15] Implement `SO_OOBINLINE`. --- src/backend/libc/net/syscalls.rs | 10 ++++++ src/backend/linux_raw/c.rs | 9 +++--- src/backend/linux_raw/net/syscalls.rs | 46 ++++++++++++++++----------- src/net/sockopt.rs | 22 +++++++++++++ 4 files changed, 64 insertions(+), 23 deletions(-) diff --git a/src/backend/libc/net/syscalls.rs b/src/backend/libc/net/syscalls.rs index 2e968ba3e..bdf70021a 100644 --- a/src/backend/libc/net/syscalls.rs +++ b/src/backend/libc/net/syscalls.rs @@ -855,6 +855,16 @@ pub(crate) mod sockopt { getsockopt(fd, c::SOL_SOCKET as _, c::SO_ACCEPTCONN).map(to_bool) } + #[inline] + pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE, from_bool(value)) + } + + #[inline] + pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE).map(to_bool) + } + #[inline] pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) diff --git a/src/backend/linux_raw/c.rs b/src/backend/linux_raw/c.rs index 0db4e2836..dc900e430 100644 --- a/src/backend/linux_raw/c.rs +++ b/src/backend/linux_raw/c.rs @@ -68,10 +68,11 @@ pub(crate) use linux_raw_sys::{ IP_MULTICAST_TTL, IP_TTL, MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, 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, SO_BROADCAST, SO_DOMAIN, SO_ERROR, SO_KEEPALIVE, - SO_LINGER, SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO, - SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, - SO_SNDTIMEO_OLD, SO_TYPE, TCP_NODELAY, + SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SO_ACCEPTCONN, SO_BROADCAST, SO_DOMAIN, SO_ERROR, + SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, + SO_RCVTIMEO_NEW as SO_RCVTIMEO, SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO_NEW, + SO_SNDTIMEO_NEW as SO_SNDTIMEO, SO_SNDTIMEO_OLD, SO_TYPE, TCP_KEEPCNT, TCP_KEEPIDLE, + TCP_KEEPINTVL, TCP_NODELAY, }, netlink::*, }; diff --git a/src/backend/linux_raw/net/syscalls.rs b/src/backend/linux_raw/net/syscalls.rs index 24a035403..df32c8048 100644 --- a/src/backend/linux_raw/net/syscalls.rs +++ b/src/backend/linux_raw/net/syscalls.rs @@ -925,10 +925,8 @@ pub(crate) mod sockopt { use crate::io; use crate::net::sockopt::Timeout; use crate::net::{AddressFamily, Ipv4Addr, Ipv6Addr, SocketType}; - use c::{SO_RCVTIMEO_NEW, SO_RCVTIMEO_OLD, SO_SNDTIMEO_NEW, SO_SNDTIMEO_OLD}; use core::time::Duration; use linux_raw_sys::general::{__kernel_old_timeval, __kernel_sock_timeval}; - use linux_raw_sys::net::{SO_ACCEPTCONN, TCP_KEEPCNT, TCP_KEEPIDLE, TCP_KEEPINTVL}; #[inline] fn getsockopt(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result { @@ -1101,11 +1099,11 @@ pub(crate) mod sockopt { ) -> io::Result<()> { let time = duration_to_linux_sock_timeval(timeout)?; let optname = match id { - Timeout::Recv => SO_RCVTIMEO_NEW, - Timeout::Send => SO_SNDTIMEO_NEW, + Timeout::Recv => c::SO_RCVTIMEO_NEW, + Timeout::Send => c::SO_SNDTIMEO_NEW, }; match setsockopt(fd, c::SOL_SOCKET, optname, time) { - Err(io::Errno::NOPROTOOPT) if SO_RCVTIMEO_NEW != SO_RCVTIMEO_OLD => { + Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { set_socket_timeout_old(fd, id, timeout) } otherwise => otherwise, @@ -1121,8 +1119,8 @@ pub(crate) mod sockopt { ) -> io::Result<()> { let time = duration_to_linux_old_timeval(timeout)?; let optname = match id { - Timeout::Recv => SO_RCVTIMEO_OLD, - Timeout::Send => SO_SNDTIMEO_OLD, + Timeout::Recv => c::SO_RCVTIMEO_OLD, + Timeout::Send => c::SO_SNDTIMEO_OLD, }; setsockopt(fd, c::SOL_SOCKET, optname, time) } @@ -1133,11 +1131,11 @@ pub(crate) mod sockopt { id: Timeout, ) -> io::Result> { let optname = match id { - Timeout::Recv => SO_RCVTIMEO_NEW, - Timeout::Send => SO_SNDTIMEO_NEW, + Timeout::Recv => c::SO_RCVTIMEO_NEW, + Timeout::Send => c::SO_SNDTIMEO_NEW, }; let time: __kernel_sock_timeval = match getsockopt(fd, c::SOL_SOCKET, optname) { - Err(io::Errno::NOPROTOOPT) if SO_RCVTIMEO_NEW != SO_RCVTIMEO_OLD => { + Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { return get_socket_timeout_old(fd, id) } otherwise => otherwise?, @@ -1149,8 +1147,8 @@ pub(crate) mod sockopt { /// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. fn get_socket_timeout_old(fd: BorrowedFd<'_>, id: Timeout) -> io::Result> { let optname = match id { - Timeout::Recv => SO_RCVTIMEO_OLD, - Timeout::Send => SO_SNDTIMEO_OLD, + Timeout::Recv => c::SO_RCVTIMEO_OLD, + Timeout::Send => c::SO_SNDTIMEO_OLD, }; let time: __kernel_old_timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; Ok(duration_from_linux_old_timeval(time)) @@ -1296,7 +1294,17 @@ pub(crate) mod sockopt { #[inline] pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, SO_ACCEPTCONN).map(to_bool) + getsockopt(fd, c::SOL_SOCKET as _, c::SO_ACCEPTCONN).map(to_bool) + } + + #[inline] + pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE, from_bool(value)) + } + + #[inline] + pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE).map(to_bool) } #[inline] @@ -1449,35 +1457,35 @@ pub(crate) mod sockopt { #[inline] pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPCNT, count) + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT, count) } #[inline] pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPCNT) + getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT) } #[inline] pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE, secs) + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPIDLE, secs) } #[inline] pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE)?; + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPIDLE)?; Ok(Duration::from_secs(secs as u64)) } #[inline] pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPINTVL, secs) + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL, secs) } #[inline] pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPINTVL)?; + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL)?; Ok(Duration::from_secs(secs as u64)) } diff --git a/src/net/sockopt.rs b/src/net/sockopt.rs index c718aed20..d7bb1deed 100644 --- a/src/net/sockopt.rs +++ b/src/net/sockopt.rs @@ -439,6 +439,28 @@ pub fn get_socket_acceptconn(fd: Fd) -> io::Result { backend::net::syscalls::sockopt::get_socket_acceptconn(fd.as_fd()) } +/// `setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[inline] +#[doc(alias = "SO_OOBINLINE")] +pub fn set_socket_oobinline(fd: Fd, value: bool) -> io::Result<()> { + backend::net::syscalls::sockopt::set_socket_oobinline(fd.as_fd(), value) +} + +/// `getsockopt(fd, SOL_SOCKET, SO_OOBINLINE)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[inline] +#[doc(alias = "SO_OOBINLINE")] +pub fn get_socket_oobinline(fd: Fd) -> io::Result { + backend::net::syscalls::sockopt::get_socket_oobinline(fd.as_fd()) +} + /// `setsockopt(fd, IPPROTO_IP, IP_TTL, value)` /// /// See the [module-level documentation] for more. From 2062ba674fd8d7e640a3a795677ddc81e5f3d6a4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 26 Sep 2023 23:40:23 -0700 Subject: [PATCH 03/15] Split the `sockopt` modules into their own files. --- src/backend/libc/net/mod.rs | 2 + src/backend/libc/net/sockopt.rs | 621 +++++++++++++++++++++++++ src/backend/libc/net/syscalls.rs | 644 -------------------------- src/backend/linux_raw/net/mod.rs | 1 + src/backend/linux_raw/net/sockopt.rs | 600 ++++++++++++++++++++++++ src/backend/linux_raw/net/syscalls.rs | 627 ------------------------- src/net/sockopt.rs | 100 ++-- 7 files changed, 1274 insertions(+), 1321 deletions(-) create mode 100644 src/backend/libc/net/sockopt.rs create mode 100644 src/backend/linux_raw/net/sockopt.rs diff --git a/src/backend/libc/net/mod.rs b/src/backend/libc/net/mod.rs index 65c7d0654..c425ec01f 100644 --- a/src/backend/libc/net/mod.rs +++ b/src/backend/libc/net/mod.rs @@ -4,5 +4,7 @@ pub(crate) mod ext; pub(crate) mod msghdr; pub(crate) mod read_sockaddr; pub(crate) mod send_recv; +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) mod sockopt; pub(crate) mod syscalls; pub(crate) mod write_sockaddr; diff --git a/src/backend/libc/net/sockopt.rs b/src/backend/libc/net/sockopt.rs new file mode 100644 index 000000000..d9ec78cc7 --- /dev/null +++ b/src/backend/libc/net/sockopt.rs @@ -0,0 +1,621 @@ +//! libc syscalls supporting `rustix::net::sockopt`. + +use super::ext::{in6_addr_new, in_addr_new}; +use crate::backend::c; +use crate::backend::conv::{borrowed_fd, ret}; +use crate::fd::BorrowedFd; +use crate::io; +use crate::net::sockopt::Timeout; +#[cfg(not(any( + apple, + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "espidf", + target_os = "haiku", + target_os = "netbsd", + target_os = "nto", +)))] +use crate::net::AddressFamily; +use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; +use crate::utils::{as_mut_ptr, as_ptr}; +#[cfg(apple)] +use c::TCP_KEEPALIVE as TCP_KEEPIDLE; +#[cfg(not(any(apple, target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +use c::TCP_KEEPIDLE; +use core::mem::size_of; +use core::time::Duration; +#[cfg(windows)] +use windows_sys::Win32::Foundation::BOOL; + +#[inline] +fn getsockopt(fd: BorrowedFd<'_>, level: i32, optname: i32) -> io::Result { + let mut optlen = core::mem::size_of::().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::(), + "Socket APIs don't ever use `bool` directly" + ); + + unsafe { + let mut value = core::mem::zeroed::(); + ret(c::getsockopt( + borrowed_fd(fd), + level, + optname, + as_mut_ptr(&mut value).cast(), + &mut optlen, + ))?; + // On Windows at least, `getsockopt` has been observed writing 1 + // byte on at least (`IPPROTO_TCP`, `TCP_NODELAY`), even though + // Windows' documentation says that should write a 4-byte `BOOL`. + // So, we initialize the memory to zeros above, and just assert + // that `getsockopt` doesn't write too many bytes here. + assert!( + optlen as usize <= size_of::(), + "unexpected getsockopt size" + ); + Ok(value) + } +} + +#[inline] +fn setsockopt(fd: BorrowedFd<'_>, level: i32, optname: i32, value: T) -> io::Result<()> { + let optlen = core::mem::size_of::().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::(), + "Socket APIs don't ever use `bool` directly" + ); + + unsafe { + ret(c::setsockopt( + borrowed_fd(fd), + level, + optname, + as_ptr(&value).cast(), + optlen, + )) + } +} + +#[inline] +pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) +} + +#[inline] +pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { + setsockopt( + fd, + c::SOL_SOCKET as _, + c::SO_REUSEADDR, + from_bool(reuseaddr), + ) +} + +#[inline] +pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_REUSEADDR).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { + setsockopt( + fd, + c::SOL_SOCKET as _, + c::SO_BROADCAST, + from_bool(broadcast), + ) +} + +#[inline] +pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_linger(fd: BorrowedFd<'_>, linger: Option) -> io::Result<()> { + // Convert `linger` to seconds, rounding up. + let l_linger = if let Some(linger) = linger { + duration_to_secs(linger)? + } else { + 0 + }; + let linger = c::linger { + l_onoff: linger.is_some() as _, + l_linger, + }; + setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) +} + +#[inline] +pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { + let linger: c::linger = getsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER)?; + Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_timeout( + fd: BorrowedFd<'_>, + id: Timeout, + timeout: Option, +) -> io::Result<()> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO, + Timeout::Send => c::SO_SNDTIMEO, + }; + + #[cfg(not(windows))] + let timeout = match timeout { + Some(timeout) => { + if timeout == Duration::ZERO { + return Err(io::Errno::INVAL); + } + + // Rust's musl libc bindings deprecated `time_t` while they + // transition to 64-bit `time_t`. What we want here is just + // “whatever type `timeval`'s `tv_sec` is”, so we're ok using + // the deprecated type. + #[allow(deprecated)] + let tv_sec = timeout.as_secs().try_into().unwrap_or(c::time_t::MAX); + + // `subsec_micros` rounds down, so we use `subsec_nanos` and + // manually round up. + let mut timeout = c::timeval { + tv_sec, + tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => c::timeval { + tv_sec: 0, + tv_usec: 0, + }, + }; + + #[cfg(windows)] + let timeout: u32 = match timeout { + Some(timeout) => { + if timeout == Duration::ZERO { + return Err(io::Errno::INVAL); + } + + // `as_millis` rounds down, so we use `as_nanos` and + // manually round up. + let mut timeout: u32 = ((timeout.as_nanos() + 999_999) / 1_000_000) + .try_into() + .map_err(|_convert_err| io::Errno::INVAL)?; + if timeout == 0 { + timeout = 1; + } + timeout + } + None => 0, + }; + + setsockopt(fd, c::SOL_SOCKET, optname, timeout) +} + +#[inline] +pub(crate) fn get_socket_timeout(fd: BorrowedFd<'_>, id: Timeout) -> io::Result> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO, + Timeout::Send => c::SO_SNDTIMEO, + }; + + #[cfg(not(windows))] + { + let timeout: c::timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + Ok(None) + } else { + Ok(Some( + Duration::from_secs(timeout.tv_sec as u64) + + Duration::from_micros(timeout.tv_usec as u64), + )) + } + } + + #[cfg(windows)] + { + let timeout: u32 = getsockopt(fd, c::SOL_SOCKET, optname)?; + if timeout == 0 { + Ok(None) + } else { + Ok(Some(Duration::from_millis(timeout as u64))) + } + } +} + +#[cfg(any(apple, target_os = "freebsd"))] +#[inline] +pub(crate) fn get_socket_nosigpipe(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE).map(to_bool) +} + +#[cfg(any(apple, target_os = "freebsd"))] +#[inline] +pub(crate) fn set_socket_nosigpipe(fd: BorrowedFd<'_>, val: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE, from_bool(val)) +} + +#[inline] +pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result> { + let err: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_ERROR)?; + Ok(if err == 0 { + Ok(()) + } else { + Err(io::Errno::from_raw_os_error(err)) + }) +} + +#[inline] +pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { + setsockopt( + fd, + c::SOL_SOCKET as _, + c::SO_KEEPALIVE, + from_bool(keepalive), + ) +} + +#[inline] +pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_KEEPALIVE).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; + setsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF, size) +} + +#[inline] +pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF).map(|size: u32| size as usize) +} + +#[inline] +pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; + setsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF, size) +} + +#[inline] +pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF).map(|size: u32| size as usize) +} + +#[inline] +#[cfg(not(any( + apple, + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "espidf", + target_os = "haiku", + target_os = "netbsd", + target_os = "nto", +)))] +pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result { + let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_DOMAIN)?; + Ok(AddressFamily( + domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, + )) +} + +#[inline] +#[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it. +pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_ACCEPTCONN).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE, from_bool(value)) +} + +#[inline] +pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) +} + +#[inline] +pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) +} + +#[inline] +pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) +} + +#[inline] +pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IP as _, + c::IP_MULTICAST_LOOP, + from_bool(multicast_loop), + ) +} + +#[inline] +pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) +} + +#[inline] +pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) +} + +#[inline] +pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IPV6 as _, + c::IPV6_MULTICAST_LOOP, + from_bool(multicast_loop), + ) +} + +#[inline] +pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) +} + +#[inline] +pub(crate) fn set_ipv6_multicast_hops(fd: BorrowedFd<'_>, multicast_hops: u32) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IP as _, + c::IPV6_MULTICAST_HOPS, + multicast_hops, + ) +} + +#[inline] +pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_HOPS) +} + +#[inline] +pub(crate) fn set_ip_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, +) -> io::Result<()> { + let mreq = to_imr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ipv6_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, +) -> io::Result<()> { + #[cfg(not(any( + bsd, + solarish, + target_os = "haiku", + target_os = "l4re", + target_os = "nto" + )))] + use c::IPV6_ADD_MEMBERSHIP; + #[cfg(any( + bsd, + solarish, + target_os = "haiku", + target_os = "l4re", + target_os = "nto" + ))] + use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; + + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_ADD_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ip_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, +) -> io::Result<()> { + let mreq = to_imr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ipv6_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, +) -> io::Result<()> { + #[cfg(not(any( + bsd, + solarish, + target_os = "haiku", + target_os = "l4re", + target_os = "nto" + )))] + use c::IPV6_DROP_MEMBERSHIP; + #[cfg(any( + bsd, + solarish, + target_os = "haiku", + target_os = "l4re", + target_os = "nto" + ))] + use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; + + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_DROP_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) +} + +#[inline] +pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io::Result<()> { + let hops = match hops { + Some(hops) => hops as c::c_int, + None => -1, + }; + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) +} + +#[inline] +pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) +} + +#[inline] +pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT, count) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { + let secs: c::c_uint = duration_to_secs(duration)?; + setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE, secs) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result { + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE)?; + Ok(Duration::from_secs(secs as u64)) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { + let secs: c::c_uint = duration_to_secs(duration)?; + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL, secs) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL)?; + Ok(Duration::from_secs(secs as u64)) +} + +#[inline] +fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { + c::ip_mreq { + imr_multiaddr: to_imr_addr(multiaddr), + imr_interface: to_imr_addr(interface), + } +} + +#[inline] +fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { + in_addr_new(u32::from_ne_bytes(addr.octets())) +} + +#[inline] +fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { + c::ipv6_mreq { + ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), + ipv6mr_interface: to_ipv6mr_interface(interface), + } +} + +#[inline] +fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { + in6_addr_new(multiaddr.octets()) +} + +#[cfg(target_os = "android")] +#[inline] +fn to_ipv6mr_interface(interface: u32) -> c::c_int { + interface as c::c_int +} + +#[cfg(not(target_os = "android"))] +#[inline] +fn to_ipv6mr_interface(interface: u32) -> c::c_uint { + interface as c::c_uint +} + +// `getsockopt` and `setsockopt` represent boolean values as integers. +#[cfg(not(windows))] +type RawSocketBool = c::c_int; +#[cfg(windows)] +type RawSocketBool = BOOL; + +// Wrap `RawSocketBool` in a newtype to discourage misuse. +#[repr(transparent)] +#[derive(Copy, Clone)] +struct SocketBool(RawSocketBool); + +// Convert from a `bool` to a `SocketBool`. +#[inline] +fn from_bool(value: bool) -> SocketBool { + SocketBool(value as _) +} + +// Convert from a `SocketBool` to a `bool`. +#[inline] +fn to_bool(value: SocketBool) -> bool { + value.0 != 0 +} + +/// Convert to seconds, rounding up if necessary. +#[inline] +fn duration_to_secs>(duration: Duration) -> io::Result { + let mut secs = duration.as_secs(); + if duration.subsec_nanos() != 0 { + secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; + } + T::try_from(secs).map_err(|_e| io::Errno::INVAL) +} diff --git a/src/backend/libc/net/syscalls.rs b/src/backend/libc/net/syscalls.rs index bdf70021a..94248c5d8 100644 --- a/src/backend/libc/net/syscalls.rs +++ b/src/backend/libc/net/syscalls.rs @@ -2,7 +2,6 @@ #[cfg(unix)] use super::addr::SocketAddrUnix; -use super::ext::{in6_addr_new, in_addr_new}; use crate::backend::c; use crate::backend::conv::{borrowed_fd, ret, ret_owned_fd, ret_send_recv, send_recv_len}; use crate::fd::{BorrowedFd, OwnedFd}; @@ -515,646 +514,3 @@ pub(crate) fn socketpair( Ok((fd0, fd1)) } } - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) mod sockopt { - use super::{c, in6_addr_new, in_addr_new, BorrowedFd}; - use crate::io; - use crate::net::sockopt::Timeout; - #[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "netbsd", - target_os = "nto", - )))] - use crate::net::AddressFamily; - use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; - use crate::utils::as_mut_ptr; - #[cfg(apple)] - use c::TCP_KEEPALIVE as TCP_KEEPIDLE; - #[cfg(not(any(apple, target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - use c::TCP_KEEPIDLE; - use core::time::Duration; - #[cfg(windows)] - use windows_sys::Win32::Foundation::BOOL; - - #[inline] - fn getsockopt(fd: BorrowedFd<'_>, level: i32, optname: i32) -> io::Result { - use super::*; - - let mut optlen = core::mem::size_of::().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - - unsafe { - let mut value = core::mem::zeroed::(); - ret(c::getsockopt( - borrowed_fd(fd), - level, - optname, - as_mut_ptr(&mut value).cast(), - &mut optlen, - ))?; - // On Windows at least, `getsockopt` has been observed writing 1 - // byte on at least (`IPPROTO_TCP`, `TCP_NODELAY`), even though - // Windows' documentation says that should write a 4-byte `BOOL`. - // So, we initialize the memory to zeros above, and just assert - // that `getsockopt` doesn't write too many bytes here. - assert!( - optlen as usize <= size_of::(), - "unexpected getsockopt size" - ); - Ok(value) - } - } - - #[inline] - fn setsockopt( - fd: BorrowedFd<'_>, - level: i32, - optname: i32, - value: T, - ) -> io::Result<()> { - use super::*; - - let optlen = core::mem::size_of::().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - - unsafe { - ret(c::setsockopt( - borrowed_fd(fd), - level, - optname, - as_ptr(&value).cast(), - optlen, - )) - } - } - - #[inline] - pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) - } - - #[inline] - pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_REUSEADDR, - from_bool(reuseaddr), - ) - } - - #[inline] - pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_REUSEADDR).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_BROADCAST, - from_bool(broadcast), - ) - } - - #[inline] - pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_linger( - fd: BorrowedFd<'_>, - linger: Option, - ) -> io::Result<()> { - // Convert `linger` to seconds, rounding up. - let l_linger = if let Some(linger) = linger { - duration_to_secs(linger)? - } else { - 0 - }; - let linger = c::linger { - l_onoff: linger.is_some() as _, - l_linger, - }; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) - } - - #[inline] - pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { - let linger: c::linger = getsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER)?; - Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) - } - - #[cfg(linux_kernel)] - #[inline] - pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) - } - - #[cfg(linux_kernel)] - #[inline] - pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option, - ) -> io::Result<()> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO, - Timeout::Send => c::SO_SNDTIMEO, - }; - - #[cfg(not(windows))] - let timeout = match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // Rust's musl libc bindings deprecated `time_t` while they - // transition to 64-bit `time_t`. What we want here is just - // “whatever type `timeval`'s `tv_sec` is”, so we're ok using - // the deprecated type. - #[allow(deprecated)] - let tv_sec = timeout.as_secs().try_into().unwrap_or(c::time_t::MAX); - - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = c::timeval { - tv_sec, - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => c::timeval { - tv_sec: 0, - tv_usec: 0, - }, - }; - - #[cfg(windows)] - let timeout: u32 = match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // `as_millis` rounds down, so we use `as_nanos` and - // manually round up. - let mut timeout: u32 = ((timeout.as_nanos() + 999_999) / 1_000_000) - .try_into() - .map_err(|_convert_err| io::Errno::INVAL)?; - if timeout == 0 { - timeout = 1; - } - timeout - } - None => 0, - }; - - setsockopt(fd, c::SOL_SOCKET, optname, timeout) - } - - #[inline] - pub(crate) fn get_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - ) -> io::Result> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO, - Timeout::Send => c::SO_SNDTIMEO, - }; - - #[cfg(not(windows))] - { - let timeout: c::timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - Ok(None) - } else { - Ok(Some( - Duration::from_secs(timeout.tv_sec as u64) - + Duration::from_micros(timeout.tv_usec as u64), - )) - } - } - - #[cfg(windows)] - { - let timeout: u32 = getsockopt(fd, c::SOL_SOCKET, optname)?; - if timeout == 0 { - Ok(None) - } else { - Ok(Some(Duration::from_millis(timeout as u64))) - } - } - } - - #[cfg(any(apple, target_os = "freebsd"))] - #[inline] - pub(crate) fn get_socket_nosigpipe(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE).map(to_bool) - } - - #[cfg(any(apple, target_os = "freebsd"))] - #[inline] - pub(crate) fn set_socket_nosigpipe(fd: BorrowedFd<'_>, val: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE, from_bool(val)) - } - - #[inline] - pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result> { - let err: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_ERROR)?; - Ok(if err == 0 { - Ok(()) - } else { - Err(io::Errno::from_raw_os_error(err)) - }) - } - - #[inline] - pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_KEEPALIVE, - from_bool(keepalive), - ) - } - - #[inline] - pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_KEEPALIVE).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF, size) - } - - #[inline] - pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF).map(|size: u32| size as usize) - } - - #[inline] - pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF, size) - } - - #[inline] - pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF).map(|size: u32| size as usize) - } - - #[inline] - #[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "netbsd", - target_os = "nto", - )))] - pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result { - let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_DOMAIN)?; - Ok(AddressFamily( - domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, - )) - } - - #[inline] - #[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it. - pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_ACCEPTCONN).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE, from_bool(value)) - } - - #[inline] - pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) - } - - #[inline] - pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) - } - - #[inline] - pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IP_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) - } - - #[inline] - pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IPV6 as _, - c::IPV6_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_hops( - fd: BorrowedFd<'_>, - multicast_hops: u32, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IPV6_MULTICAST_HOPS, - multicast_hops, - ) - } - - #[inline] - pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_HOPS) - } - - #[inline] - pub(crate) fn set_ip_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - #[cfg(not(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - )))] - use c::IPV6_ADD_MEMBERSHIP; - #[cfg(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - ))] - use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; - - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ip_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - #[cfg(not(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - )))] - use c::IPV6_DROP_MEMBERSHIP; - #[cfg(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - ))] - use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; - - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) - } - - #[inline] - pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io::Result<()> { - let hops = match hops { - Some(hops) => hops as c::c_int, - None => -1, - }; - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) - } - - #[inline] - pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) - } - - #[inline] - pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT, count) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE, secs) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE)?; - Ok(Duration::from_secs(secs as u64)) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL, secs) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL)?; - Ok(Duration::from_secs(secs as u64)) - } - - #[inline] - fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { - c::ip_mreq { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - } - } - - #[inline] - fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { - in_addr_new(u32::from_ne_bytes(addr.octets())) - } - - #[inline] - fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { - c::ipv6_mreq { - ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), - ipv6mr_interface: to_ipv6mr_interface(interface), - } - } - - #[inline] - fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { - in6_addr_new(multiaddr.octets()) - } - - #[cfg(target_os = "android")] - #[inline] - fn to_ipv6mr_interface(interface: u32) -> c::c_int { - interface as c::c_int - } - - #[cfg(not(target_os = "android"))] - #[inline] - fn to_ipv6mr_interface(interface: u32) -> c::c_uint { - interface as c::c_uint - } - - // `getsockopt` and `setsockopt` represent boolean values as integers. - #[cfg(not(windows))] - type RawSocketBool = c::c_int; - #[cfg(windows)] - type RawSocketBool = BOOL; - - // Wrap `RawSocketBool` in a newtype to discourage misuse. - #[repr(transparent)] - #[derive(Copy, Clone)] - struct SocketBool(RawSocketBool); - - // Convert from a `bool` to a `SocketBool`. - #[inline] - fn from_bool(value: bool) -> SocketBool { - SocketBool(value as _) - } - - // Convert from a `SocketBool` to a `bool`. - #[inline] - fn to_bool(value: SocketBool) -> bool { - value.0 != 0 - } - - /// Convert to seconds, rounding up if necessary. - #[inline] - fn duration_to_secs>(duration: Duration) -> io::Result { - let mut secs = duration.as_secs(); - if duration.subsec_nanos() != 0 { - secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; - } - T::try_from(secs).map_err(|_e| io::Errno::INVAL) - } -} diff --git a/src/backend/linux_raw/net/mod.rs b/src/backend/linux_raw/net/mod.rs index 2b6ab34ba..f83c54621 100644 --- a/src/backend/linux_raw/net/mod.rs +++ b/src/backend/linux_raw/net/mod.rs @@ -2,5 +2,6 @@ pub(crate) mod addr; pub(crate) mod msghdr; pub(crate) mod read_sockaddr; pub(crate) mod send_recv; +pub(crate) mod sockopt; pub(crate) mod syscalls; pub(crate) mod write_sockaddr; diff --git a/src/backend/linux_raw/net/sockopt.rs b/src/backend/linux_raw/net/sockopt.rs new file mode 100644 index 000000000..0b3e96966 --- /dev/null +++ b/src/backend/linux_raw/net/sockopt.rs @@ -0,0 +1,600 @@ +//! linux_raw syscalls supporting `rustix::net::sockopt`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] + +use crate::backend::c; +use crate::backend::conv::{by_mut, by_ref, c_uint, ret, socklen_t}; +use crate::fd::BorrowedFd; +use crate::io; +use crate::net::sockopt::Timeout; +use crate::net::{AddressFamily, Ipv4Addr, Ipv6Addr, SocketType}; +use core::mem::MaybeUninit; +use core::time::Duration; +use linux_raw_sys::general::{__kernel_old_timeval, __kernel_sock_timeval}; + +#[inline] +fn getsockopt(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result { + let mut optlen = core::mem::size_of::(); + debug_assert!( + optlen as usize >= core::mem::size_of::(), + "Socket APIs don't ever use `bool` directly" + ); + + #[cfg(not(target_arch = "x86"))] + unsafe { + let mut value = MaybeUninit::::uninit(); + ret(syscall!( + __NR_getsockopt, + fd, + c_uint(level), + c_uint(optname), + &mut value, + by_mut(&mut optlen) + ))?; + + assert_eq!( + optlen as usize, + core::mem::size_of::(), + "unexpected getsockopt size" + ); + Ok(value.assume_init()) + } + #[cfg(target_arch = "x86")] + unsafe { + let mut value = MaybeUninit::::uninit(); + ret(syscall!( + __NR_socketcall, + x86_sys(SYS_GETSOCKOPT), + slice_just_addr::, _>(&[ + fd.into(), + c_uint(level), + c_uint(optname), + (&mut value).into(), + by_mut(&mut optlen), + ]) + ))?; + assert_eq!( + optlen as usize, + core::mem::size_of::(), + "unexpected getsockopt size" + ); + Ok(value.assume_init()) + } +} + +#[inline] +fn setsockopt(fd: BorrowedFd<'_>, level: u32, optname: u32, value: T) -> io::Result<()> { + let optlen = core::mem::size_of::().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::(), + "Socket APIs don't ever use `bool` directly" + ); + + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!( + __NR_setsockopt, + fd, + c_uint(level), + c_uint(optname), + by_ref(&value), + socklen_t(optlen) + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_SETSOCKOPT), + slice_just_addr::, _>(&[ + fd.into(), + c_uint(level), + c_uint(optname), + by_ref(&value), + socklen_t(optlen), + ]) + )) + } +} + +#[inline] +pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) +} + +#[inline] +pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { + setsockopt( + fd, + c::SOL_SOCKET as _, + c::SO_REUSEADDR, + from_bool(reuseaddr), + ) +} + +#[inline] +pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_REUSEADDR).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { + setsockopt( + fd, + c::SOL_SOCKET as _, + c::SO_BROADCAST, + from_bool(broadcast), + ) +} + +#[inline] +pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_linger(fd: BorrowedFd<'_>, linger: Option) -> io::Result<()> { + // Convert `linger` to seconds, rounding up. + let l_linger = if let Some(linger) = linger { + duration_to_secs(linger)? + } else { + 0 + }; + let linger = c::linger { + l_onoff: c::c_int::from(linger.is_some()), + l_linger, + }; + setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) +} + +#[inline] +pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { + let linger: c::linger = getsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER)?; + Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) +} + +#[inline] +pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) +} + +#[inline] +pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_timeout( + fd: BorrowedFd<'_>, + id: Timeout, + timeout: Option, +) -> io::Result<()> { + let time = duration_to_linux_sock_timeval(timeout)?; + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_NEW, + Timeout::Send => c::SO_SNDTIMEO_NEW, + }; + match setsockopt(fd, c::SOL_SOCKET, optname, time) { + Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { + set_socket_timeout_old(fd, id, timeout) + } + otherwise => otherwise, + } +} + +/// Same as `set_socket_timeout` but uses `__kernel_old_timeval` instead of +/// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. +fn set_socket_timeout_old( + fd: BorrowedFd<'_>, + id: Timeout, + timeout: Option, +) -> io::Result<()> { + let time = duration_to_linux_old_timeval(timeout)?; + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_OLD, + Timeout::Send => c::SO_SNDTIMEO_OLD, + }; + setsockopt(fd, c::SOL_SOCKET, optname, time) +} + +#[inline] +pub(crate) fn get_socket_timeout(fd: BorrowedFd<'_>, id: Timeout) -> io::Result> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_NEW, + Timeout::Send => c::SO_SNDTIMEO_NEW, + }; + let time: __kernel_sock_timeval = match getsockopt(fd, c::SOL_SOCKET, optname) { + Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { + return get_socket_timeout_old(fd, id) + } + otherwise => otherwise?, + }; + Ok(duration_from_linux_sock_timeval(time)) +} + +/// Same as `get_socket_timeout` but uses `__kernel_old_timeval` instead of +/// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. +fn get_socket_timeout_old(fd: BorrowedFd<'_>, id: Timeout) -> io::Result> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_OLD, + Timeout::Send => c::SO_SNDTIMEO_OLD, + }; + let time: __kernel_old_timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; + Ok(duration_from_linux_old_timeval(time)) +} + +/// Convert a `__linux_sock_timeval` to a Rust `Option`. +#[inline] +fn duration_from_linux_sock_timeval(time: __kernel_sock_timeval) -> Option { + if time.tv_sec == 0 && time.tv_usec == 0 { + None + } else { + Some(Duration::from_secs(time.tv_sec as u64) + Duration::from_micros(time.tv_usec as u64)) + } +} + +/// Like `duration_from_linux` but uses Linux's old 32-bit +/// `__kernel_old_timeval`. +fn duration_from_linux_old_timeval(time: __kernel_old_timeval) -> Option { + if time.tv_sec == 0 && time.tv_usec == 0 { + None + } else { + Some(Duration::from_secs(time.tv_sec as u64) + Duration::from_micros(time.tv_usec as u64)) + } +} + +/// Convert a Rust `Option` to a `__kernel_sock_timeval`. +#[inline] +fn duration_to_linux_sock_timeval(timeout: Option) -> io::Result<__kernel_sock_timeval> { + Ok(match timeout { + Some(timeout) => { + if timeout == Duration::ZERO { + return Err(io::Errno::INVAL); + } + // `subsec_micros` rounds down, so we use `subsec_nanos` and + // manually round up. + let mut timeout = __kernel_sock_timeval { + tv_sec: timeout.as_secs().try_into().unwrap_or(i64::MAX), + tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => __kernel_sock_timeval { + tv_sec: 0, + tv_usec: 0, + }, + }) +} + +/// Like `duration_to_linux` but uses Linux's old 32-bit +/// `__kernel_old_timeval`. +fn duration_to_linux_old_timeval(timeout: Option) -> io::Result<__kernel_old_timeval> { + Ok(match timeout { + Some(timeout) => { + if timeout == Duration::ZERO { + return Err(io::Errno::INVAL); + } + + // `subsec_micros` rounds down, so we use `subsec_nanos` and + // manually round up. + let mut timeout = __kernel_old_timeval { + tv_sec: timeout.as_secs().try_into().unwrap_or(c::c_long::MAX), + tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => __kernel_old_timeval { + tv_sec: 0, + tv_usec: 0, + }, + }) +} + +#[inline] +pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result> { + let err: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_ERROR)?; + Ok(if err == 0 { + Ok(()) + } else { + Err(io::Errno::from_raw_os_error(err)) + }) +} + +#[inline] +pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { + setsockopt( + fd, + c::SOL_SOCKET as _, + c::SO_KEEPALIVE, + from_bool(keepalive), + ) +} + +#[inline] +pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_KEEPALIVE).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::OVERFLOW)?; + setsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF, size) +} + +#[inline] +pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF).map(|size: u32| size as usize) +} + +#[inline] +pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::OVERFLOW)?; + setsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF, size) +} + +#[inline] +pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF).map(|size: u32| size as usize) +} + +#[inline] +pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result { + let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_DOMAIN)?; + Ok(AddressFamily( + domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, + )) +} + +#[inline] +pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_ACCEPTCONN).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE, from_bool(value)) +} + +#[inline] +pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) +} + +#[inline] +pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) +} + +#[inline] +pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) +} + +#[inline] +pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IP as _, + c::IP_MULTICAST_LOOP, + from_bool(multicast_loop), + ) +} + +#[inline] +pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) +} + +#[inline] +pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) +} + +#[inline] +pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IPV6 as _, + c::IPV6_MULTICAST_LOOP, + from_bool(multicast_loop), + ) +} + +#[inline] +pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) +} + +#[inline] +pub(crate) fn set_ipv6_multicast_hops(fd: BorrowedFd<'_>, multicast_hops: u32) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IP as _, + c::IPV6_MULTICAST_HOPS, + multicast_hops, + ) +} + +#[inline] +pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_HOPS) +} + +#[inline] +pub(crate) fn set_ip_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, +) -> io::Result<()> { + let mreq = to_imr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ipv6_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, +) -> io::Result<()> { + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_ADD_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ip_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, +) -> io::Result<()> { + let mreq = to_imr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ipv6_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, +) -> io::Result<()> { + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_DROP_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) +} + +#[inline] +pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io::Result<()> { + let hops = match hops { + Some(hops) => hops.into(), + None => -1, + }; + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) +} + +#[inline] +pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) +} + +#[inline] +pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) +} + +#[inline] +pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT, count) +} + +#[inline] +pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT) +} + +#[inline] +pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { + let secs: c::c_uint = duration_to_secs(duration)?; + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPIDLE, secs) +} + +#[inline] +pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result { + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPIDLE)?; + Ok(Duration::from_secs(secs as u64)) +} + +#[inline] +pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { + let secs: c::c_uint = duration_to_secs(duration)?; + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL, secs) +} + +#[inline] +pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL)?; + Ok(Duration::from_secs(secs as u64)) +} + +#[inline] +fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { + c::ip_mreq { + imr_multiaddr: to_imr_addr(multiaddr), + imr_interface: to_imr_addr(interface), + } +} + +#[inline] +fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { + c::in_addr { + s_addr: u32::from_ne_bytes(addr.octets()), + } +} + +#[inline] +fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { + c::ipv6_mreq { + ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), + ipv6mr_ifindex: to_ipv6mr_interface(interface), + } +} + +#[inline] +fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { + c::in6_addr { + in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { + u6_addr8: multiaddr.octets(), + }, + } +} + +#[inline] +fn to_ipv6mr_interface(interface: u32) -> c::c_int { + interface as c::c_int +} + +#[inline] +fn from_bool(value: bool) -> c::c_uint { + c::c_uint::from(value) +} + +#[inline] +fn to_bool(value: c::c_uint) -> bool { + value != 0 +} + +/// Convert to seconds, rounding up if necessary. +#[inline] +fn duration_to_secs>(duration: Duration) -> io::Result { + let mut secs = duration.as_secs(); + if duration.subsec_nanos() != 0 { + secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; + } + T::try_from(secs).map_err(|_e| io::Errno::INVAL) +} diff --git a/src/backend/linux_raw/net/syscalls.rs b/src/backend/linux_raw/net/syscalls.rs index df32c8048..e2aa9f786 100644 --- a/src/backend/linux_raw/net/syscalls.rs +++ b/src/backend/linux_raw/net/syscalls.rs @@ -919,630 +919,3 @@ pub(crate) fn listen(fd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { )) } } - -pub(crate) mod sockopt { - use super::{c, BorrowedFd}; - use crate::io; - use crate::net::sockopt::Timeout; - use crate::net::{AddressFamily, Ipv4Addr, Ipv6Addr, SocketType}; - use core::time::Duration; - use linux_raw_sys::general::{__kernel_old_timeval, __kernel_sock_timeval}; - - #[inline] - fn getsockopt(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result { - use super::*; - - let mut optlen = core::mem::size_of::(); - debug_assert!( - optlen as usize >= core::mem::size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut value = MaybeUninit::::uninit(); - ret(syscall!( - __NR_getsockopt, - fd, - c_uint(level), - c_uint(optname), - &mut value, - by_mut(&mut optlen) - ))?; - - assert_eq!( - optlen as usize, - core::mem::size_of::(), - "unexpected getsockopt size" - ); - Ok(value.assume_init()) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut value = MaybeUninit::::uninit(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETSOCKOPT), - slice_just_addr::, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - (&mut value).into(), - by_mut(&mut optlen), - ]) - ))?; - assert_eq!( - optlen as usize, - core::mem::size_of::(), - "unexpected getsockopt size" - ); - Ok(value.assume_init()) - } - } - - #[inline] - fn setsockopt( - fd: BorrowedFd<'_>, - level: u32, - optname: u32, - value: T, - ) -> io::Result<()> { - use super::*; - - let optlen = core::mem::size_of::().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_setsockopt, - fd, - c_uint(level), - c_uint(optname), - by_ref(&value), - socklen_t(optlen) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SETSOCKOPT), - slice_just_addr::, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - by_ref(&value), - socklen_t(optlen), - ]) - )) - } - } - - #[inline] - pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) - } - - #[inline] - pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_REUSEADDR, - from_bool(reuseaddr), - ) - } - - #[inline] - pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_REUSEADDR).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_BROADCAST, - from_bool(broadcast), - ) - } - - #[inline] - pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_linger( - fd: BorrowedFd<'_>, - linger: Option, - ) -> io::Result<()> { - // Convert `linger` to seconds, rounding up. - let l_linger = if let Some(linger) = linger { - duration_to_secs(linger)? - } else { - 0 - }; - let linger = c::linger { - l_onoff: c::c_int::from(linger.is_some()), - l_linger, - }; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) - } - - #[inline] - pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { - let linger: c::linger = getsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER)?; - Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) - } - - #[inline] - pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) - } - - #[inline] - pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option, - ) -> io::Result<()> { - let time = duration_to_linux_sock_timeval(timeout)?; - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_NEW, - Timeout::Send => c::SO_SNDTIMEO_NEW, - }; - match setsockopt(fd, c::SOL_SOCKET, optname, time) { - Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { - set_socket_timeout_old(fd, id, timeout) - } - otherwise => otherwise, - } - } - - /// Same as `set_socket_timeout` but uses `__kernel_old_timeval` instead of - /// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. - fn set_socket_timeout_old( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option, - ) -> io::Result<()> { - let time = duration_to_linux_old_timeval(timeout)?; - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_OLD, - Timeout::Send => c::SO_SNDTIMEO_OLD, - }; - setsockopt(fd, c::SOL_SOCKET, optname, time) - } - - #[inline] - pub(crate) fn get_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - ) -> io::Result> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_NEW, - Timeout::Send => c::SO_SNDTIMEO_NEW, - }; - let time: __kernel_sock_timeval = match getsockopt(fd, c::SOL_SOCKET, optname) { - Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { - return get_socket_timeout_old(fd, id) - } - otherwise => otherwise?, - }; - Ok(duration_from_linux_sock_timeval(time)) - } - - /// Same as `get_socket_timeout` but uses `__kernel_old_timeval` instead of - /// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. - fn get_socket_timeout_old(fd: BorrowedFd<'_>, id: Timeout) -> io::Result> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_OLD, - Timeout::Send => c::SO_SNDTIMEO_OLD, - }; - let time: __kernel_old_timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; - Ok(duration_from_linux_old_timeval(time)) - } - - /// Convert a `__linux_sock_timeval` to a Rust `Option`. - #[inline] - fn duration_from_linux_sock_timeval(time: __kernel_sock_timeval) -> Option { - if time.tv_sec == 0 && time.tv_usec == 0 { - None - } else { - Some( - Duration::from_secs(time.tv_sec as u64) - + Duration::from_micros(time.tv_usec as u64), - ) - } - } - - /// Like `duration_from_linux` but uses Linux's old 32-bit - /// `__kernel_old_timeval`. - fn duration_from_linux_old_timeval(time: __kernel_old_timeval) -> Option { - if time.tv_sec == 0 && time.tv_usec == 0 { - None - } else { - Some( - Duration::from_secs(time.tv_sec as u64) - + Duration::from_micros(time.tv_usec as u64), - ) - } - } - - /// Convert a Rust `Option` to a `__kernel_sock_timeval`. - #[inline] - fn duration_to_linux_sock_timeval( - timeout: Option, - ) -> io::Result<__kernel_sock_timeval> { - Ok(match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = __kernel_sock_timeval { - tv_sec: timeout.as_secs().try_into().unwrap_or(i64::MAX), - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => __kernel_sock_timeval { - tv_sec: 0, - tv_usec: 0, - }, - }) - } - - /// Like `duration_to_linux` but uses Linux's old 32-bit - /// `__kernel_old_timeval`. - fn duration_to_linux_old_timeval( - timeout: Option, - ) -> io::Result<__kernel_old_timeval> { - Ok(match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = __kernel_old_timeval { - tv_sec: timeout.as_secs().try_into().unwrap_or(c::c_long::MAX), - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => __kernel_old_timeval { - tv_sec: 0, - tv_usec: 0, - }, - }) - } - - #[inline] - pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result> { - let err: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_ERROR)?; - Ok(if err == 0 { - Ok(()) - } else { - Err(io::Errno::from_raw_os_error(err)) - }) - } - - #[inline] - pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_KEEPALIVE, - from_bool(keepalive), - ) - } - - #[inline] - pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_KEEPALIVE).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::OVERFLOW)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF, size) - } - - #[inline] - pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF).map(|size: u32| size as usize) - } - - #[inline] - pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::OVERFLOW)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF, size) - } - - #[inline] - pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF).map(|size: u32| size as usize) - } - - #[inline] - pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result { - let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_DOMAIN)?; - Ok(AddressFamily( - domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, - )) - } - - #[inline] - pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_ACCEPTCONN).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE, from_bool(value)) - } - - #[inline] - pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) - } - - #[inline] - pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) - } - - #[inline] - pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IP_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) - } - - #[inline] - pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IPV6 as _, - c::IPV6_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_hops( - fd: BorrowedFd<'_>, - multicast_hops: u32, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IPV6_MULTICAST_HOPS, - multicast_hops, - ) - } - - #[inline] - pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_HOPS) - } - - #[inline] - pub(crate) fn set_ip_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ip_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) - } - - #[inline] - pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io::Result<()> { - let hops = match hops { - Some(hops) => hops.into(), - None => -1, - }; - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) - } - - #[inline] - pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) - } - - #[inline] - pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) - } - - #[inline] - pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT, count) - } - - #[inline] - pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT) - } - - #[inline] - pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPIDLE, secs) - } - - #[inline] - pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPIDLE)?; - Ok(Duration::from_secs(secs as u64)) - } - - #[inline] - pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL, secs) - } - - #[inline] - pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL)?; - Ok(Duration::from_secs(secs as u64)) - } - - #[inline] - fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { - c::ip_mreq { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - } - } - - #[inline] - fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { - c::in_addr { - s_addr: u32::from_ne_bytes(addr.octets()), - } - } - - #[inline] - fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { - c::ipv6_mreq { - ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), - ipv6mr_ifindex: to_ipv6mr_interface(interface), - } - } - - #[inline] - fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { - c::in6_addr { - in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { - u6_addr8: multiaddr.octets(), - }, - } - } - - #[inline] - fn to_ipv6mr_interface(interface: u32) -> c::c_int { - interface as c::c_int - } - - #[inline] - fn from_bool(value: bool) -> c::c_uint { - c::c_uint::from(value) - } - - #[inline] - fn to_bool(value: c::c_uint) -> bool { - value != 0 - } - - /// Convert to seconds, rounding up if necessary. - #[inline] - fn duration_to_secs>(duration: Duration) -> io::Result { - let mut secs = duration.as_secs(); - if duration.subsec_nanos() != 0 { - secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; - } - T::try_from(secs).map_err(|_e| io::Errno::INVAL) - } -} diff --git a/src/net/sockopt.rs b/src/net/sockopt.rs index d7bb1deed..b9d7829ea 100644 --- a/src/net/sockopt.rs +++ b/src/net/sockopt.rs @@ -181,7 +181,7 @@ pub enum Timeout { #[inline] #[doc(alias = "SO_TYPE")] pub fn get_socket_type(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_socket_type(fd.as_fd()) + backend::net::sockopt::get_socket_type(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, value)`—Set whether local @@ -193,7 +193,7 @@ pub fn get_socket_type(fd: Fd) -> io::Result { #[inline] #[doc(alias = "SO_REUSEADDR")] pub fn set_socket_reuseaddr(fd: Fd, value: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_reuseaddr(fd.as_fd(), value) + backend::net::sockopt::set_socket_reuseaddr(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_REUSEADDR)` @@ -204,7 +204,7 @@ pub fn set_socket_reuseaddr(fd: Fd, value: bool) -> io::Result<()> { #[inline] #[doc(alias = "SO_REUSEADDR")] pub fn get_socket_reuseaddr(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_socket_reuseaddr(fd.as_fd()) + backend::net::sockopt::get_socket_reuseaddr(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, SO_BROADCAST, broadcast)` @@ -215,7 +215,7 @@ pub fn get_socket_reuseaddr(fd: Fd) -> io::Result { #[inline] #[doc(alias = "SO_BROADCAST")] pub fn set_socket_broadcast(fd: Fd, value: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_broadcast(fd.as_fd(), value) + backend::net::sockopt::set_socket_broadcast(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_BROADCAST)` @@ -226,7 +226,7 @@ pub fn set_socket_broadcast(fd: Fd, value: bool) -> io::Result<()> { #[inline] #[doc(alias = "SO_BROADCAST")] pub fn get_socket_broadcast(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_socket_broadcast(fd.as_fd()) + backend::net::sockopt::get_socket_broadcast(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, SO_LINGER, value)` @@ -237,7 +237,7 @@ pub fn get_socket_broadcast(fd: Fd) -> io::Result { #[inline] #[doc(alias = "SO_LINGER")] pub fn set_socket_linger(fd: Fd, value: Option) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_linger(fd.as_fd(), value) + backend::net::sockopt::set_socket_linger(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_LINGER)` @@ -248,7 +248,7 @@ pub fn set_socket_linger(fd: Fd, value: Option) -> io::Resul #[inline] #[doc(alias = "SO_LINGER")] pub fn get_socket_linger(fd: Fd) -> io::Result> { - backend::net::syscalls::sockopt::get_socket_linger(fd.as_fd()) + backend::net::sockopt::get_socket_linger(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, SO_PASSCRED, value)` @@ -260,7 +260,7 @@ pub fn get_socket_linger(fd: Fd) -> io::Result> { #[inline] #[doc(alias = "SO_PASSCRED")] pub fn set_socket_passcred(fd: Fd, value: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_passcred(fd.as_fd(), value) + backend::net::sockopt::set_socket_passcred(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_PASSCRED)` @@ -272,7 +272,7 @@ pub fn set_socket_passcred(fd: Fd, value: bool) -> io::Result<()> { #[inline] #[doc(alias = "SO_PASSCRED")] pub fn get_socket_passcred(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_socket_passcred(fd.as_fd()) + backend::net::sockopt::get_socket_passcred(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, id, timeout)`—Set the sending or receiving @@ -289,7 +289,7 @@ pub fn set_socket_timeout( id: Timeout, timeout: Option, ) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_timeout(fd.as_fd(), id, timeout) + backend::net::sockopt::set_socket_timeout(fd.as_fd(), id, timeout) } /// `getsockopt(fd, SOL_SOCKET, id)`—Get the sending or receiving timeout. @@ -301,7 +301,7 @@ pub fn set_socket_timeout( #[doc(alias = "SO_RCVTIMEO")] #[doc(alias = "SO_SNDTIMEO")] pub fn get_socket_timeout(fd: Fd, id: Timeout) -> io::Result> { - backend::net::syscalls::sockopt::get_socket_timeout(fd.as_fd(), id) + backend::net::sockopt::get_socket_timeout(fd.as_fd(), id) } /// `getsockopt(fd, SOL_SOCKET, SO_ERROR)` @@ -312,7 +312,7 @@ pub fn get_socket_timeout(fd: Fd, id: Timeout) -> io::Result(fd: Fd) -> io::Result> { - backend::net::syscalls::sockopt::get_socket_error(fd.as_fd()) + backend::net::sockopt::get_socket_error(fd.as_fd()) } /// `getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE)` @@ -324,7 +324,7 @@ pub fn get_socket_error(fd: Fd) -> io::Result> { #[doc(alias = "SO_NOSIGPIPE")] #[inline] pub fn get_socket_nosigpipe(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_socket_nosigpipe(fd.as_fd()) + backend::net::sockopt::get_socket_nosigpipe(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, value)` @@ -336,7 +336,7 @@ pub fn get_socket_nosigpipe(fd: Fd) -> io::Result { #[doc(alias = "SO_NOSIGPIPE")] #[inline] pub fn set_socket_nosigpipe(fd: Fd, value: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_nosigpipe(fd.as_fd(), value) + backend::net::sockopt::set_socket_nosigpipe(fd.as_fd(), value) } /// `setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, value)` @@ -347,7 +347,7 @@ pub fn set_socket_nosigpipe(fd: Fd, value: bool) -> io::Result<()> { #[inline] #[doc(alias = "SO_KEEPALIVE")] pub fn set_socket_keepalive(fd: Fd, value: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_keepalive(fd.as_fd(), value) + backend::net::sockopt::set_socket_keepalive(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE)` @@ -358,7 +358,7 @@ pub fn set_socket_keepalive(fd: Fd, value: bool) -> io::Result<()> { #[inline] #[doc(alias = "SO_KEEPALIVE")] pub fn get_socket_keepalive(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_socket_keepalive(fd.as_fd()) + backend::net::sockopt::get_socket_keepalive(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, SO_RCVBUF, value)` @@ -369,7 +369,7 @@ pub fn get_socket_keepalive(fd: Fd) -> io::Result { #[inline] #[doc(alias = "SO_RCVBUF")] pub fn set_socket_recv_buffer_size(fd: Fd, value: usize) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_recv_buffer_size(fd.as_fd(), value) + backend::net::sockopt::set_socket_recv_buffer_size(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_RCVBUF)` @@ -380,7 +380,7 @@ pub fn set_socket_recv_buffer_size(fd: Fd, value: usize) -> io::Result #[inline] #[doc(alias = "SO_RCVBUF")] pub fn get_socket_recv_buffer_size(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_socket_recv_buffer_size(fd.as_fd()) + backend::net::sockopt::get_socket_recv_buffer_size(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, SO_SNDBUF, value)` @@ -391,7 +391,7 @@ pub fn get_socket_recv_buffer_size(fd: Fd) -> io::Result { #[inline] #[doc(alias = "SO_SNDBUF")] pub fn set_socket_send_buffer_size(fd: Fd, value: usize) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_send_buffer_size(fd.as_fd(), value) + backend::net::sockopt::set_socket_send_buffer_size(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_SNDBUF)` @@ -402,7 +402,7 @@ pub fn set_socket_send_buffer_size(fd: Fd, value: usize) -> io::Result #[inline] #[doc(alias = "SO_SNDBUF")] pub fn get_socket_send_buffer_size(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_socket_send_buffer_size(fd.as_fd()) + backend::net::sockopt::get_socket_send_buffer_size(fd.as_fd()) } /// `getsockopt(fd, SOL_SOCKET, SO_DOMAIN)` @@ -424,7 +424,7 @@ pub fn get_socket_send_buffer_size(fd: Fd) -> io::Result { #[inline] #[doc(alias = "SO_DOMAIN")] pub fn get_socket_domain(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_socket_domain(fd.as_fd()) + backend::net::sockopt::get_socket_domain(fd.as_fd()) } /// `getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN)` @@ -436,7 +436,7 @@ pub fn get_socket_domain(fd: Fd) -> io::Result { #[inline] #[doc(alias = "SO_ACCEPTCONN")] pub fn get_socket_acceptconn(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_socket_acceptconn(fd.as_fd()) + backend::net::sockopt::get_socket_acceptconn(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, value)` @@ -447,7 +447,7 @@ pub fn get_socket_acceptconn(fd: Fd) -> io::Result { #[inline] #[doc(alias = "SO_OOBINLINE")] pub fn set_socket_oobinline(fd: Fd, value: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_oobinline(fd.as_fd(), value) + backend::net::sockopt::set_socket_oobinline(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_OOBINLINE)` @@ -458,7 +458,7 @@ pub fn set_socket_oobinline(fd: Fd, value: bool) -> io::Result<()> { #[inline] #[doc(alias = "SO_OOBINLINE")] pub fn get_socket_oobinline(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_socket_oobinline(fd.as_fd()) + backend::net::sockopt::get_socket_oobinline(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IP, IP_TTL, value)` @@ -469,7 +469,7 @@ pub fn get_socket_oobinline(fd: Fd) -> io::Result { #[inline] #[doc(alias = "IP_TTL")] pub fn set_ip_ttl(fd: Fd, value: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_ttl(fd.as_fd(), value) + backend::net::sockopt::set_ip_ttl(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IP, IP_TTL)` @@ -480,7 +480,7 @@ pub fn set_ip_ttl(fd: Fd, value: u32) -> io::Result<()> { #[inline] #[doc(alias = "IP_TTL")] pub fn get_ip_ttl(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_ip_ttl(fd.as_fd()) + backend::net::sockopt::get_ip_ttl(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, only_v6)` @@ -491,7 +491,7 @@ pub fn get_ip_ttl(fd: Fd) -> io::Result { #[inline] #[doc(alias = "IPV6_V6ONLY")] pub fn set_ipv6_v6only(fd: Fd, value: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_v6only(fd.as_fd(), value) + backend::net::sockopt::set_ipv6_v6only(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY)` @@ -502,7 +502,7 @@ pub fn set_ipv6_v6only(fd: Fd, value: bool) -> io::Result<()> { #[inline] #[doc(alias = "IPV6_V6ONLY")] pub fn get_ipv6_v6only(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_ipv6_v6only(fd.as_fd()) + backend::net::sockopt::get_ipv6_v6only(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, value)` @@ -513,7 +513,7 @@ pub fn get_ipv6_v6only(fd: Fd) -> io::Result { #[inline] #[doc(alias = "IP_MULTICAST_LOOP")] pub fn set_ip_multicast_loop(fd: Fd, value: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_multicast_loop(fd.as_fd(), value) + backend::net::sockopt::set_ip_multicast_loop(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP)` @@ -524,7 +524,7 @@ pub fn set_ip_multicast_loop(fd: Fd, value: bool) -> io::Result<()> { #[inline] #[doc(alias = "IP_MULTICAST_LOOP")] pub fn get_ip_multicast_loop(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_ip_multicast_loop(fd.as_fd()) + backend::net::sockopt::get_ip_multicast_loop(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, value)` @@ -535,7 +535,7 @@ pub fn get_ip_multicast_loop(fd: Fd) -> io::Result { #[inline] #[doc(alias = "IP_MULTICAST_TTL")] pub fn set_ip_multicast_ttl(fd: Fd, value: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_multicast_ttl(fd.as_fd(), value) + backend::net::sockopt::set_ip_multicast_ttl(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL)` @@ -546,7 +546,7 @@ pub fn set_ip_multicast_ttl(fd: Fd, value: u32) -> io::Result<()> { #[inline] #[doc(alias = "IP_MULTICAST_TTL")] pub fn get_ip_multicast_ttl(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_ip_multicast_ttl(fd.as_fd()) + backend::net::sockopt::get_ip_multicast_ttl(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, value)` @@ -557,7 +557,7 @@ pub fn get_ip_multicast_ttl(fd: Fd) -> io::Result { #[inline] #[doc(alias = "IPV6_MULTICAST_LOOP")] pub fn set_ipv6_multicast_loop(fd: Fd, value: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_multicast_loop(fd.as_fd(), value) + backend::net::sockopt::set_ipv6_multicast_loop(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP)` @@ -568,7 +568,7 @@ pub fn set_ipv6_multicast_loop(fd: Fd, value: bool) -> io::Result<()> #[inline] #[doc(alias = "IPV6_MULTICAST_LOOP")] pub fn get_ipv6_multicast_loop(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_ipv6_multicast_loop(fd.as_fd()) + backend::net::sockopt::get_ipv6_multicast_loop(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, multicast_hops)` @@ -579,7 +579,7 @@ pub fn get_ipv6_multicast_loop(fd: Fd) -> io::Result { #[inline] #[doc(alias = "IP_MULTICAST_TTL")] pub fn set_ipv6_multicast_hops(fd: Fd, value: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_multicast_hops(fd.as_fd(), value) + backend::net::sockopt::set_ipv6_multicast_hops(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS)` @@ -590,7 +590,7 @@ pub fn set_ipv6_multicast_hops(fd: Fd, value: u32) -> io::Result<()> { #[inline] #[doc(alias = "IPV6_UNICAST_HOPS")] pub fn get_ipv6_unicast_hops(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_ipv6_unicast_hops(fd.as_fd()) + backend::net::sockopt::get_ipv6_unicast_hops(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, unicast_hops)` @@ -601,7 +601,7 @@ pub fn get_ipv6_unicast_hops(fd: Fd) -> io::Result { #[inline] #[doc(alias = "IPV6_UNICAST_HOPS")] pub fn set_ipv6_unicast_hops(fd: Fd, value: Option) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_unicast_hops(fd.as_fd(), value) + backend::net::sockopt::set_ipv6_unicast_hops(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS)` @@ -612,7 +612,7 @@ pub fn set_ipv6_unicast_hops(fd: Fd, value: Option) -> io::Result< #[inline] #[doc(alias = "IP_MULTICAST_TTL")] pub fn get_ipv6_multicast_hops(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_ipv6_multicast_hops(fd.as_fd()) + backend::net::sockopt::get_ipv6_multicast_hops(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, interface)` @@ -627,7 +627,7 @@ pub fn set_ip_add_membership( multiaddr: &Ipv4Addr, interface: &Ipv4Addr, ) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface) + backend::net::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, multiaddr, interface)` @@ -643,7 +643,7 @@ pub fn set_ipv6_add_membership( multiaddr: &Ipv6Addr, interface: u32, ) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_add_membership(fd.as_fd(), multiaddr, interface) + backend::net::sockopt::set_ipv6_add_membership(fd.as_fd(), multiaddr, interface) } /// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)` @@ -658,7 +658,7 @@ pub fn set_ip_drop_membership( multiaddr: &Ipv4Addr, interface: &Ipv4Addr, ) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_drop_membership(fd.as_fd(), multiaddr, interface) + backend::net::sockopt::set_ip_drop_membership(fd.as_fd(), multiaddr, interface) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, multiaddr, interface)` @@ -674,7 +674,7 @@ pub fn set_ipv6_drop_membership( multiaddr: &Ipv6Addr, interface: u32, ) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface) + backend::net::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface) } /// `setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, value)` @@ -685,7 +685,7 @@ pub fn set_ipv6_drop_membership( #[inline] #[doc(alias = "TCP_NODELAY")] pub fn set_tcp_nodelay(fd: Fd, value: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_nodelay(fd.as_fd(), value) + backend::net::sockopt::set_tcp_nodelay(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_NODELAY)` @@ -696,7 +696,7 @@ pub fn set_tcp_nodelay(fd: Fd, value: bool) -> io::Result<()> { #[inline] #[doc(alias = "TCP_NODELAY")] pub fn get_tcp_nodelay(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_tcp_nodelay(fd.as_fd()) + backend::net::sockopt::get_tcp_nodelay(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, value)` @@ -708,7 +708,7 @@ pub fn get_tcp_nodelay(fd: Fd) -> io::Result { #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPCNT")] pub fn set_tcp_keepcnt(fd: Fd, value: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_keepcnt(fd.as_fd(), value) + backend::net::sockopt::set_tcp_keepcnt(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT)` @@ -720,7 +720,7 @@ pub fn set_tcp_keepcnt(fd: Fd, value: u32) -> io::Result<()> { #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPCNT")] pub fn get_tcp_keepcnt(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_tcp_keepcnt(fd.as_fd()) + backend::net::sockopt::get_tcp_keepcnt(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, value)` @@ -734,7 +734,7 @@ pub fn get_tcp_keepcnt(fd: Fd) -> io::Result { #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPIDLE")] pub fn set_tcp_keepidle(fd: Fd, value: Duration) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_keepidle(fd.as_fd(), value) + backend::net::sockopt::set_tcp_keepidle(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE)` @@ -748,7 +748,7 @@ pub fn set_tcp_keepidle(fd: Fd, value: Duration) -> io::Result<()> { #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPIDLE")] pub fn get_tcp_keepidle(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_tcp_keepidle(fd.as_fd()) + backend::net::sockopt::get_tcp_keepidle(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, value)` @@ -760,7 +760,7 @@ pub fn get_tcp_keepidle(fd: Fd) -> io::Result { #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPINTVL")] pub fn set_tcp_keepintvl(fd: Fd, value: Duration) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_keepintvl(fd.as_fd(), value) + backend::net::sockopt::set_tcp_keepintvl(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL)` @@ -772,7 +772,7 @@ pub fn set_tcp_keepintvl(fd: Fd, value: Duration) -> io::Result<()> { #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] #[doc(alias = "TCP_KEEPINTVL")] pub fn get_tcp_keepintvl(fd: Fd) -> io::Result { - backend::net::syscalls::sockopt::get_tcp_keepintvl(fd.as_fd()) + backend::net::sockopt::get_tcp_keepintvl(fd.as_fd()) } #[test] From 305fe73a0819d4988617a2c1edabebd9e623d20e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 26 Sep 2023 23:45:54 -0700 Subject: [PATCH 04/15] Use `EINVAL` for reporting invalid `setsockopt` values. --- src/backend/linux_raw/net/sockopt.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/linux_raw/net/sockopt.rs b/src/backend/linux_raw/net/sockopt.rs index 0b3e96966..21354c9b1 100644 --- a/src/backend/linux_raw/net/sockopt.rs +++ b/src/backend/linux_raw/net/sockopt.rs @@ -326,7 +326,7 @@ pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result { #[inline] pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::OVERFLOW)?; + let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; setsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF, size) } @@ -337,7 +337,7 @@ pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::OVERFLOW)?; + let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; setsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF, size) } From 74670a72ca48f556c342408051c4cb757482f34f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 26 Sep 2023 23:53:16 -0700 Subject: [PATCH 05/15] Implement several more socket options. Implement TCP_USER_TIMEOUT, IP_TOS, IPV6_RECVTCLASS, IP_RECVTOS, and IP_ADD_SOURCE_MEMBERSHIP. --- src/backend/libc/net/sockopt.rs | 71 ++++++++++++++ src/backend/linux_raw/c.rs | 29 +++--- src/backend/linux_raw/net/sockopt.rs | 69 ++++++++++++++ src/net/sockopt.rs | 135 ++++++++++++++++++++++++--- 4 files changed, 278 insertions(+), 26 deletions(-) diff --git a/src/backend/libc/net/sockopt.rs b/src/backend/libc/net/sockopt.rs index d9ec78cc7..4e75399f9 100644 --- a/src/backend/libc/net/sockopt.rs +++ b/src/backend/libc/net/sockopt.rs @@ -421,6 +421,22 @@ pub(crate) fn set_ip_add_membership( setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) } +#[inline] +pub(crate) fn set_ip_add_source_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); + setsockopt( + fd, + c::IPPROTO_IP as _, + c::IP_ADD_SOURCE_MEMBERSHIP, + mreq_source, + ) +} + #[inline] pub(crate) fn set_ipv6_add_membership( fd: BorrowedFd<'_>, @@ -499,6 +515,36 @@ pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io: setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) } +#[inline] +pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_TOS, value) +} + +#[inline] +pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_TOS) +} + +#[inline] +pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_RECVTOS, value) +} + +#[inline] +pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_RECVTOS).map(|value: i32| value > 0) +} + +#[inline] +pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_RECVTCLASS, value) +} + +#[inline] +pub(crate) fn get_ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_RECVTCLASS).map(|value: i32| value > 0) +} + #[inline] pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) @@ -549,6 +595,18 @@ pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { Ok(Duration::from_secs(secs as u64)) } +#[inline] +#[cfg(any(linux_like, target_os = "fuchsia"))] +pub(crate) fn set_tcp_user_timeout(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_USER_TIMEOUT, value) +} + +#[inline] +#[cfg(any(linux_like, target_os = "fuchsia"))] +pub(crate) fn get_tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_USER_TIMEOUT) +} + #[inline] fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { c::ip_mreq { @@ -557,6 +615,19 @@ fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { } } +#[inline] +fn to_imr_source( + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> c::ip_mreq_source { + c::ip_mreq_source { + imr_multiaddr: to_imr_addr(multiaddr), + imr_interface: to_imr_addr(interface), + imr_sourceaddr: to_imr_addr(sourceaddr), + } +} + #[inline] fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { in_addr_new(u32::from_ne_bytes(addr.octets())) diff --git a/src/backend/linux_raw/c.rs b/src/backend/linux_raw/c.rs index dc900e430..aed0e1e79 100644 --- a/src/backend/linux_raw/c.rs +++ b/src/backend/linux_raw/c.rs @@ -53,26 +53,27 @@ pub(crate) use linux_raw_sys::{ net::{ AF_DECnet, __kernel_sa_family_t as sa_family_t, __kernel_sockaddr_storage as sockaddr_storage, cmsghdr, in6_addr, in_addr, ip_mreq, - ipv6_mreq, linger, msghdr, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_un, socklen_t, - AF_APPLETALK, AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, AF_BLUETOOTH, AF_BRIDGE, AF_CAN, - AF_ECONET, AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_ISDN, AF_IUCV, AF_KEY, - AF_LLC, AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, AF_PPPOX, AF_RDS, AF_ROSE, - AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, AF_WANPIPE, AF_X25, IPPROTO_AH, - IPPROTO_BEETPH, IPPROTO_COMP, IPPROTO_DCCP, IPPROTO_EGP, IPPROTO_ENCAP, IPPROTO_ESP, - IPPROTO_ETHERNET, IPPROTO_FRAGMENT, IPPROTO_GRE, IPPROTO_ICMP, IPPROTO_ICMPV6, IPPROTO_IDP, - IPPROTO_IGMP, IPPROTO_IP, IPPROTO_IPIP, IPPROTO_IPV6, IPPROTO_MH, IPPROTO_MPLS, - IPPROTO_MPTCP, IPPROTO_MTP, IPPROTO_PIM, IPPROTO_PUP, IPPROTO_RAW, IPPROTO_ROUTING, - IPPROTO_RSVP, IPPROTO_SCTP, IPPROTO_TCP, IPPROTO_TP, IPPROTO_UDP, IPPROTO_UDPLITE, - IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_HOPS, IPV6_MULTICAST_LOOP, - IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, - IP_MULTICAST_TTL, IP_TTL, MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, + ip_mreq_source, ipv6_mreq, linger, msghdr, sockaddr, sockaddr_in, sockaddr_in6, + sockaddr_un, socklen_t, AF_APPLETALK, AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, AF_BLUETOOTH, + AF_BRIDGE, AF_CAN, AF_ECONET, AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_ISDN, + AF_IUCV, AF_KEY, AF_LLC, AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, AF_PPPOX, + AF_RDS, AF_ROSE, AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, AF_WANPIPE, + AF_X25, IPPROTO_AH, IPPROTO_BEETPH, IPPROTO_COMP, IPPROTO_DCCP, IPPROTO_EGP, IPPROTO_ENCAP, + IPPROTO_ESP, IPPROTO_ETHERNET, IPPROTO_FRAGMENT, IPPROTO_GRE, IPPROTO_ICMP, IPPROTO_ICMPV6, + IPPROTO_IDP, IPPROTO_IGMP, IPPROTO_IP, IPPROTO_IPIP, IPPROTO_IPV6, IPPROTO_MH, + IPPROTO_MPLS, IPPROTO_MPTCP, IPPROTO_MTP, IPPROTO_PIM, IPPROTO_PUP, IPPROTO_RAW, + IPPROTO_ROUTING, IPPROTO_RSVP, IPPROTO_SCTP, IPPROTO_TCP, IPPROTO_TP, IPPROTO_UDP, + IPPROTO_UDPLITE, IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_HOPS, + IPV6_MULTICAST_LOOP, IPV6_RECVTCLASS, IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, + IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, + IP_RECVTOS, IP_TOS, IP_TTL, MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, 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, SO_ACCEPTCONN, SO_BROADCAST, SO_DOMAIN, SO_ERROR, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO, SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, SO_SNDTIMEO_OLD, SO_TYPE, TCP_KEEPCNT, TCP_KEEPIDLE, - TCP_KEEPINTVL, TCP_NODELAY, + TCP_KEEPINTVL, TCP_NODELAY, TCP_USER_TIMEOUT, }, netlink::*, }; diff --git a/src/backend/linux_raw/net/sockopt.rs b/src/backend/linux_raw/net/sockopt.rs index 21354c9b1..3dca2ae4a 100644 --- a/src/backend/linux_raw/net/sockopt.rs +++ b/src/backend/linux_raw/net/sockopt.rs @@ -454,6 +454,22 @@ pub(crate) fn set_ip_add_membership( setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) } +#[inline] +pub(crate) fn set_ip_add_source_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); + setsockopt( + fd, + c::IPPROTO_IP as _, + c::IP_ADD_SOURCE_MEMBERSHIP, + mreq_source, + ) +} + #[inline] pub(crate) fn set_ipv6_add_membership( fd: BorrowedFd<'_>, @@ -498,6 +514,36 @@ pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io: setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) } +#[inline] +pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_TOS, value) +} + +#[inline] +pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_TOS) +} + +#[inline] +pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_RECVTOS, value) +} + +#[inline] +pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_RECVTOS).map(|value: i32| value > 0) +} + +#[inline] +pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_RECVTCLASS, value) +} + +#[inline] +pub(crate) fn get_ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_RECVTCLASS).map(|value: i32| value > 0) +} + #[inline] pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) @@ -542,6 +588,16 @@ pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { Ok(Duration::from_secs(secs as u64)) } +#[inline] +pub(crate) fn set_tcp_user_timeout(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_USER_TIMEOUT, value) +} + +#[inline] +pub(crate) fn get_tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_USER_TIMEOUT) +} + #[inline] fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { c::ip_mreq { @@ -550,6 +606,19 @@ fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { } } +#[inline] +fn to_imr_source( + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> c::ip_mreq_source { + c::ip_mreq_source { + imr_multiaddr: to_imr_addr(multiaddr).s_addr, + imr_interface: to_imr_addr(interface).s_addr, + imr_sourceaddr: to_imr_addr(sourceaddr).s_addr, + } +} + #[inline] fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { c::in_addr { diff --git a/src/net/sockopt.rs b/src/net/sockopt.rs index b9d7829ea..6743f235d 100644 --- a/src/net/sockopt.rs +++ b/src/net/sockopt.rs @@ -571,37 +571,37 @@ pub fn get_ipv6_multicast_loop(fd: Fd) -> io::Result { backend::net::sockopt::get_ipv6_multicast_loop(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, multicast_hops)` +/// `getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS)` /// /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] -#[doc(alias = "IP_MULTICAST_TTL")] -pub fn set_ipv6_multicast_hops(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_ipv6_multicast_hops(fd.as_fd(), value) +#[doc(alias = "IPV6_UNICAST_HOPS")] +pub fn get_ipv6_unicast_hops(fd: Fd) -> io::Result { + backend::net::sockopt::get_ipv6_unicast_hops(fd.as_fd()) } -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS)` +/// `setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, value)` /// /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_UNICAST_HOPS")] -pub fn get_ipv6_unicast_hops(fd: Fd) -> io::Result { - backend::net::sockopt::get_ipv6_unicast_hops(fd.as_fd()) +pub fn set_ipv6_unicast_hops(fd: Fd, value: Option) -> io::Result<()> { + backend::net::sockopt::set_ipv6_unicast_hops(fd.as_fd(), value) } -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, unicast_hops)` +/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, value)` /// /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] -#[doc(alias = "IPV6_UNICAST_HOPS")] -pub fn set_ipv6_unicast_hops(fd: Fd, value: Option) -> io::Result<()> { - backend::net::sockopt::set_ipv6_unicast_hops(fd.as_fd(), value) +#[doc(alias = "IPV6_MULTICAST_HOPS")] +pub fn set_ipv6_multicast_hops(fd: Fd, value: u32) -> io::Result<()> { + backend::net::sockopt::set_ipv6_multicast_hops(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS)` @@ -610,7 +610,7 @@ pub fn set_ipv6_unicast_hops(fd: Fd, value: Option) -> io::Result< /// /// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] -#[doc(alias = "IP_MULTICAST_TTL")] +#[doc(alias = "IPV6_MULTICAST_HOPS")] pub fn get_ipv6_multicast_hops(fd: Fd) -> io::Result { backend::net::sockopt::get_ipv6_multicast_hops(fd.as_fd()) } @@ -630,6 +630,27 @@ pub fn set_ip_add_membership( backend::net::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface) } +/// `setsockopt(fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[inline] +#[doc(alias = "IP_ADD_SOURCE_MEMBERSHIP")] +pub fn set_ip_add_source_membership( + fd: Fd, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + backend::net::sockopt::set_ip_add_source_membership( + fd.as_fd(), + multiaddr, + interface, + sourceaddr, + ) +} + /// `setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, multiaddr, interface)` /// /// See the [module-level documentation] for more. @@ -677,6 +698,72 @@ pub fn set_ipv6_drop_membership( backend::net::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface) } +/// `setsockopt(fd, IPPROTO_IP, IP_TOS, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[inline] +#[doc(alias = "IP_TOS")] +pub fn set_ip_tos(fd: Fd, value: u8) -> io::Result<()> { + backend::net::sockopt::set_ip_tos(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_IP, IP_TOS)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[inline] +#[doc(alias = "IP_TOS")] +pub fn get_ip_tos(fd: Fd) -> io::Result { + backend::net::sockopt::get_ip_tos(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_IP, IP_RECVTOS, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[inline] +#[doc(alias = "IP_RECVTOS")] +pub fn set_ip_recvtos(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_ip_recvtos(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_IP, IP_RECVTOS)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[inline] +#[doc(alias = "IP_RECVTOS")] +pub fn get_ip_recvtos(fd: Fd) -> io::Result { + backend::net::sockopt::get_ip_recvtos(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[inline] +#[doc(alias = "IPV6_RECVTCLASS")] +pub fn set_ipv6_recvtclass(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_ipv6_recvtclass(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[inline] +#[doc(alias = "IPV6_RECVTCLASS")] +pub fn get_ipv6_recvtclass(fd: Fd) -> io::Result { + backend::net::sockopt::get_ipv6_recvtclass(fd.as_fd()) +} + /// `setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, value)` /// /// See the [module-level documentation] for more. @@ -775,6 +862,30 @@ pub fn get_tcp_keepintvl(fd: Fd) -> io::Result { backend::net::sockopt::get_tcp_keepintvl(fd.as_fd()) } +/// `setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[inline] +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[doc(alias = "TCP_USER_TIMEOUT")] +pub fn set_tcp_user_timeout(fd: Fd, value: u32) -> io::Result<()> { + backend::net::sockopt::set_tcp_user_timeout(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[inline] +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[doc(alias = "TCP_USER_TIMEOUT")] +pub fn get_tcp_user_timeout(fd: Fd) -> io::Result { + backend::net::sockopt::get_tcp_user_timeout(fd.as_fd()) +} + #[test] fn test_sizes() { use c::c_int; From 5b49780ce9de7536f595931d7d682dacfcdac437 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Sep 2023 06:34:33 -0700 Subject: [PATCH 06/15] Reduce the number of ` as _`'s needed. --- src/backend/libc/net/sockopt.rs | 139 +++++++++++---------------- src/backend/linux_raw/c.rs | 52 +++++++--- src/backend/linux_raw/net/sockopt.rs | 135 +++++++++++--------------- 3 files changed, 151 insertions(+), 175 deletions(-) diff --git a/src/backend/libc/net/sockopt.rs b/src/backend/libc/net/sockopt.rs index 4e75399f9..ca908e60d 100644 --- a/src/backend/libc/net/sockopt.rs +++ b/src/backend/libc/net/sockopt.rs @@ -80,37 +80,27 @@ fn setsockopt(fd: BorrowedFd<'_>, level: i32, optname: i32, value: T) - #[inline] pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) + getsockopt(fd, c::SOL_SOCKET, c::SO_TYPE) } #[inline] pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_REUSEADDR, - from_bool(reuseaddr), - ) + setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR, from_bool(reuseaddr)) } #[inline] pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_REUSEADDR).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR).map(to_bool) } #[inline] pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_BROADCAST, - from_bool(broadcast), - ) + setsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST, from_bool(broadcast)) } #[inline] pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST).map(to_bool) } #[inline] @@ -122,28 +112,28 @@ pub(crate) fn set_socket_linger(fd: BorrowedFd<'_>, linger: Option) -> 0 }; let linger = c::linger { - l_onoff: linger.is_some() as _, + l_onoff: linger.is_some().into(), l_linger, }; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) + setsockopt(fd, c::SOL_SOCKET, c::SO_LINGER, linger) } #[inline] pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { - let linger: c::linger = getsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER)?; + let linger: c::linger = getsockopt(fd, c::SOL_SOCKET, c::SO_LINGER)?; Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) } #[cfg(linux_kernel)] #[inline] pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) + setsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED, from_bool(passcred)) } #[cfg(linux_kernel)] #[inline] pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED).map(to_bool) } #[inline] @@ -256,7 +246,7 @@ pub(crate) fn set_socket_nosigpipe(fd: BorrowedFd<'_>, val: bool) -> io::Result< #[inline] pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result> { - let err: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_ERROR)?; + let err: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_ERROR)?; Ok(if err == 0 { Ok(()) } else { @@ -266,39 +256,34 @@ pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result, keepalive: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_KEEPALIVE, - from_bool(keepalive), - ) + setsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE, from_bool(keepalive)) } #[inline] pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_KEEPALIVE).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE).map(to_bool) } #[inline] pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF, size) + setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF, size) } #[inline] pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF).map(|size: u32| size as usize) + getsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF).map(|size: u32| size as usize) } #[inline] pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF, size) + setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF, size) } #[inline] pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF).map(|size: u32| size as usize) + getsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF).map(|size: u32| size as usize) } #[inline] @@ -314,7 +299,7 @@ pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result) -> io::Result { - let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_DOMAIN)?; + let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_DOMAIN)?; Ok(AddressFamily( domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, )) @@ -323,44 +308,44 @@ pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result #[inline] #[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it. pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_ACCEPTCONN).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_ACCEPTCONN).map(to_bool) } #[inline] pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE, from_bool(value)) + setsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE, from_bool(value)) } #[inline] pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE).map(to_bool) } #[inline] pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) + setsockopt(fd, c::IPPROTO_IP, c::IP_TTL, ttl) } #[inline] pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) + getsockopt(fd, c::IPPROTO_IP, c::IP_TTL) } #[inline] pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY, from_bool(only_v6)) } #[inline] pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY).map(to_bool) } #[inline] pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { setsockopt( fd, - c::IPPROTO_IP as _, + c::IPPROTO_IP, c::IP_MULTICAST_LOOP, from_bool(multicast_loop), ) @@ -368,24 +353,24 @@ pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> #[inline] pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) + getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_LOOP).map(to_bool) } #[inline] pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) + setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl) } #[inline] pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) + getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL) } #[inline] pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { setsockopt( fd, - c::IPPROTO_IPV6 as _, + c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP, from_bool(multicast_loop), ) @@ -393,22 +378,17 @@ pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) #[inline] pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP).map(to_bool) } #[inline] pub(crate) fn set_ipv6_multicast_hops(fd: BorrowedFd<'_>, multicast_hops: u32) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IPV6_MULTICAST_HOPS, - multicast_hops, - ) + setsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS, multicast_hops) } #[inline] pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_HOPS) + getsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS) } #[inline] @@ -418,7 +398,7 @@ pub(crate) fn set_ip_add_membership( interface: &Ipv4Addr, ) -> io::Result<()> { let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) } #[inline] @@ -429,12 +409,7 @@ pub(crate) fn set_ip_add_source_membership( sourceaddr: &Ipv4Addr, ) -> io::Result<()> { let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IP_ADD_SOURCE_MEMBERSHIP, - mreq_source, - ) + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_SOURCE_MEMBERSHIP, mreq_source) } #[inline] @@ -461,7 +436,7 @@ pub(crate) fn set_ipv6_add_membership( use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_ADD_MEMBERSHIP, mreq) + setsockopt(fd, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq) } #[inline] @@ -471,7 +446,7 @@ pub(crate) fn set_ip_drop_membership( interface: &Ipv4Addr, ) -> io::Result<()> { let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) } #[inline] @@ -498,12 +473,12 @@ pub(crate) fn set_ipv6_drop_membership( use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_DROP_MEMBERSHIP, mreq) + setsockopt(fd, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq) } #[inline] pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) } #[inline] @@ -512,72 +487,72 @@ pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io: Some(hops) => hops as c::c_int, None => -1, }; - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS, hops) } #[inline] pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_TOS, value) + setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, value) } #[inline] pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_TOS) + getsockopt(fd, c::IPPROTO_IP, c::IP_TOS) } #[inline] pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_RECVTOS, value) + setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, value) } #[inline] pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_RECVTOS).map(|value: i32| value > 0) + getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(|value: i32| value > 0) } #[inline] pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_RECVTCLASS, value) + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, value) } #[inline] pub(crate) fn get_ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_RECVTCLASS).map(|value: i32| value > 0) + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(|value: i32| value > 0) } #[inline] pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) + setsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY, from_bool(nodelay)) } #[inline] pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) + getsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY).map(to_bool) } #[inline] #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT, count) + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT, count) } #[inline] #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT) + getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT) } #[inline] #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE, secs) + setsockopt(fd, c::IPPROTO_TCP, TCP_KEEPIDLE, secs) } #[inline] #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE)?; + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, TCP_KEEPIDLE)?; Ok(Duration::from_secs(secs as u64)) } @@ -585,26 +560,26 @@ pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result { #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL, secs) + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL, secs) } #[inline] #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL)?; + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL)?; Ok(Duration::from_secs(secs as u64)) } #[inline] #[cfg(any(linux_like, target_os = "fuchsia"))] pub(crate) fn set_tcp_user_timeout(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_USER_TIMEOUT, value) + setsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT, value) } #[inline] #[cfg(any(linux_like, target_os = "fuchsia"))] pub(crate) fn get_tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_USER_TIMEOUT) + getsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT) } #[inline] @@ -672,7 +647,7 @@ struct SocketBool(RawSocketBool); // Convert from a `bool` to a `SocketBool`. #[inline] fn from_bool(value: bool) -> SocketBool { - SocketBool(value as _) + SocketBool(value.into()) } // Convert from a `SocketBool` to a `bool`. diff --git a/src/backend/linux_raw/c.rs b/src/backend/linux_raw/c.rs index aed0e1e79..810e04a8c 100644 --- a/src/backend/linux_raw/c.rs +++ b/src/backend/linux_raw/c.rs @@ -58,19 +58,15 @@ pub(crate) use linux_raw_sys::{ AF_BRIDGE, AF_CAN, AF_ECONET, AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_ISDN, AF_IUCV, AF_KEY, AF_LLC, AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, AF_PPPOX, AF_RDS, AF_ROSE, AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, AF_WANPIPE, - AF_X25, IPPROTO_AH, IPPROTO_BEETPH, IPPROTO_COMP, IPPROTO_DCCP, IPPROTO_EGP, IPPROTO_ENCAP, - IPPROTO_ESP, IPPROTO_ETHERNET, IPPROTO_FRAGMENT, IPPROTO_GRE, IPPROTO_ICMP, IPPROTO_ICMPV6, - IPPROTO_IDP, IPPROTO_IGMP, IPPROTO_IP, IPPROTO_IPIP, IPPROTO_IPV6, IPPROTO_MH, - IPPROTO_MPLS, IPPROTO_MPTCP, IPPROTO_MTP, IPPROTO_PIM, IPPROTO_PUP, IPPROTO_RAW, - IPPROTO_ROUTING, IPPROTO_RSVP, IPPROTO_SCTP, IPPROTO_TCP, IPPROTO_TP, IPPROTO_UDP, - IPPROTO_UDPLITE, IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_HOPS, - IPV6_MULTICAST_LOOP, IPV6_RECVTCLASS, IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, - IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, - IP_RECVTOS, IP_TOS, IP_TTL, MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, - 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, SO_ACCEPTCONN, SO_BROADCAST, SO_DOMAIN, SO_ERROR, - SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, + AF_X25, IPPROTO_FRAGMENT, IPPROTO_ICMPV6, IPPROTO_MH, IPPROTO_ROUTING, IPV6_ADD_MEMBERSHIP, + IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_HOPS, IPV6_MULTICAST_LOOP, IPV6_RECVTCLASS, + IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, IP_ADD_SOURCE_MEMBERSHIP, + IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, IP_RECVTOS, IP_TOS, IP_TTL, + MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, 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, SO_ACCEPTCONN, SO_BROADCAST, SO_DOMAIN, SO_ERROR, SO_KEEPALIVE, + SO_LINGER, SO_OOBINLINE, SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO, SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, SO_SNDTIMEO_OLD, SO_TYPE, TCP_KEEPCNT, TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_NODELAY, TCP_USER_TIMEOUT, @@ -78,6 +74,36 @@ pub(crate) use linux_raw_sys::{ netlink::*, }; +// Cast away bindgen's `enum` type to make these consistent with the other +// `setsockopt`/`getsockopt` level values. +pub(crate) const IPPROTO_IP: u32 = linux_raw_sys::net::IPPROTO_IP as _; +pub(crate) const IPPROTO_ICMP: u32 = linux_raw_sys::net::IPPROTO_ICMP as _; +pub(crate) const IPPROTO_IGMP: u32 = linux_raw_sys::net::IPPROTO_IGMP as _; +pub(crate) const IPPROTO_IPIP: u32 = linux_raw_sys::net::IPPROTO_IPIP as _; +pub(crate) const IPPROTO_TCP: u32 = linux_raw_sys::net::IPPROTO_TCP as _; +pub(crate) const IPPROTO_EGP: u32 = linux_raw_sys::net::IPPROTO_EGP as _; +pub(crate) const IPPROTO_PUP: u32 = linux_raw_sys::net::IPPROTO_PUP as _; +pub(crate) const IPPROTO_UDP: u32 = linux_raw_sys::net::IPPROTO_UDP as _; +pub(crate) const IPPROTO_IDP: u32 = linux_raw_sys::net::IPPROTO_IDP as _; +pub(crate) const IPPROTO_TP: u32 = linux_raw_sys::net::IPPROTO_TP as _; +pub(crate) const IPPROTO_DCCP: u32 = linux_raw_sys::net::IPPROTO_DCCP as _; +pub(crate) const IPPROTO_IPV6: u32 = linux_raw_sys::net::IPPROTO_IPV6 as _; +pub(crate) const IPPROTO_RSVP: u32 = linux_raw_sys::net::IPPROTO_RSVP as _; +pub(crate) const IPPROTO_GRE: u32 = linux_raw_sys::net::IPPROTO_GRE as _; +pub(crate) const IPPROTO_ESP: u32 = linux_raw_sys::net::IPPROTO_ESP as _; +pub(crate) const IPPROTO_AH: u32 = linux_raw_sys::net::IPPROTO_AH as _; +pub(crate) const IPPROTO_MTP: u32 = linux_raw_sys::net::IPPROTO_MTP as _; +pub(crate) const IPPROTO_BEETPH: u32 = linux_raw_sys::net::IPPROTO_BEETPH as _; +pub(crate) const IPPROTO_ENCAP: u32 = linux_raw_sys::net::IPPROTO_ENCAP as _; +pub(crate) const IPPROTO_PIM: u32 = linux_raw_sys::net::IPPROTO_PIM as _; +pub(crate) const IPPROTO_COMP: u32 = linux_raw_sys::net::IPPROTO_COMP as _; +pub(crate) const IPPROTO_SCTP: u32 = linux_raw_sys::net::IPPROTO_SCTP as _; +pub(crate) const IPPROTO_UDPLITE: u32 = linux_raw_sys::net::IPPROTO_UDPLITE as _; +pub(crate) const IPPROTO_MPLS: u32 = linux_raw_sys::net::IPPROTO_MPLS as _; +pub(crate) const IPPROTO_ETHERNET: u32 = linux_raw_sys::net::IPPROTO_ETHERNET as _; +pub(crate) const IPPROTO_RAW: u32 = linux_raw_sys::net::IPPROTO_RAW as _; +pub(crate) const IPPROTO_MPTCP: u32 = linux_raw_sys::net::IPPROTO_MPTCP as _; + #[cfg(any(feature = "process", feature = "runtime"))] pub(crate) use linux_raw_sys::general::siginfo_t; diff --git a/src/backend/linux_raw/net/sockopt.rs b/src/backend/linux_raw/net/sockopt.rs index 3dca2ae4a..fecb50e17 100644 --- a/src/backend/linux_raw/net/sockopt.rs +++ b/src/backend/linux_raw/net/sockopt.rs @@ -102,37 +102,27 @@ fn setsockopt(fd: BorrowedFd<'_>, level: u32, optname: u32, value: T) - #[inline] pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) + getsockopt(fd, c::SOL_SOCKET, c::SO_TYPE) } #[inline] pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_REUSEADDR, - from_bool(reuseaddr), - ) + setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR, from_bool(reuseaddr)) } #[inline] pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_REUSEADDR).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR).map(to_bool) } #[inline] pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_BROADCAST, - from_bool(broadcast), - ) + setsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST, from_bool(broadcast)) } #[inline] pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST).map(to_bool) } #[inline] @@ -147,23 +137,23 @@ pub(crate) fn set_socket_linger(fd: BorrowedFd<'_>, linger: Option) -> l_onoff: c::c_int::from(linger.is_some()), l_linger, }; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) + setsockopt(fd, c::SOL_SOCKET, c::SO_LINGER, linger) } #[inline] pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { - let linger: c::linger = getsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER)?; + let linger: c::linger = getsockopt(fd, c::SOL_SOCKET, c::SO_LINGER)?; Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) } #[inline] pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) + setsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED, from_bool(passcred)) } #[inline] pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED).map(to_bool) } #[inline] @@ -301,7 +291,7 @@ fn duration_to_linux_old_timeval(timeout: Option) -> io::Result<__kern #[inline] pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result> { - let err: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_ERROR)?; + let err: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_ERROR)?; Ok(if err == 0 { Ok(()) } else { @@ -311,44 +301,39 @@ pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result, keepalive: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_KEEPALIVE, - from_bool(keepalive), - ) + setsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE, from_bool(keepalive)) } #[inline] pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_KEEPALIVE).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE).map(to_bool) } #[inline] pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF, size) + setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF, size) } #[inline] pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF).map(|size: u32| size as usize) + getsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF).map(|size: u32| size as usize) } #[inline] pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF, size) + setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF, size) } #[inline] pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF).map(|size: u32| size as usize) + getsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF).map(|size: u32| size as usize) } #[inline] pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result { - let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_DOMAIN)?; + let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_DOMAIN)?; Ok(AddressFamily( domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, )) @@ -356,44 +341,44 @@ pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result #[inline] pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_ACCEPTCONN).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_ACCEPTCONN).map(to_bool) } #[inline] pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE, from_bool(value)) + setsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE, from_bool(value)) } #[inline] pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_OOBINLINE).map(to_bool) + getsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE).map(to_bool) } #[inline] pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) + setsockopt(fd, c::IPPROTO_IP, c::IP_TTL, ttl) } #[inline] pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) + getsockopt(fd, c::IPPROTO_IP, c::IP_TTL) } #[inline] pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY, from_bool(only_v6)) } #[inline] pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY).map(to_bool) } #[inline] pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { setsockopt( fd, - c::IPPROTO_IP as _, + c::IPPROTO_IP, c::IP_MULTICAST_LOOP, from_bool(multicast_loop), ) @@ -401,24 +386,24 @@ pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> #[inline] pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) + getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_LOOP).map(to_bool) } #[inline] pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) + setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl) } #[inline] pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) + getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL) } #[inline] pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { setsockopt( fd, - c::IPPROTO_IPV6 as _, + c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP, from_bool(multicast_loop), ) @@ -426,22 +411,17 @@ pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) #[inline] pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP).map(to_bool) } #[inline] pub(crate) fn set_ipv6_multicast_hops(fd: BorrowedFd<'_>, multicast_hops: u32) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IPV6_MULTICAST_HOPS, - multicast_hops, - ) + setsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS, multicast_hops) } #[inline] pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_HOPS) + getsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS) } #[inline] @@ -451,7 +431,7 @@ pub(crate) fn set_ip_add_membership( interface: &Ipv4Addr, ) -> io::Result<()> { let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) } #[inline] @@ -462,12 +442,7 @@ pub(crate) fn set_ip_add_source_membership( sourceaddr: &Ipv4Addr, ) -> io::Result<()> { let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IP_ADD_SOURCE_MEMBERSHIP, - mreq_source, - ) + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_SOURCE_MEMBERSHIP, mreq_source) } #[inline] @@ -477,7 +452,7 @@ pub(crate) fn set_ipv6_add_membership( interface: u32, ) -> io::Result<()> { let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_ADD_MEMBERSHIP, mreq) + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_ADD_MEMBERSHIP, mreq) } #[inline] @@ -487,7 +462,7 @@ pub(crate) fn set_ip_drop_membership( interface: &Ipv4Addr, ) -> io::Result<()> { let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) } #[inline] @@ -497,12 +472,12 @@ pub(crate) fn set_ipv6_drop_membership( interface: u32, ) -> io::Result<()> { let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_DROP_MEMBERSHIP, mreq) + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_DROP_MEMBERSHIP, mreq) } #[inline] pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) } #[inline] @@ -511,91 +486,91 @@ pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io: Some(hops) => hops.into(), None => -1, }; - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS, hops) } #[inline] pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_TOS, value) + setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, value) } #[inline] pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_TOS) + getsockopt(fd, c::IPPROTO_IP, c::IP_TOS) } #[inline] pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_RECVTOS, value) + setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, value) } #[inline] pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_RECVTOS).map(|value: i32| value > 0) + getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(|value: i32| value > 0) } #[inline] pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_RECVTCLASS, value) + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, value) } #[inline] pub(crate) fn get_ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_RECVTCLASS).map(|value: i32| value > 0) + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(|value: i32| value > 0) } #[inline] pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) + setsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY, from_bool(nodelay)) } #[inline] pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) + getsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY).map(to_bool) } #[inline] pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT, count) + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT, count) } #[inline] pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT) + getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT) } #[inline] pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPIDLE, secs) + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPIDLE, secs) } #[inline] pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPIDLE)?; + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPIDLE)?; Ok(Duration::from_secs(secs as u64)) } #[inline] pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL, secs) + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL, secs) } #[inline] pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL)?; + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL)?; Ok(Duration::from_secs(secs as u64)) } #[inline] pub(crate) fn set_tcp_user_timeout(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_USER_TIMEOUT, value) + setsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT, value) } #[inline] pub(crate) fn get_tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_USER_TIMEOUT) + getsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT) } #[inline] From f0791e7328a721795e2d31122704c9f4e9f95827 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Sep 2023 07:10:56 -0700 Subject: [PATCH 07/15] Implement more socket options. Add `*_ifindex` variations of `IP_ADD_MEMBERSHIP` and `IP_DROP_MEMBERSHIP`, and add `IP_DROP_SOURCE_MEMBERSHIP`. --- src/backend/libc/net/sockopt.rs | 61 ++++++++++++++++++---- src/backend/linux_raw/c.rs | 55 ++++++++++++++------ src/backend/linux_raw/net/sockopt.rs | 61 ++++++++++++++++++---- src/net/sockopt.rs | 75 ++++++++++++++++++++++++++++ 4 files changed, 220 insertions(+), 32 deletions(-) diff --git a/src/backend/libc/net/sockopt.rs b/src/backend/libc/net/sockopt.rs index ca908e60d..03ef9af39 100644 --- a/src/backend/libc/net/sockopt.rs +++ b/src/backend/libc/net/sockopt.rs @@ -397,10 +397,21 @@ pub(crate) fn set_ip_add_membership( multiaddr: &Ipv4Addr, interface: &Ipv4Addr, ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); + let mreq = to_ip_mreq(multiaddr, interface); setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) } +#[inline] +pub(crate) fn set_ip_add_membership_with_ifindex( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + let mreqn = to_ip_mreqn(multiaddr, address, ifindex); + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreqn) +} + #[inline] pub(crate) fn set_ip_add_source_membership( fd: BorrowedFd<'_>, @@ -412,6 +423,17 @@ pub(crate) fn set_ip_add_source_membership( setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_SOURCE_MEMBERSHIP, mreq_source) } +#[inline] +pub(crate) fn set_ip_drop_source_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_SOURCE_MEMBERSHIP, mreq_source) +} + #[inline] pub(crate) fn set_ipv6_add_membership( fd: BorrowedFd<'_>, @@ -445,10 +467,21 @@ pub(crate) fn set_ip_drop_membership( multiaddr: &Ipv4Addr, interface: &Ipv4Addr, ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); + let mreq = to_ip_mreq(multiaddr, interface); setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) } +#[inline] +pub(crate) fn set_ip_drop_membership_with_ifindex( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + let mreqn = to_ip_mreqn(multiaddr, address, ifindex); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreqn) +} + #[inline] pub(crate) fn set_ipv6_drop_membership( fd: BorrowedFd<'_>, @@ -492,32 +525,33 @@ pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io: #[inline] pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, value) + setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, i32::from(value)) } #[inline] pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IP_TOS) + let value: i32 = getsockopt(fd, c::IPPROTO_IP, c::IP_TOS)?; + Ok(value as u8) } #[inline] pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, value) + setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, from_bool(value)) } #[inline] pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(|value: i32| value > 0) + getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) } #[inline] pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, value) + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, from_bool(value)) } #[inline] pub(crate) fn get_ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(|value: i32| value > 0) + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(to_bool) } #[inline] @@ -583,13 +617,22 @@ pub(crate) fn get_tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result { } #[inline] -fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { +fn to_ip_mreq(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { c::ip_mreq { imr_multiaddr: to_imr_addr(multiaddr), imr_interface: to_imr_addr(interface), } } +#[inline] +fn to_ip_mreqn(multiaddr: &Ipv4Addr, address: &Ipv4Addr, ifindex: i32) -> c::ip_mreqn { + c::ip_mreqn { + imr_multiaddr: to_imr_addr(multiaddr), + imr_address: to_imr_addr(address), + imr_ifindex: ifindex, + } +} + #[inline] fn to_imr_source( multiaddr: &Ipv4Addr, diff --git a/src/backend/linux_raw/c.rs b/src/backend/linux_raw/c.rs index 810e04a8c..80fbbc141 100644 --- a/src/backend/linux_raw/c.rs +++ b/src/backend/linux_raw/c.rs @@ -51,22 +51,22 @@ pub(crate) use linux_raw_sys::{ general::{O_CLOEXEC as SOCK_CLOEXEC, O_NONBLOCK as SOCK_NONBLOCK}, if_ether::*, net::{ - AF_DECnet, __kernel_sa_family_t as sa_family_t, - __kernel_sockaddr_storage as sockaddr_storage, cmsghdr, in6_addr, in_addr, ip_mreq, - ip_mreq_source, ipv6_mreq, linger, msghdr, sockaddr, sockaddr_in, sockaddr_in6, - sockaddr_un, socklen_t, AF_APPLETALK, AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, AF_BLUETOOTH, - AF_BRIDGE, AF_CAN, AF_ECONET, AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_ISDN, - AF_IUCV, AF_KEY, AF_LLC, AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, AF_PPPOX, - AF_RDS, AF_ROSE, AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, AF_WANPIPE, - AF_X25, IPPROTO_FRAGMENT, IPPROTO_ICMPV6, IPPROTO_MH, IPPROTO_ROUTING, IPV6_ADD_MEMBERSHIP, + linger, msghdr, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_un, socklen_t, AF_DECnet, + __kernel_sa_family_t as sa_family_t, __kernel_sockaddr_storage as sockaddr_storage, + cmsghdr, in6_addr, in_addr, ip_mreq, ip_mreq_source, ip_mreqn, ipv6_mreq, AF_APPLETALK, + AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, AF_BLUETOOTH, AF_BRIDGE, AF_CAN, AF_ECONET, + AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_ISDN, AF_IUCV, AF_KEY, AF_LLC, + AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, AF_PPPOX, AF_RDS, AF_ROSE, + AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, AF_WANPIPE, AF_X25, + IPPROTO_FRAGMENT, IPPROTO_ICMPV6, IPPROTO_MH, IPPROTO_ROUTING, IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_HOPS, IPV6_MULTICAST_LOOP, IPV6_RECVTCLASS, IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, IP_ADD_SOURCE_MEMBERSHIP, - IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, IP_RECVTOS, IP_TOS, IP_TTL, - MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, 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, SO_ACCEPTCONN, SO_BROADCAST, SO_DOMAIN, SO_ERROR, SO_KEEPALIVE, - SO_LINGER, SO_OOBINLINE, SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, + IP_DROP_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, + IP_RECVTOS, IP_TOS, IP_TTL, MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, + 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, SO_ACCEPTCONN, SO_BROADCAST, SO_DOMAIN, SO_ERROR, + SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO, SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, SO_SNDTIMEO_OLD, SO_TYPE, TCP_KEEPCNT, TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_NODELAY, TCP_USER_TIMEOUT, @@ -76,32 +76,59 @@ pub(crate) use linux_raw_sys::{ // Cast away bindgen's `enum` type to make these consistent with the other // `setsockopt`/`getsockopt` level values. +#[cfg(feature = "net")] pub(crate) const IPPROTO_IP: u32 = linux_raw_sys::net::IPPROTO_IP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_ICMP: u32 = linux_raw_sys::net::IPPROTO_ICMP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_IGMP: u32 = linux_raw_sys::net::IPPROTO_IGMP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_IPIP: u32 = linux_raw_sys::net::IPPROTO_IPIP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_TCP: u32 = linux_raw_sys::net::IPPROTO_TCP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_EGP: u32 = linux_raw_sys::net::IPPROTO_EGP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_PUP: u32 = linux_raw_sys::net::IPPROTO_PUP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_UDP: u32 = linux_raw_sys::net::IPPROTO_UDP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_IDP: u32 = linux_raw_sys::net::IPPROTO_IDP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_TP: u32 = linux_raw_sys::net::IPPROTO_TP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_DCCP: u32 = linux_raw_sys::net::IPPROTO_DCCP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_IPV6: u32 = linux_raw_sys::net::IPPROTO_IPV6 as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_RSVP: u32 = linux_raw_sys::net::IPPROTO_RSVP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_GRE: u32 = linux_raw_sys::net::IPPROTO_GRE as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_ESP: u32 = linux_raw_sys::net::IPPROTO_ESP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_AH: u32 = linux_raw_sys::net::IPPROTO_AH as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_MTP: u32 = linux_raw_sys::net::IPPROTO_MTP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_BEETPH: u32 = linux_raw_sys::net::IPPROTO_BEETPH as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_ENCAP: u32 = linux_raw_sys::net::IPPROTO_ENCAP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_PIM: u32 = linux_raw_sys::net::IPPROTO_PIM as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_COMP: u32 = linux_raw_sys::net::IPPROTO_COMP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_SCTP: u32 = linux_raw_sys::net::IPPROTO_SCTP as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_UDPLITE: u32 = linux_raw_sys::net::IPPROTO_UDPLITE as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_MPLS: u32 = linux_raw_sys::net::IPPROTO_MPLS as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_ETHERNET: u32 = linux_raw_sys::net::IPPROTO_ETHERNET as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_RAW: u32 = linux_raw_sys::net::IPPROTO_RAW as _; +#[cfg(feature = "net")] pub(crate) const IPPROTO_MPTCP: u32 = linux_raw_sys::net::IPPROTO_MPTCP as _; #[cfg(any(feature = "process", feature = "runtime"))] diff --git a/src/backend/linux_raw/net/sockopt.rs b/src/backend/linux_raw/net/sockopt.rs index fecb50e17..e5ee5c128 100644 --- a/src/backend/linux_raw/net/sockopt.rs +++ b/src/backend/linux_raw/net/sockopt.rs @@ -430,10 +430,21 @@ pub(crate) fn set_ip_add_membership( multiaddr: &Ipv4Addr, interface: &Ipv4Addr, ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); + let mreq = to_ip_mreq(multiaddr, interface); setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) } +#[inline] +pub(crate) fn set_ip_add_membership_with_ifindex( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + let mreqn = to_ip_mreqn(multiaddr, address, ifindex); + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreqn) +} + #[inline] pub(crate) fn set_ip_add_source_membership( fd: BorrowedFd<'_>, @@ -445,6 +456,17 @@ pub(crate) fn set_ip_add_source_membership( setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_SOURCE_MEMBERSHIP, mreq_source) } +#[inline] +pub(crate) fn set_ip_drop_source_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_SOURCE_MEMBERSHIP, mreq_source) +} + #[inline] pub(crate) fn set_ipv6_add_membership( fd: BorrowedFd<'_>, @@ -461,10 +483,21 @@ pub(crate) fn set_ip_drop_membership( multiaddr: &Ipv4Addr, interface: &Ipv4Addr, ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); + let mreq = to_ip_mreq(multiaddr, interface); setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) } +#[inline] +pub(crate) fn set_ip_drop_membership_with_ifindex( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + let mreqn = to_ip_mreqn(multiaddr, address, ifindex); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreqn) +} + #[inline] pub(crate) fn set_ipv6_drop_membership( fd: BorrowedFd<'_>, @@ -491,32 +524,33 @@ pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io: #[inline] pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, value) + setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, i32::from(value)) } #[inline] pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IP_TOS) + let value: i32 = getsockopt(fd, c::IPPROTO_IP, c::IP_TOS)?; + Ok(value as u8) } #[inline] pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, value) + setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, from_bool(value)) } #[inline] pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(|value: i32| value > 0) + getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) } #[inline] pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, value) + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, from_bool(value)) } #[inline] pub(crate) fn get_ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(|value: i32| value > 0) + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(to_bool) } #[inline] @@ -574,13 +608,22 @@ pub(crate) fn get_tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result { } #[inline] -fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { +fn to_ip_mreq(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { c::ip_mreq { imr_multiaddr: to_imr_addr(multiaddr), imr_interface: to_imr_addr(interface), } } +#[inline] +fn to_ip_mreqn(multiaddr: &Ipv4Addr, address: &Ipv4Addr, ifindex: i32) -> c::ip_mreqn { + c::ip_mreqn { + imr_multiaddr: to_imr_addr(multiaddr), + imr_address: to_imr_addr(address), + imr_ifindex: ifindex, + } +} + #[inline] fn to_imr_source( multiaddr: &Ipv4Addr, diff --git a/src/net/sockopt.rs b/src/net/sockopt.rs index 6743f235d..db28b061f 100644 --- a/src/net/sockopt.rs +++ b/src/net/sockopt.rs @@ -617,6 +617,9 @@ pub fn get_ipv6_multicast_hops(fd: Fd) -> io::Result { /// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, interface)` /// +/// This is similar to [`set_ip_add_membership`] but always sets `ifindex` value +/// to zero. +/// /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions @@ -630,6 +633,30 @@ pub fn set_ip_add_membership( backend::net::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface) } +/// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, address, ifindex)` +/// +/// This is similar to [`set_ip_add_membership_with_ifindex`] but additionally +/// allows a `ifindex` value to be given. +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[inline] +#[doc(alias = "IP_ADD_MEMBERSHIP")] +pub fn set_ip_add_membership_with_ifindex( + fd: Fd, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + backend::net::sockopt::set_ip_add_membership_with_ifindex( + fd.as_fd(), + multiaddr, + address, + ifindex, + ) +} + /// `setsockopt(fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP)` /// /// See the [module-level documentation] for more. @@ -651,6 +678,27 @@ pub fn set_ip_add_source_membership( ) } +/// `setsockopt(fd, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[inline] +#[doc(alias = "IP_DROP_SOURCE_MEMBERSHIP")] +pub fn set_ip_drop_source_membership( + fd: Fd, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + backend::net::sockopt::set_ip_drop_source_membership( + fd.as_fd(), + multiaddr, + interface, + sourceaddr, + ) +} + /// `setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, multiaddr, interface)` /// /// See the [module-level documentation] for more. @@ -669,6 +717,9 @@ pub fn set_ipv6_add_membership( /// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)` /// +/// This is similar to [`set_ip_drop_membership`] but always sets `ifindex` value +/// to zero. +/// /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions @@ -682,6 +733,30 @@ pub fn set_ip_drop_membership( backend::net::sockopt::set_ip_drop_membership(fd.as_fd(), multiaddr, interface) } +/// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)` +/// +/// This is similar to [`set_ip_drop_membership_with_ifindex`] but additionally +/// allows a `ifindex` value to be given. +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[inline] +#[doc(alias = "IP_DROP_MEMBERSHIP")] +pub fn set_ip_drop_membership_with_ifindex( + fd: Fd, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + backend::net::sockopt::set_ip_drop_membership_with_ifindex( + fd.as_fd(), + multiaddr, + address, + ifindex, + ) +} + /// `setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, multiaddr, interface)` /// /// See the [module-level documentation] for more. From 31c00d0671fa9418d85b80604f3aa7e46543a8a1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Sep 2023 08:35:55 -0700 Subject: [PATCH 08/15] Add tests for new socket options. Reorganize the sockopt test so that socket and tcp options are consistently tested on both ipv4 and ipv6 sockets, and add new tests for the new socket options. --- tests/net/sockopt.rs | 296 ++++++++++++++++++++++++------------------- 1 file changed, 166 insertions(+), 130 deletions(-) diff --git a/tests/net/sockopt.rs b/tests/net/sockopt.rs index b85babde0..b75b5f848 100644 --- a/tests/net/sockopt.rs +++ b/tests/net/sockopt.rs @@ -1,84 +1,39 @@ -#[test] -fn test_sockopts_ipv4() { - use rustix::net::{AddressFamily, SocketType}; - use std::time::Duration; - - let s = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, None).unwrap(); +use rustix::fd::OwnedFd; +use rustix::net::sockopt; +use rustix::net::{AddressFamily, SocketType}; +use std::time::Duration; +// Test `socket` socket options. +fn test_sockopts_socket(s: &OwnedFd) { // On a new socket we shouldn't have a timeout yet. - assert!( - rustix::net::sockopt::get_socket_timeout(&s, rustix::net::sockopt::Timeout::Recv) - .unwrap() - .is_none() - ); - assert_eq!( - rustix::net::sockopt::get_socket_type(&s).unwrap(), - SocketType::STREAM - ); - assert!(!rustix::net::sockopt::get_socket_reuseaddr(&s).unwrap()); - #[cfg(not(windows))] - assert!(!rustix::net::sockopt::get_socket_broadcast(&s).unwrap()); - // On a new socket we shouldn't have a linger yet. - assert!(rustix::net::sockopt::get_socket_linger(&s) + assert!(sockopt::get_socket_timeout(&s, sockopt::Timeout::Recv) .unwrap() .is_none()); + assert_eq!(sockopt::get_socket_type(&s).unwrap(), SocketType::STREAM); + assert!(!sockopt::get_socket_reuseaddr(&s).unwrap()); + #[cfg(not(windows))] + assert!(!sockopt::get_socket_broadcast(&s).unwrap()); + // On a new socket we shouldn't have a linger yet. + assert!(sockopt::get_socket_linger(&s).unwrap().is_none()); #[cfg(linux_kernel)] - assert!(!rustix::net::sockopt::get_socket_passcred(&s).unwrap()); - assert_ne!(rustix::net::sockopt::get_ip_ttl(&s).unwrap(), 0); - assert_ne!(rustix::net::sockopt::get_ip_ttl(&s).unwrap(), 77); - #[cfg(not(any(bsd, windows, target_os = "illumos")))] - assert!(rustix::net::sockopt::get_ip_multicast_loop(&s).unwrap()); - #[cfg(not(any(bsd, windows, target_os = "illumos")))] - assert_eq!(rustix::net::sockopt::get_ip_multicast_ttl(&s).unwrap(), 1); - assert!(!rustix::net::sockopt::get_tcp_nodelay(&s).unwrap()); + assert!(!sockopt::get_socket_passcred(&s).unwrap()); - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - { - assert!(rustix::net::sockopt::get_tcp_keepcnt(&s).is_ok()); - assert!(rustix::net::sockopt::get_tcp_keepidle(&s).is_ok()); - assert!(rustix::net::sockopt::get_tcp_keepintvl(&s).is_ok()); - } // On a new socket we shouldn't have an error yet. - assert_eq!(rustix::net::sockopt::get_socket_error(&s).unwrap(), Ok(())); - assert!(!rustix::net::sockopt::get_socket_keepalive(&s).unwrap()); - assert_ne!( - rustix::net::sockopt::get_socket_recv_buffer_size(&s).unwrap(), - 0 - ); - assert_ne!( - rustix::net::sockopt::get_socket_send_buffer_size(&s).unwrap(), - 0 - ); - #[cfg(not(any( - apple, - windows, - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "netbsd", - target_os = "nto", - )))] - assert_eq!( - rustix::net::sockopt::get_socket_domain(&s).unwrap(), - AddressFamily::INET - ); + assert_eq!(sockopt::get_socket_error(&s).unwrap(), Ok(())); + assert!(!sockopt::get_socket_keepalive(&s).unwrap()); + assert_ne!(sockopt::get_socket_recv_buffer_size(&s).unwrap(), 0); + assert_ne!(sockopt::get_socket_send_buffer_size(&s).unwrap(), 0); #[cfg(not(apple))] - assert!(!rustix::net::sockopt::get_socket_acceptconn(&s).unwrap()); + assert!(!sockopt::get_socket_acceptconn(&s).unwrap()); // Set a timeout. - rustix::net::sockopt::set_socket_timeout( - &s, - rustix::net::sockopt::Timeout::Recv, - Some(Duration::new(1, 1)), - ) - .unwrap(); + sockopt::set_socket_timeout(&s, sockopt::Timeout::Recv, Some(Duration::new(1, 1))).unwrap(); // Check that we have a timeout of at least the time we set. if cfg!(not(any(target_os = "freebsd", target_os = "netbsd"))) { assert!( - rustix::net::sockopt::get_socket_timeout(&s, rustix::net::sockopt::Timeout::Recv) + sockopt::get_socket_timeout(&s, sockopt::Timeout::Recv) .unwrap() .unwrap() >= Duration::new(1, 1) @@ -86,7 +41,7 @@ fn test_sockopts_ipv4() { } else { // On FreeBSD <= 12 and NetBSD, it appears the system rounds the timeout down. assert!( - rustix::net::sockopt::get_socket_timeout(&s, rustix::net::sockopt::Timeout::Recv) + sockopt::get_socket_timeout(&s, sockopt::Timeout::Recv) .unwrap() .unwrap() >= Duration::new(1, 0) @@ -94,139 +49,213 @@ fn test_sockopts_ipv4() { } // Set a timeout with more than a million nanoseconds. - rustix::net::sockopt::set_socket_timeout( - &s, - rustix::net::sockopt::Timeout::Recv, - Some(Duration::new(1, 10000000)), - ) - .unwrap(); + sockopt::set_socket_timeout(&s, sockopt::Timeout::Recv, Some(Duration::new(1, 10000000))) + .unwrap(); // Check that we have a timeout of at least the time we set. assert!( - rustix::net::sockopt::get_socket_timeout(&s, rustix::net::sockopt::Timeout::Recv) + sockopt::get_socket_timeout(&s, sockopt::Timeout::Recv) .unwrap() .unwrap() >= Duration::new(1, 10000000) ); // Set the reuse address flag - rustix::net::sockopt::set_socket_reuseaddr(&s, true).unwrap(); + sockopt::set_socket_reuseaddr(&s, true).unwrap(); // Check that the reuse address flag is set. - assert!(rustix::net::sockopt::get_socket_reuseaddr(&s).unwrap()); + assert!(sockopt::get_socket_reuseaddr(&s).unwrap()); #[cfg(not(windows))] { // Set the broadcast flag; - rustix::net::sockopt::set_socket_broadcast(&s, true).unwrap(); + sockopt::set_socket_broadcast(&s, true).unwrap(); // Check that the broadcast flag is set. This has no effect on stream // sockets, and not all platforms even remember the value. #[cfg(not(bsd))] - assert!(rustix::net::sockopt::get_socket_broadcast(&s).unwrap()); + assert!(sockopt::get_socket_broadcast(&s).unwrap()); } // Set the keepalive flag; - rustix::net::sockopt::set_socket_keepalive(&s, true).unwrap(); + sockopt::set_socket_keepalive(&s, true).unwrap(); // Check that the keepalive flag is set. - assert!(rustix::net::sockopt::get_socket_keepalive(&s).unwrap()); + assert!(sockopt::get_socket_keepalive(&s).unwrap()); // Set a linger. - rustix::net::sockopt::set_socket_linger(&s, Some(Duration::new(1, 1))).unwrap(); + sockopt::set_socket_linger(&s, Some(Duration::new(1, 1))).unwrap(); // Check that we have a linger of at least the time we set. - assert!( - dbg!(rustix::net::sockopt::get_socket_linger(&s) - .unwrap() - .unwrap()) - >= Duration::new(1, 1) - ); + assert!(dbg!(sockopt::get_socket_linger(&s).unwrap().unwrap()) >= Duration::new(1, 1)); #[cfg(linux_kernel)] { // Set the passcred flag; - rustix::net::sockopt::set_socket_passcred(&s, true).unwrap(); + sockopt::set_socket_passcred(&s, true).unwrap(); // Check that the passcred flag is set. - assert!(rustix::net::sockopt::get_socket_passcred(&s).unwrap()); + assert!(sockopt::get_socket_passcred(&s).unwrap()); } - // Set the ip ttl. - rustix::net::sockopt::set_ip_ttl(&s, 77).unwrap(); + // Set the receive buffer size. + let size = sockopt::get_socket_recv_buffer_size(&s).unwrap(); + sockopt::set_socket_recv_buffer_size(&s, size * 2).unwrap(); - // Check the ip ttl. - assert_eq!(rustix::net::sockopt::get_ip_ttl(&s).unwrap(), 77); + // Check that the receive buffer size is set. + assert!(sockopt::get_socket_recv_buffer_size(&s).unwrap() >= size * 2); - #[cfg(not(any(bsd, windows, target_os = "illumos")))] + // Set the send buffer size. + let size = sockopt::get_socket_send_buffer_size(&s).unwrap(); + sockopt::set_socket_send_buffer_size(&s, size * 4).unwrap(); + + // Check that the send buffer size is set. + assert!(sockopt::get_socket_send_buffer_size(&s).unwrap() >= size * 4); + + // Check that the oobinline flag is not initially set. + assert!(!sockopt::get_socket_oobinline(&s).unwrap()); + + // Set the oobinline flag; + sockopt::set_socket_oobinline(&s, true).unwrap(); + + // Check that the oobinline flag is set. + assert!(sockopt::get_socket_oobinline(&s).unwrap()); +} + +// Test `tcp` socket options. +fn test_sockopts_tcp(s: &OwnedFd) { + #[cfg(any(linux_like, taraget_os = "fuchsia"))] { - // Set the multicast loop flag; - rustix::net::sockopt::set_ip_multicast_loop(&s, false).unwrap(); + assert_eq!(sockopt::get_tcp_user_timeout(&s).unwrap(), 0); + sockopt::set_tcp_user_timeout(&s, 7).unwrap(); + assert_eq!(sockopt::get_tcp_user_timeout(&s).unwrap(), 7); + } - // Check that the multicast loop flag is set. - assert!(!rustix::net::sockopt::get_ip_multicast_loop(&s).unwrap()); + assert!(!sockopt::get_tcp_nodelay(&s).unwrap()); + + #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] + { + assert!(sockopt::get_tcp_keepcnt(&s).is_ok()); + assert!(sockopt::get_tcp_keepidle(&s).is_ok()); + assert!(sockopt::get_tcp_keepintvl(&s).is_ok()); } // Set the nodelay flag; - rustix::net::sockopt::set_tcp_nodelay(&s, true).unwrap(); + sockopt::set_tcp_nodelay(&s, true).unwrap(); // Check that the nodelay flag is set. - assert!(rustix::net::sockopt::get_tcp_nodelay(&s).unwrap()); + assert!(sockopt::get_tcp_nodelay(&s).unwrap()); #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] { // Set keepalive values: - rustix::net::sockopt::set_tcp_keepcnt(&s, 42).unwrap(); - rustix::net::sockopt::set_tcp_keepidle(&s, Duration::from_secs(3601)).unwrap(); - rustix::net::sockopt::set_tcp_keepintvl(&s, Duration::from_secs(61)).unwrap(); + sockopt::set_tcp_keepcnt(&s, 42).unwrap(); + sockopt::set_tcp_keepidle(&s, Duration::from_secs(3601)).unwrap(); + sockopt::set_tcp_keepintvl(&s, Duration::from_secs(61)).unwrap(); // Check keepalive values: - assert_eq!(rustix::net::sockopt::get_tcp_keepcnt(&s).unwrap(), 42); + assert_eq!(sockopt::get_tcp_keepcnt(&s).unwrap(), 42); assert_eq!( - rustix::net::sockopt::get_tcp_keepidle(&s).unwrap(), + sockopt::get_tcp_keepidle(&s).unwrap(), Duration::from_secs(3601) ); assert_eq!( - rustix::net::sockopt::get_tcp_keepintvl(&s).unwrap(), + sockopt::get_tcp_keepintvl(&s).unwrap(), Duration::from_secs(61) ); } +} - // Set the receive buffer size. - let size = rustix::net::sockopt::get_socket_recv_buffer_size(&s).unwrap(); - rustix::net::sockopt::set_socket_recv_buffer_size(&s, size * 2).unwrap(); +#[test] +fn test_sockopts_ipv4() { + let s = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, None).unwrap(); - // Check that the receive buffer size is set. - assert!(rustix::net::sockopt::get_socket_recv_buffer_size(&s).unwrap() >= size * 2); + test_sockopts_socket(&s); - // Set the send buffer size. - let size = rustix::net::sockopt::get_socket_send_buffer_size(&s).unwrap(); - rustix::net::sockopt::set_socket_send_buffer_size(&s, size * 4).unwrap(); + #[cfg(not(any( + apple, + windows, + target_os = "dragonfly", + target_os = "emscripten", + target_os = "espidf", + target_os = "haiku", + target_os = "netbsd", + target_os = "nto", + )))] + assert_eq!(sockopt::get_socket_domain(&s).unwrap(), AddressFamily::INET); + assert_ne!(sockopt::get_ip_ttl(&s).unwrap(), 0); + assert_ne!(sockopt::get_ip_ttl(&s).unwrap(), 77); + #[cfg(not(any(bsd, windows, target_os = "illumos")))] + assert!(sockopt::get_ip_multicast_loop(&s).unwrap()); + #[cfg(not(any(bsd, windows, target_os = "illumos")))] + assert_eq!(sockopt::get_ip_multicast_ttl(&s).unwrap(), 1); - // Check that the send buffer size is set. - assert!(rustix::net::sockopt::get_socket_send_buffer_size(&s).unwrap() >= size * 4); + // Set the ip ttl. + sockopt::set_ip_ttl(&s, 77).unwrap(); + + // Check the ip ttl. + assert_eq!(sockopt::get_ip_ttl(&s).unwrap(), 77); + + #[cfg(not(any(bsd, windows, target_os = "illumos")))] + { + // Set the multicast loop flag; + sockopt::set_ip_multicast_loop(&s, false).unwrap(); + + // Check that the multicast loop flag is set. + assert!(!sockopt::get_ip_multicast_loop(&s).unwrap()); + } + + // Check the initial value of IP TOS, set it, and check it. + #[cfg(linux_kernel)] + { + assert_eq!(sockopt::get_ip_tos(&s).unwrap(), 0); + sockopt::set_ip_tos(&s, libc::IPTOS_THROUGHPUT).unwrap(); + assert_eq!(sockopt::get_ip_tos(&s).unwrap(), libc::IPTOS_THROUGHPUT); + } + + // Check the initial value of IP RECVTOS, set it, and check it. + assert!(!sockopt::get_ip_recvtos(&s).unwrap()); + sockopt::set_ip_recvtos(&s, true).unwrap(); + assert!(sockopt::get_ip_recvtos(&s).unwrap()); + + test_sockopts_tcp(&s); } #[test] fn test_sockopts_ipv6() { - use rustix::net::{AddressFamily, SocketType}; - let s = rustix::net::socket(AddressFamily::INET6, SocketType::STREAM, None).unwrap(); - assert_ne!(rustix::net::sockopt::get_ipv6_unicast_hops(&s).unwrap(), 0); - match rustix::net::sockopt::get_ipv6_multicast_loop(&s) { + test_sockopts_socket(&s); + + #[cfg(not(any( + apple, + windows, + target_os = "dragonfly", + target_os = "emscripten", + target_os = "espidf", + target_os = "haiku", + target_os = "netbsd", + target_os = "nto", + )))] + assert_eq!( + sockopt::get_socket_domain(&s).unwrap(), + AddressFamily::INET6 + ); + + assert_ne!(sockopt::get_ipv6_unicast_hops(&s).unwrap(), 0); + match sockopt::get_ipv6_multicast_loop(&s) { Ok(multicast_loop) => assert!(multicast_loop), Err(rustix::io::Errno::OPNOTSUPP) => (), Err(rustix::io::Errno::INVAL) => (), Err(rustix::io::Errno::NOPROTOOPT) => (), Err(err) => Err(err).unwrap(), } - assert_ne!(rustix::net::sockopt::get_ipv6_unicast_hops(&s).unwrap(), 0); + assert_ne!(sockopt::get_ipv6_unicast_hops(&s).unwrap(), 0); // On NetBSD, `get_ipv6_multicasthops` returns 1 here. It's not evident // why it differs from other OS's. #[cfg(not(target_os = "netbsd"))] - match rustix::net::sockopt::get_ipv6_multicast_hops(&s) { + match sockopt::get_ipv6_multicast_hops(&s) { Ok(hops) => assert_eq!(hops, 0), Err(rustix::io::Errno::NOPROTOOPT) => (), Err(rustix::io::Errno::INVAL) => (), @@ -235,16 +264,16 @@ fn test_sockopts_ipv6() { // Set the IPV4 V6OONLY value. let v6only = rustix::net::sockopt::get_ipv6_v6only(&s).unwrap(); - rustix::net::sockopt::set_ipv6_v6only(&s, !v6only).unwrap(); + sockopt::set_ipv6_v6only(&s, !v6only).unwrap(); // Check that the IPV6 V6ONLY value is set. - assert_eq!(rustix::net::sockopt::get_ipv6_v6only(&s).unwrap(), !v6only); + assert_eq!(sockopt::get_ipv6_v6only(&s).unwrap(), !v6only); // Set the IPV6 multicast loop value. - match rustix::net::sockopt::set_ipv6_multicast_loop(&s, false) { + match sockopt::set_ipv6_multicast_loop(&s, false) { Ok(()) => { // Check that the IPV6 multicast loop value is set. - match rustix::net::sockopt::get_ipv6_multicast_loop(&s) { + match sockopt::get_ipv6_multicast_loop(&s) { Ok(multicast_loop) => assert!(!multicast_loop), Err(err) => Err(err).unwrap(), } @@ -256,14 +285,21 @@ fn test_sockopts_ipv6() { } // Set the IPV6 unicast hops value to the default value. - rustix::net::sockopt::set_ipv6_unicast_hops(&s, None).unwrap(); + sockopt::set_ipv6_unicast_hops(&s, None).unwrap(); // Check that the IPV6 unicast hops value is set. - assert_ne!(rustix::net::sockopt::get_ipv6_unicast_hops(&s).unwrap(), 0); + assert_ne!(sockopt::get_ipv6_unicast_hops(&s).unwrap(), 0); // Set the IPV6 unicast hops value to a specific value. - rustix::net::sockopt::set_ipv6_unicast_hops(&s, Some(8)).unwrap(); + sockopt::set_ipv6_unicast_hops(&s, Some(8)).unwrap(); // Check that the IPV6 unicast hops value is set. - assert_eq!(rustix::net::sockopt::get_ipv6_unicast_hops(&s).unwrap(), 8); + assert_eq!(sockopt::get_ipv6_unicast_hops(&s).unwrap(), 8); + + // Check the initial value of IPV6 RECVTCLASS, set it, and check it. + assert!(!sockopt::get_ipv6_recvtclass(&s).unwrap()); + sockopt::set_ipv6_recvtclass(&s, true).unwrap(); + assert!(sockopt::get_ipv6_recvtclass(&s).unwrap()); + + test_sockopts_tcp(&s); } From bfee5845e172a86133aed9e6ac3774db5ea02e64 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Sep 2023 11:22:12 -0700 Subject: [PATCH 09/15] Add `cfg`s for various platforms. --- src/backend/libc/net/sockopt.rs | 26 ++++++++++++++++++++++++++ src/net/sockopt.rs | 18 ++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/backend/libc/net/sockopt.rs b/src/backend/libc/net/sockopt.rs index 03ef9af39..1a984cdcb 100644 --- a/src/backend/libc/net/sockopt.rs +++ b/src/backend/libc/net/sockopt.rs @@ -401,6 +401,13 @@ pub(crate) fn set_ip_add_membership( setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) } +#[cfg(any( + apple, + freebsdlike, + linux_like, + target_os = "fuchsia", + target_os = "openbsd" +))] #[inline] pub(crate) fn set_ip_add_membership_with_ifindex( fd: BorrowedFd<'_>, @@ -412,6 +419,7 @@ pub(crate) fn set_ip_add_membership_with_ifindex( setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreqn) } +#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] #[inline] pub(crate) fn set_ip_add_source_membership( fd: BorrowedFd<'_>, @@ -423,6 +431,7 @@ pub(crate) fn set_ip_add_source_membership( setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_SOURCE_MEMBERSHIP, mreq_source) } +#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] #[inline] pub(crate) fn set_ip_drop_source_membership( fd: BorrowedFd<'_>, @@ -471,6 +480,13 @@ pub(crate) fn set_ip_drop_membership( setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) } +#[cfg(any( + apple, + freebsdlike, + linux_like, + target_os = "fuchsia", + target_os = "openbsd" +))] #[inline] pub(crate) fn set_ip_drop_membership_with_ifindex( fd: BorrowedFd<'_>, @@ -534,11 +550,13 @@ pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result { Ok(value as u8) } +#[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] #[inline] pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, from_bool(value)) } +#[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] #[inline] pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result { getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) @@ -624,6 +642,13 @@ fn to_ip_mreq(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { } } +#[cfg(any( + apple, + freebsdlike, + linux_like, + target_os = "fuchsia", + target_os = "openbsd" +))] #[inline] fn to_ip_mreqn(multiaddr: &Ipv4Addr, address: &Ipv4Addr, ifindex: i32) -> c::ip_mreqn { c::ip_mreqn { @@ -633,6 +658,7 @@ fn to_ip_mreqn(multiaddr: &Ipv4Addr, address: &Ipv4Addr, ifindex: i32) -> c::ip_ } } +#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] #[inline] fn to_imr_source( multiaddr: &Ipv4Addr, diff --git a/src/net/sockopt.rs b/src/net/sockopt.rs index db28b061f..b174c158e 100644 --- a/src/net/sockopt.rs +++ b/src/net/sockopt.rs @@ -641,6 +641,13 @@ pub fn set_ip_add_membership( /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any( + apple, + freebsdlike, + linux_like, + target_os = "fuchsia", + target_os = "openbsd" +))] #[inline] #[doc(alias = "IP_ADD_MEMBERSHIP")] pub fn set_ip_add_membership_with_ifindex( @@ -662,6 +669,7 @@ pub fn set_ip_add_membership_with_ifindex( /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] #[inline] #[doc(alias = "IP_ADD_SOURCE_MEMBERSHIP")] pub fn set_ip_add_source_membership( @@ -683,6 +691,7 @@ pub fn set_ip_add_source_membership( /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] #[inline] #[doc(alias = "IP_DROP_SOURCE_MEMBERSHIP")] pub fn set_ip_drop_source_membership( @@ -741,6 +750,13 @@ pub fn set_ip_drop_membership( /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any( + apple, + freebsdlike, + linux_like, + target_os = "fuchsia", + target_os = "openbsd" +))] #[inline] #[doc(alias = "IP_DROP_MEMBERSHIP")] pub fn set_ip_drop_membership_with_ifindex( @@ -800,6 +816,7 @@ pub fn get_ip_tos(fd: Fd) -> io::Result { /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] #[inline] #[doc(alias = "IP_RECVTOS")] pub fn set_ip_recvtos(fd: Fd, value: bool) -> io::Result<()> { @@ -811,6 +828,7 @@ pub fn set_ip_recvtos(fd: Fd, value: bool) -> io::Result<()> { /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] #[inline] #[doc(alias = "IP_RECVTOS")] pub fn get_ip_recvtos(fd: Fd) -> io::Result { From cfe2edebc4c5e0ac94a846ea097c3e0726f56b3c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Sep 2023 11:31:47 -0700 Subject: [PATCH 10/15] Add `cfg` to the tests too. --- tests/net/sockopt.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/net/sockopt.rs b/tests/net/sockopt.rs index b75b5f848..92c14b158 100644 --- a/tests/net/sockopt.rs +++ b/tests/net/sockopt.rs @@ -214,9 +214,12 @@ fn test_sockopts_ipv4() { } // Check the initial value of IP RECVTOS, set it, and check it. - assert!(!sockopt::get_ip_recvtos(&s).unwrap()); - sockopt::set_ip_recvtos(&s, true).unwrap(); - assert!(sockopt::get_ip_recvtos(&s).unwrap()); + #[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] + { + assert!(!sockopt::get_ip_recvtos(&s).unwrap()); + sockopt::set_ip_recvtos(&s, true).unwrap(); + assert!(sockopt::get_ip_recvtos(&s).unwrap()); + } test_sockopts_tcp(&s); } From ff13f661b4298f9c8d0d098995d098bf6faaa10e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Sep 2023 11:43:16 -0700 Subject: [PATCH 11/15] `cfg` for `IP_TOS`. --- src/backend/libc/net/sockopt.rs | 18 ++++++++++++++++++ src/net/sockopt.rs | 18 ++++++++++++++++++ tests/net/sockopt.rs | 10 +++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/backend/libc/net/sockopt.rs b/src/backend/libc/net/sockopt.rs index 1a984cdcb..cadb0d1a2 100644 --- a/src/backend/libc/net/sockopt.rs +++ b/src/backend/libc/net/sockopt.rs @@ -539,11 +539,29 @@ pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io: setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS, hops) } +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "haiku", + target_os = "nto", + target_env = "newlib" +))] #[inline] pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, i32::from(value)) } +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "haiku", + target_os = "nto", + target_env = "newlib" +))] #[inline] pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result { let value: i32 = getsockopt(fd, c::IPPROTO_IP, c::IP_TOS)?; diff --git a/src/net/sockopt.rs b/src/net/sockopt.rs index b174c158e..0a431cd52 100644 --- a/src/net/sockopt.rs +++ b/src/net/sockopt.rs @@ -794,6 +794,15 @@ pub fn set_ipv6_drop_membership( /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "haiku", + target_os = "nto", + target_env = "newlib" +))] #[inline] #[doc(alias = "IP_TOS")] pub fn set_ip_tos(fd: Fd, value: u8) -> io::Result<()> { @@ -805,6 +814,15 @@ pub fn set_ip_tos(fd: Fd, value: u8) -> io::Result<()> { /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "haiku", + target_os = "nto", + target_env = "newlib" +))] #[inline] #[doc(alias = "IP_TOS")] pub fn get_ip_tos(fd: Fd) -> io::Result { diff --git a/tests/net/sockopt.rs b/tests/net/sockopt.rs index 92c14b158..ba3b9efc7 100644 --- a/tests/net/sockopt.rs +++ b/tests/net/sockopt.rs @@ -206,7 +206,15 @@ fn test_sockopts_ipv4() { } // Check the initial value of IP TOS, set it, and check it. - #[cfg(linux_kernel)] + #[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "haiku", + target_os = "nto", + target_env = "newlib" + ))] { assert_eq!(sockopt::get_ip_tos(&s).unwrap(), 0); sockopt::set_ip_tos(&s, libc::IPTOS_THROUGHPUT).unwrap(); From 3f1a070d6767527f1de50af22c3c7b5a130daa7a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Sep 2023 12:22:48 -0700 Subject: [PATCH 12/15] More cfg. --- tests/net/sockopt.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/net/sockopt.rs b/tests/net/sockopt.rs index ba3b9efc7..07f454009 100644 --- a/tests/net/sockopt.rs +++ b/tests/net/sockopt.rs @@ -217,8 +217,12 @@ fn test_sockopts_ipv4() { ))] { assert_eq!(sockopt::get_ip_tos(&s).unwrap(), 0); - sockopt::set_ip_tos(&s, libc::IPTOS_THROUGHPUT).unwrap(); - assert_eq!(sockopt::get_ip_tos(&s).unwrap(), libc::IPTOS_THROUGHPUT); + + #[cfg(any(linux_like, target_os = "aix", target_os = "nto"))] + { + sockopt::set_ip_tos(&s, libc::IPTOS_THROUGHPUT).unwrap(); + assert_eq!(sockopt::get_ip_tos(&s).unwrap(), libc::IPTOS_THROUGHPUT); + } } // Check the initial value of IP RECVTOS, set it, and check it. From dc6ed1faff76f7dbc71a2a0d55741ae348f05209 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Sep 2023 12:32:12 -0700 Subject: [PATCH 13/15] Cfg's for `IPV6_RECVTCLASS`. --- src/backend/libc/net/sockopt.rs | 14 ++++++++++++++ src/net/sockopt.rs | 14 ++++++++++++++ tests/net/sockopt.rs | 15 ++++++++++++--- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/backend/libc/net/sockopt.rs b/src/backend/libc/net/sockopt.rs index cadb0d1a2..02695a4c5 100644 --- a/src/backend/libc/net/sockopt.rs +++ b/src/backend/libc/net/sockopt.rs @@ -580,11 +580,25 @@ pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result { getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) } +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "nto" +))] #[inline] pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, from_bool(value)) } +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "nto" +))] #[inline] pub(crate) fn get_ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result { getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(to_bool) diff --git a/src/net/sockopt.rs b/src/net/sockopt.rs index 0a431cd52..66f48f5bd 100644 --- a/src/net/sockopt.rs +++ b/src/net/sockopt.rs @@ -858,6 +858,13 @@ pub fn get_ip_recvtos(fd: Fd) -> io::Result { /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "nto" +))] #[inline] #[doc(alias = "IPV6_RECVTCLASS")] pub fn set_ipv6_recvtclass(fd: Fd, value: bool) -> io::Result<()> { @@ -869,6 +876,13 @@ pub fn set_ipv6_recvtclass(fd: Fd, value: bool) -> io::Result<()> { /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "nto" +))] #[inline] #[doc(alias = "IPV6_RECVTCLASS")] pub fn get_ipv6_recvtclass(fd: Fd) -> io::Result { diff --git a/tests/net/sockopt.rs b/tests/net/sockopt.rs index 07f454009..7ddbfe614 100644 --- a/tests/net/sockopt.rs +++ b/tests/net/sockopt.rs @@ -312,9 +312,18 @@ fn test_sockopts_ipv6() { assert_eq!(sockopt::get_ipv6_unicast_hops(&s).unwrap(), 8); // Check the initial value of IPV6 RECVTCLASS, set it, and check it. - assert!(!sockopt::get_ipv6_recvtclass(&s).unwrap()); - sockopt::set_ipv6_recvtclass(&s, true).unwrap(); - assert!(sockopt::get_ipv6_recvtclass(&s).unwrap()); + #[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "nto" + ))] + { + assert!(!sockopt::get_ipv6_recvtclass(&s).unwrap()); + sockopt::set_ipv6_recvtclass(&s, true).unwrap(); + assert!(sockopt::get_ipv6_recvtclass(&s).unwrap()); + } test_sockopts_tcp(&s); } From 5756d7ff7bbd87da1db92c1dc2d2f13911e7f7ed Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Sep 2023 12:40:07 -0700 Subject: [PATCH 14/15] DragonFly doesn't have `IP_RECVTOS`. --- src/backend/libc/net/sockopt.rs | 4 ++-- src/net/sockopt.rs | 4 ++-- tests/net/sockopt.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/libc/net/sockopt.rs b/src/backend/libc/net/sockopt.rs index 02695a4c5..29c87f541 100644 --- a/src/backend/libc/net/sockopt.rs +++ b/src/backend/libc/net/sockopt.rs @@ -568,13 +568,13 @@ pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result { Ok(value as u8) } -#[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] +#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))] #[inline] pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, from_bool(value)) } -#[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] +#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))] #[inline] pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result { getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) diff --git a/src/net/sockopt.rs b/src/net/sockopt.rs index 66f48f5bd..ea736c2af 100644 --- a/src/net/sockopt.rs +++ b/src/net/sockopt.rs @@ -834,7 +834,7 @@ pub fn get_ip_tos(fd: Fd) -> io::Result { /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] +#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))] #[inline] #[doc(alias = "IP_RECVTOS")] pub fn set_ip_recvtos(fd: Fd, value: bool) -> io::Result<()> { @@ -846,7 +846,7 @@ pub fn set_ip_recvtos(fd: Fd, value: bool) -> io::Result<()> { /// See the [module-level documentation] for more. /// /// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] +#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))] #[inline] #[doc(alias = "IP_RECVTOS")] pub fn get_ip_recvtos(fd: Fd) -> io::Result { diff --git a/tests/net/sockopt.rs b/tests/net/sockopt.rs index 7ddbfe614..69b7be6aa 100644 --- a/tests/net/sockopt.rs +++ b/tests/net/sockopt.rs @@ -226,7 +226,7 @@ fn test_sockopts_ipv4() { } // Check the initial value of IP RECVTOS, set it, and check it. - #[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] + #[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))] { assert!(!sockopt::get_ip_recvtos(&s).unwrap()); sockopt::set_ip_recvtos(&s, true).unwrap(); From f83becd954ad6c6575737f563a832b31c90226fc Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Sep 2023 12:48:35 -0700 Subject: [PATCH 15/15] Fix compilation on x86. --- src/backend/linux_raw/net/sockopt.rs | 6 ++++++ src/backend/linux_raw/net/syscalls.rs | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/backend/linux_raw/net/sockopt.rs b/src/backend/linux_raw/net/sockopt.rs index e5ee5c128..24cabbe5e 100644 --- a/src/backend/linux_raw/net/sockopt.rs +++ b/src/backend/linux_raw/net/sockopt.rs @@ -14,6 +14,12 @@ use crate::net::{AddressFamily, Ipv4Addr, Ipv6Addr, SocketType}; use core::mem::MaybeUninit; use core::time::Duration; use linux_raw_sys::general::{__kernel_old_timeval, __kernel_sock_timeval}; +#[cfg(target_arch = "x86")] +use { + crate::backend::conv::{slice_just_addr, x86_sys}, + crate::backend::reg::{ArgReg, SocketArg}, + linux_raw_sys::net::{SYS_GETSOCKOPT, SYS_SETSOCKOPT}, +}; #[inline] fn getsockopt(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result { diff --git a/src/backend/linux_raw/net/syscalls.rs b/src/backend/linux_raw/net/syscalls.rs index e2aa9f786..908cf773f 100644 --- a/src/backend/linux_raw/net/syscalls.rs +++ b/src/backend/linux_raw/net/syscalls.rs @@ -30,8 +30,8 @@ use { crate::backend::reg::{ArgReg, SocketArg}, linux_raw_sys::net::{ SYS_ACCEPT, SYS_ACCEPT4, SYS_BIND, SYS_CONNECT, SYS_GETPEERNAME, SYS_GETSOCKNAME, - SYS_GETSOCKOPT, SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_RECVMSG, SYS_SEND, SYS_SENDMSG, - SYS_SENDTO, SYS_SETSOCKOPT, SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, + SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_RECVMSG, SYS_SEND, SYS_SENDMSG, SYS_SENDTO, + SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, }, };