diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-15 16:37:08 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-17 16:30:22 -0600 |
| commit | 45df4d0d9b577fecee798d672695fe24ff57fb1b (patch) | |
| tree | 1b99bf645035b58e0d6db08c7a83521f41f7a75b /vendor/rustix/src/net | |
| parent | f94f79608393d4ab127db63cc41668445ef6b243 (diff) | |
feat: migrate from Cedar to SpiceDB authorization system
This is a major architectural change that replaces the Cedar policy-based
authorization system with SpiceDB's relation-based authorization.
Key changes:
- Migrate from Rust to Go implementation
- Replace Cedar policies with SpiceDB schema and relationships
- Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks
- Update build system and dependencies for Go ecosystem
- Maintain Envoy integration for external authorization
This change enables more flexible permission modeling through SpiceDB's
Google Zanzibar inspired relation-based system, supporting complex
hierarchical permissions that were difficult to express in Cedar.
Breaking change: Existing Cedar policies and Rust-based configuration
will no longer work and need to be migrated to SpiceDB schema.
Diffstat (limited to 'vendor/rustix/src/net')
| -rw-r--r-- | vendor/rustix/src/net/addr.rs | 182 | ||||
| -rw-r--r-- | vendor/rustix/src/net/mod.rs | 35 | ||||
| -rw-r--r-- | vendor/rustix/src/net/netdevice.rs | 107 | ||||
| -rw-r--r-- | vendor/rustix/src/net/send_recv/mod.rs | 192 | ||||
| -rw-r--r-- | vendor/rustix/src/net/send_recv/msg.rs | 961 | ||||
| -rw-r--r-- | vendor/rustix/src/net/socket.rs | 461 | ||||
| -rw-r--r-- | vendor/rustix/src/net/socket_addr_any.rs | 344 | ||||
| -rw-r--r-- | vendor/rustix/src/net/socketpair.rs | 36 | ||||
| -rw-r--r-- | vendor/rustix/src/net/sockopt.rs | 1649 | ||||
| -rw-r--r-- | vendor/rustix/src/net/types.rs | 2132 | ||||
| -rw-r--r-- | vendor/rustix/src/net/wsa.rs | 49 |
11 files changed, 0 insertions, 6148 deletions
diff --git a/vendor/rustix/src/net/addr.rs b/vendor/rustix/src/net/addr.rs deleted file mode 100644 index 13e5c24f..00000000 --- a/vendor/rustix/src/net/addr.rs +++ /dev/null @@ -1,182 +0,0 @@ -//! Types for implementers of socket address types or code that is generic over -//! address types. -//! -//! The concrete address types and [`SocketAddrAny`] are in -//! [the parent module][`super`]. - -#![allow(unsafe_code)] -use core::mem::{size_of, MaybeUninit}; -use core::ptr; - -use crate::backend::net::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; -use crate::utils::as_ptr; - -use super::{SocketAddr, SocketAddrAny, SocketAddrV4, SocketAddrV6}; - -pub use crate::backend::net::addr::SocketAddrStorage; - -#[cfg(unix)] -use super::SocketAddrUnix; - -/// Opaque type equivalent to `sockaddr` in C. -/// -/// This is always used behind a raw pointer that is cast from a pointer to a -/// `sockaddr`-compatible C type, and then cast back to a `sockaddr` pointer to -/// be passed to a system call. -#[repr(C)] -pub struct SocketAddrOpaque { - _data: [u8; 0], -} - -/// A type for the length of a socket address. -/// -/// This type will always be big enough to hold any socket address, but never -/// bigger than `usize`. -#[doc(alias = "socklen_t")] -pub type SocketAddrLen = u32; - -/// A trait abstracting over the types that can be passed as a `sockaddr`. -/// -/// # Safety -/// -/// Implementers of this trait must ensure that `with_sockaddr` calls `f` with -/// a pointer that is readable for the passed length, and points to data that -/// is a valid socket address for the system calls that accept `sockaddr` as a -/// const pointer. -pub unsafe trait SocketAddrArg { - /// Call a closure with the pointer and length to the corresponding C type. - /// - /// The memory pointed to by the pointer of size length is guaranteed to be - /// valid only for the duration of the call. - /// - /// The API uses a closure so that: - /// - The libc types are not exposed in the rustix API. - /// - Types like `SocketAddrUnix` that contain their corresponding C type - /// can pass it directly without a copy. - /// - Other socket types can construct their C-compatible struct on the - /// stack and call the closure with a pointer to it. - /// - /// # Safety - /// - /// For `f` to use its pointer argument, it'll contain an `unsafe` block. - /// The caller of `with_sockaddr` here is responsible for ensuring that the - /// safety condition for that `unsafe` block is satisfied by the guarantee - /// that `with_sockaddr` here provides. - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R; - - /// Convert to `SocketAddrAny`. - fn as_any(&self) -> SocketAddrAny { - let mut storage = MaybeUninit::<SocketAddrStorage>::uninit(); - // SAFETY: We've allocated `storage` here, we're writing to it, and - // we're using the number of bytes written. - unsafe { - let len = self.write_sockaddr(storage.as_mut_ptr()); - SocketAddrAny::new(storage, len) - } - } - - /// Encode an address into a `SocketAddrStorage`. - /// - /// Returns the number of bytes that were written. - /// - /// For a safe interface to this functionality, use [`as_any`]. - /// - /// [`as_any`]: Self::as_any - /// - /// # Safety - /// - /// `storage` must be valid to write up to `size_of<SocketAddrStorage>()` - /// bytes to. - unsafe fn write_sockaddr(&self, storage: *mut SocketAddrStorage) -> SocketAddrLen { - // The closure dereferences exactly `len` bytes at `ptr`. - self.with_sockaddr(|ptr, len| { - ptr::copy_nonoverlapping(ptr.cast::<u8>(), storage.cast::<u8>(), len as usize); - len - }) - } -} - -/// Helper for implementing `SocketAddrArg::with_sockaddr`. -/// -/// # Safety -/// -/// This calls `f` with a pointer to an object it has a reference to, with the -/// and the length of that object, so they'll be valid for the duration of the -/// call. -pub(crate) unsafe fn call_with_sockaddr<A, R>( - addr: &A, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, -) -> R { - let ptr = as_ptr(addr).cast(); - let len = size_of::<A>() as SocketAddrLen; - f(ptr, len) -} - -// SAFETY: This just forwards to the inner `SocketAddrArg` implementations. -unsafe impl SocketAddrArg for SocketAddr { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - match self { - Self::V4(v4) => v4.with_sockaddr(f), - Self::V6(v6) => v6.with_sockaddr(f), - } - } -} - -// SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which handles -// calling `f` with the needed preconditions. -unsafe impl SocketAddrArg for SocketAddrV4 { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - call_with_sockaddr(&encode_sockaddr_v4(self), f) - } -} - -// SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which handles -// calling `f` with the needed preconditions. -unsafe impl SocketAddrArg for SocketAddrV6 { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - call_with_sockaddr(&encode_sockaddr_v6(self), f) - } -} - -#[cfg(unix)] -// SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which handles -// calling `f` with the needed preconditions. -unsafe impl SocketAddrArg for SocketAddrUnix { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - f(as_ptr(&self.unix).cast(), self.addr_len()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::backend::c; - - #[test] - fn test_layouts() { - assert_eq_size!(SocketAddrLen, c::socklen_t); - - #[cfg(not(any(windows, target_os = "redox")))] - assert_eq!( - memoffset::span_of!(c::msghdr, msg_namelen).len(), - size_of::<SocketAddrLen>() - ); - - assert!(size_of::<SocketAddrLen>() <= size_of::<usize>()); - } -} diff --git a/vendor/rustix/src/net/mod.rs b/vendor/rustix/src/net/mod.rs deleted file mode 100644 index e5560905..00000000 --- a/vendor/rustix/src/net/mod.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! Network-related operations. -//! -//! On Windows, one must call [`wsa_startup`] in the process before calling any -//! of these APIs. [`wsa_cleanup`] may be used in the process if these APIs are -//! no longer needed. -//! -//! [`wsa_startup`]: https://docs.rs/rustix/*/x86_64-pc-windows-msvc/rustix/net/fn.wsa_startup.html -//! [`wsa_cleanup`]: https://docs.rs/rustix/*/x86_64-pc-windows-msvc/rustix/net/fn.wsa_cleanup.html - -pub mod addr; -mod send_recv; -mod socket; -mod socket_addr_any; -#[cfg(not(any(windows, target_os = "wasi")))] -mod socketpair; -mod types; -#[cfg(windows)] -mod wsa; - -#[cfg(linux_kernel)] -pub mod netdevice; -pub mod sockopt; - -pub use crate::maybe_polyfill::net::{ - IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, -}; -pub use send_recv::*; -pub use socket::*; -pub use socket_addr_any::SocketAddrAny; -pub(crate) use socket_addr_any::SocketAddrBuf; -#[cfg(not(any(windows, target_os = "wasi")))] -pub use socketpair::socketpair; -pub use types::*; -#[cfg(windows)] -pub use wsa::{wsa_cleanup, wsa_startup}; diff --git a/vendor/rustix/src/net/netdevice.rs b/vendor/rustix/src/net/netdevice.rs deleted file mode 100644 index 1ddd918e..00000000 --- a/vendor/rustix/src/net/netdevice.rs +++ /dev/null @@ -1,107 +0,0 @@ -//! Low-level Linux network device access -//! -//! The methods in this module take a socket's file descriptor to communicate -//! with the kernel in their ioctl call: -//! - glibc uses an `AF_UNIX`, `AF_INET`, or `AF_INET6` socket. The address -//! family itself does not matter and glibc tries the next address family if -//! socket creation with one fails. -//! - Android (bionic) uses an `AF_INET` socket. -//! - Both create the socket with `SOCK_DGRAM|SOCK_CLOEXEC` type/flag. -//! - The [manual pages] specify that the ioctl calls “can be used on any -//! socket's file descriptor regardless of the family or type”. -//! -//! # References -//! - [Linux] -//! -//! [manual pages]: https://man7.org/linux/man-pages/man7/netdevice.7.html -//! [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html - -use crate::fd::AsFd; -use crate::io; -#[cfg(feature = "alloc")] -use alloc::string::String; - -/// `ioctl(fd, SIOCGIFINDEX, ifreq)`—Returns the interface index for a given -/// name. -/// -/// See the [module-level documentation] for information about `fd` usage. -/// -/// # References -/// - [Linux] -/// -/// [module-level documentation]: self -/// [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html -#[inline] -#[doc(alias = "SIOCGIFINDEX")] -pub fn name_to_index<Fd: AsFd>(fd: Fd, if_name: &str) -> io::Result<u32> { - crate::backend::net::netdevice::name_to_index(fd.as_fd(), if_name) -} - -/// `ioctl(fd, SIOCGIFNAME, ifreq)`—Returns the interface name for a given -/// index. -/// -/// See the [module-level documentation] for information about `fd` usage. -/// -/// # References -/// - [Linux] -/// -/// [module-level documentation]: self -/// [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html -#[inline] -#[doc(alias = "SIOCGIFNAME")] -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn index_to_name<Fd: AsFd>(fd: Fd, index: u32) -> io::Result<String> { - crate::backend::net::netdevice::index_to_name(fd.as_fd(), index) -} - -#[cfg(test)] -mod tests { - use crate::backend::net::netdevice::{index_to_name, name_to_index}; - use crate::fd::AsFd; - use crate::net::{AddressFamily, SocketFlags, SocketType}; - - #[test] - fn test_name_to_index() { - let fd = crate::net::socket_with( - AddressFamily::INET, - SocketType::DGRAM, - SocketFlags::CLOEXEC, - None, - ) - .unwrap(); - - let loopback_index = std::fs::read_to_string("/sys/class/net/lo/ifindex") - .unwrap() - .as_str() - .split_at(1) - .0 - .parse::<u32>() - .unwrap(); - assert_eq!(Ok(loopback_index), name_to_index(fd.as_fd(), "lo")); - } - - #[test] - #[cfg(feature = "alloc")] - fn test_index_to_name() { - let fd = crate::net::socket_with( - AddressFamily::INET, - SocketType::DGRAM, - SocketFlags::CLOEXEC, - None, - ) - .unwrap(); - - let loopback_index = std::fs::read_to_string("/sys/class/net/lo/ifindex") - .unwrap() - .as_str() - .split_at(1) - .0 - .parse::<u32>() - .unwrap(); - assert_eq!( - Ok("lo".to_owned()), - index_to_name(fd.as_fd(), loopback_index) - ); - } -} diff --git a/vendor/rustix/src/net/send_recv/mod.rs b/vendor/rustix/src/net/send_recv/mod.rs deleted file mode 100644 index 0aac6d2e..00000000 --- a/vendor/rustix/src/net/send_recv/mod.rs +++ /dev/null @@ -1,192 +0,0 @@ -//! `recv`, `send`, and variants. - -#![allow(unsafe_code)] - -use crate::buffer::Buffer; -use crate::net::addr::SocketAddrArg; -use crate::net::SocketAddrAny; -use crate::{backend, io}; -use backend::fd::AsFd; -use core::cmp::min; - -pub use backend::net::send_recv::{RecvFlags, ReturnFlags, SendFlags}; - -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -mod msg; - -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub use msg::*; - -/// `recv(fd, buf, flags)`—Reads data from a socket. -/// -/// In addition to the `Buffer::Output` return value, this also returns the -/// number of bytes received before any truncation due to the -/// [`RecvFlags::TRUNC`] flag. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendrecv -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/recv.html -/// [Linux]: https://man7.org/linux/man-pages/man2/recv.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recv.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recv -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=recv&sektion=2 -/// [NetBSD]: https://man.netbsd.org/recv.2 -/// [OpenBSD]: https://man.openbsd.org/recv.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=recv§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/recv -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Receiving-Data.html -#[inline] -#[allow(clippy::type_complexity)] -pub fn recv<Fd: AsFd, Buf: Buffer<u8>>( - fd: Fd, - mut buf: Buf, - flags: RecvFlags, -) -> io::Result<(Buf::Output, usize)> { - let (ptr, len) = buf.parts_mut(); - // SAFETY: `recv` behaves. - let recv_len = unsafe { backend::net::syscalls::recv(fd.as_fd(), (ptr, len), flags)? }; - // If the `TRUNC` flag is set, the returned `length` may be longer than the - // buffer length. - let min_len = min(len, recv_len); - // SAFETY: `recv` behaves. - unsafe { Ok((buf.assume_init(min_len), recv_len)) } -} - -/// `send(fd, buf, flags)`—Writes data to a socket. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendrecv -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/send.html -/// [Linux]: https://man7.org/linux/man-pages/man2/send.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/send.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=send&sektion=2 -/// [NetBSD]: https://man.netbsd.org/send.2 -/// [OpenBSD]: https://man.openbsd.org/send.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=send§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/send -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Sending-Data.html -#[inline] -pub fn send<Fd: AsFd>(fd: Fd, buf: &[u8], flags: SendFlags) -> io::Result<usize> { - backend::net::syscalls::send(fd.as_fd(), buf, flags) -} - -/// `recvfrom(fd, buf, flags, addr, len)`—Reads data from a socket and -/// returns the sender address. -/// -/// In addition to the `Buffer::Output` return value, this also returns the -/// number of bytes received before any truncation due to the -/// [`RecvFlags::TRUNC`] flag. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/recvfrom.html -/// [Linux]: https://man7.org/linux/man-pages/man2/recvfrom.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recvfrom.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recvfrom -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=recvfrom&sektion=2 -/// [NetBSD]: https://man.netbsd.org/recvfrom.2 -/// [OpenBSD]: https://man.openbsd.org/recvfrom.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=recvfrom§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/recvfrom -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Receiving-Datagrams.html -#[inline] -pub fn recvfrom<Fd: AsFd, Buf: Buffer<u8>>( - fd: Fd, - mut buf: Buf, - flags: RecvFlags, -) -> io::Result<(Buf::Output, usize, Option<SocketAddrAny>)> { - let (ptr, len) = buf.parts_mut(); - // SAFETY: `recvfrom` behaves. - let (recv_len, addr) = - unsafe { backend::net::syscalls::recvfrom(fd.as_fd(), (ptr, len), flags)? }; - // If the `TRUNC` flag is set, the returned `length` may be longer than the - // buffer length. - let min_len = min(len, recv_len); - // SAFETY: `recvfrom` behaves. - unsafe { Ok((buf.assume_init(min_len), recv_len, addr)) } -} - -/// `sendto(fd, buf, flags, addr)`—Writes data to a socket to a specific IP -/// address. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sendto.html -/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendto&sektion=2 -/// [NetBSD]: https://man.netbsd.org/sendto.2 -/// [OpenBSD]: https://man.openbsd.org/sendto.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendto§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/sendto -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Sending-Datagrams.html -pub fn sendto<Fd: AsFd>( - fd: Fd, - buf: &[u8], - flags: SendFlags, - addr: &impl SocketAddrArg, -) -> io::Result<usize> { - backend::net::syscalls::sendto(fd.as_fd(), buf, flags, addr) -} diff --git a/vendor/rustix/src/net/send_recv/msg.rs b/vendor/rustix/src/net/send_recv/msg.rs deleted file mode 100644 index 7df60a5e..00000000 --- a/vendor/rustix/src/net/send_recv/msg.rs +++ /dev/null @@ -1,961 +0,0 @@ -//! [`recvmsg`], [`sendmsg`], and related functions. - -#![allow(unsafe_code)] - -#[cfg(target_os = "linux")] -use crate::backend::net::msghdr::noaddr_msghdr; -use crate::backend::{self, c}; -use crate::fd::{AsFd, BorrowedFd, OwnedFd}; -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::net::addr::SocketAddrArg; -#[cfg(linux_kernel)] -use crate::net::UCred; -use core::iter::FusedIterator; -use core::marker::PhantomData; -use core::mem::{align_of, size_of, size_of_val, take, MaybeUninit}; -#[cfg(linux_kernel)] -use core::ptr::addr_of; -use core::{ptr, slice}; - -use super::{RecvFlags, ReturnFlags, SendFlags, SocketAddrAny}; - -/// Macro for defining the amount of space to allocate in a buffer for use with -/// [`RecvAncillaryBuffer::new`] and [`SendAncillaryBuffer::new`]. -/// -/// # Examples -/// -/// Allocate a buffer for a single file descriptor: -/// ``` -/// # use std::mem::MaybeUninit; -/// # use rustix::cmsg_space; -/// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(1))]; -/// # let _: &[MaybeUninit<u8>] = space.as_slice(); -/// ``` -/// -/// Allocate a buffer for credentials: -/// ``` -/// # #[cfg(linux_kernel)] -/// # { -/// # use std::mem::MaybeUninit; -/// # use rustix::cmsg_space; -/// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; -/// # let _: &[MaybeUninit<u8>] = space.as_slice(); -/// # } -/// ``` -/// -/// Allocate a buffer for two file descriptors and credentials: -/// ``` -/// # #[cfg(linux_kernel)] -/// # { -/// # use std::mem::MaybeUninit; -/// # use rustix::cmsg_space; -/// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; -/// # let _: &[MaybeUninit<u8>] = space.as_slice(); -/// # } -/// ``` -#[macro_export] -macro_rules! cmsg_space { - // Base Rules - (ScmRights($len:expr)) => { - $crate::net::__cmsg_space( - $len * ::core::mem::size_of::<$crate::fd::BorrowedFd<'static>>(), - ) - }; - (ScmCredentials($len:expr)) => { - $crate::net::__cmsg_space( - $len * ::core::mem::size_of::<$crate::net::UCred>(), - ) - }; - - // Combo Rules - ($firstid:ident($firstex:expr), $($restid:ident($restex:expr)),*) => {{ - // We only have to add `cmsghdr` alignment once; all other times we can - // use `cmsg_aligned_space`. - let sum = $crate::cmsg_space!($firstid($firstex)); - $( - let sum = sum + $crate::cmsg_aligned_space!($restid($restex)); - )* - sum - }}; -} - -/// Like `cmsg_space`, but doesn't add padding for `cmsghdr` alignment. -#[doc(hidden)] -#[macro_export] -macro_rules! cmsg_aligned_space { - // Base Rules - (ScmRights($len:expr)) => { - $crate::net::__cmsg_aligned_space( - $len * ::core::mem::size_of::<$crate::fd::BorrowedFd<'static>>(), - ) - }; - (ScmCredentials($len:expr)) => { - $crate::net::__cmsg_aligned_space( - $len * ::core::mem::size_of::<$crate::net::UCred>(), - ) - }; - - // Combo Rules - ($firstid:ident($firstex:expr), $($restid:ident($restex:expr)),*) => {{ - let sum = cmsg_aligned_space!($firstid($firstex)); - $( - let sum = sum + cmsg_aligned_space!($restid($restex)); - )* - sum - }}; -} - -/// Helper function for [`cmsg_space`]. -#[doc(hidden)] -pub const fn __cmsg_space(len: usize) -> usize { - // Add `align_of::<c::cmsghdr>()` so that we can align the user-provided - // `&[u8]` to the required alignment boundary. - let len = len + align_of::<c::cmsghdr>(); - - __cmsg_aligned_space(len) -} - -/// Helper function for [`cmsg_aligned_space`]. -#[doc(hidden)] -pub const fn __cmsg_aligned_space(len: usize) -> usize { - // Convert `len` to `u32` for `CMSG_SPACE`. This would be `try_into()` if - // we could call that in a `const fn`. - let converted_len = len as u32; - if converted_len as usize != len { - unreachable!(); // `CMSG_SPACE` size overflow - } - - unsafe { c::CMSG_SPACE(converted_len) as usize } -} - -/// Ancillary message for [`sendmsg`] and [`sendmsg_addr`]. -#[non_exhaustive] -pub enum SendAncillaryMessage<'slice, 'fd> { - /// Send file descriptors. - #[doc(alias = "SCM_RIGHTS")] - ScmRights(&'slice [BorrowedFd<'fd>]), - /// Send process credentials. - #[cfg(linux_kernel)] - #[doc(alias = "SCM_CREDENTIAL")] - ScmCredentials(UCred), -} - -impl SendAncillaryMessage<'_, '_> { - /// Get the maximum size of an ancillary message. - /// - /// This can be used to determine the size of the buffer to allocate for a - /// [`SendAncillaryBuffer::new`] with one message. - pub const fn size(&self) -> usize { - match self { - Self::ScmRights(slice) => cmsg_space!(ScmRights(slice.len())), - #[cfg(linux_kernel)] - Self::ScmCredentials(_) => cmsg_space!(ScmCredentials(1)), - } - } -} - -/// Ancillary message for [`recvmsg`]. -#[non_exhaustive] -pub enum RecvAncillaryMessage<'a> { - /// Received file descriptors. - #[doc(alias = "SCM_RIGHTS")] - ScmRights(AncillaryIter<'a, OwnedFd>), - /// Received process credentials. - #[cfg(linux_kernel)] - #[doc(alias = "SCM_CREDENTIALS")] - ScmCredentials(UCred), -} - -/// Buffer for sending ancillary messages with [`sendmsg`] and -/// [`sendmsg_addr`]. -/// -/// Use the [`push`] function to add messages to send. -/// -/// [`push`]: SendAncillaryBuffer::push -pub struct SendAncillaryBuffer<'buf, 'slice, 'fd> { - /// Raw byte buffer for messages. - buffer: &'buf mut [MaybeUninit<u8>], - - /// The amount of the buffer that is used. - length: usize, - - /// Phantom data for lifetime of `&'slice [BorrowedFd<'fd>]`. - _phantom: PhantomData<&'slice [BorrowedFd<'fd>]>, -} - -impl<'buf> From<&'buf mut [MaybeUninit<u8>]> for SendAncillaryBuffer<'buf, '_, '_> { - fn from(buffer: &'buf mut [MaybeUninit<u8>]) -> Self { - Self::new(buffer) - } -} - -impl Default for SendAncillaryBuffer<'_, '_, '_> { - fn default() -> Self { - Self { - buffer: &mut [], - length: 0, - _phantom: PhantomData, - } - } -} - -impl<'buf, 'slice, 'fd> SendAncillaryBuffer<'buf, 'slice, 'fd> { - /// Create a new, empty `SendAncillaryBuffer` from a raw byte buffer. - /// - /// The buffer size may be computed with [`cmsg_space`], or it may be - /// zero for an empty buffer, however in that case, consider `default()` - /// instead, or even using [`send`] instead of `sendmsg`. - /// - /// # Examples - /// - /// Allocate a buffer for a single file descriptor: - /// ``` - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::SendAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(1))]; - /// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); - /// ``` - /// - /// Allocate a buffer for credentials: - /// ``` - /// # #[cfg(linux_kernel)] - /// # { - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::SendAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; - /// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); - /// # } - /// ``` - /// - /// Allocate a buffer for two file descriptors and credentials: - /// ``` - /// # #[cfg(linux_kernel)] - /// # { - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::SendAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; - /// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); - /// # } - /// ``` - /// - /// [`send`]: crate::net::send - #[inline] - pub fn new(buffer: &'buf mut [MaybeUninit<u8>]) -> Self { - Self { - buffer: align_for_cmsghdr(buffer), - length: 0, - _phantom: PhantomData, - } - } - - /// Returns a pointer to the message data. - pub(crate) fn as_control_ptr(&mut self) -> *mut u8 { - // When the length is zero, we may be using a `&[]` address, which may - // be an invalid but non-null pointer, and on some platforms, that - // causes `sendmsg` to fail with `EFAULT` or `EINVAL` - #[cfg(not(linux_kernel))] - if self.length == 0 { - return core::ptr::null_mut(); - } - - self.buffer.as_mut_ptr().cast() - } - - /// Returns the length of the message data. - pub(crate) fn control_len(&self) -> usize { - self.length - } - - /// Delete all messages from the buffer. - pub fn clear(&mut self) { - self.length = 0; - } - - /// Add an ancillary message to the buffer. - /// - /// Returns `true` if the message was added successfully. - pub fn push(&mut self, msg: SendAncillaryMessage<'slice, 'fd>) -> bool { - match msg { - SendAncillaryMessage::ScmRights(fds) => { - let fds_bytes = - unsafe { slice::from_raw_parts(fds.as_ptr().cast::<u8>(), size_of_val(fds)) }; - self.push_ancillary(fds_bytes, c::SOL_SOCKET as _, c::SCM_RIGHTS as _) - } - #[cfg(linux_kernel)] - SendAncillaryMessage::ScmCredentials(ucred) => { - let ucred_bytes = unsafe { - slice::from_raw_parts(addr_of!(ucred).cast::<u8>(), size_of_val(&ucred)) - }; - self.push_ancillary(ucred_bytes, c::SOL_SOCKET as _, c::SCM_CREDENTIALS as _) - } - } - } - - /// Pushes an ancillary message to the buffer. - fn push_ancillary(&mut self, source: &[u8], cmsg_level: c::c_int, cmsg_type: c::c_int) -> bool { - macro_rules! leap { - ($e:expr) => {{ - match ($e) { - Some(x) => x, - None => return false, - } - }}; - } - - // Calculate the length of the message. - let source_len = leap!(u32::try_from(source.len()).ok()); - - // Calculate the new length of the buffer. - let additional_space = unsafe { c::CMSG_SPACE(source_len) }; - let new_length = leap!(self.length.checked_add(additional_space as usize)); - let buffer = leap!(self.buffer.get_mut(..new_length)); - - // Fill the new part of the buffer with zeroes. - buffer[self.length..new_length].fill(MaybeUninit::new(0)); - self.length = new_length; - - // Get the last header in the buffer. - let last_header = leap!(messages::Messages::new(buffer).last()); - - // Set the header fields. - last_header.cmsg_len = unsafe { c::CMSG_LEN(source_len) } as _; - last_header.cmsg_level = cmsg_level; - last_header.cmsg_type = cmsg_type; - - // Get the pointer to the payload and copy the data. - unsafe { - let payload = c::CMSG_DATA(last_header); - ptr::copy_nonoverlapping(source.as_ptr(), payload, source_len as usize); - } - - true - } -} - -impl<'slice, 'fd> Extend<SendAncillaryMessage<'slice, 'fd>> - for SendAncillaryBuffer<'_, 'slice, 'fd> -{ - fn extend<T: IntoIterator<Item = SendAncillaryMessage<'slice, 'fd>>>(&mut self, iter: T) { - // TODO: This could be optimized to add every message in one go. - iter.into_iter().all(|msg| self.push(msg)); - } -} - -/// Buffer for receiving ancillary messages with [`recvmsg`]. -/// -/// Use the [`drain`] function to iterate over the received messages. -/// -/// [`drain`]: RecvAncillaryBuffer::drain -#[derive(Default)] -pub struct RecvAncillaryBuffer<'buf> { - /// Raw byte buffer for messages. - buffer: &'buf mut [MaybeUninit<u8>], - - /// The portion of the buffer we've read from already. - read: usize, - - /// The amount of the buffer that is used. - length: usize, -} - -impl<'buf> From<&'buf mut [MaybeUninit<u8>]> for RecvAncillaryBuffer<'buf> { - fn from(buffer: &'buf mut [MaybeUninit<u8>]) -> Self { - Self::new(buffer) - } -} - -impl<'buf> RecvAncillaryBuffer<'buf> { - /// Create a new, empty `RecvAncillaryBuffer` from a raw byte buffer. - /// - /// The buffer size may be computed with [`cmsg_space`], or it may be - /// zero for an empty buffer, however in that case, consider `default()` - /// instead, or even using [`recv`] instead of `recvmsg`. - /// - /// # Examples - /// - /// Allocate a buffer for a single file descriptor: - /// ``` - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::RecvAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(1))]; - /// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space); - /// ``` - /// - /// Allocate a buffer for credentials: - /// ``` - /// # #[cfg(linux_kernel)] - /// # { - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::RecvAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; - /// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space); - /// # } - /// ``` - /// - /// Allocate a buffer for two file descriptors and credentials: - /// ``` - /// # #[cfg(linux_kernel)] - /// # { - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::RecvAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; - /// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space); - /// # } - /// ``` - /// - /// [`recv`]: crate::net::recv - #[inline] - pub fn new(buffer: &'buf mut [MaybeUninit<u8>]) -> Self { - Self { - buffer: align_for_cmsghdr(buffer), - read: 0, - length: 0, - } - } - - /// Returns a pointer to the message data. - pub(crate) fn as_control_ptr(&mut self) -> *mut u8 { - // When the length is zero, we may be using a `&[]` address, which may - // be an invalid but non-null pointer, and on some platforms, that - // causes `sendmsg` to fail with `EFAULT` or `EINVAL` - #[cfg(not(linux_kernel))] - if self.buffer.is_empty() { - return core::ptr::null_mut(); - } - - self.buffer.as_mut_ptr().cast() - } - - /// Returns the length of the message data. - pub(crate) fn control_len(&self) -> usize { - self.buffer.len() - } - - /// Set the length of the message data. - /// - /// # Safety - /// - /// The buffer must be filled with valid message data. - pub(crate) unsafe fn set_control_len(&mut self, len: usize) { - self.length = len; - self.read = 0; - } - - /// Delete all messages from the buffer. - pub(crate) fn clear(&mut self) { - self.drain().for_each(drop); - } - - /// Drain all messages from the buffer. - pub fn drain(&mut self) -> AncillaryDrain<'_> { - AncillaryDrain { - messages: messages::Messages::new(&mut self.buffer[self.read..][..self.length]), - read_and_length: Some((&mut self.read, &mut self.length)), - } - } -} - -impl Drop for RecvAncillaryBuffer<'_> { - fn drop(&mut self) { - self.clear(); - } -} - -/// Return a slice of `buffer` starting at the first `cmsghdr` alignment -/// boundary. -#[inline] -fn align_for_cmsghdr(buffer: &mut [MaybeUninit<u8>]) -> &mut [MaybeUninit<u8>] { - // If the buffer is empty, we won't be writing anything into it, so it - // doesn't need to be aligned. - if buffer.is_empty() { - return buffer; - } - - let align = align_of::<c::cmsghdr>(); - let addr = buffer.as_ptr() as usize; - let adjusted = (addr + (align - 1)) & align.wrapping_neg(); - &mut buffer[adjusted - addr..] -} - -/// An iterator that drains messages from a [`RecvAncillaryBuffer`]. -pub struct AncillaryDrain<'buf> { - /// Inner iterator over messages. - messages: messages::Messages<'buf>, - - /// Increment the number of messages we've read. - /// Decrement the total length. - read_and_length: Option<(&'buf mut usize, &'buf mut usize)>, -} - -impl<'buf> AncillaryDrain<'buf> { - /// Create an iterator for control messages that were received without - /// [`RecvAncillaryBuffer`]. - /// - /// # Safety - /// - /// The buffer must contain valid message data (or be empty). - pub unsafe fn parse(buffer: &'buf mut [u8]) -> Self { - Self { - messages: messages::Messages::new(buffer), - read_and_length: None, - } - } - - fn advance( - read_and_length: &mut Option<(&'buf mut usize, &'buf mut usize)>, - msg: &c::cmsghdr, - ) -> Option<RecvAncillaryMessage<'buf>> { - // Advance the `read` pointer. - if let Some((read, length)) = read_and_length { - let msg_len = msg.cmsg_len as usize; - **read += msg_len; - **length -= msg_len; - } - - Self::cvt_msg(msg) - } - - /// A closure that converts a message into a [`RecvAncillaryMessage`]. - fn cvt_msg(msg: &c::cmsghdr) -> Option<RecvAncillaryMessage<'buf>> { - unsafe { - // Get a pointer to the payload. - let payload = c::CMSG_DATA(msg); - let payload_len = msg.cmsg_len as usize - c::CMSG_LEN(0) as usize; - - // Get a mutable slice of the payload. - let payload: &'buf mut [u8] = slice::from_raw_parts_mut(payload, payload_len); - - // Determine what type it is. - let (level, msg_type) = (msg.cmsg_level, msg.cmsg_type); - match (level as _, msg_type as _) { - (c::SOL_SOCKET, c::SCM_RIGHTS) => { - // Create an iterator that reads out the file descriptors. - let fds = AncillaryIter::new(payload); - - Some(RecvAncillaryMessage::ScmRights(fds)) - } - #[cfg(linux_kernel)] - (c::SOL_SOCKET, c::SCM_CREDENTIALS) => { - if payload_len >= size_of::<UCred>() { - let ucred = payload.as_ptr().cast::<UCred>().read_unaligned(); - Some(RecvAncillaryMessage::ScmCredentials(ucred)) - } else { - None - } - } - _ => None, - } - } - } -} - -impl<'buf> Iterator for AncillaryDrain<'buf> { - type Item = RecvAncillaryMessage<'buf>; - - fn next(&mut self) -> Option<Self::Item> { - self.messages - .find_map(|ev| Self::advance(&mut self.read_and_length, ev)) - } - - fn size_hint(&self) -> (usize, Option<usize>) { - let (_, max) = self.messages.size_hint(); - (0, max) - } - - fn fold<B, F>(mut self, init: B, f: F) -> B - where - Self: Sized, - F: FnMut(B, Self::Item) -> B, - { - self.messages - .filter_map(|ev| Self::advance(&mut self.read_and_length, ev)) - .fold(init, f) - } - - fn count(mut self) -> usize { - self.messages - .filter_map(|ev| Self::advance(&mut self.read_and_length, ev)) - .count() - } - - fn last(mut self) -> Option<Self::Item> - where - Self: Sized, - { - self.messages - .filter_map(|ev| Self::advance(&mut self.read_and_length, ev)) - .last() - } - - fn collect<B: FromIterator<Self::Item>>(mut self) -> B - where - Self: Sized, - { - self.messages - .filter_map(|ev| Self::advance(&mut self.read_and_length, ev)) - .collect() - } -} - -impl FusedIterator for AncillaryDrain<'_> {} - -/// An ABI-compatible wrapper for `mmsghdr`, for sending multiple messages with -/// [sendmmsg]. -#[cfg(target_os = "linux")] -#[repr(transparent)] -pub struct MMsgHdr<'a> { - raw: c::mmsghdr, - _phantom: PhantomData<&'a mut ()>, -} - -#[cfg(target_os = "linux")] -impl<'a> MMsgHdr<'a> { - /// Constructs a new message with no destination address. - pub fn new(iov: &'a [IoSlice<'_>], control: &'a mut SendAncillaryBuffer<'_, '_, '_>) -> Self { - Self::wrap(noaddr_msghdr(iov, control)) - } - - /// Constructs a new message to a specific address. - /// - /// This requires a `SocketAddrAny` instead of using `impl SocketAddrArg`; - /// to obtain a `SocketAddrAny`, use [`SocketAddrArg::as_any`]. - pub fn new_with_addr( - addr: &'a SocketAddrAny, - iov: &'a [IoSlice<'_>], - control: &'a mut SendAncillaryBuffer<'_, '_, '_>, - ) -> Self { - // The reason we use `SocketAddrAny` instead of `SocketAddrArg` here, - // and avoid `use_msghdr`, is that we need a pointer that will remain - // valid for the duration of the `'a` lifetime. `SocketAddrAny` can - // give us a pointer directly, so we use that. - let mut msghdr = noaddr_msghdr(iov, control); - msghdr.msg_name = addr.as_ptr() as _; - msghdr.msg_namelen = bitcast!(addr.addr_len()); - - Self::wrap(msghdr) - } - - fn wrap(msg_hdr: c::msghdr) -> Self { - Self { - raw: c::mmsghdr { - msg_hdr, - msg_len: 0, - }, - _phantom: PhantomData, - } - } - - /// Returns the number of bytes sent. This will return 0 until after a - /// successful call to [sendmmsg]. - pub fn bytes_sent(&self) -> usize { - self.raw.msg_len as usize - } -} - -/// `sendmsg(msghdr)`—Sends a message on a socket. -/// -/// This function is for use on connected sockets, as it doesn't have a way to -/// specify an address. See [`sendmsg_addr`] to send messages on unconnected -/// sockets. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sendmsg.html -/// [Linux]: https://man7.org/linux/man-pages/man2/sendmsg.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendmsg.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendmsg&sektion=2 -/// [NetBSD]: https://man.netbsd.org/sendmsg.2 -/// [OpenBSD]: https://man.openbsd.org/sendmsg.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendmsg§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/sendmsg -#[inline] -pub fn sendmsg<Fd: AsFd>( - socket: Fd, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - flags: SendFlags, -) -> io::Result<usize> { - backend::net::syscalls::sendmsg(socket.as_fd(), iov, control, flags) -} - -/// `sendmsg(msghdr)`—Sends a message on a socket to a specific address. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sendmsg.html -/// [Linux]: https://man7.org/linux/man-pages/man2/sendmsg.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendmsg.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendmsg&sektion=2 -/// [NetBSD]: https://man.netbsd.org/sendmsg.2 -/// [OpenBSD]: https://man.openbsd.org/sendmsg.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendmsg§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/sendmsg -#[inline] -pub fn sendmsg_addr<Fd: AsFd>( - socket: Fd, - addr: &impl SocketAddrArg, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - flags: SendFlags, -) -> io::Result<usize> { - backend::net::syscalls::sendmsg_addr(socket.as_fd(), addr, iov, control, flags) -} - -/// `sendmmsg(msghdr)`—Sends multiple messages on a socket. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/sendmmsg.2.html -#[inline] -#[cfg(target_os = "linux")] -pub fn sendmmsg<Fd: AsFd>( - socket: Fd, - msgs: &mut [MMsgHdr<'_>], - flags: SendFlags, -) -> io::Result<usize> { - backend::net::syscalls::sendmmsg(socket.as_fd(), msgs, flags) -} - -/// `recvmsg(msghdr)`—Receives a message from a socket. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/recvmsg.html -/// [Linux]: https://man7.org/linux/man-pages/man2/recvmsg.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recvmsg.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=recvmsg&sektion=2 -/// [NetBSD]: https://man.netbsd.org/recvmsg.2 -/// [OpenBSD]: https://man.openbsd.org/recvmsg.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=recvmsg§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/recvmsg -#[inline] -pub fn recvmsg<Fd: AsFd>( - socket: Fd, - iov: &mut [IoSliceMut<'_>], - control: &mut RecvAncillaryBuffer<'_>, - flags: RecvFlags, -) -> io::Result<RecvMsg> { - backend::net::syscalls::recvmsg(socket.as_fd(), iov, control, flags) -} - -/// The result of a successful [`recvmsg`] call. -#[derive(Debug, Clone)] -pub struct RecvMsg { - /// The number of bytes received. - /// - /// When `RecvFlags::TRUNC` is in use, this may be greater than the length - /// of the buffer, as it reflects the number of bytes received before - /// truncation into the buffer. - pub bytes: usize, - - /// The flags received. - pub flags: ReturnFlags, - - /// The address of the socket we received from, if any. - pub address: Option<SocketAddrAny>, -} - -/// An iterator over data in an ancillary buffer. -pub struct AncillaryIter<'data, T> { - /// The data we're iterating over. - data: &'data mut [u8], - - /// The raw data we're removing. - _marker: PhantomData<T>, -} - -impl<'data, T> AncillaryIter<'data, T> { - /// Create a new iterator over data in an ancillary buffer. - /// - /// # Safety - /// - /// The buffer must contain valid ancillary data. - unsafe fn new(data: &'data mut [u8]) -> Self { - assert_eq!(data.len() % size_of::<T>(), 0); - - Self { - data, - _marker: PhantomData, - } - } -} - -impl<'data, T> Drop for AncillaryIter<'data, T> { - fn drop(&mut self) { - self.for_each(drop); - } -} - -impl<T> Iterator for AncillaryIter<'_, T> { - type Item = T; - - fn next(&mut self) -> Option<Self::Item> { - // See if there is a next item. - if self.data.len() < size_of::<T>() { - return None; - } - - // Get the next item. - let item = unsafe { self.data.as_ptr().cast::<T>().read_unaligned() }; - - // Move forward. - let data = take(&mut self.data); - self.data = &mut data[size_of::<T>()..]; - - Some(item) - } - - fn size_hint(&self) -> (usize, Option<usize>) { - let len = self.len(); - (len, Some(len)) - } - - fn count(self) -> usize { - self.len() - } - - fn last(mut self) -> Option<Self::Item> { - self.next_back() - } -} - -impl<T> FusedIterator for AncillaryIter<'_, T> {} - -impl<T> ExactSizeIterator for AncillaryIter<'_, T> { - fn len(&self) -> usize { - self.data.len() / size_of::<T>() - } -} - -impl<T> DoubleEndedIterator for AncillaryIter<'_, T> { - fn next_back(&mut self) -> Option<Self::Item> { - // See if there is a next item. - if self.data.len() < size_of::<T>() { - return None; - } - - // Get the next item. - let item = unsafe { - let ptr = self.data.as_ptr().add(self.data.len() - size_of::<T>()); - ptr.cast::<T>().read_unaligned() - }; - - // Move forward. - let len = self.data.len(); - let data = take(&mut self.data); - self.data = &mut data[..len - size_of::<T>()]; - - Some(item) - } -} - -mod messages { - use crate::backend::c; - use crate::backend::net::msghdr; - use core::iter::FusedIterator; - use core::marker::PhantomData; - use core::mem::MaybeUninit; - use core::ptr::NonNull; - - /// An iterator over the messages in an ancillary buffer. - pub(super) struct Messages<'buf> { - /// The message header we're using to iterate over the messages. - msghdr: c::msghdr, - - /// The current pointer to the next message header to return. - /// - /// This has a lifetime of `'buf`. - header: Option<NonNull<c::cmsghdr>>, - - /// Capture the original lifetime of the buffer. - _buffer: PhantomData<&'buf mut [MaybeUninit<u8>]>, - } - - pub(super) trait AllowedMsgBufType {} - impl AllowedMsgBufType for u8 {} - impl AllowedMsgBufType for MaybeUninit<u8> {} - - impl<'buf> Messages<'buf> { - /// Create a new iterator over messages from a byte buffer. - pub(super) fn new(buf: &'buf mut [impl AllowedMsgBufType]) -> Self { - let mut msghdr = msghdr::zero_msghdr(); - msghdr.msg_control = buf.as_mut_ptr().cast(); - msghdr.msg_controllen = buf.len().try_into().expect("buffer too large for msghdr"); - - // Get the first header. - let header = NonNull::new(unsafe { c::CMSG_FIRSTHDR(&msghdr) }); - - Self { - msghdr, - header, - _buffer: PhantomData, - } - } - } - - impl<'a> Iterator for Messages<'a> { - type Item = &'a mut c::cmsghdr; - - #[inline] - fn next(&mut self) -> Option<Self::Item> { - // Get the current header. - let header = self.header?; - - // Get the next header. - self.header = NonNull::new(unsafe { c::CMSG_NXTHDR(&self.msghdr, header.as_ptr()) }); - - // If the headers are equal, we're done. - if Some(header) == self.header { - self.header = None; - } - - // SAFETY: The lifetime of `header` is tied to this. - Some(unsafe { &mut *header.as_ptr() }) - } - - fn size_hint(&self) -> (usize, Option<usize>) { - if self.header.is_some() { - // The remaining buffer *could* be filled with zero-length - // messages. - let max_size = unsafe { c::CMSG_LEN(0) } as usize; - let remaining_count = self.msghdr.msg_controllen as usize / max_size; - (1, Some(remaining_count)) - } else { - (0, Some(0)) - } - } - } - - impl FusedIterator for Messages<'_> {} -} diff --git a/vendor/rustix/src/net/socket.rs b/vendor/rustix/src/net/socket.rs deleted file mode 100644 index fff302ad..00000000 --- a/vendor/rustix/src/net/socket.rs +++ /dev/null @@ -1,461 +0,0 @@ -use crate::fd::OwnedFd; -use crate::net::addr::SocketAddrArg; -use crate::net::SocketAddrAny; -use crate::{backend, io}; -use backend::fd::AsFd; - -pub use crate::net::{AddressFamily, Protocol, Shutdown, SocketFlags, SocketType}; -#[cfg(unix)] -pub use backend::net::addr::SocketAddrUnix; - -/// `socket(domain, type_, protocol)`—Creates a socket. -/// -/// POSIX guarantees that `socket` will use the lowest unused file descriptor, -/// however it is not safe in general to rely on this, as file descriptors may -/// be unexpectedly allocated on other threads or in libraries. -/// -/// To pass extra flags such as [`SocketFlags::CLOEXEC`] or -/// [`SocketFlags::NONBLOCK`], use [`socket_with`]. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#socket -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/socket.html -/// [Linux]: https://man7.org/linux/man-pages/man2/socket.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socket.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2 -/// [NetBSD]: https://man.netbsd.org/socket.2 -/// [OpenBSD]: https://man.openbsd.org/socket.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socket§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/socket -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Creating-a-Socket.html -#[inline] -pub fn socket( - domain: AddressFamily, - type_: SocketType, - protocol: Option<Protocol>, -) -> io::Result<OwnedFd> { - backend::net::syscalls::socket(domain, type_, protocol) -} - -/// `socket_with(domain, type_ | flags, protocol)`—Creates a socket, with -/// flags. -/// -/// POSIX guarantees that `socket` will use the lowest unused file descriptor, -/// however it is not safe in general to rely on this, as file descriptors may -/// be unexpectedly allocated on other threads or in libraries. -/// -/// `socket_with` is the same as [`socket`] but adds an additional flags -/// operand. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#socket -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/socket.html -/// [Linux]: https://man7.org/linux/man-pages/man2/socket.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socket.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2 -/// [NetBSD]: https://man.netbsd.org/socket.2 -/// [OpenBSD]: https://man.openbsd.org/socket.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socket§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/socket -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Creating-a-Socket.html -#[doc(alias("socket"))] -#[inline] -pub fn socket_with( - domain: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option<Protocol>, -) -> io::Result<OwnedFd> { - backend::net::syscalls::socket_with(domain, type_, flags, protocol) -} - -/// `bind(sockfd, addr)`—Binds a socket to an IP address. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/bind.html -/// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2 -/// [NetBSD]: https://man.netbsd.org/bind.2 -/// [OpenBSD]: https://man.openbsd.org/bind.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/bind -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Setting-Address.html -pub fn bind<Fd: AsFd>(sockfd: Fd, addr: &impl SocketAddrArg) -> io::Result<()> { - backend::net::syscalls::bind(sockfd.as_fd(), addr) -} - -/// `connect(sockfd, addr)`—Initiates a connection to an IP address. -/// -/// On Windows, a non-blocking socket returns [`Errno::WOULDBLOCK`] if the -/// connection cannot be completed immediately, rather than -/// `Errno::INPROGRESS`. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/connect.html -/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2 -/// [NetBSD]: https://man.netbsd.org/connect.2 -/// [OpenBSD]: https://man.openbsd.org/connect.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/connect -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Connecting.html -/// [`Errno::WOULDBLOCK`]: io::Errno::WOULDBLOCK -pub fn connect<Fd: AsFd>(sockfd: Fd, addr: &impl SocketAddrArg) -> io::Result<()> { - backend::net::syscalls::connect(sockfd.as_fd(), addr) -} - -/// `connect(sockfd, {.sa_family = AF_UNSPEC}, sizeof(struct sockaddr))`— -/// Dissolve the socket's association. -/// -/// On UDP sockets, BSD platforms report [`Errno::AFNOSUPPORT`] or -/// [`Errno::INVAL`] even if the disconnect was successful. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/connect.html -/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2 -/// [NetBSD]: https://man.netbsd.org/connect.2 -/// [OpenBSD]: https://man.openbsd.org/connect.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/connect -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Connecting.html -/// [`Errno::AFNOSUPPORT`]: io::Errno::AFNOSUPPORT -/// [`Errno::INVAL`]: io::Errno::INVAL -#[inline] -#[doc(alias = "connect")] -pub fn connect_unspec<Fd: AsFd>(sockfd: Fd) -> io::Result<()> { - backend::net::syscalls::connect_unspec(sockfd.as_fd()) -} - -/// `listen(fd, backlog)`—Enables listening for incoming connections. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#listen -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/listen.html -/// [Linux]: https://man7.org/linux/man-pages/man2/listen.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/listen.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=listen&sektion=2 -/// [NetBSD]: https://man.netbsd.org/listen.2 -/// [OpenBSD]: https://man.openbsd.org/listen.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=listen§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/listen -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Listening.html -#[inline] -pub fn listen<Fd: AsFd>(sockfd: Fd, backlog: i32) -> io::Result<()> { - backend::net::syscalls::listen(sockfd.as_fd(), backlog) -} - -/// `accept(fd, NULL, NULL)`—Accepts an incoming connection. -/// -/// Use [`acceptfrom`] to retrieve the peer address. -/// -/// POSIX guarantees that `accept` will use the lowest unused file descriptor, -/// however it is not safe in general to rely on this, as file descriptors may -/// be unexpectedly allocated on other threads or in libraries. -/// -/// See [`accept_with`] to pass additional flags. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#acceptthank-you-for-calling-port-3490. -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/accept.html -/// [Linux]: https://man7.org/linux/man-pages/man2/accept.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/accept.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2 -/// [NetBSD]: https://man.netbsd.org/accept.2 -/// [OpenBSD]: https://man.openbsd.org/accept.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/accept -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Accepting-Connections.html -#[inline] -pub fn accept<Fd: AsFd>(sockfd: Fd) -> io::Result<OwnedFd> { - backend::net::syscalls::accept(sockfd.as_fd()) -} - -/// `accept4(fd, NULL, NULL, flags)`—Accepts an incoming connection, with -/// flags. -/// -/// Use [`acceptfrom_with`] to retrieve the peer address. -/// -/// Even though POSIX guarantees that this will use the lowest unused file -/// descriptor, it is not safe in general to rely on this, as file descriptors -/// may be unexpectedly allocated on other threads or in libraries. -/// -/// `accept_with` is the same as [`accept`] but adds an additional flags -/// operand. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/accept4.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept4&sektion=2 -/// [NetBSD]: https://man.netbsd.org/accept4.2 -/// [OpenBSD]: https://man.openbsd.org/accept4.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept4§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/accept4 -#[inline] -#[doc(alias = "accept4")] -pub fn accept_with<Fd: AsFd>(sockfd: Fd, flags: SocketFlags) -> io::Result<OwnedFd> { - backend::net::syscalls::accept_with(sockfd.as_fd(), flags) -} - -/// `accept(fd, &addr, &len)`—Accepts an incoming connection and returns the -/// peer address. -/// -/// Use [`accept`] if the peer address isn't needed. -/// -/// See [`acceptfrom_with`] to pass additional flags. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#acceptthank-you-for-calling-port-3490. -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/accept.html -/// [Linux]: https://man7.org/linux/man-pages/man2/accept.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/accept.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2 -/// [NetBSD]: https://man.netbsd.org/accept.2 -/// [OpenBSD]: https://man.openbsd.org/accept.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/accept -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Accepting-Connections.html -#[inline] -#[doc(alias = "accept")] -pub fn acceptfrom<Fd: AsFd>(sockfd: Fd) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> { - backend::net::syscalls::acceptfrom(sockfd.as_fd()) -} - -/// `accept4(fd, &addr, &len, flags)`—Accepts an incoming connection and -/// returns the peer address, with flags. -/// -/// Use [`accept_with`] if the peer address isn't needed. -/// -/// `acceptfrom_with` is the same as [`acceptfrom`] but adds an additional -/// flags operand. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/accept4.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept4&sektion=2 -/// [NetBSD]: https://man.netbsd.org/accept4.2 -/// [OpenBSD]: https://man.openbsd.org/accept4.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept4§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/accept4 -#[inline] -#[doc(alias = "accept4")] -pub fn acceptfrom_with<Fd: AsFd>( - sockfd: Fd, - flags: SocketFlags, -) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> { - backend::net::syscalls::acceptfrom_with(sockfd.as_fd(), flags) -} - -/// `shutdown(fd, how)`—Closes the read and/or write sides of a stream. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#close-and-shutdownget-outta-my-face -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/shutdown.html -/// [Linux]: https://man7.org/linux/man-pages/man2/shutdown.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/shutdown.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-shutdown -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=shutdown&sektion=2 -/// [NetBSD]: https://man.netbsd.org/shutdown.2 -/// [OpenBSD]: https://man.openbsd.org/shutdown.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=shutdown§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/shutdown -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Closing-a-Socket.html -#[inline] -pub fn shutdown<Fd: AsFd>(sockfd: Fd, how: Shutdown) -> io::Result<()> { - backend::net::syscalls::shutdown(sockfd.as_fd(), how) -} - -/// `getsockname(fd, addr, len)`—Returns the address a socket is bound to. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getsockname.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getsockname.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockname.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockname -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockname&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockname.2 -/// [OpenBSD]: https://man.openbsd.org/getsockname.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockname§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockname -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Reading-Address.html -#[inline] -pub fn getsockname<Fd: AsFd>(sockfd: Fd) -> io::Result<SocketAddrAny> { - backend::net::syscalls::getsockname(sockfd.as_fd()) -} - -/// `getpeername(fd, addr, len)`—Returns the address a socket is connected -/// to. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#getpeernamewho-are-you -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpeername.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpeername.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getpeername.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getpeername -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getpeername.2 -/// [OpenBSD]: https://man.openbsd.org/getpeername.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getpeername§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getpeername -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Who-is-Connected.html -#[inline] -pub fn getpeername<Fd: AsFd>(sockfd: Fd) -> io::Result<Option<SocketAddrAny>> { - backend::net::syscalls::getpeername(sockfd.as_fd()) -} diff --git a/vendor/rustix/src/net/socket_addr_any.rs b/vendor/rustix/src/net/socket_addr_any.rs deleted file mode 100644 index 7a953044..00000000 --- a/vendor/rustix/src/net/socket_addr_any.rs +++ /dev/null @@ -1,344 +0,0 @@ -//! The [`SocketAddrAny`] type and related utilities. - -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::backend::net::read_sockaddr; -use crate::io::Errno; -use crate::net::addr::{SocketAddrArg, SocketAddrLen, SocketAddrOpaque, SocketAddrStorage}; -#[cfg(unix)] -use crate::net::SocketAddrUnix; -use crate::net::{AddressFamily, SocketAddr, SocketAddrV4, SocketAddrV6}; -use core::fmt; -use core::mem::{size_of, MaybeUninit}; -use core::num::NonZeroU32; - -/// Temporary buffer for creating a `SocketAddrAny` from a syscall that writes -/// to a `sockaddr_t` and `socklen_t` -/// -/// Unlike `SocketAddrAny`, this does not maintain the invariant that `len` -/// bytes are initialized. -pub(crate) struct SocketAddrBuf { - pub(crate) len: c::socklen_t, - pub(crate) storage: MaybeUninit<SocketAddrStorage>, -} - -impl SocketAddrBuf { - #[inline] - pub(crate) const fn new() -> Self { - Self { - len: size_of::<SocketAddrStorage>() as c::socklen_t, - storage: MaybeUninit::<SocketAddrStorage>::uninit(), - } - } - - /// Convert the buffer into [`SocketAddrAny`]. - /// - /// # Safety - /// - /// A valid address must have been written into `self.storage` and its - /// length written into `self.len`. - #[inline] - pub(crate) unsafe fn into_any(self) -> SocketAddrAny { - SocketAddrAny::new(self.storage, bitcast!(self.len)) - } - - /// Convert the buffer into [`Option<SocketAddrAny>`]. - /// - /// This returns `None` if `len` is zero or other platform-specific - /// conditions define the address as empty. - /// - /// # Safety - /// - /// Either valid address must have been written into `self.storage` and its - /// length written into `self.len`, or `self.len` must have been set to 0. - #[inline] - pub(crate) unsafe fn into_any_option(self) -> Option<SocketAddrAny> { - let len = bitcast!(self.len); - if read_sockaddr::sockaddr_nonempty(self.storage.as_ptr().cast(), len) { - Some(SocketAddrAny::new(self.storage, len)) - } else { - None - } - } -} - -/// A type that can hold any kind of socket address, as a safe abstraction for -/// `sockaddr_storage`. -/// -/// Socket addresses can be converted to `SocketAddrAny` via the [`From`] and -/// [`Into`] traits. `SocketAddrAny` can be converted back to a specific socket -/// address type with [`TryFrom`] and [`TryInto`]. These implementations return -/// [`Errno::AFNOSUPPORT`] if the address family does not match the requested -/// type. -#[derive(Clone)] -#[doc(alias = "sockaddr_storage")] -pub struct SocketAddrAny { - // Invariants: - // - `len` is at least `size_of::<backend::c::sa_family_t>()` - // - `len` is at most `size_of::<SocketAddrStorage>()` - // - The first `len` bytes of `storage` are initialized. - pub(crate) len: NonZeroU32, - pub(crate) storage: MaybeUninit<SocketAddrStorage>, -} - -impl SocketAddrAny { - /// Creates a socket address from `storage`, which is initialized for `len` - /// bytes. - /// - /// # Panics - /// - /// if `len` is smaller than the sockaddr header or larger than - /// `SocketAddrStorage`. - /// - /// # Safety - /// - /// - `storage` must contain a valid socket address. - /// - `len` bytes must be initialized. - #[inline] - pub const unsafe fn new(storage: MaybeUninit<SocketAddrStorage>, len: SocketAddrLen) -> Self { - assert!(len as usize >= size_of::<read_sockaddr::sockaddr_header>()); - assert!(len as usize <= size_of::<SocketAddrStorage>()); - let len = NonZeroU32::new_unchecked(len); - Self { storage, len } - } - - /// Creates a socket address from reading from `ptr`, which points at `len` - /// initialized bytes. - /// - /// # Panics - /// - /// if `len` is smaller than the sockaddr header or larger than - /// `SocketAddrStorage`. - /// - /// # Safety - /// - /// - `ptr` must be a pointer to memory containing a valid socket address. - /// - `len` bytes must be initialized. - pub unsafe fn read(ptr: *const SocketAddrStorage, len: SocketAddrLen) -> Self { - assert!(len as usize >= size_of::<read_sockaddr::sockaddr_header>()); - assert!(len as usize <= size_of::<SocketAddrStorage>()); - let mut storage = MaybeUninit::<SocketAddrStorage>::uninit(); - core::ptr::copy_nonoverlapping( - ptr.cast::<u8>(), - storage.as_mut_ptr().cast::<u8>(), - len as usize, - ); - let len = NonZeroU32::new_unchecked(len); - Self { storage, len } - } - - /// Gets the initialized part of the storage as bytes. - #[inline] - fn bytes(&self) -> &[u8] { - let len = self.len.get() as usize; - unsafe { core::slice::from_raw_parts(self.storage.as_ptr().cast(), len) } - } - - /// Gets the address family of this socket address. - #[inline] - pub fn address_family(&self) -> AddressFamily { - // SAFETY: Our invariants maintain that the `sa_family` field is - // initialized. - unsafe { - AddressFamily::from_raw(crate::backend::net::read_sockaddr::read_sa_family( - self.storage.as_ptr().cast(), - )) - } - } - - /// Returns a raw pointer to the sockaddr. - #[inline] - pub fn as_ptr(&self) -> *const SocketAddrStorage { - self.storage.as_ptr() - } - - /// Returns a raw mutable pointer to the sockaddr. - #[inline] - pub fn as_mut_ptr(&mut self) -> *mut SocketAddrStorage { - self.storage.as_mut_ptr() - } - - /// Returns the length of the encoded sockaddr. - #[inline] - pub fn addr_len(&self) -> SocketAddrLen { - self.len.get() - } -} - -impl PartialEq<Self> for SocketAddrAny { - fn eq(&self, other: &Self) -> bool { - self.bytes() == other.bytes() - } -} - -impl Eq for SocketAddrAny {} - -// This just forwards to another `partial_cmp`. -#[allow(clippy::non_canonical_partial_ord_impl)] -impl PartialOrd<Self> for SocketAddrAny { - fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { - self.bytes().partial_cmp(other.bytes()) - } -} - -impl Ord for SocketAddrAny { - fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.bytes().cmp(other.bytes()) - } -} - -impl core::hash::Hash for SocketAddrAny { - fn hash<H: core::hash::Hasher>(&self, state: &mut H) { - self.bytes().hash(state) - } -} - -impl fmt::Debug for SocketAddrAny { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.address_family() { - AddressFamily::INET => { - if let Ok(addr) = SocketAddrV4::try_from(self.clone()) { - return addr.fmt(f); - } - } - AddressFamily::INET6 => { - if let Ok(addr) = SocketAddrV6::try_from(self.clone()) { - return addr.fmt(f); - } - } - #[cfg(unix)] - AddressFamily::UNIX => { - if let Ok(addr) = SocketAddrUnix::try_from(self.clone()) { - return addr.fmt(f); - } - } - #[cfg(target_os = "linux")] - AddressFamily::XDP => { - if let Ok(addr) = crate::net::xdp::SocketAddrXdp::try_from(self.clone()) { - return addr.fmt(f); - } - } - #[cfg(linux_kernel)] - AddressFamily::NETLINK => { - if let Ok(addr) = crate::net::netlink::SocketAddrNetlink::try_from(self.clone()) { - return addr.fmt(f); - } - } - _ => {} - } - - f.debug_struct("SocketAddrAny") - .field("address_family", &self.address_family()) - .field("namelen", &self.addr_len()) - .finish() - } -} - -// SAFETY: `with_sockaddr` calls `f` with a pointer to its own storage. -unsafe impl SocketAddrArg for SocketAddrAny { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - f(self.as_ptr().cast(), self.addr_len()) - } -} - -impl From<SocketAddr> for SocketAddrAny { - #[inline] - fn from(from: SocketAddr) -> Self { - from.as_any() - } -} - -impl TryFrom<SocketAddrAny> for SocketAddr { - type Error = Errno; - - /// Convert if the address is an IPv4 or IPv6 address. - /// - /// Returns `Err(Errno::AFNOSUPPORT)` if the address family is not IPv4 or - /// IPv6. - #[inline] - fn try_from(value: SocketAddrAny) -> Result<Self, Self::Error> { - match value.address_family() { - AddressFamily::INET => read_sockaddr::read_sockaddr_v4(&value).map(SocketAddr::V4), - AddressFamily::INET6 => read_sockaddr::read_sockaddr_v6(&value).map(SocketAddr::V6), - _ => Err(Errno::AFNOSUPPORT), - } - } -} - -impl From<SocketAddrV4> for SocketAddrAny { - #[inline] - fn from(from: SocketAddrV4) -> Self { - from.as_any() - } -} - -impl TryFrom<SocketAddrAny> for SocketAddrV4 { - type Error = Errno; - - /// Convert if the address is an IPv4 address. - /// - /// Returns `Err(Errno::AFNOSUPPORT)` if the address family is not IPv4. - #[inline] - fn try_from(value: SocketAddrAny) -> Result<Self, Self::Error> { - read_sockaddr::read_sockaddr_v4(&value) - } -} - -impl From<SocketAddrV6> for SocketAddrAny { - #[inline] - fn from(from: SocketAddrV6) -> Self { - from.as_any() - } -} - -impl TryFrom<SocketAddrAny> for SocketAddrV6 { - type Error = Errno; - - /// Convert if the address is an IPv6 address. - /// - /// Returns `Err(Errno::AFNOSUPPORT)` if the address family is not IPv6. - #[inline] - fn try_from(value: SocketAddrAny) -> Result<Self, Self::Error> { - read_sockaddr::read_sockaddr_v6(&value) - } -} - -#[cfg(unix)] -impl From<SocketAddrUnix> for SocketAddrAny { - #[inline] - fn from(from: SocketAddrUnix) -> Self { - from.as_any() - } -} - -#[cfg(unix)] -impl TryFrom<SocketAddrAny> for SocketAddrUnix { - type Error = Errno; - - /// Convert if the address is a Unix socket address. - /// - /// Returns `Err(Errno::AFNOSUPPORT)` if the address family is not Unix. - #[inline] - fn try_from(value: SocketAddrAny) -> Result<Self, Self::Error> { - read_sockaddr::read_sockaddr_unix(&value) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn any_read() { - let localhost = std::net::Ipv6Addr::LOCALHOST; - let addr = SocketAddrAny::from(SocketAddrV6::new(localhost, 7, 8, 9)); - unsafe { - let same = SocketAddrAny::read(addr.as_ptr(), addr.addr_len()); - assert_eq!(addr, same); - } - } -} diff --git a/vendor/rustix/src/net/socketpair.rs b/vendor/rustix/src/net/socketpair.rs deleted file mode 100644 index 29227f96..00000000 --- a/vendor/rustix/src/net/socketpair.rs +++ /dev/null @@ -1,36 +0,0 @@ -use crate::fd::OwnedFd; -use crate::net::{AddressFamily, Protocol, SocketFlags, SocketType}; -use crate::{backend, io}; - -/// `socketpair(domain, type_ | accept_flags, protocol)`—Create a pair of -/// sockets that are connected to each other. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/socketpair.html -/// [Linux]: https://man7.org/linux/man-pages/man2/socketpair.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socketpair.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socketpair&sektion=2 -/// [NetBSD]: https://man.netbsd.org/socketpair.2 -/// [OpenBSD]: https://man.openbsd.org/socketpair.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socketpair§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/socketpair -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Socket-Pairs.html -#[inline] -pub fn socketpair( - domain: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option<Protocol>, -) -> io::Result<(OwnedFd, OwnedFd)> { - backend::net::syscalls::socketpair(domain, type_, flags, protocol) -} diff --git a/vendor/rustix/src/net/sockopt.rs b/vendor/rustix/src/net/sockopt.rs deleted file mode 100644 index ef8176ae..00000000 --- a/vendor/rustix/src/net/sockopt.rs +++ /dev/null @@ -1,1649 +0,0 @@ -//! `getsockopt` and `setsockopt` functions. -//! -//! 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 getter functions: -//! -//! - [POSIX `getsockopt`] -//! - [Linux `getsockopt`] -//! - [Winsock `getsockopt`] -//! - [Apple `getsockopt`] -//! - [FreeBSD `getsockopt`] -//! - [NetBSD `getsockopt`] -//! - [OpenBSD `getsockopt`] -//! - [DragonFly BSD `getsockopt`] -//! - [illumos `getsockopt`] -//! - [glibc `getsockopt`] -//! -//! [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getsockopt.html -//! [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -//! [Winsock `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://sourceware.org/glibc/manual/latest/html_node/Socket-Option-Functions.html -//! -//! # References for all `set_*` functions: -//! -//! - [POSIX `setsockopt`] -//! - [Linux `setsockopt`] -//! - [Winsock `setsockopt`] -//! - [Apple `setsockopt`] -//! - [FreeBSD `setsockopt`] -//! - [NetBSD `setsockopt`] -//! - [OpenBSD `setsockopt`] -//! - [DragonFly BSD `setsockopt`] -//! - [illumos `setsockopt`] -//! - [glibc `setsockopt`] -//! -//! [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setsockopt.html -//! [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -//! [Winsock `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://sourceware.org/glibc/manual/latest/html_node/Socket-Option-Functions.html -//! -//! # References for `get_socket_*` and `set_socket_*` functions: -//! -//! - [References for all getter functions] -//! - [References for all `set_*` functions] -//! - [POSIX `sys/socket.h`] -//! - [Linux `socket`] -//! - [Winsock `SOL_SOCKET` options] -//! - [glibc `SOL_SOCKET` Options] -//! -//! [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_socket.h.html -//! [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -//! [Winsock `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -//! [glibc `SOL_SOCKET` options]: https://sourceware.org/glibc/manual/latest/html_node/Socket_002dLevel-Options.html -//! -//! # References for `get_ip_*` and `set_ip_*` functions: -//! -//! - [References for all getter functions] -//! - [References for all `set_*` functions] -//! - [POSIX `netinet/in.h`] -//! - [Linux `ip`] -//! - [Winsock `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/9799919799/basedefs/netinet_in.h.html -//! [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -//! [Winsock `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -//! [Apple `ip`]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man4/ip.4 -//! [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 getter functions] -//! - [References for all `set_*` functions] -//! - [POSIX `netinet/in.h`] -//! - [Linux `ipv6`] -//! - [Winsock `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/9799919799/basedefs/netinet_in.h.html -//! [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -//! [Winsock `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -//! [Apple `ip6`]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man4/ip6.4 -//! [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 getter functions] -//! - [References for all `set_*` functions] -//! - [POSIX `netinet/tcp.h`] -//! - [Linux `tcp`] -//! - [Winsock `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/9799919799/basedefs/netinet_tcp.h.html -//! [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -//! [Winsock `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -//! [Apple `tcp`]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man4/tcp.4 -//! [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 getter functions]: #references-for-all-getter-functions -//! [References for all `set_*` functions]: #references-for-all-set_-functions - -#![doc(alias = "getsockopt")] -#![doc(alias = "setsockopt")] - -#[cfg(target_os = "linux")] -use crate::net::xdp::{XdpMmapOffsets, XdpOptionsFlags, XdpStatistics, XdpUmemReg}; -#[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "netbsd", - target_os = "nto", - target_os = "vita", -)))] -use crate::net::AddressFamily; -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "openbsd", - target_os = "redox", - target_env = "newlib" -))] -use crate::net::Protocol; -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -use crate::net::SocketAddrV4; -#[cfg(linux_kernel)] -use crate::net::SocketAddrV6; -use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; -use crate::{backend, io}; -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -use alloc::string::String; -use backend::c; -use backend::fd::AsFd; -use core::time::Duration; - -/// Timeout identifier for use with [`set_socket_timeout`] and -/// [`socket_timeout`]. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum Timeout { - /// `SO_RCVTIMEO`—Timeout for receiving. - Recv = c::SO_RCVTIMEO as _, - - /// `SO_SNDTIMEO`—Timeout for sending. - Send = c::SO_SNDTIMEO as _, -} - -/// `getsockopt(fd, SOL_SOCKET, SO_TYPE)`—Returns the type of a socket. -/// -/// 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 socket_type<Fd: AsFd>(fd: Fd) -> io::Result<SocketType> { - backend::net::sockopt::socket_type(fd.as_fd()) -} - -/// `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: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_reuseaddr(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_REUSEADDR)` -/// -/// 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 socket_reuseaddr<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_reuseaddr(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_BROADCAST, value)` -/// -/// 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: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_broadcast(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_BROADCAST)` -/// -/// 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 socket_broadcast<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_broadcast(fd.as_fd()) -} - -/// `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: AsFd>(fd: Fd, value: Option<Duration>) -> io::Result<()> { - backend::net::sockopt::set_socket_linger(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_LINGER)` -/// -/// 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 socket_linger<Fd: AsFd>(fd: Fd) -> io::Result<Option<Duration>> { - backend::net::sockopt::socket_linger(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_PASSCRED, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [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: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_passcred(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_PASSCRED)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "SO_PASSCRED")] -pub fn socket_passcred<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_passcred(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, id, value)`—Set the sending or receiving -/// timeout. -/// -/// 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")] -pub fn set_socket_timeout<Fd: AsFd>( - fd: Fd, - id: Timeout, - value: Option<Duration>, -) -> io::Result<()> { - backend::net::sockopt::set_socket_timeout(fd.as_fd(), id, value) -} - -/// `getsockopt(fd, SOL_SOCKET, id)`—Get the sending or receiving timeout. -/// -/// 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")] -pub fn socket_timeout<Fd: AsFd>(fd: Fd, id: Timeout) -> io::Result<Option<Duration>> { - backend::net::sockopt::socket_timeout(fd.as_fd(), id) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_ERROR)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_ERROR")] -pub fn socket_error<Fd: AsFd>(fd: Fd) -> io::Result<Result<(), io::Errno>> { - backend::net::sockopt::socket_error(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(any(apple, freebsdlike, target_os = "netbsd"))] -#[doc(alias = "SO_NOSIGPIPE")] -#[inline] -pub fn socket_nosigpipe<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_nosigpipe(fd.as_fd()) -} - -/// `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, freebsdlike, target_os = "netbsd"))] -#[doc(alias = "SO_NOSIGPIPE")] -#[inline] -pub fn set_socket_nosigpipe<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_nosigpipe(fd.as_fd(), value) -} - -/// `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: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_keepalive(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE)` -/// -/// 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 socket_keepalive<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_keepalive(fd.as_fd()) -} - -/// `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: AsFd>(fd: Fd, value: usize) -> io::Result<()> { - backend::net::sockopt::set_socket_recv_buffer_size(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "redox"))] -#[inline] -#[doc(alias = "SO_RCVBUFFORCE")] -pub fn set_socket_recv_buffer_size_force<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> { - backend::net::sockopt::set_socket_recv_buffer_size_force(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_RCVBUF)` -/// -/// 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 socket_recv_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> { - backend::net::sockopt::socket_recv_buffer_size(fd.as_fd()) -} - -/// `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: AsFd>(fd: Fd, value: usize) -> io::Result<()> { - backend::net::sockopt::set_socket_send_buffer_size(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "redox"))] -#[inline] -#[doc(alias = "SO_SNDBUFFORCE")] -pub fn set_socket_send_buffer_size_force<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> { - backend::net::sockopt::set_socket_send_buffer_size_force(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_SNDBUF)` -/// -/// 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 socket_send_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> { - backend::net::sockopt::socket_send_buffer_size(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_DOMAIN)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "netbsd", - target_os = "nto", - target_os = "vita", -)))] -#[inline] -#[doc(alias = "SO_DOMAIN")] -pub fn socket_domain<Fd: AsFd>(fd: Fd) -> io::Result<AddressFamily> { - backend::net::sockopt::socket_domain(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN)` -/// -/// 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")] -pub fn socket_acceptconn<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::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: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::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 socket_oobinline<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_oobinline(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(not(any(solarish, windows, target_os = "cygwin")))] -#[cfg(not(windows))] -#[inline] -#[doc(alias = "SO_REUSEPORT")] -pub fn set_socket_reuseport<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_reuseport(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_REUSEPORT)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(not(any(solarish, windows, target_os = "cygwin")))] -#[inline] -#[doc(alias = "SO_REUSEPORT")] -pub fn socket_reuseport<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_reuseport(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(target_os = "freebsd")] -#[inline] -#[doc(alias = "SO_REUSEPORT_LB")] -pub fn set_socket_reuseport_lb<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_reuseport_lb(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(target_os = "freebsd")] -#[inline] -#[doc(alias = "SO_REUSEPORT_LB")] -pub fn socket_reuseport_lb<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_reuseport_lb(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_PROTOCOL)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "openbsd", - target_os = "redox", - target_env = "newlib" -))] -#[inline] -#[doc(alias = "SO_PROTOCOL")] -pub fn socket_protocol<Fd: AsFd>(fd: Fd) -> io::Result<Option<Protocol>> { - backend::net::sockopt::socket_protocol(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_COOKIE)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(target_os = "linux")] -#[inline] -#[doc(alias = "SO_COOKIE")] -pub fn socket_cookie<Fd: AsFd>(fd: Fd) -> io::Result<u64> { - backend::net::sockopt::socket_cookie(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(target_os = "linux")] -#[inline] -#[doc(alias = "SO_INCOMING_CPU")] -pub fn socket_incoming_cpu<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::socket_incoming_cpu(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(target_os = "linux")] -#[inline] -#[doc(alias = "SO_INCOMING_CPU")] -pub fn set_socket_incoming_cpu<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_socket_incoming_cpu(fd.as_fd(), value) -} - -/// `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: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_ip_ttl(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_TTL)` -/// -/// 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 ip_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ip_ttl(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, value)` -/// -/// 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: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ipv6_v6only(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY)` -/// -/// 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 ipv6_v6only<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ipv6_v6only(fd.as_fd()) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_MTU)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[cfg(any(linux_kernel, target_os = "cygwin"))] -#[doc(alias = "IP_MTU")] -pub fn ip_mtu<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ip_mtu(fd.as_fd()) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MTU)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[cfg(any(linux_kernel, target_os = "cygwin"))] -#[doc(alias = "IPV6_MTU")] -pub fn ipv6_mtu<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ipv6_mtu(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, 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_IF")] -pub fn set_ip_multicast_if<Fd: AsFd>(fd: Fd, value: &Ipv4Addr) -> io::Result<()> { - backend::net::sockopt::set_ip_multicast_if(fd.as_fd(), value) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, multiaddr, address, -/// ifindex)` -/// -/// This is similar to [`set_ip_multicast_if`] but additionally allows an -/// `ifindex` value to be given. -/// -/// 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_MULTICAST_IF")] -pub fn set_ip_multicast_if_with_ifindex<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - backend::net::sockopt::set_ip_multicast_if_with_ifindex(fd.as_fd(), multiaddr, address, ifindex) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IP_MULTICAST_IF")] -pub fn ip_multicast_if<Fd: AsFd>(fd: Fd) -> io::Result<Ipv4Addr> { - backend::net::sockopt::ip_multicast_if(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IPV6_MULTICAST_IF")] -pub fn set_ipv6_multicast_if<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_ipv6_multicast_if(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IPV6_MULTICAST_IF")] -pub fn ipv6_multicast_if<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ipv6_multicast_if(fd.as_fd()) -} - -/// `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: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ip_multicast_loop(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP)` -/// -/// 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 ip_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ip_multicast_loop(fd.as_fd()) -} - -/// `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: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_ip_multicast_ttl(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL)` -/// -/// 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 ip_multicast_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ip_multicast_ttl(fd.as_fd()) -} - -/// `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: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ipv6_multicast_loop(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP)` -/// -/// 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 ipv6_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ipv6_multicast_loop(fd.as_fd()) -} - -/// `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 = "IPV6_UNICAST_HOPS")] -pub fn ipv6_unicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u8> { - backend::net::sockopt::ipv6_unicast_hops(fd.as_fd()) -} - -/// `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 set_ipv6_unicast_hops<Fd: AsFd>(fd: Fd, value: Option<u8>) -> io::Result<()> { - backend::net::sockopt::set_ipv6_unicast_hops(fd.as_fd(), value) -} - -/// `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_MULTICAST_HOPS")] -pub fn set_ipv6_multicast_hops<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_ipv6_multicast_hops(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_MULTICAST_HOPS")] -pub fn ipv6_multicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ipv6_multicast_hops(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, interface)` -/// -/// This is similar to [`set_ip_add_membership`] but always sets the `ifindex` -/// value to zero. See [`set_ip_add_membership_with_ifindex`] instead to also -/// give the `ifindex` value. -/// -/// 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<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, -) -> io::Result<()> { - 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`] but additionally allows an -/// `ifindex` value to be given. -/// -/// 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<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> 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, value)` -/// -/// 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<Fd: AsFd>( - 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_IP, IP_DROP_SOURCE_MEMBERSHIP, value)` -/// -/// 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<Fd: AsFd>( - 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. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_JOIN_GROUP")] -#[doc(alias = "IPV6_ADD_MEMBERSHIP")] -pub fn set_ipv6_add_membership<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv6Addr, - interface: u32, -) -> io::Result<()> { - backend::net::sockopt::set_ipv6_add_membership(fd.as_fd(), multiaddr, interface) -} - -/// `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 -#[inline] -#[doc(alias = "IP_DROP_MEMBERSHIP")] -pub fn set_ip_drop_membership<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, -) -> io::Result<()> { - 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 -#[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<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> 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. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_LEAVE_GROUP")] -#[doc(alias = "IPV6_DROP_MEMBERSHIP")] -pub fn set_ipv6_drop_membership<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv6Addr, - interface: u32, -) -> io::Result<()> { - 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 -#[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: AsFd>(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 -#[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 ip_tos<Fd: AsFd>(fd: Fd) -> io::Result<u8> { - backend::net::sockopt::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 -#[cfg(any( - apple, - linux_like, - target_os = "cygwin", - target_os = "freebsd", - target_os = "fuchsia", -))] -#[inline] -#[doc(alias = "IP_RECVTOS")] -pub fn set_ip_recvtos<Fd: AsFd>(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 -#[cfg(any( - apple, - linux_like, - target_os = "cygwin", - target_os = "freebsd", - target_os = "fuchsia", -))] -#[inline] -#[doc(alias = "IP_RECVTOS")] -pub fn ip_recvtos<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::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 -#[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: AsFd>(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 -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "nto" -))] -#[inline] -#[doc(alias = "IPV6_RECVTCLASS")] -pub fn ipv6_recvtclass<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ipv6_recvtclass(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_FREEBIND, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "IP_FREEBIND")] -pub fn set_ip_freebind<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ip_freebind(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_FREEBIND)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "IP_FREEBIND")] -pub fn ip_freebind<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ip_freebind(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_FREEBIND, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "IPV6_FREEBIND")] -pub fn set_ipv6_freebind<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ipv6_freebind(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_FREEBIND)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "IPV6_FREEBIND")] -pub fn ipv6_freebind<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ipv6_freebind(fd.as_fd()) -} - -/// `getsockopt(fd, IPPROTO_IP, SO_ORIGINAL_DST)` -/// -/// Even though this corresponds to a `SO_*` constant, it is an `IPPROTO_IP` -/// option. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "SO_ORIGINAL_DST")] -pub fn ip_original_dst<Fd: AsFd>(fd: Fd) -> io::Result<SocketAddrV4> { - backend::net::sockopt::ip_original_dst(fd.as_fd()) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST)` -/// -/// Even though this corresponds to a `IP6T_*` constant, it is an -/// `IPPROTO_IPV6` option. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "IP6T_SO_ORIGINAL_DST")] -pub fn ipv6_original_dst<Fd: AsFd>(fd: Fd) -> io::Result<SocketAddrV6> { - backend::net::sockopt::ipv6_original_dst(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -#[inline] -#[doc(alias = "IPV6_TCLASS")] -pub fn set_ipv6_tclass<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_ipv6_tclass(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -#[inline] -#[doc(alias = "IPV6_TCLASS")] -pub fn ipv6_tclass<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ipv6_tclass(fd.as_fd()) -} - -/// `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: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_tcp_nodelay(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_NODELAY)` -/// -/// 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 tcp_nodelay<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::tcp_nodelay(fd.as_fd()) -} - -/// `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 -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -#[inline] -#[doc(alias = "TCP_KEEPCNT")] -pub fn set_tcp_keepcnt<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_tcp_keepcnt(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -#[inline] -#[doc(alias = "TCP_KEEPCNT")] -pub fn tcp_keepcnt<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::tcp_keepcnt(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, value)` -/// -/// `TCP_KEEPALIVE` on Apple platforms. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(not(any(target_os = "haiku", target_os = "nto", target_os = "openbsd")))] -#[inline] -#[doc(alias = "TCP_KEEPIDLE")] -pub fn set_tcp_keepidle<Fd: AsFd>(fd: Fd, value: Duration) -> io::Result<()> { - backend::net::sockopt::set_tcp_keepidle(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE)` -/// -/// `TCP_KEEPALIVE` on Apple platforms. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(not(any(target_os = "haiku", target_os = "nto", target_os = "openbsd")))] -#[inline] -#[doc(alias = "TCP_KEEPIDLE")] -pub fn tcp_keepidle<Fd: AsFd>(fd: Fd) -> io::Result<Duration> { - backend::net::sockopt::tcp_keepidle(fd.as_fd()) -} - -/// `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 -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -#[inline] -#[doc(alias = "TCP_KEEPINTVL")] -pub fn set_tcp_keepintvl<Fd: AsFd>(fd: Fd, value: Duration) -> io::Result<()> { - backend::net::sockopt::set_tcp_keepintvl(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -#[inline] -#[doc(alias = "TCP_KEEPINTVL")] -pub fn tcp_keepintvl<Fd: AsFd>(fd: Fd) -> io::Result<Duration> { - backend::net::sockopt::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 -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_USER_TIMEOUT")] -pub fn set_tcp_user_timeout<Fd: AsFd>(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 -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_USER_TIMEOUT")] -pub fn tcp_user_timeout<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::tcp_user_timeout(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_QUICKACK")] -pub fn set_tcp_quickack<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_tcp_quickack(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_QUICKACK)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_QUICKACK")] -pub fn tcp_quickack<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::tcp_quickack(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -#[inline] -#[doc(alias = "TCP_CONGESTION")] -pub fn set_tcp_congestion<Fd: AsFd>(fd: Fd, value: &str) -> io::Result<()> { - backend::net::sockopt::set_tcp_congestion(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_CONGESTION)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -#[inline] -#[doc(alias = "TCP_CONGESTION")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn tcp_congestion<Fd: AsFd>(fd: Fd) -> io::Result<String> { - backend::net::sockopt::tcp_congestion(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_THIN_LINEAR_TIMEOUTS")] -pub fn set_tcp_thin_linear_timeouts<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_tcp_thin_linear_timeouts(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_THIN_LINEAR_TIMEOUTS")] -pub fn tcp_thin_linear_timeouts<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::tcp_thin_linear_timeouts(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_CORK, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_CORK")] -pub fn set_tcp_cork<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_tcp_cork(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_CORK)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_CORK")] -pub fn tcp_cork<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::tcp_cork(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_PEERCRED)`—Get credentials of Unix domain -/// socket peer process. -/// -/// # References -/// - [Linux `unix`] -/// -/// [Linux `unix`]: https://man7.org/linux/man-pages/man7/unix.7.html -#[cfg(linux_kernel)] -#[doc(alias = "SO_PEERCRED")] -pub fn socket_peercred<Fd: AsFd>(fd: Fd) -> io::Result<super::UCred> { - backend::net::sockopt::socket_peercred(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_XDP, XDP_UMEM_REG, value)` -/// -/// On kernel versions only supporting v1, the flags are ignored. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-umem-reg-setsockopt -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_UMEM_REG")] -pub fn set_xdp_umem_reg<Fd: AsFd>(fd: Fd, value: XdpUmemReg) -> io::Result<()> { - backend::net::sockopt::set_xdp_umem_reg(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_XDP, XDP_UMEM_FILL_RING, value)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_UMEM_FILL_RING")] -pub fn set_xdp_umem_fill_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_xdp_umem_fill_ring_size(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_XDP, XDP_UMEM_COMPLETION_RING, value)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_UMEM_COMPLETION_RING")] -pub fn set_xdp_umem_completion_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_xdp_umem_completion_ring_size(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_XDP, XDP_TX_RING, value)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_TX_RING")] -pub fn set_xdp_tx_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_xdp_tx_ring_size(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_XDP, XDP_RX_RING, value)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_RX_RING")] -pub fn set_xdp_rx_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_xdp_rx_ring_size(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_XDP, XDP_MMAP_OFFSETS)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_MMAP_OFFSETS")] -pub fn xdp_mmap_offsets<Fd: AsFd>(fd: Fd) -> io::Result<XdpMmapOffsets> { - backend::net::sockopt::xdp_mmap_offsets(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_XDP, XDP_STATISTICS)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-statistics-getsockopt -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_STATISTICS")] -pub fn xdp_statistics<Fd: AsFd>(fd: Fd) -> io::Result<XdpStatistics> { - backend::net::sockopt::xdp_statistics(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_XDP, XDP_OPTIONS)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-options-getsockopt -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_OPTIONS")] -pub fn xdp_options<Fd: AsFd>(fd: Fd) -> io::Result<XdpOptionsFlags> { - backend::net::sockopt::xdp_options(fd.as_fd()) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_sizes() { - use c::c_int; - - // Backend code needs to cast these to `c_int` so make sure that cast - // isn't lossy. - assert_eq_size!(Timeout, c_int); - } -} diff --git a/vendor/rustix/src/net/types.rs b/vendor/rustix/src/net/types.rs deleted file mode 100644 index 057f944d..00000000 --- a/vendor/rustix/src/net/types.rs +++ /dev/null @@ -1,2132 +0,0 @@ -//! Types and constants for `rustix::net`. - -use crate::backend::c; -use crate::ffi; -use bitflags::bitflags; - -/// A type for holding raw integer socket types. -pub type RawSocketType = u32; - -/// `SOCK_*` constants for use with [`socket`]. -/// -/// [`socket`]: crate::net::socket() -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct SocketType(pub(crate) RawSocketType); - -#[rustfmt::skip] -impl SocketType { - /// `SOCK_STREAM` - pub const STREAM: Self = Self(c::SOCK_STREAM as _); - - /// `SOCK_DGRAM` - pub const DGRAM: Self = Self(c::SOCK_DGRAM as _); - - /// `SOCK_SEQPACKET` - #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] - pub const SEQPACKET: Self = Self(c::SOCK_SEQPACKET as _); - - /// `SOCK_RAW` - #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] - pub const RAW: Self = Self(c::SOCK_RAW as _); - - /// `SOCK_RDM` - #[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox" - )))] - pub const RDM: Self = Self(c::SOCK_RDM as _); - - /// Constructs a `SocketType` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawSocketType) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `SocketType`. - #[inline] - pub const fn as_raw(self) -> RawSocketType { - self.0 - } -} - -/// A type for holding raw integer address families. -pub type RawAddressFamily = crate::ffi::c_ushort; - -/// `AF_*` constants for use with [`socket`], [`socket_with`], and -/// [`socketpair`]. -/// -/// [`socket`]: crate::net::socket() -/// [`socket_with`]: crate::net::socket_with -/// [`socketpair`]: crate::net::socketpair() -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct AddressFamily(pub(crate) RawAddressFamily); - -#[rustfmt::skip] -#[allow(non_upper_case_globals)] -impl AddressFamily { - /// `AF_UNSPEC` - pub const UNSPEC: Self = Self(c::AF_UNSPEC as _); - /// `AF_INET` - /// - /// # References - /// - [Linux] - /// - /// [Linux]: https://man7.org/linux/man-pages/man7/ip.7.html - pub const INET: Self = Self(c::AF_INET as _); - /// `AF_INET6` - /// - /// # References - /// - [Linux] - /// - /// [Linux]: https://man7.org/linux/man-pages/man7/ipv6.7.html - pub const INET6: Self = Self(c::AF_INET6 as _); - /// `AF_NETLINK` - /// - /// # References - /// - [Linux] - /// - /// [Linux]: https://man7.org/linux/man-pages/man7/netlink.7.html - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const NETLINK: Self = Self(c::AF_NETLINK as _); - /// `AF_UNIX`, aka `AF_LOCAL` - #[doc(alias = "LOCAL")] - pub const UNIX: Self = Self(c::AF_UNIX as _); - /// `AF_AX25` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const AX25: Self = Self(c::AF_AX25 as _); - /// `AF_IPX` - #[cfg(not(any( - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const IPX: Self = Self(c::AF_IPX as _); - /// `AF_APPLETALK` - #[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const APPLETALK: Self = Self(c::AF_APPLETALK as _); - /// `AF_NETROM` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const NETROM: Self = Self(c::AF_NETROM as _); - /// `AF_BRIDGE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const BRIDGE: Self = Self(c::AF_BRIDGE as _); - /// `AF_ATMPVC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const ATMPVC: Self = Self(c::AF_ATMPVC as _); - /// `AF_X25` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const X25: Self = Self(c::AF_X25 as _); - /// `AF_ROSE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const ROSE: Self = Self(c::AF_ROSE as _); - /// `AF_DECnet` - #[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const DECnet: Self = Self(c::AF_DECnet as _); - /// `AF_NETBEUI` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const NETBEUI: Self = Self(c::AF_NETBEUI as _); - /// `AF_SECURITY` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const SECURITY: Self = Self(c::AF_SECURITY as _); - /// `AF_KEY` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const KEY: Self = Self(c::AF_KEY as _); - /// `AF_PACKET` - /// - /// # References - /// - [Linux] - /// - /// [Linux]: https://man7.org/linux/man-pages/man7/packet.7.html - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const PACKET: Self = Self(c::AF_PACKET as _); - /// `AF_ASH` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const ASH: Self = Self(c::AF_ASH as _); - /// `AF_ECONET` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const ECONET: Self = Self(c::AF_ECONET as _); - /// `AF_ATMSVC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const ATMSVC: Self = Self(c::AF_ATMSVC as _); - /// `AF_RDS` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const RDS: Self = Self(c::AF_RDS as _); - /// `AF_SNA` - #[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const SNA: Self = Self(c::AF_SNA as _); - /// `AF_IRDA` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const IRDA: Self = Self(c::AF_IRDA as _); - /// `AF_PPPOX` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const PPPOX: Self = Self(c::AF_PPPOX as _); - /// `AF_WANPIPE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const WANPIPE: Self = Self(c::AF_WANPIPE as _); - /// `AF_LLC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const LLC: Self = Self(c::AF_LLC as _); - /// `AF_CAN` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const CAN: Self = Self(c::AF_CAN as _); - /// `AF_TIPC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const TIPC: Self = Self(c::AF_TIPC as _); - /// `AF_BLUETOOTH` - #[cfg(not(any( - apple, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "horizon", - target_os = "hurd", - target_os = "redox", - target_os = "vita", - )))] - pub const BLUETOOTH: Self = Self(c::AF_BLUETOOTH as _); - /// `AF_IUCV` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const IUCV: Self = Self(c::AF_IUCV as _); - /// `AF_RXRPC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const RXRPC: Self = Self(c::AF_RXRPC as _); - /// `AF_ISDN` - #[cfg(not(any( - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "redox", - target_os = "vita", - )))] - pub const ISDN: Self = Self(c::AF_ISDN as _); - /// `AF_PHONET` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const PHONET: Self = Self(c::AF_PHONET as _); - /// `AF_IEEE802154` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const IEEE802154: Self = Self(c::AF_IEEE802154 as _); - /// `AF_802` - #[cfg(solarish)] - pub const EIGHT_ZERO_TWO: Self = Self(c::AF_802 as _); - #[cfg(target_os = "fuchsia")] - /// `AF_ALG` - pub const ALG: Self = Self(c::AF_ALG as _); - #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "nto"))] - /// `AF_ARP` - pub const ARP: Self = Self(c::AF_ARP as _); - /// `AF_ATM` - #[cfg(freebsdlike)] - pub const ATM: Self = Self(c::AF_ATM as _); - /// `AF_CAIF` - #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia"))] - pub const CAIF: Self = Self(c::AF_CAIF as _); - /// `AF_CCITT` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const CCITT: Self = Self(c::AF_CCITT as _); - /// `AF_CHAOS` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const CHAOS: Self = Self(c::AF_CHAOS as _); - /// `AF_CNT` - #[cfg(any(bsd, target_os = "nto"))] - pub const CNT: Self = Self(c::AF_CNT as _); - /// `AF_COIP` - #[cfg(any(bsd, target_os = "nto"))] - pub const COIP: Self = Self(c::AF_COIP as _); - /// `AF_DATAKIT` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const DATAKIT: Self = Self(c::AF_DATAKIT as _); - /// `AF_DLI` - #[cfg(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto" - ))] - pub const DLI: Self = Self(c::AF_DLI as _); - /// `AF_E164` - #[cfg(any(bsd, target_os = "nto"))] - pub const E164: Self = Self(c::AF_E164 as _); - /// `AF_ECMA` - #[cfg(any( - apple, - freebsdlike, - solarish, - target_os = "aix", - target_os = "nto", - target_os = "openbsd" - ))] - pub const ECMA: Self = Self(c::AF_ECMA as _); - /// `AF_ENCAP` - #[cfg(target_os = "openbsd")] - pub const ENCAP: Self = Self(c::AF_ENCAP as _); - /// `AF_FILE` - #[cfg(solarish)] - pub const FILE: Self = Self(c::AF_FILE as _); - /// `AF_GOSIP` - #[cfg(solarish)] - pub const GOSIP: Self = Self(c::AF_GOSIP as _); - /// `AF_HYLINK` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const HYLINK: Self = Self(c::AF_HYLINK as _); - /// `AF_IB` - #[cfg(any(target_os = "emscripten", target_os = "fuchsia"))] - pub const IB: Self = Self(c::AF_IB as _); - /// `AF_IMPLINK` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const IMPLINK: Self = Self(c::AF_IMPLINK as _); - /// `AF_IEEE80211` - #[cfg(any(apple, freebsdlike, target_os = "netbsd"))] - pub const IEEE80211: Self = Self(c::AF_IEEE80211 as _); - /// `AF_INET6_SDP` - #[cfg(target_os = "freebsd")] - pub const INET6_SDP: Self = Self(c::AF_INET6_SDP as _); - /// `AF_INET_OFFLOAD` - #[cfg(solarish)] - pub const INET_OFFLOAD: Self = Self(c::AF_INET_OFFLOAD as _); - /// `AF_INET_SDP` - #[cfg(target_os = "freebsd")] - pub const INET_SDP: Self = Self(c::AF_INET_SDP as _); - /// `AF_INTF` - #[cfg(target_os = "aix")] - pub const INTF: Self = Self(c::AF_INTF as _); - /// `AF_ISO` - #[cfg(any(bsd, target_os = "aix", target_os = "nto"))] - pub const ISO: Self = Self(c::AF_ISO as _); - /// `AF_LAT` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const LAT: Self = Self(c::AF_LAT as _); - /// `AF_LINK` - #[cfg(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto" - ))] - pub const LINK: Self = Self(c::AF_LINK as _); - /// `AF_MPLS` - #[cfg(any( - netbsdlike, - target_os = "dragonfly", - target_os = "emscripten", - target_os = "fuchsia" - ))] - pub const MPLS: Self = Self(c::AF_MPLS as _); - /// `AF_NATM` - #[cfg(any(bsd, target_os = "nto"))] - pub const NATM: Self = Self(c::AF_NATM as _); - /// `AF_NBS` - #[cfg(solarish)] - pub const NBS: Self = Self(c::AF_NBS as _); - /// `AF_NCA` - #[cfg(target_os = "illumos")] - pub const NCA: Self = Self(c::AF_NCA as _); - /// `AF_NDD` - #[cfg(target_os = "aix")] - pub const NDD: Self = Self(c::AF_NDD as _); - /// `AF_NDRV` - #[cfg(apple)] - pub const NDRV: Self = Self(c::AF_NDRV as _); - /// `AF_NETBIOS` - #[cfg(any(apple, freebsdlike))] - pub const NETBIOS: Self = Self(c::AF_NETBIOS as _); - /// `AF_NETGRAPH` - #[cfg(freebsdlike)] - pub const NETGRAPH: Self = Self(c::AF_NETGRAPH as _); - /// `AF_NIT` - #[cfg(solarish)] - pub const NIT: Self = Self(c::AF_NIT as _); - /// `AF_NOTIFY` - #[cfg(target_os = "haiku")] - pub const NOTIFY: Self = Self(c::AF_NOTIFY as _); - /// `AF_NFC` - #[cfg(any(target_os = "emscripten", target_os = "fuchsia"))] - pub const NFC: Self = Self(c::AF_NFC as _); - /// `AF_NS` - #[cfg(any(apple, solarish, netbsdlike, target_os = "aix", target_os = "nto"))] - pub const NS: Self = Self(c::AF_NS as _); - /// `AF_OROUTE` - #[cfg(target_os = "netbsd")] - pub const OROUTE: Self = Self(c::AF_OROUTE as _); - /// `AF_OSI` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const OSI: Self = Self(c::AF_OSI as _); - /// `AF_OSINET` - #[cfg(solarish)] - pub const OSINET: Self = Self(c::AF_OSINET as _); - /// `AF_POLICY` - #[cfg(solarish)] - pub const POLICY: Self = Self(c::AF_POLICY as _); - /// `AF_PPP` - #[cfg(apple)] - pub const PPP: Self = Self(c::AF_PPP as _); - /// `AF_PUP` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const PUP: Self = Self(c::AF_PUP as _); - /// `AF_RIF` - #[cfg(target_os = "aix")] - pub const RIF: Self = Self(c::AF_RIF as _); - /// `AF_ROUTE` - #[cfg(any( - bsd, - solarish, - target_os = "android", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "haiku", - target_os = "nto" - ))] - pub const ROUTE: Self = Self(c::AF_ROUTE as _); - /// `AF_SCLUSTER` - #[cfg(target_os = "freebsd")] - pub const SCLUSTER: Self = Self(c::AF_SCLUSTER as _); - /// `AF_SIP` - #[cfg(any(apple, target_os = "freebsd", target_os = "openbsd"))] - pub const SIP: Self = Self(c::AF_SIP as _); - /// `AF_SLOW` - #[cfg(target_os = "freebsd")] - pub const SLOW: Self = Self(c::AF_SLOW as _); - /// `AF_SYS_CONTROL` - #[cfg(apple)] - pub const SYS_CONTROL: Self = Self(c::AF_SYS_CONTROL as _); - /// `AF_SYSTEM` - #[cfg(apple)] - pub const SYSTEM: Self = Self(c::AF_SYSTEM as _); - /// `AF_TRILL` - #[cfg(solarish)] - pub const TRILL: Self = Self(c::AF_TRILL as _); - /// `AF_UTUN` - #[cfg(apple)] - pub const UTUN: Self = Self(c::AF_UTUN as _); - /// `AF_VSOCK` - #[cfg(any(apple, target_os = "emscripten", target_os = "fuchsia"))] - pub const VSOCK: Self = Self(c::AF_VSOCK as _); - /// `AF_XDP` - #[cfg(target_os = "linux")] - pub const XDP: Self = Self(c::AF_XDP as _); - - /// Constructs a `AddressFamily` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawAddressFamily) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `AddressFamily`. - #[inline] - pub const fn as_raw(self) -> RawAddressFamily { - self.0 - } -} - -/// A type for holding raw integer protocols. -pub type RawProtocol = core::num::NonZeroU32; - -const fn new_raw_protocol(u: u32) -> RawProtocol { - match RawProtocol::new(u) { - Some(p) => p, - None => panic!("new_raw_protocol: protocol must be non-zero"), - } -} - -/// `IPPROTO_*` and other constants for use with [`socket`], [`socket_with`], -/// and [`socketpair`] when a nondefault value is desired. -/// -/// See the [`ipproto`], [`sysproto`], and [`netlink`] modules for possible -/// values. -/// -/// For the default values, such as `IPPROTO_IP` or `NETLINK_ROUTE`, pass -/// `None` as the `protocol` argument in these functions. -/// -/// [`socket`]: crate::net::socket() -/// [`socket_with`]: crate::net::socket_with -/// [`socketpair`]: crate::net::socketpair() -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -#[doc(alias = "IPPROTO_IP")] -#[doc(alias = "NETLINK_ROUTE")] -pub struct Protocol(pub(crate) RawProtocol); - -/// `IPPROTO_*` constants. -/// -/// For `IPPROTO_IP`, pass `None` as the `protocol` argument. -pub mod ipproto { - use super::{new_raw_protocol, Protocol}; - use crate::backend::c; - - /// `IPPROTO_ICMP` - pub const ICMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ICMP as _)); - /// `IPPROTO_IGMP` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "vita" - )))] - pub const IGMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IGMP as _)); - /// `IPPROTO_IPIP` - #[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const IPIP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IPIP as _)); - /// `IPPROTO_TCP` - pub const TCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_TCP as _)); - /// `IPPROTO_EGP` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const EGP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_EGP as _)); - /// `IPPROTO_PUP` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "vita" - )))] - pub const PUP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_PUP as _)); - /// `IPPROTO_UDP` - pub const UDP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_UDP as _)); - /// `IPPROTO_IDP` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "vita" - )))] - pub const IDP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IDP as _)); - /// `IPPROTO_TP` - #[cfg(not(any( - solarish, - windows, - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const TP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_TP as _)); - /// `IPPROTO_DCCP` - #[cfg(not(any( - apple, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - )))] - pub const DCCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_DCCP as _)); - /// `IPPROTO_IPV6` - pub const IPV6: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IPV6 as _)); - /// `IPPROTO_RSVP` - #[cfg(not(any( - solarish, - windows, - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const RSVP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_RSVP as _)); - /// `IPPROTO_GRE` - #[cfg(not(any( - solarish, - windows, - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const GRE: Protocol = Protocol(new_raw_protocol(c::IPPROTO_GRE as _)); - /// `IPPROTO_ESP` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const ESP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ESP as _)); - /// `IPPROTO_AH` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const AH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_AH as _)); - /// `IPPROTO_MTP` - #[cfg(not(any( - solarish, - netbsdlike, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const MTP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MTP as _)); - /// `IPPROTO_BEETPH` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const BEETPH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_BEETPH as _)); - /// `IPPROTO_ENCAP` - #[cfg(not(any( - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const ENCAP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ENCAP as _)); - /// `IPPROTO_PIM` - #[cfg(not(any( - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const PIM: Protocol = Protocol(new_raw_protocol(c::IPPROTO_PIM as _)); - /// `IPPROTO_COMP` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const COMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_COMP as _)); - /// `IPPROTO_SCTP` - #[cfg(not(any( - solarish, - target_os = "cygwin", - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - )))] - pub const SCTP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_SCTP as _)); - /// `IPPROTO_UDPLITE` - #[cfg(not(any( - apple, - netbsdlike, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const UDPLITE: Protocol = Protocol(new_raw_protocol(c::IPPROTO_UDPLITE as _)); - /// `IPPROTO_MPLS` - #[cfg(not(any( - apple, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const MPLS: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MPLS as _)); - /// `IPPROTO_ETHERNET` - #[cfg(linux_kernel)] - pub const ETHERNET: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ETHERNET as _)); - /// `IPPROTO_RAW` - #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] - pub const RAW: Protocol = Protocol(new_raw_protocol(c::IPPROTO_RAW as _)); - /// `IPPROTO_MPTCP` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const MPTCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MPTCP as _)); - /// `IPPROTO_FRAGMENT` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const FRAGMENT: Protocol = Protocol(new_raw_protocol(c::IPPROTO_FRAGMENT as _)); - /// `IPPROTO_ICMPV6` - pub const ICMPV6: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ICMPV6 as _)); - /// `IPPROTO_MH` - #[cfg(not(any( - apple, - netbsdlike, - solarish, - windows, - target_os = "cygwin", - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const MH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MH as _)); - /// `IPPROTO_ROUTING` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const ROUTING: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ROUTING as _)); -} - -/// `SYSPROTO_*` constants. -pub mod sysproto { - #[cfg(apple)] - use { - super::{new_raw_protocol, Protocol}, - crate::backend::c, - }; - - /// `SYSPROTO_EVENT` - #[cfg(apple)] - pub const EVENT: Protocol = Protocol(new_raw_protocol(c::SYSPROTO_EVENT as _)); - - /// `SYSPROTO_CONTROL` - #[cfg(apple)] - pub const CONTROL: Protocol = Protocol(new_raw_protocol(c::SYSPROTO_CONTROL as _)); -} - -/// `NETLINK_*` constants. -/// -/// For `NETLINK_ROUTE`, pass `None` as the `protocol` argument. -pub mod netlink { - #[cfg(linux_kernel)] - use { - super::{new_raw_protocol, Protocol}, - crate::backend::c, - crate::backend::net::read_sockaddr::read_sockaddr_netlink, - crate::net::{ - addr::{call_with_sockaddr, SocketAddrArg, SocketAddrLen, SocketAddrOpaque}, - SocketAddrAny, - }, - core::mem, - }; - - /// `NETLINK_UNUSED` - #[cfg(linux_kernel)] - pub const UNUSED: Protocol = Protocol(new_raw_protocol(c::NETLINK_UNUSED as _)); - /// `NETLINK_USERSOCK` - #[cfg(linux_kernel)] - pub const USERSOCK: Protocol = Protocol(new_raw_protocol(c::NETLINK_USERSOCK as _)); - /// `NETLINK_FIREWALL` - #[cfg(linux_kernel)] - pub const FIREWALL: Protocol = Protocol(new_raw_protocol(c::NETLINK_FIREWALL as _)); - /// `NETLINK_SOCK_DIAG` - #[cfg(linux_kernel)] - pub const SOCK_DIAG: Protocol = Protocol(new_raw_protocol(c::NETLINK_SOCK_DIAG as _)); - /// `NETLINK_NFLOG` - #[cfg(linux_kernel)] - pub const NFLOG: Protocol = Protocol(new_raw_protocol(c::NETLINK_NFLOG as _)); - /// `NETLINK_XFRM` - #[cfg(linux_kernel)] - pub const XFRM: Protocol = Protocol(new_raw_protocol(c::NETLINK_XFRM as _)); - /// `NETLINK_SELINUX` - #[cfg(linux_kernel)] - pub const SELINUX: Protocol = Protocol(new_raw_protocol(c::NETLINK_SELINUX as _)); - /// `NETLINK_ISCSI` - #[cfg(linux_kernel)] - pub const ISCSI: Protocol = Protocol(new_raw_protocol(c::NETLINK_ISCSI as _)); - /// `NETLINK_AUDIT` - #[cfg(linux_kernel)] - pub const AUDIT: Protocol = Protocol(new_raw_protocol(c::NETLINK_AUDIT as _)); - /// `NETLINK_FIB_LOOKUP` - #[cfg(linux_kernel)] - pub const FIB_LOOKUP: Protocol = Protocol(new_raw_protocol(c::NETLINK_FIB_LOOKUP as _)); - /// `NETLINK_CONNECTOR` - #[cfg(linux_kernel)] - pub const CONNECTOR: Protocol = Protocol(new_raw_protocol(c::NETLINK_CONNECTOR as _)); - /// `NETLINK_NETFILTER` - #[cfg(linux_kernel)] - pub const NETFILTER: Protocol = Protocol(new_raw_protocol(c::NETLINK_NETFILTER as _)); - /// `NETLINK_IP6_FW` - #[cfg(linux_kernel)] - pub const IP6_FW: Protocol = Protocol(new_raw_protocol(c::NETLINK_IP6_FW as _)); - /// `NETLINK_DNRTMSG` - #[cfg(linux_kernel)] - pub const DNRTMSG: Protocol = Protocol(new_raw_protocol(c::NETLINK_DNRTMSG as _)); - /// `NETLINK_KOBJECT_UEVENT` - #[cfg(linux_kernel)] - pub const KOBJECT_UEVENT: Protocol = Protocol(new_raw_protocol(c::NETLINK_KOBJECT_UEVENT as _)); - /// `NETLINK_GENERIC` - // This is defined on FreeBSD too, but it has the value 0, so it doesn't - // fit in or `NonZeroU32`. It's unclear whether FreeBSD intends - // `NETLINK_GENERIC` to be the default when Linux has `NETLINK_ROUTE` as - // the default. - #[cfg(linux_kernel)] - pub const GENERIC: Protocol = Protocol(new_raw_protocol(c::NETLINK_GENERIC as _)); - /// `NETLINK_SCSITRANSPORT` - #[cfg(linux_kernel)] - pub const SCSITRANSPORT: Protocol = Protocol(new_raw_protocol(c::NETLINK_SCSITRANSPORT as _)); - /// `NETLINK_ECRYPTFS` - #[cfg(linux_kernel)] - pub const ECRYPTFS: Protocol = Protocol(new_raw_protocol(c::NETLINK_ECRYPTFS as _)); - /// `NETLINK_RDMA` - #[cfg(linux_kernel)] - pub const RDMA: Protocol = Protocol(new_raw_protocol(c::NETLINK_RDMA as _)); - /// `NETLINK_CRYPTO` - #[cfg(linux_kernel)] - pub const CRYPTO: Protocol = Protocol(new_raw_protocol(c::NETLINK_CRYPTO as _)); - /// `NETLINK_INET_DIAG` - #[cfg(linux_kernel)] - pub const INET_DIAG: Protocol = Protocol(new_raw_protocol(c::NETLINK_INET_DIAG as _)); - - /// A Netlink socket address. - /// - /// Used to bind to a Netlink socket. - /// - /// Not ABI compatible with `struct sockaddr_nl` - #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)] - #[cfg(linux_kernel)] - pub struct SocketAddrNetlink { - /// Port ID - pid: u32, - - /// Multicast groups mask - groups: u32, - } - - #[cfg(linux_kernel)] - impl SocketAddrNetlink { - /// Construct a netlink address - #[inline] - pub const fn new(pid: u32, groups: u32) -> Self { - Self { pid, groups } - } - - /// Return port id. - #[inline] - pub const fn pid(&self) -> u32 { - self.pid - } - - /// Set port id. - #[inline] - pub fn set_pid(&mut self, pid: u32) { - self.pid = pid; - } - - /// Return multicast groups mask. - #[inline] - pub const fn groups(&self) -> u32 { - self.groups - } - - /// Set multicast groups mask. - #[inline] - pub fn set_groups(&mut self, groups: u32) { - self.groups = groups; - } - } - - #[cfg(linux_kernel)] - #[allow(unsafe_code)] - // SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which - // handles calling `f` with the needed preconditions. - unsafe impl SocketAddrArg for SocketAddrNetlink { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - let mut addr: c::sockaddr_nl = mem::zeroed(); - addr.nl_family = c::AF_NETLINK as _; - addr.nl_pid = self.pid; - addr.nl_groups = self.groups; - call_with_sockaddr(&addr, f) - } - } - - #[cfg(linux_kernel)] - impl From<SocketAddrNetlink> for SocketAddrAny { - #[inline] - fn from(from: SocketAddrNetlink) -> Self { - from.as_any() - } - } - - #[cfg(linux_kernel)] - impl TryFrom<SocketAddrAny> for SocketAddrNetlink { - type Error = crate::io::Errno; - - fn try_from(addr: SocketAddrAny) -> Result<Self, Self::Error> { - read_sockaddr_netlink(&addr) - } - } -} - -/// `ETH_P_*` constants. -// These are translated into 16-bit big-endian form because that's what the -// [`AddressFamily::PACKET`] address family [expects]. -// -// [expects]: https://man7.org/linux/man-pages/man7/packet.7.html -pub mod eth { - #[cfg(linux_kernel)] - use { - super::{new_raw_protocol, Protocol}, - crate::backend::c, - }; - - /// `ETH_P_LOOP` - #[cfg(linux_kernel)] - pub const LOOP: Protocol = Protocol(new_raw_protocol((c::ETH_P_LOOP as u16).to_be() as u32)); - /// `ETH_P_PUP` - #[cfg(linux_kernel)] - pub const PUP: Protocol = Protocol(new_raw_protocol((c::ETH_P_PUP as u16).to_be() as u32)); - /// `ETH_P_PUPAT` - #[cfg(linux_kernel)] - pub const PUPAT: Protocol = Protocol(new_raw_protocol((c::ETH_P_PUPAT as u16).to_be() as u32)); - /// `ETH_P_TSN` - #[cfg(linux_kernel)] - pub const TSN: Protocol = Protocol(new_raw_protocol((c::ETH_P_TSN as u16).to_be() as u32)); - /// `ETH_P_ERSPAN2` - #[cfg(linux_kernel)] - pub const ERSPAN2: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ERSPAN2 as u16).to_be() as u32)); - /// `ETH_P_IP` - #[cfg(linux_kernel)] - pub const IP: Protocol = Protocol(new_raw_protocol((c::ETH_P_IP as u16).to_be() as u32)); - /// `ETH_P_X25` - #[cfg(linux_kernel)] - pub const X25: Protocol = Protocol(new_raw_protocol((c::ETH_P_X25 as u16).to_be() as u32)); - /// `ETH_P_ARP` - #[cfg(linux_kernel)] - pub const ARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_ARP as u16).to_be() as u32)); - /// `ETH_P_BPQ` - #[cfg(linux_kernel)] - pub const BPQ: Protocol = Protocol(new_raw_protocol((c::ETH_P_BPQ as u16).to_be() as u32)); - /// `ETH_P_IEEEPUP` - #[cfg(linux_kernel)] - pub const IEEEPUP: Protocol = - Protocol(new_raw_protocol((c::ETH_P_IEEEPUP as u16).to_be() as u32)); - /// `ETH_P_IEEEPUPAT` - #[cfg(linux_kernel)] - pub const IEEEPUPAT: Protocol = - Protocol(new_raw_protocol((c::ETH_P_IEEEPUPAT as u16).to_be() as u32)); - /// `ETH_P_BATMAN` - #[cfg(linux_kernel)] - pub const BATMAN: Protocol = - Protocol(new_raw_protocol((c::ETH_P_BATMAN as u16).to_be() as u32)); - /// `ETH_P_DEC` - #[cfg(linux_kernel)] - pub const DEC: Protocol = Protocol(new_raw_protocol((c::ETH_P_DEC as u16).to_be() as u32)); - /// `ETH_P_DNA_DL` - #[cfg(linux_kernel)] - pub const DNA_DL: Protocol = - Protocol(new_raw_protocol((c::ETH_P_DNA_DL as u16).to_be() as u32)); - /// `ETH_P_DNA_RC` - #[cfg(linux_kernel)] - pub const DNA_RC: Protocol = - Protocol(new_raw_protocol((c::ETH_P_DNA_RC as u16).to_be() as u32)); - /// `ETH_P_DNA_RT` - #[cfg(linux_kernel)] - pub const DNA_RT: Protocol = - Protocol(new_raw_protocol((c::ETH_P_DNA_RT as u16).to_be() as u32)); - /// `ETH_P_LAT` - #[cfg(linux_kernel)] - pub const LAT: Protocol = Protocol(new_raw_protocol((c::ETH_P_LAT as u16).to_be() as u32)); - /// `ETH_P_DIAG` - #[cfg(linux_kernel)] - pub const DIAG: Protocol = Protocol(new_raw_protocol((c::ETH_P_DIAG as u16).to_be() as u32)); - /// `ETH_P_CUST` - #[cfg(linux_kernel)] - pub const CUST: Protocol = Protocol(new_raw_protocol((c::ETH_P_CUST as u16).to_be() as u32)); - /// `ETH_P_SCA` - #[cfg(linux_kernel)] - pub const SCA: Protocol = Protocol(new_raw_protocol((c::ETH_P_SCA as u16).to_be() as u32)); - /// `ETH_P_TEB` - #[cfg(linux_kernel)] - pub const TEB: Protocol = Protocol(new_raw_protocol((c::ETH_P_TEB as u16).to_be() as u32)); - /// `ETH_P_RARP` - #[cfg(linux_kernel)] - pub const RARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_RARP as u16).to_be() as u32)); - /// `ETH_P_ATALK` - #[cfg(linux_kernel)] - pub const ATALK: Protocol = Protocol(new_raw_protocol((c::ETH_P_ATALK as u16).to_be() as u32)); - /// `ETH_P_AARP` - #[cfg(linux_kernel)] - pub const AARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_AARP as u16).to_be() as u32)); - /// `ETH_P_8021Q` - #[cfg(linux_kernel)] - pub const P_8021Q: Protocol = - Protocol(new_raw_protocol((c::ETH_P_8021Q as u16).to_be() as u32)); - /// `ETH_P_ERSPAN` - #[cfg(linux_kernel)] - pub const ERSPAN: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ERSPAN as u16).to_be() as u32)); - /// `ETH_P_IPX` - #[cfg(linux_kernel)] - pub const IPX: Protocol = Protocol(new_raw_protocol((c::ETH_P_IPX as u16).to_be() as u32)); - /// `ETH_P_IPV6` - #[cfg(linux_kernel)] - pub const IPV6: Protocol = Protocol(new_raw_protocol((c::ETH_P_IPV6 as u16).to_be() as u32)); - /// `ETH_P_PAUSE` - #[cfg(linux_kernel)] - pub const PAUSE: Protocol = Protocol(new_raw_protocol((c::ETH_P_PAUSE as u16).to_be() as u32)); - /// `ETH_P_SLOW` - #[cfg(linux_kernel)] - pub const SLOW: Protocol = Protocol(new_raw_protocol((c::ETH_P_SLOW as u16).to_be() as u32)); - /// `ETH_P_WCCP` - #[cfg(linux_kernel)] - pub const WCCP: Protocol = Protocol(new_raw_protocol((c::ETH_P_WCCP as u16).to_be() as u32)); - /// `ETH_P_MPLS_UC` - #[cfg(linux_kernel)] - pub const MPLS_UC: Protocol = - Protocol(new_raw_protocol((c::ETH_P_MPLS_UC as u16).to_be() as u32)); - /// `ETH_P_MPLS_MC` - #[cfg(linux_kernel)] - pub const MPLS_MC: Protocol = - Protocol(new_raw_protocol((c::ETH_P_MPLS_MC as u16).to_be() as u32)); - /// `ETH_P_ATMMPOA` - #[cfg(linux_kernel)] - pub const ATMMPOA: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ATMMPOA as u16).to_be() as u32)); - /// `ETH_P_PPP_DISC` - #[cfg(linux_kernel)] - pub const PPP_DISC: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PPP_DISC as u16).to_be() as u32)); - /// `ETH_P_PPP_SES` - #[cfg(linux_kernel)] - pub const PPP_SES: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PPP_SES as u16).to_be() as u32)); - /// `ETH_P_LINK_CTL` - #[cfg(linux_kernel)] - pub const LINK_CTL: Protocol = - Protocol(new_raw_protocol((c::ETH_P_LINK_CTL as u16).to_be() as u32)); - /// `ETH_P_ATMFATE` - #[cfg(linux_kernel)] - pub const ATMFATE: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ATMFATE as u16).to_be() as u32)); - /// `ETH_P_PAE` - #[cfg(linux_kernel)] - pub const PAE: Protocol = Protocol(new_raw_protocol((c::ETH_P_PAE as u16).to_be() as u32)); - /// `ETH_P_PROFINET` - #[cfg(linux_kernel)] - pub const PROFINET: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PROFINET as u16).to_be() as u32)); - /// `ETH_P_REALTEK` - #[cfg(linux_kernel)] - pub const REALTEK: Protocol = - Protocol(new_raw_protocol((c::ETH_P_REALTEK as u16).to_be() as u32)); - /// `ETH_P_AOE` - #[cfg(linux_kernel)] - pub const AOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_AOE as u16).to_be() as u32)); - /// `ETH_P_ETHERCAT` - #[cfg(linux_kernel)] - pub const ETHERCAT: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ETHERCAT as u16).to_be() as u32)); - /// `ETH_P_8021AD` - #[cfg(linux_kernel)] - pub const P_8021AD: Protocol = - Protocol(new_raw_protocol((c::ETH_P_8021AD as u16).to_be() as u32)); - /// `ETH_P_802_EX1` - #[cfg(linux_kernel)] - pub const P_802_EX1: Protocol = - Protocol(new_raw_protocol((c::ETH_P_802_EX1 as u16).to_be() as u32)); - /// `ETH_P_PREAUTH` - #[cfg(linux_kernel)] - pub const PREAUTH: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PREAUTH as u16).to_be() as u32)); - /// `ETH_P_TIPC` - #[cfg(linux_kernel)] - pub const TIPC: Protocol = Protocol(new_raw_protocol((c::ETH_P_TIPC as u16).to_be() as u32)); - /// `ETH_P_LLDP` - #[cfg(linux_kernel)] - pub const LLDP: Protocol = Protocol(new_raw_protocol((c::ETH_P_LLDP as u16).to_be() as u32)); - /// `ETH_P_MRP` - #[cfg(linux_kernel)] - pub const MRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MRP as u16).to_be() as u32)); - /// `ETH_P_MACSEC` - #[cfg(linux_kernel)] - pub const MACSEC: Protocol = - Protocol(new_raw_protocol((c::ETH_P_MACSEC as u16).to_be() as u32)); - /// `ETH_P_8021AH` - #[cfg(linux_kernel)] - pub const P_8021AH: Protocol = - Protocol(new_raw_protocol((c::ETH_P_8021AH as u16).to_be() as u32)); - /// `ETH_P_MVRP` - #[cfg(linux_kernel)] - pub const MVRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MVRP as u16).to_be() as u32)); - /// `ETH_P_1588` - #[cfg(linux_kernel)] - pub const P_1588: Protocol = Protocol(new_raw_protocol((c::ETH_P_1588 as u16).to_be() as u32)); - /// `ETH_P_NCSI` - #[cfg(linux_kernel)] - pub const NCSI: Protocol = Protocol(new_raw_protocol((c::ETH_P_NCSI as u16).to_be() as u32)); - /// `ETH_P_PRP` - #[cfg(linux_kernel)] - pub const PRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_PRP as u16).to_be() as u32)); - /// `ETH_P_CFM` - #[cfg(linux_kernel)] - pub const CFM: Protocol = Protocol(new_raw_protocol((c::ETH_P_CFM as u16).to_be() as u32)); - /// `ETH_P_FCOE` - #[cfg(linux_kernel)] - pub const FCOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_FCOE as u16).to_be() as u32)); - /// `ETH_P_IBOE` - #[cfg(linux_kernel)] - pub const IBOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_IBOE as u16).to_be() as u32)); - /// `ETH_P_TDLS` - #[cfg(linux_kernel)] - pub const TDLS: Protocol = Protocol(new_raw_protocol((c::ETH_P_TDLS as u16).to_be() as u32)); - /// `ETH_P_FIP` - #[cfg(linux_kernel)] - pub const FIP: Protocol = Protocol(new_raw_protocol((c::ETH_P_FIP as u16).to_be() as u32)); - /// `ETH_P_80221` - #[cfg(linux_kernel)] - pub const P_80221: Protocol = - Protocol(new_raw_protocol((c::ETH_P_80221 as u16).to_be() as u32)); - /// `ETH_P_HSR` - #[cfg(linux_kernel)] - pub const HSR: Protocol = Protocol(new_raw_protocol((c::ETH_P_HSR as u16).to_be() as u32)); - /// `ETH_P_NSH` - #[cfg(linux_kernel)] - pub const NSH: Protocol = Protocol(new_raw_protocol((c::ETH_P_NSH as u16).to_be() as u32)); - /// `ETH_P_LOOPBACK` - #[cfg(linux_kernel)] - pub const LOOPBACK: Protocol = - Protocol(new_raw_protocol((c::ETH_P_LOOPBACK as u16).to_be() as u32)); - /// `ETH_P_QINQ1` - #[cfg(linux_kernel)] - pub const QINQ1: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ1 as u16).to_be() as u32)); - /// `ETH_P_QINQ2` - #[cfg(linux_kernel)] - pub const QINQ2: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ2 as u16).to_be() as u32)); - /// `ETH_P_QINQ3` - #[cfg(linux_kernel)] - pub const QINQ3: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ3 as u16).to_be() as u32)); - /// `ETH_P_EDSA` - #[cfg(linux_kernel)] - pub const EDSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_EDSA as u16).to_be() as u32)); - /// `ETH_P_DSA_8021Q` - #[cfg(linux_kernel)] - pub const DSA_8021Q: Protocol = - Protocol(new_raw_protocol((c::ETH_P_DSA_8021Q as u16).to_be() as u32)); - /// `ETH_P_DSA_A5PSW` - #[cfg(linux_kernel)] - pub const DSA_A5PSW: Protocol = - Protocol(new_raw_protocol((c::ETH_P_DSA_A5PSW as u16).to_be() as u32)); - /// `ETH_P_IFE` - #[cfg(linux_kernel)] - pub const IFE: Protocol = Protocol(new_raw_protocol((c::ETH_P_IFE as u16).to_be() as u32)); - /// `ETH_P_AF_IUCV` - #[cfg(linux_kernel)] - pub const AF_IUCV: Protocol = - Protocol(new_raw_protocol((c::ETH_P_AF_IUCV as u16).to_be() as u32)); - /// `ETH_P_802_3_MIN` - #[cfg(linux_kernel)] - pub const P_802_3_MIN: Protocol = - Protocol(new_raw_protocol((c::ETH_P_802_3_MIN as u16).to_be() as u32)); - /// `ETH_P_802_3` - #[cfg(linux_kernel)] - pub const P_802_3: Protocol = - Protocol(new_raw_protocol((c::ETH_P_802_3 as u16).to_be() as u32)); - /// `ETH_P_AX25` - #[cfg(linux_kernel)] - pub const AX25: Protocol = Protocol(new_raw_protocol((c::ETH_P_AX25 as u16).to_be() as u32)); - /// `ETH_P_ALL` - #[cfg(linux_kernel)] - pub const ALL: Protocol = Protocol(new_raw_protocol((c::ETH_P_ALL as u16).to_be() as u32)); - /// `ETH_P_802_2` - #[cfg(linux_kernel)] - pub const P_802_2: Protocol = - Protocol(new_raw_protocol((c::ETH_P_802_2 as u16).to_be() as u32)); - /// `ETH_P_SNAP` - #[cfg(linux_kernel)] - pub const SNAP: Protocol = Protocol(new_raw_protocol((c::ETH_P_SNAP as u16).to_be() as u32)); - /// `ETH_P_DDCMP` - #[cfg(linux_kernel)] - pub const DDCMP: Protocol = Protocol(new_raw_protocol((c::ETH_P_DDCMP as u16).to_be() as u32)); - /// `ETH_P_WAN_PPP` - #[cfg(linux_kernel)] - pub const WAN_PPP: Protocol = - Protocol(new_raw_protocol((c::ETH_P_WAN_PPP as u16).to_be() as u32)); - /// `ETH_P_PPP_MP` - #[cfg(linux_kernel)] - pub const PPP_MP: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PPP_MP as u16).to_be() as u32)); - /// `ETH_P_LOCALTALK` - #[cfg(linux_kernel)] - pub const LOCALTALK: Protocol = - Protocol(new_raw_protocol((c::ETH_P_LOCALTALK as u16).to_be() as u32)); - /// `ETH_P_CAN` - #[cfg(linux_kernel)] - pub const CAN: Protocol = Protocol(new_raw_protocol((c::ETH_P_CAN as u16).to_be() as u32)); - /// `ETH_P_CANFD` - #[cfg(linux_kernel)] - pub const CANFD: Protocol = Protocol(new_raw_protocol((c::ETH_P_CANFD as u16).to_be() as u32)); - /// `ETH_P_CANXL` - #[cfg(linux_kernel)] - pub const CANXL: Protocol = Protocol(new_raw_protocol((c::ETH_P_CANXL as u16).to_be() as u32)); - /// `ETH_P_PPPTALK` - #[cfg(linux_kernel)] - pub const PPPTALK: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PPPTALK as u16).to_be() as u32)); - /// `ETH_P_TR_802_2` - #[cfg(linux_kernel)] - pub const TR_802_2: Protocol = - Protocol(new_raw_protocol((c::ETH_P_TR_802_2 as u16).to_be() as u32)); - /// `ETH_P_MOBITEX` - #[cfg(linux_kernel)] - pub const MOBITEX: Protocol = - Protocol(new_raw_protocol((c::ETH_P_MOBITEX as u16).to_be() as u32)); - /// `ETH_P_CONTROL` - #[cfg(linux_kernel)] - pub const CONTROL: Protocol = - Protocol(new_raw_protocol((c::ETH_P_CONTROL as u16).to_be() as u32)); - /// `ETH_P_IRDA` - #[cfg(linux_kernel)] - pub const IRDA: Protocol = Protocol(new_raw_protocol((c::ETH_P_IRDA as u16).to_be() as u32)); - /// `ETH_P_ECONET` - #[cfg(linux_kernel)] - pub const ECONET: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ECONET as u16).to_be() as u32)); - /// `ETH_P_HDLC` - #[cfg(linux_kernel)] - pub const HDLC: Protocol = Protocol(new_raw_protocol((c::ETH_P_HDLC as u16).to_be() as u32)); - /// `ETH_P_ARCNET` - #[cfg(linux_kernel)] - pub const ARCNET: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ARCNET as u16).to_be() as u32)); - /// `ETH_P_DSA` - #[cfg(linux_kernel)] - pub const DSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_DSA as u16).to_be() as u32)); - /// `ETH_P_TRAILER` - #[cfg(linux_kernel)] - pub const TRAILER: Protocol = - Protocol(new_raw_protocol((c::ETH_P_TRAILER as u16).to_be() as u32)); - /// `ETH_P_PHONET` - #[cfg(linux_kernel)] - pub const PHONET: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PHONET as u16).to_be() as u32)); - /// `ETH_P_IEEE802154` - #[cfg(linux_kernel)] - pub const IEEE802154: Protocol = - Protocol(new_raw_protocol((c::ETH_P_IEEE802154 as u16).to_be() as u32)); - /// `ETH_P_CAIF` - #[cfg(linux_kernel)] - pub const CAIF: Protocol = Protocol(new_raw_protocol((c::ETH_P_CAIF as u16).to_be() as u32)); - /// `ETH_P_XDSA` - #[cfg(linux_kernel)] - pub const XDSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_XDSA as u16).to_be() as u32)); - /// `ETH_P_MAP` - #[cfg(linux_kernel)] - pub const MAP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MAP as u16).to_be() as u32)); - /// `ETH_P_MCTP` - #[cfg(linux_kernel)] - pub const MCTP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MCTP as u16).to_be() as u32)); -} - -#[rustfmt::skip] -impl Protocol { - /// Constructs a `Protocol` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawProtocol) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `Protocol`. - #[inline] - pub const fn as_raw(self) -> RawProtocol { - self.0 - } -} - -/// `SHUT_*` constants for use with [`shutdown`]. -/// -/// [`shutdown`]: crate::net::shutdown -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum Shutdown { - /// `SHUT_RD`—Disable further read operations. - Read = c::SHUT_RD as _, - /// `SHUT_WR`—Disable further write operations. - Write = c::SHUT_WR as _, - /// `SHUT_RDWR`—Disable further read and write operations. - Both = c::SHUT_RDWR as _, -} - -bitflags! { - /// `SOCK_*` constants for use with [`socket_with`], [`accept_with`] and - /// [`acceptfrom_with`]. - /// - /// [`socket_with`]: crate::net::socket_with - /// [`accept_with`]: crate::net::accept_with - /// [`acceptfrom_with`]: crate::net::acceptfrom_with - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SocketFlags: ffi::c_uint { - /// `SOCK_NONBLOCK` - #[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "vita", - )))] - const NONBLOCK = bitcast!(c::SOCK_NONBLOCK); - - /// `SOCK_CLOEXEC` - #[cfg(not(any(apple, windows, target_os = "aix", target_os = "haiku")))] - const CLOEXEC = bitcast!(c::SOCK_CLOEXEC); - - // This deliberately lacks a `const _ = !0`, so that users can use - // `from_bits_truncate` to extract the `SocketFlags` from a flags - // value that also includes a `SocketType`. - } -} - -/// `AF_XDP` related types and constants. -#[cfg(target_os = "linux")] -pub mod xdp { - use crate::backend::net::read_sockaddr::read_sockaddr_xdp; - use crate::fd::{AsRawFd, BorrowedFd}; - use crate::net::addr::{call_with_sockaddr, SocketAddrArg, SocketAddrLen, SocketAddrOpaque}; - use crate::net::SocketAddrAny; - - use super::{bitflags, c}; - - bitflags! { - /// `XDP_OPTIONS_*` constants returned by [`get_xdp_options`]. - /// - /// [`get_xdp_options`]: crate::net::sockopt::get_xdp_options - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpOptionsFlags: u32 { - /// `XDP_OPTIONS_ZEROCOPY` - const XDP_OPTIONS_ZEROCOPY = bitcast!(c::XDP_OPTIONS_ZEROCOPY); - } - } - - // Constant needs to be cast because bindgen does generate a `u32` but the - // struct expects a `u16`. - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n15> - bitflags! { - /// `XDP_*` constants for use in [`SocketAddrXdp`]. - #[repr(transparent)] - #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)] - pub struct SocketAddrXdpFlags: u16 { - /// `XDP_SHARED_UMEM` - const XDP_SHARED_UMEM = bitcast!(c::XDP_SHARED_UMEM as u16); - /// `XDP_COPY` - const XDP_COPY = bitcast!(c::XDP_COPY as u16); - /// `XDP_COPY` - const XDP_ZEROCOPY = bitcast!(c::XDP_ZEROCOPY as u16); - /// `XDP_USE_NEED_WAKEUP` - const XDP_USE_NEED_WAKEUP = bitcast!(c::XDP_USE_NEED_WAKEUP as u16); - // requires kernel 6.6 - /// `XDP_USE_SG` - const XDP_USE_SG = bitcast!(c::XDP_USE_SG as u16); - } - } - - bitflags! { - /// `XDP_RING_*` constants for use in fill and/or Tx ring. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpRingFlags: u32 { - /// `XDP_RING_NEED_WAKEUP` - const XDP_RING_NEED_WAKEUP = bitcast!(c::XDP_RING_NEED_WAKEUP); - } - } - - bitflags! { - /// `XDP_UMEM_*` constants for use in [`XdpUmemReg`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpUmemRegFlags: u32 { - /// `XDP_UMEM_UNALIGNED_CHUNK_FLAG` - const XDP_UMEM_UNALIGNED_CHUNK_FLAG = bitcast!(c::XDP_UMEM_UNALIGNED_CHUNK_FLAG); - } - } - - /// A XDP socket address. - /// - /// Used to bind to XDP socket. - /// - /// Not ABI compatible with `struct sockaddr_xdp`. - /// - /// To add a shared UMEM file descriptor, use - /// [`SocketAddrXdpWithSharedUmem`]. - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n48> - #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)] - pub struct SocketAddrXdp { - /// Flags. - sxdp_flags: SocketAddrXdpFlags, - /// Interface index. - sxdp_ifindex: u32, - /// Queue ID. - sxdp_queue_id: u32, - } - - impl SocketAddrXdp { - /// Construct a new XDP address. - #[inline] - pub const fn new(flags: SocketAddrXdpFlags, interface_index: u32, queue_id: u32) -> Self { - Self { - sxdp_flags: flags, - sxdp_ifindex: interface_index, - sxdp_queue_id: queue_id, - } - } - - /// Return flags. - #[inline] - pub fn flags(&self) -> SocketAddrXdpFlags { - self.sxdp_flags - } - - /// Set flags. - #[inline] - pub fn set_flags(&mut self, flags: SocketAddrXdpFlags) { - self.sxdp_flags = flags; - } - - /// Return interface index. - #[inline] - pub fn interface_index(&self) -> u32 { - self.sxdp_ifindex - } - - /// Set interface index. - #[inline] - pub fn set_interface_index(&mut self, interface_index: u32) { - self.sxdp_ifindex = interface_index; - } - - /// Return queue ID. - #[inline] - pub fn queue_id(&self) -> u32 { - self.sxdp_queue_id - } - - /// Set queue ID. - #[inline] - pub fn set_queue_id(&mut self, queue_id: u32) { - self.sxdp_queue_id = queue_id; - } - } - - #[allow(unsafe_code)] - // SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which - // handles calling `f` with the needed preconditions. - unsafe impl SocketAddrArg for SocketAddrXdp { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - let addr = c::sockaddr_xdp { - sxdp_family: c::AF_XDP as _, - sxdp_flags: self.flags().bits(), - sxdp_ifindex: self.interface_index(), - sxdp_queue_id: self.queue_id(), - sxdp_shared_umem_fd: !0, - }; - - call_with_sockaddr(&addr, f) - } - } - - impl From<SocketAddrXdp> for SocketAddrAny { - #[inline] - fn from(from: SocketAddrXdp) -> Self { - from.as_any() - } - } - - impl TryFrom<SocketAddrAny> for SocketAddrXdp { - type Error = crate::io::Errno; - - fn try_from(addr: SocketAddrAny) -> Result<Self, Self::Error> { - read_sockaddr_xdp(&addr) - } - } - - /// An XDP socket address with a shared UMEM file descriptor. - /// - /// This implements `SocketAddrArg` so that it can be passed to [`bind`]. - /// - /// [`bind`]: crate::net::bind - #[derive(Debug)] - pub struct SocketAddrXdpWithSharedUmem<'a> { - /// XDP address. - pub addr: SocketAddrXdp, - /// Shared UMEM file descriptor. - pub shared_umem_fd: BorrowedFd<'a>, - } - - #[allow(unsafe_code)] - // SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which - // handles calling `f` with the needed preconditions. - unsafe impl<'a> SocketAddrArg for SocketAddrXdpWithSharedUmem<'a> { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - let addr = c::sockaddr_xdp { - sxdp_family: c::AF_XDP as _, - sxdp_flags: self.addr.flags().bits(), - sxdp_ifindex: self.addr.interface_index(), - sxdp_queue_id: self.addr.queue_id(), - sxdp_shared_umem_fd: self.shared_umem_fd.as_raw_fd() as u32, - }; - - call_with_sockaddr(&addr, f) - } - } - - /// XDP ring offset. - /// - /// Used to mmap rings from kernel. - /// - /// Not ABI compatible with `struct xdp_ring_offset`. - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n59> - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpRingOffset { - /// Producer offset. - pub producer: u64, - /// Consumer offset. - pub consumer: u64, - /// Descriptors offset. - pub desc: u64, - /// Flags offset. - /// - /// Is `None` if the kernel version (<5.4) does not yet support flags. - pub flags: Option<u64>, - } - - /// XDP mmap offsets. - /// - /// Not ABI compatible with `struct xdp_mmap_offsets` - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n66> - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpMmapOffsets { - /// Rx ring offsets. - pub rx: XdpRingOffset, - /// Tx ring offsets. - pub tx: XdpRingOffset, - /// Fill ring offsets. - pub fr: XdpRingOffset, - /// Completion ring offsets. - pub cr: XdpRingOffset, - } - - /// XDP umem registration. - /// - /// `struct xdp_umem_reg` - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n79> - #[repr(C)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpUmemReg { - /// Start address of UMEM. - pub addr: u64, - /// Umem length in bytes. - pub len: u64, - /// Chunk size in bytes. - pub chunk_size: u32, - /// Headroom in bytes. - pub headroom: u32, - /// Flags. - /// - /// Requires kernel version 5.4. - pub flags: XdpUmemRegFlags, - /// `AF_XDP` TX metadata length - /// - /// Requires kernel version 6.8. - pub tx_metadata_len: u32, - } - - /// XDP statistics. - /// - /// Not ABI compatible with `struct xdp_statistics` - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n92> - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpStatistics { - /// Rx dropped. - pub rx_dropped: u64, - /// Rx invalid descriptors. - pub rx_invalid_descs: u64, - /// Tx invalid descriptors. - pub tx_invalid_descs: u64, - /// Rx ring full. - /// - /// Is `None` if the kernel version (<5.9) does not yet support flags. - pub rx_ring_full: Option<u64>, - /// Rx fill ring empty descriptors. - /// - /// Is `None` if the kernel version (<5.9) does not yet support flags. - pub rx_fill_ring_empty_descs: Option<u64>, - /// Tx ring empty descriptors. - /// - /// Is `None` if the kernel version (<5.9) does not yet support flags. - pub tx_ring_empty_descs: Option<u64>, - } - - /// XDP options. - /// - /// Requires kernel version 5.3. - /// `struct xdp_options` - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n101> - #[repr(C)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpOptions { - /// Flags. - pub flags: XdpOptionsFlags, - } - - /// XDP rx/tx frame descriptor. - /// - /// `struct xdp_desc` - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n154> - #[repr(C)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpDesc { - /// Offset from the start of the UMEM. - pub addr: u64, - /// Length of packet in bytes. - pub len: u32, - /// Options. - pub options: XdpDescOptions, - } - - #[cfg(target_os = "linux")] - bitflags! { - /// `XDP_*` constants for use in [`XdpDesc`]. - /// - /// Requires kernel version 6.6. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpDescOptions: u32 { - /// `XDP_PKT_CONTD` - const XDP_PKT_CONTD = bitcast!(c::XDP_PKT_CONTD); - } - } - - /// Offset for mmapping rx ring. - pub const XDP_PGOFF_RX_RING: u64 = c::XDP_PGOFF_RX_RING as u64; - /// Offset for mmapping tx ring. - pub const XDP_PGOFF_TX_RING: u64 = c::XDP_PGOFF_TX_RING as u64; - /// Offset for mmapping fill ring. - pub const XDP_UMEM_PGOFF_FILL_RING: u64 = c::XDP_UMEM_PGOFF_FILL_RING; - /// Offset for mmapping completion ring. - pub const XDP_UMEM_PGOFF_COMPLETION_RING: u64 = c::XDP_UMEM_PGOFF_COMPLETION_RING; - - /// Offset used to shift the [`XdpDesc`] addr to the right to extract the - /// address offset in unaligned mode. - pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT: u64 = c::XSK_UNALIGNED_BUF_OFFSET_SHIFT as u64; - /// Mask used to binary `and` the [`XdpDesc`] addr to extract the address - /// without the offset carried in the upper 16 bits of the address in - /// unaligned mode. - pub const XSK_UNALIGNED_BUF_ADDR_MASK: u64 = c::XSK_UNALIGNED_BUF_ADDR_MASK; -} - -/// UNIX credentials of socket peer, for use with [`get_socket_peercred`] -/// [`SendAncillaryMessage::ScmCredentials`] and -/// [`RecvAncillaryMessage::ScmCredentials`]. -/// -/// [`get_socket_peercred`]: crate::net::sockopt::socket_peercred -/// [`SendAncillaryMessage::ScmCredentials`]: crate::net::SendAncillaryMessage::ScmCredentials -/// [`RecvAncillaryMessage::ScmCredentials`]: crate::net::RecvAncillaryMessage::ScmCredentials -#[cfg(linux_kernel)] -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(C)] -pub struct UCred { - /// Process ID of peer - pub pid: crate::pid::Pid, - /// User ID of peer - pub uid: crate::ugid::Uid, - /// Group ID of peer - pub gid: crate::ugid::Gid, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_sizes() { - #[cfg(target_os = "linux")] - use crate::backend::c; - use crate::ffi::c_int; - use crate::net::addr::SocketAddrStorage; - use core::mem::transmute; - - // Backend code needs to cast these to `c_int` so make sure that cast isn't - // lossy. - assert_eq_size!(RawProtocol, c_int); - assert_eq_size!(Protocol, c_int); - assert_eq_size!(Option<RawProtocol>, c_int); - assert_eq_size!(Option<Protocol>, c_int); - assert_eq_size!(RawSocketType, c_int); - assert_eq_size!(SocketType, c_int); - assert_eq_size!(SocketFlags, c_int); - assert_eq_size!(SocketAddrStorage, c::sockaddr_storage); - - // Rustix doesn't depend on `Option<Protocol>` matching the ABI of a raw - // integer for correctness, but it should work nonetheless. - #[allow(unsafe_code)] - unsafe { - let t: Option<Protocol> = None; - assert_eq!(0_u32, transmute::<Option<Protocol>, u32>(t)); - - let t: Option<Protocol> = Some(Protocol::from_raw(RawProtocol::new(4567).unwrap())); - assert_eq!(4567_u32, transmute::<Option<Protocol>, u32>(t)); - } - - #[cfg(linux_kernel)] - assert_eq_size!(UCred, libc::ucred); - - #[cfg(target_os = "linux")] - assert_eq_size!(super::xdp::XdpUmemReg, c::xdp_umem_reg); - #[cfg(target_os = "linux")] - assert_eq_size!(super::xdp::XdpOptions, c::xdp_options); - #[cfg(target_os = "linux")] - assert_eq_size!(super::xdp::XdpDesc, c::xdp_desc); - } -} diff --git a/vendor/rustix/src/net/wsa.rs b/vendor/rustix/src/net/wsa.rs deleted file mode 100644 index 0ad4db5e..00000000 --- a/vendor/rustix/src/net/wsa.rs +++ /dev/null @@ -1,49 +0,0 @@ -use crate::io; -use core::mem::MaybeUninit; -use windows_sys::Win32::Networking::WinSock::{WSACleanup, WSAGetLastError, WSAStartup, WSADATA}; - -/// `WSAStartup()`—Initialize process-wide Windows support for sockets. -/// -/// On Windows, it's necessary to initialize the sockets subsystem before -/// using sockets APIs. The function performs the necessary initialization. -/// -/// # References -/// - [Winsock] -/// -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastartup -pub fn wsa_startup() -> io::Result<WSADATA> { - // Request version 2.2, which has been the latest version since far older - // versions of Windows than we support here. For more information about - // the version, see [here]. - // - // [here]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastartup#remarks - let version = 0x202; - let mut data = MaybeUninit::uninit(); - unsafe { - let ret = WSAStartup(version, data.as_mut_ptr()); - if ret == 0 { - Ok(data.assume_init()) - } else { - Err(io::Errno::from_raw_os_error(WSAGetLastError())) - } - } -} - -/// `WSACleanup()`—Clean up process-wide Windows support for sockets. -/// -/// In a program where `init` is called, if sockets are no longer necessary, -/// this function releases associated resources. -/// -/// # References -/// - [Winsock] -/// -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsacleanup -pub fn wsa_cleanup() -> io::Result<()> { - unsafe { - if WSACleanup() == 0 { - Ok(()) - } else { - Err(io::Errno::from_raw_os_error(WSAGetLastError())) - } - } -} |
