From 45df4d0d9b577fecee798d672695fe24ff57fb1b Mon Sep 17 00:00:00 2001 From: mo khan Date: Tue, 15 Jul 2025 16:37:08 -0600 Subject: 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. --- vendor/rustix/src/backend/libc/net/addr.rs | 390 ------ vendor/rustix/src/backend/libc/net/ext.rs | 137 -- vendor/rustix/src/backend/libc/net/mod.rs | 17 - vendor/rustix/src/backend/libc/net/msghdr.rs | 188 --- vendor/rustix/src/backend/libc/net/netdevice.rs | 55 - .../rustix/src/backend/libc/net/read_sockaddr.rs | 264 ---- vendor/rustix/src/backend/libc/net/send_recv.rs | 153 --- vendor/rustix/src/backend/libc/net/sockopt.rs | 1339 -------------------- vendor/rustix/src/backend/libc/net/syscalls.rs | 438 ------- .../rustix/src/backend/libc/net/write_sockaddr.rs | 72 -- 10 files changed, 3053 deletions(-) delete mode 100644 vendor/rustix/src/backend/libc/net/addr.rs delete mode 100644 vendor/rustix/src/backend/libc/net/ext.rs delete mode 100644 vendor/rustix/src/backend/libc/net/mod.rs delete mode 100644 vendor/rustix/src/backend/libc/net/msghdr.rs delete mode 100644 vendor/rustix/src/backend/libc/net/netdevice.rs delete mode 100644 vendor/rustix/src/backend/libc/net/read_sockaddr.rs delete mode 100644 vendor/rustix/src/backend/libc/net/send_recv.rs delete mode 100644 vendor/rustix/src/backend/libc/net/sockopt.rs delete mode 100644 vendor/rustix/src/backend/libc/net/syscalls.rs delete mode 100644 vendor/rustix/src/backend/libc/net/write_sockaddr.rs (limited to 'vendor/rustix/src/backend/libc/net') diff --git a/vendor/rustix/src/backend/libc/net/addr.rs b/vendor/rustix/src/backend/libc/net/addr.rs deleted file mode 100644 index 1699ffa9..00000000 --- a/vendor/rustix/src/backend/libc/net/addr.rs +++ /dev/null @@ -1,390 +0,0 @@ -//! Socket address utilities. - -use crate::backend::c; -use crate::net::AddressFamily; -#[cfg(unix)] -use { - crate::ffi::CStr, - crate::io, - crate::net::addr::SocketAddrLen, - crate::path, - core::cmp::Ordering, - core::fmt, - core::hash::{Hash, Hasher}, - core::slice, -}; -#[cfg(all(unix, feature = "alloc"))] -use {crate::ffi::CString, alloc::borrow::Cow, alloc::vec::Vec}; - -/// `struct sockaddr_un` -#[cfg(unix)] -#[derive(Clone)] -#[doc(alias = "sockaddr_un")] -pub struct SocketAddrUnix { - pub(crate) unix: c::sockaddr_un, - #[cfg(not(any(bsd, target_os = "haiku")))] - len: c::socklen_t, -} - -#[cfg(unix)] -impl SocketAddrUnix { - /// Construct a new Unix-domain address from a filesystem path. - #[inline] - pub fn new(path: P) -> io::Result { - path.into_with_c_str(Self::_new) - } - - #[inline] - fn _new(path: &CStr) -> io::Result { - let mut unix = Self::init(); - let mut bytes = path.to_bytes_with_nul(); - if bytes.len() > unix.sun_path.len() { - bytes = path.to_bytes(); // without NUL - if bytes.len() > unix.sun_path.len() { - return Err(io::Errno::NAMETOOLONG); - } - } - for (i, b) in bytes.iter().enumerate() { - unix.sun_path[i] = *b as c::c_char; - } - - #[cfg(any(bsd, target_os = "haiku"))] - { - unix.sun_len = (offsetof_sun_path() + bytes.len()).try_into().unwrap(); - } - - Ok(Self { - unix, - #[cfg(not(any(bsd, target_os = "haiku")))] - len: (offsetof_sun_path() + bytes.len()).try_into().unwrap(), - }) - } - - /// Construct a new abstract Unix-domain address from a byte slice. - #[cfg(linux_kernel)] - #[inline] - pub fn new_abstract_name(name: &[u8]) -> io::Result { - let mut unix = Self::init(); - if 1 + name.len() > unix.sun_path.len() { - return Err(io::Errno::NAMETOOLONG); - } - unix.sun_path[0] = 0; - for (i, b) in name.iter().enumerate() { - unix.sun_path[1 + i] = *b as c::c_char; - } - let len = offsetof_sun_path() + 1 + name.len(); - let len = len.try_into().unwrap(); - Ok(Self { - unix, - #[cfg(not(any(bsd, target_os = "haiku")))] - len, - }) - } - - /// Construct a new unnamed address. - /// - /// The kernel will assign an abstract Unix-domain address to the socket - /// when you call [`bind`][crate::net::bind]. You can inspect the assigned - /// name with [`getsockname`][crate::net::getsockname]. - /// - /// # References - /// - [Linux] - /// - /// [Linux]: https://www.man7.org/linux/man-pages/man7/unix.7.html - #[cfg(linux_kernel)] - #[inline] - pub fn new_unnamed() -> Self { - Self { - unix: Self::init(), - #[cfg(not(any(bsd, target_os = "haiku")))] - len: offsetof_sun_path() as c::socklen_t, - } - } - - const fn init() -> c::sockaddr_un { - c::sockaddr_un { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "hurd", - ))] - sun_len: 0, - #[cfg(target_os = "vita")] - ss_len: 0, - sun_family: c::AF_UNIX as _, - #[cfg(any(bsd, target_os = "horizon", target_os = "nto"))] - sun_path: [0; 104], - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "horizon", - target_os = "nto" - )))] - sun_path: [0; 108], - #[cfg(target_os = "haiku")] - sun_path: [0; 126], - #[cfg(target_os = "aix")] - sun_path: [0; 1023], - } - } - - /// For a filesystem path address, return the path. - #[inline] - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - pub fn path(&self) -> Option> { - let bytes = self.bytes()?; - if !bytes.is_empty() && bytes[0] != 0 { - if self.unix.sun_path.len() == bytes.len() { - // SAFETY: There are no NULs contained in bytes. - unsafe { Self::path_with_termination(bytes) } - } else { - // SAFETY: `from_bytes_with_nul_unchecked` since the string is - // NUL-terminated. - Some(unsafe { CStr::from_bytes_with_nul_unchecked(bytes) }.into()) - } - } else { - None - } - } - - /// If the `sun_path` field is not NUL-terminated, terminate it. - /// - /// SAFETY: The input `bytes` must not contain any NULs. - #[cfg(feature = "alloc")] - #[cold] - unsafe fn path_with_termination(bytes: &[u8]) -> Option> { - let mut owned = Vec::with_capacity(bytes.len() + 1); - owned.extend_from_slice(bytes); - owned.push(b'\0'); - // SAFETY: `from_vec_with_nul_unchecked` since the string is - // NUL-terminated and `bytes` does not contain any NULs. - Some(Cow::Owned( - CString::from_vec_with_nul_unchecked(owned).into(), - )) - } - - /// For a filesystem path address, return the path as a byte sequence, - /// excluding the NUL terminator. - #[inline] - pub fn path_bytes(&self) -> Option<&[u8]> { - let bytes = self.bytes()?; - if !bytes.is_empty() && bytes[0] != 0 { - if self.unix.sun_path.len() == self.len() - offsetof_sun_path() { - // There is no NUL terminator. - Some(bytes) - } else { - // Remove the NUL terminator. - Some(&bytes[..bytes.len() - 1]) - } - } else { - None - } - } - - /// For an abstract address, return the identifier. - #[cfg(linux_kernel)] - #[inline] - pub fn abstract_name(&self) -> Option<&[u8]> { - if let [0, bytes @ ..] = self.bytes()? { - Some(bytes) - } else { - None - } - } - - /// `true` if the socket address is unnamed. - #[cfg(linux_kernel)] - #[inline] - pub fn is_unnamed(&self) -> bool { - self.bytes() == Some(&[]) - } - - #[inline] - pub(crate) fn addr_len(&self) -> SocketAddrLen { - #[cfg(not(any(bsd, target_os = "haiku")))] - { - bitcast!(self.len) - } - #[cfg(any(bsd, target_os = "haiku"))] - { - bitcast!(c::socklen_t::from(self.unix.sun_len)) - } - } - - #[inline] - pub(crate) fn len(&self) -> usize { - self.addr_len() as usize - } - - #[inline] - fn bytes(&self) -> Option<&[u8]> { - let len = self.len(); - if len != 0 { - let bytes = &self.unix.sun_path[..len - offsetof_sun_path()]; - // SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. - Some(unsafe { slice::from_raw_parts(bytes.as_ptr().cast(), bytes.len()) }) - } else { - None - } - } -} - -#[cfg(unix)] -impl PartialEq for SocketAddrUnix { - #[inline] - fn eq(&self, other: &Self) -> bool { - let self_len = self.len() - offsetof_sun_path(); - let other_len = other.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].eq(&other.unix.sun_path[..other_len]) - } -} - -#[cfg(unix)] -impl Eq for SocketAddrUnix {} - -#[cfg(unix)] -impl PartialOrd for SocketAddrUnix { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -#[cfg(unix)] -impl Ord for SocketAddrUnix { - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - let self_len = self.len() - offsetof_sun_path(); - let other_len = other.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].cmp(&other.unix.sun_path[..other_len]) - } -} - -#[cfg(unix)] -impl Hash for SocketAddrUnix { - #[inline] - fn hash(&self, state: &mut H) { - let self_len = self.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].hash(state) - } -} - -#[cfg(unix)] -impl fmt::Debug for SocketAddrUnix { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(feature = "alloc")] - if let Some(path) = self.path() { - return path.fmt(f); - } - if let Some(bytes) = self.path_bytes() { - if let Ok(s) = core::str::from_utf8(bytes) { - return s.fmt(f); - } - return bytes.fmt(f); - } - #[cfg(linux_kernel)] - if let Some(name) = self.abstract_name() { - return name.fmt(f); - } - "(unnamed)".fmt(f) - } -} - -/// `struct sockaddr_storage` -/// -/// This type is guaranteed to be large enough to hold any encoded socket -/// address. -#[repr(transparent)] -#[derive(Copy, Clone)] -#[doc(alias = "sockaddr_storage")] -pub struct SocketAddrStorage(c::sockaddr_storage); - -impl SocketAddrStorage { - /// Return a socket addr storage initialized to all zero bytes. The - /// `sa_family` is set to [`AddressFamily::UNSPEC`]. - pub fn zeroed() -> Self { - assert_eq!(c::AF_UNSPEC, 0); - // SAFETY: `sockaddr_storage` is meant to be zero-initializable. - unsafe { core::mem::zeroed() } - } - - /// Return the `sa_family` of this socket address. - pub fn family(&self) -> AddressFamily { - // SAFETY: `self.0` is a `sockaddr_storage` so it has enough space. - unsafe { - AddressFamily::from_raw(crate::backend::net::read_sockaddr::read_sa_family( - crate::utils::as_ptr(&self.0).cast::(), - )) - } - } - - /// Clear the `sa_family` of this socket address to - /// [`AddressFamily::UNSPEC`]. - pub fn clear_family(&mut self) { - // SAFETY: `self.0` is a `sockaddr_storage` so it has enough space. - unsafe { - crate::backend::net::read_sockaddr::initialize_family_to_unspec( - crate::utils::as_mut_ptr(&mut self.0).cast::(), - ) - } - } -} - -/// Return the offset of the `sun_path` field of `sockaddr_un`. -#[cfg(not(windows))] -#[inline] -pub(crate) fn offsetof_sun_path() -> usize { - let z = c::sockaddr_un { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - ))] - sun_len: 0_u8, - #[cfg(target_os = "vita")] - ss_len: 0, - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - sun_family: 0_u8, - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - )))] - sun_family: 0_u16, - #[cfg(any(bsd, target_os = "horizon", target_os = "nto"))] - sun_path: [0; 104], - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "horizon", - target_os = "nto" - )))] - sun_path: [0; 108], - #[cfg(target_os = "haiku")] - sun_path: [0; 126], - #[cfg(target_os = "aix")] - sun_path: [0; 1023], - }; - (crate::utils::as_ptr(&z.sun_path) as usize) - (crate::utils::as_ptr(&z) as usize) -} diff --git a/vendor/rustix/src/backend/libc/net/ext.rs b/vendor/rustix/src/backend/libc/net/ext.rs deleted file mode 100644 index efd2b31c..00000000 --- a/vendor/rustix/src/backend/libc/net/ext.rs +++ /dev/null @@ -1,137 +0,0 @@ -use crate::backend::c; - -/// The windows `sockaddr_in6` type is a union with accessor functions which -/// are not `const fn`. Define our own layout-compatible version so that we -/// can transmute in and out of it. -#[cfg(windows)] -#[repr(C)] -struct sockaddr_in6 { - sin6_family: u16, - sin6_port: u16, - sin6_flowinfo: u32, - sin6_addr: c::in6_addr, - sin6_scope_id: u32, -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { - addr.s_addr -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { - // This should be `*addr.S_un.S_addr()`, except that isn't a `const fn`. - unsafe { core::mem::transmute(addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { - c::in_addr { s_addr } -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { - unsafe { core::mem::transmute(s_addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { - addr.s6_addr -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { - unsafe { core::mem::transmute(addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { - c::in6_addr { s6_addr } -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { - unsafe { core::mem::transmute(s6_addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: &c::sockaddr_in6) -> u32 { - addr.sin6_scope_id -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: &c::sockaddr_in6) -> u32 { - let addr: &sockaddr_in6 = unsafe { core::mem::transmute(addr) }; - addr.sin6_scope_id -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn sockaddr_in6_new( - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - sin6_len: u8, - sin6_family: c::sa_family_t, - sin6_port: u16, - sin6_flowinfo: u32, - sin6_addr: c::in6_addr, - sin6_scope_id: u32, -) -> c::sockaddr_in6 { - c::sockaddr_in6 { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - sin6_len, - sin6_family, - sin6_port, - sin6_flowinfo, - sin6_addr, - sin6_scope_id, - #[cfg(solarish)] - __sin6_src_id: 0, - #[cfg(target_os = "vita")] - sin6_vport: 0, - } -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn sockaddr_in6_new( - sin6_family: u16, - sin6_port: u16, - sin6_flowinfo: u32, - sin6_addr: c::in6_addr, - sin6_scope_id: u32, -) -> c::sockaddr_in6 { - let addr = sockaddr_in6 { - sin6_family, - sin6_port, - sin6_flowinfo, - sin6_addr, - sin6_scope_id, - }; - unsafe { core::mem::transmute(addr) } -} diff --git a/vendor/rustix/src/backend/libc/net/mod.rs b/vendor/rustix/src/backend/libc/net/mod.rs deleted file mode 100644 index da7e1df8..00000000 --- a/vendor/rustix/src/backend/libc/net/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -pub(crate) mod addr; -pub(crate) mod ext; -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub(crate) mod msghdr; -#[cfg(linux_kernel)] -pub(crate) mod netdevice; -pub(crate) mod read_sockaddr; -pub(crate) mod send_recv; -pub(crate) mod sockopt; -pub(crate) mod syscalls; -pub(crate) mod write_sockaddr; diff --git a/vendor/rustix/src/backend/libc/net/msghdr.rs b/vendor/rustix/src/backend/libc/net/msghdr.rs deleted file mode 100644 index fe5471b9..00000000 --- a/vendor/rustix/src/backend/libc/net/msghdr.rs +++ /dev/null @@ -1,188 +0,0 @@ -//! Utilities for dealing with message headers. -//! -//! These take closures rather than returning a `c::msghdr` directly because -//! the message headers may reference stack-local data. - -use crate::backend::c; - -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::net::addr::SocketAddrArg; -use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrBuf}; - -use core::mem::zeroed; - -/// Convert the value to the `msg_iovlen` field of a `msghdr` struct. -#[cfg(all( - not(any(windows, target_os = "espidf", target_os = "wasi")), - any( - target_os = "android", - all( - target_os = "linux", - not(target_env = "musl"), - not(all(target_env = "uclibc", any(target_arch = "arm", target_arch = "mips"))) - ) - ) -))] -#[inline] -fn msg_iov_len(len: usize) -> c::size_t { - len -} - -/// Convert the value to the `msg_iovlen` field of a `msghdr` struct. -#[cfg(all( - not(any( - windows, - target_os = "espidf", - target_os = "redox", - target_os = "vita", - target_os = "wasi" - )), - not(any( - target_os = "android", - all( - target_os = "linux", - not(target_env = "musl"), - not(all(target_env = "uclibc", any(target_arch = "arm", target_arch = "mips"))) - ) - )) -))] -#[inline] -fn msg_iov_len(len: usize) -> c::c_int { - len.try_into().unwrap_or(c::c_int::MAX) -} - -/// Convert the value to a `socklen_t`. -#[cfg(any( - bsd, - solarish, - target_env = "musl", - target_os = "aix", - target_os = "cygwin", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", -))] -#[inline] -fn msg_control_len(len: usize) -> c::socklen_t { - len.try_into().unwrap_or(c::socklen_t::MAX) -} - -/// Convert the value to a `size_t`. -#[cfg(not(any( - bsd, - solarish, - windows, - target_env = "musl", - target_os = "aix", - target_os = "cygwin", - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -fn msg_control_len(len: usize) -> c::size_t { - len -} - -/// Create a message header intended to receive a datagram. -/// -/// # Safety -/// -/// If `f` dereferences the pointers in the `msghdr`, it must do so only within -/// the bounds indicated by the associated lengths in the `msghdr`. -/// -/// And, if `f` returns `Ok`, it must have updated the `msg_controllen` field -/// of the `msghdr` to indicate how many bytes it initialized. -pub(crate) unsafe fn with_recv_msghdr( - name: &mut SocketAddrBuf, - iov: &mut [IoSliceMut<'_>], - control: &mut RecvAncillaryBuffer<'_>, - f: impl FnOnce(&mut c::msghdr) -> io::Result, -) -> io::Result { - control.clear(); - - let mut msghdr = zero_msghdr(); - msghdr.msg_name = name.storage.as_mut_ptr().cast(); - msghdr.msg_namelen = name.len; - msghdr.msg_iov = iov.as_mut_ptr().cast(); - msghdr.msg_iovlen = msg_iov_len(iov.len()); - msghdr.msg_control = control.as_control_ptr().cast(); - msghdr.msg_controllen = msg_control_len(control.control_len()); - - let res = f(&mut msghdr); - - // Reset the control length. - if res.is_ok() { - // SAFETY: `f` returned `Ok`, so our safety condition requires `f` to - // have initialized `msg_controllen` bytes. - control.set_control_len(msghdr.msg_controllen as usize); - } - - name.len = msghdr.msg_namelen; - - res -} - -/// Create a message header intended to send without an address. -/// -/// The returned `msghdr` will contain raw pointers to the memory -/// referenced by `iov` and `control`. -pub(crate) fn noaddr_msghdr( - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, -) -> c::msghdr { - let mut h = zero_msghdr(); - h.msg_iov = iov.as_ptr() as _; - h.msg_iovlen = msg_iov_len(iov.len()); - h.msg_control = control.as_control_ptr().cast(); - h.msg_controllen = msg_control_len(control.control_len()); - h -} - -/// Create a message header intended to send with the specified address. -/// -/// This creates a `c::msghdr` and calls a function `f` on it. The `msghdr`'s -/// raw pointers may point to temporaries, so this function should avoid -/// storing the pointers anywhere that would outlive the function call. -/// -/// # Safety -/// -/// If `f` dereferences the pointers in the `msghdr`, it must do so only within -/// the bounds indicated by the associated lengths in the `msghdr`. -pub(crate) unsafe fn with_msghdr( - addr: &impl SocketAddrArg, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - f: impl FnOnce(&c::msghdr) -> R, -) -> R { - addr.with_sockaddr(|addr_ptr, addr_len| { - let mut h = zero_msghdr(); - h.msg_name = addr_ptr as *mut _; - h.msg_namelen = bitcast!(addr_len); - h.msg_iov = iov.as_ptr() as _; - h.msg_iovlen = msg_iov_len(iov.len()); - h.msg_control = control.as_control_ptr().cast(); - h.msg_controllen = msg_control_len(control.control_len()); - // Pass a reference to the `c::msghdr` instead of passing it by value - // because it may contain pointers to temporary objects that won't - // live beyond the call to `with_sockaddr`. - f(&h) - }) -} - -/// Create a zero-initialized message header struct value. -#[cfg(all(unix, not(target_os = "redox")))] -pub(crate) fn zero_msghdr() -> c::msghdr { - // SAFETY: We can't initialize all the fields by value because on some - // platforms the `msghdr` struct in the libc crate contains private padding - // fields. But it is still a C type that's meant to be zero-initializable. - unsafe { zeroed() } -} diff --git a/vendor/rustix/src/backend/libc/net/netdevice.rs b/vendor/rustix/src/backend/libc/net/netdevice.rs deleted file mode 100644 index 887f768d..00000000 --- a/vendor/rustix/src/backend/libc/net/netdevice.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! Wrappers for netdevice ioctls. - -#![allow(unsafe_code)] - -#[cfg(feature = "alloc")] -use crate::alloc::string::String; -use crate::backend::c; -use crate::backend::io::syscalls::ioctl; -use crate::fd::BorrowedFd; -use crate::io; -#[cfg(feature = "alloc")] -use c::SIOCGIFNAME; -use c::{__c_anonymous_ifr_ifru, c_char, ifreq, IFNAMSIZ, SIOCGIFINDEX}; - -pub(crate) fn name_to_index(fd: BorrowedFd<'_>, if_name: &str) -> io::Result { - let if_name_bytes = if_name.as_bytes(); - if if_name_bytes.len() >= IFNAMSIZ as usize { - return Err(io::Errno::NODEV); - } - - let mut ifreq = ifreq { - ifr_name: [0; 16], - ifr_ifru: __c_anonymous_ifr_ifru { ifru_ifindex: 0 }, - }; - - let mut if_name_c_char_iter = if_name_bytes.iter().map(|byte| *byte as c_char); - ifreq.ifr_name[..if_name_bytes.len()].fill_with(|| if_name_c_char_iter.next().unwrap()); - - unsafe { ioctl(fd, SIOCGIFINDEX as _, &mut ifreq as *mut ifreq as _) }?; - let index = unsafe { ifreq.ifr_ifru.ifru_ifindex }; - Ok(index as u32) -} - -#[cfg(feature = "alloc")] -pub(crate) fn index_to_name(fd: BorrowedFd<'_>, index: u32) -> io::Result { - let mut ifreq = ifreq { - ifr_name: [0; 16], - ifr_ifru: __c_anonymous_ifr_ifru { - ifru_ifindex: index as _, - }, - }; - - unsafe { ioctl(fd, SIOCGIFNAME as _, &mut ifreq as *mut ifreq as _) }?; - - if let Some(nul_byte) = ifreq.ifr_name.iter().position(|char| *char == 0) { - let name: String = ifreq.ifr_name[..nul_byte] - .iter() - .map(|v| *v as u8 as char) - .collect(); - - Ok(name) - } else { - Err(io::Errno::INVAL) - } -} diff --git a/vendor/rustix/src/backend/libc/net/read_sockaddr.rs b/vendor/rustix/src/backend/libc/net/read_sockaddr.rs deleted file mode 100644 index 5f8c48ec..00000000 --- a/vendor/rustix/src/backend/libc/net/read_sockaddr.rs +++ /dev/null @@ -1,264 +0,0 @@ -//! The BSD sockets API requires us to read the `sa_family` field before we can -//! interpret the rest of a `sockaddr` produced by the kernel. - -#[cfg(unix)] -use super::addr::SocketAddrUnix; -use super::ext::{in6_addr_s6_addr, in_addr_s_addr, sockaddr_in6_sin6_scope_id}; -use crate::backend::c; -#[cfg(not(windows))] -use crate::ffi::CStr; -use crate::io::Errno; -use crate::net::addr::SocketAddrLen; -#[cfg(linux_kernel)] -use crate::net::netlink::SocketAddrNetlink; -#[cfg(target_os = "linux")] -use crate::net::xdp::{SocketAddrXdp, SocketAddrXdpFlags}; -use crate::net::{AddressFamily, Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrV4, SocketAddrV6}; -use core::mem::size_of; - -// This must match the header of `sockaddr`. -#[repr(C)] -pub(crate) struct sockaddr_header { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "nto", - target_os = "vita" - ))] - sa_len: u8, - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "nto", - target_os = "vita" - ))] - sa_family: u8, - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "nto", - target_os = "vita" - )))] - sa_family: u16, -} - -/// Read the `sa_family` field from a socket address returned from the OS. -/// -/// # Safety -/// -/// `storage` must point to a valid socket address returned from the OS. -#[inline] -pub(crate) unsafe fn read_sa_family(storage: *const c::sockaddr) -> u16 { - // Assert that we know the layout of `sockaddr`. - let _ = c::sockaddr { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - sa_len: 0_u8, - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - sa_family: 0_u8, - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - )))] - sa_family: 0_u16, - #[cfg(not(any(target_os = "haiku", target_os = "horizon")))] - sa_data: [0; 14], - #[cfg(target_os = "horizon")] - sa_data: [0; 26], - #[cfg(target_os = "haiku")] - sa_data: [0; 30], - }; - - (*storage.cast::()).sa_family.into() -} - -/// Read the first byte of the `sun_path` field, assuming we have an `AF_UNIX` -/// socket address. -#[cfg(apple)] -#[inline] -unsafe fn read_sun_path0(storage: *const c::sockaddr) -> u8 { - // In `read_sa_family` we assert that we know the layout of `sockaddr`. - storage - .cast::() - .add(super::addr::offsetof_sun_path()) - .read() -} - -/// Check if a socket address returned from the OS is considered non-empty. -/// -/// # Safety -/// -/// `storage` must point to a least an initialized `sockaddr_header`. -#[inline] -pub(crate) unsafe fn sockaddr_nonempty(storage: *const c::sockaddr, len: SocketAddrLen) -> bool { - if len == 0 { - return false; - } - - assert!(len as usize >= size_of::()); - let family: c::c_int = read_sa_family(storage.cast::()).into(); - if family == c::AF_UNSPEC { - return false; - } - - // On macOS, if we get an `AF_UNIX` with an empty path, treat it as an - // absent address. - #[cfg(apple)] - if family == c::AF_UNIX && read_sun_path0(storage) == 0 { - return false; - } - - true -} - -/// Set the `sa_family` field of a socket address to `AF_UNSPEC`, so that we -/// can test for `AF_UNSPEC` to test whether it was stored to. -/// -/// # Safety -/// -/// `storage` must point to a least an initialized `sockaddr_header`. -pub(crate) unsafe fn initialize_family_to_unspec(storage: *mut c::sockaddr) { - (*storage.cast::()).sa_family = c::AF_UNSPEC as _; -} - -#[inline] -pub(crate) fn read_sockaddr_v4(addr: &SocketAddrAny) -> Result { - if addr.address_family() != AddressFamily::INET { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::()); - let decode = unsafe { &*addr.as_ptr().cast::() }; - Ok(SocketAddrV4::new( - Ipv4Addr::from(u32::from_be(in_addr_s_addr(decode.sin_addr))), - u16::from_be(decode.sin_port), - )) -} - -#[inline] -pub(crate) fn read_sockaddr_v6(addr: &SocketAddrAny) -> Result { - if addr.address_family() != AddressFamily::INET6 { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::()); - let decode = unsafe { &*addr.as_ptr().cast::() }; - Ok(SocketAddrV6::new( - Ipv6Addr::from(in6_addr_s6_addr(decode.sin6_addr)), - u16::from_be(decode.sin6_port), - u32::from_be(decode.sin6_flowinfo), - sockaddr_in6_sin6_scope_id(decode), - )) -} - -#[cfg(unix)] -#[inline] -pub(crate) fn read_sockaddr_unix(addr: &SocketAddrAny) -> Result { - if addr.address_family() != AddressFamily::UNIX { - return Err(Errno::AFNOSUPPORT); - } - - let offsetof_sun_path = super::addr::offsetof_sun_path(); - let len = addr.addr_len() as usize; - - assert!(len >= offsetof_sun_path); - - if len == offsetof_sun_path { - SocketAddrUnix::new(&[][..]) - } else { - let decode = unsafe { &*addr.as_ptr().cast::() }; - - // On Linux check for Linux's [abstract namespace]. - // - // [abstract namespace]: https://man7.org/linux/man-pages/man7/unix.7.html - #[cfg(linux_kernel)] - if decode.sun_path[0] == 0 { - let name = &decode.sun_path[1..len - offsetof_sun_path]; - let name = unsafe { core::mem::transmute::<&[c::c_char], &[u8]>(name) }; - return SocketAddrUnix::new_abstract_name(name); - } - - // Otherwise we expect a NUL-terminated filesystem path. - - // Trim off unused bytes from the end of `path_bytes`. - let path_bytes = if cfg!(any(solarish, target_os = "freebsd")) { - // FreeBSD and illumos sometimes set the length to longer - // than the length of the NUL-terminated string. Find the - // NUL and truncate the string accordingly. - &decode.sun_path[..decode - .sun_path - .iter() - .position(|b| *b == 0) - .ok_or(Errno::INVAL)?] - } else { - // Otherwise, use the provided length. - let provided_len = len - 1 - offsetof_sun_path; - if decode.sun_path[provided_len] != 0 { - return Err(Errno::INVAL); - } - debug_assert_eq!( - unsafe { CStr::from_ptr(decode.sun_path.as_ptr().cast()) } - .to_bytes() - .len(), - provided_len - ); - &decode.sun_path[..provided_len] - }; - - SocketAddrUnix::new(unsafe { core::mem::transmute::<&[c::c_char], &[u8]>(path_bytes) }) - } -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn read_sockaddr_xdp(addr: &SocketAddrAny) -> Result { - if addr.address_family() != AddressFamily::XDP { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::()); - let decode = unsafe { &*addr.as_ptr().cast::() }; - - // This ignores the `sxdp_shared_umem_fd` field, which is only expected to - // be significant in `bind` calls, and not returned from `acceptfrom` or - // `recvmsg` or similar. - Ok(SocketAddrXdp::new( - SocketAddrXdpFlags::from_bits_retain(decode.sxdp_flags), - u32::from_be(decode.sxdp_ifindex), - u32::from_be(decode.sxdp_queue_id), - )) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn read_sockaddr_netlink(addr: &SocketAddrAny) -> Result { - if addr.address_family() != AddressFamily::NETLINK { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::()); - let decode = unsafe { &*addr.as_ptr().cast::() }; - Ok(SocketAddrNetlink::new(decode.nl_pid, decode.nl_groups)) -} diff --git a/vendor/rustix/src/backend/libc/net/send_recv.rs b/vendor/rustix/src/backend/libc/net/send_recv.rs deleted file mode 100644 index 4b67f2c5..00000000 --- a/vendor/rustix/src/backend/libc/net/send_recv.rs +++ /dev/null @@ -1,153 +0,0 @@ -use crate::backend::c; -use bitflags::bitflags; - -bitflags! { - /// `MSG_*` flags for use with [`send`], [`sendto`], and related - /// functions. - /// - /// [`send`]: crate::net::send - /// [`sendto`]: crate::net::sendto - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SendFlags: u32 { - /// `MSG_CONFIRM` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "nto", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "redox", - target_os = "vita", - )))] - const CONFIRM = bitcast!(c::MSG_CONFIRM); - /// `MSG_DONTROUTE` - const DONTROUTE = bitcast!(c::MSG_DONTROUTE); - /// `MSG_DONTWAIT` - #[cfg(not(windows))] - const DONTWAIT = bitcast!(c::MSG_DONTWAIT); - /// `MSG_EOR` - #[cfg(not(any(windows, target_os = "horizon")))] - const EOR = bitcast!(c::MSG_EOR); - /// `MSG_MORE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - const MORE = bitcast!(c::MSG_MORE); - #[cfg(not(any(apple, windows, target_os = "redox", target_os = "vita")))] - /// `MSG_NOSIGNAL` - const NOSIGNAL = bitcast!(c::MSG_NOSIGNAL); - /// `MSG_OOB` - const OOB = bitcast!(c::MSG_OOB); - - /// - const _ = !0; - } -} - -bitflags! { - /// `MSG_*` flags for use with [`recv`], [`recvfrom`], and related - /// functions. - /// - /// [`recv`]: crate::net::recv - /// [`recvfrom`]: crate::net::recvfrom - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct RecvFlags: u32 { - /// `MSG_CMSG_CLOEXEC` - #[cfg(not(any( - apple, - solarish, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - const CMSG_CLOEXEC = bitcast!(c::MSG_CMSG_CLOEXEC); - /// `MSG_DONTWAIT` - #[cfg(not(windows))] - const DONTWAIT = bitcast!(c::MSG_DONTWAIT); - /// `MSG_ERRQUEUE` - #[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", - )))] - const ERRQUEUE = bitcast!(c::MSG_ERRQUEUE); - /// `MSG_OOB` - const OOB = bitcast!(c::MSG_OOB); - /// `MSG_PEEK` - const PEEK = bitcast!(c::MSG_PEEK); - /// `MSG_TRUNC` - // Apple, illumos, and NetBSD have `MSG_TRUNC` but it's not documented - // for use with `recv` and friends, and in practice appears to be - // ignored. - #[cfg(not(any(apple, solarish, target_os = "horizon", target_os = "netbsd")))] - const TRUNC = bitcast!(c::MSG_TRUNC); - /// `MSG_WAITALL` - const WAITALL = bitcast!(c::MSG_WAITALL); - - /// - const _ = !0; - } -} - -bitflags! { - /// `MSG_*` flags returned from [`recvmsg`], in the `flags` field of - /// [`RecvMsg`] - /// - /// [`recvmsg`]: crate::net::recvmsg - /// [`RecvMsg`]: crate::net::RecvMsg - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ReturnFlags: u32 { - /// `MSG_OOB` - const OOB = bitcast!(c::MSG_OOB); - /// `MSG_EOR` - #[cfg(not(any(windows, target_os = "horizon")))] - const EOR = bitcast!(c::MSG_EOR); - /// `MSG_TRUNC` - #[cfg(not(target_os = "horizon"))] - const TRUNC = bitcast!(c::MSG_TRUNC); - /// `MSG_CTRUNC` - #[cfg(not(target_os = "horizon"))] - const CTRUNC = bitcast!(c::MSG_CTRUNC); - - /// `MSG_CMSG_CLOEXEC` - #[cfg(linux_kernel)] - const CMSG_CLOEXEC = bitcast!(c::MSG_CMSG_CLOEXEC); - /// `MSG_ERRQUEUE` - #[cfg(linux_kernel)] - const ERRQUEUE = bitcast!(c::MSG_ERRQUEUE); - - /// - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/libc/net/sockopt.rs b/vendor/rustix/src/backend/libc/net/sockopt.rs deleted file mode 100644 index 132ebe75..00000000 --- a/vendor/rustix/src/backend/libc/net/sockopt.rs +++ /dev/null @@ -1,1339 +0,0 @@ -//! libc syscalls supporting `rustix::net::sockopt`. - -use super::ext::{in6_addr_new, in_addr_new}; -use crate::backend::c; -use crate::backend::conv::{borrowed_fd, ret}; -use crate::fd::BorrowedFd; -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -use crate::ffi::CStr; -use crate::io; -use crate::net::sockopt::Timeout; -#[cfg(target_os = "linux")] -use crate::net::xdp::{XdpMmapOffsets, XdpOptionsFlags, XdpRingOffset, 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 = "freebsd", - target_os = "fuchsia", - target_os = "openbsd", - target_os = "redox", - target_env = "newlib" -))] -use crate::net::RawProtocol; -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -use crate::net::SocketAddrV4; -use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; -#[cfg(linux_kernel)] -use crate::net::{SocketAddrV6, UCred}; -use crate::utils::as_mut_ptr; -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -use alloc::borrow::ToOwned as _; -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -use alloc::string::String; -#[cfg(apple)] -use c::TCP_KEEPALIVE as TCP_KEEPIDLE; -#[cfg(not(any(apple, target_os = "haiku", target_os = "nto", target_os = "openbsd")))] -use c::TCP_KEEPIDLE; -use core::mem::{size_of, MaybeUninit}; -use core::time::Duration; -#[cfg(target_os = "linux")] -use linux_raw_sys::xdp::{xdp_mmap_offsets, xdp_statistics, xdp_statistics_v1}; -#[cfg(windows)] -use windows_sys::Win32::Foundation::BOOL; - -#[inline] -fn getsockopt(fd: BorrowedFd<'_>, level: i32, optname: i32) -> io::Result { - let mut optlen = size_of::().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - - let mut value = MaybeUninit::::zeroed(); - getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; - - // On Windows at least, `getsockopt` has been observed writing 1 - // byte on at least (`IPPROTO_TCP`, `TCP_NODELAY`), even though - // Windows' documentation says that should write a 4-byte `BOOL`. - // So, we initialize the memory to zeros above, and just assert - // that `getsockopt` doesn't write too many bytes here. - assert!( - optlen as usize <= size_of::(), - "unexpected getsockopt size" - ); - - unsafe { Ok(value.assume_init()) } -} - -#[inline] -fn getsockopt_raw( - fd: BorrowedFd<'_>, - level: i32, - optname: i32, - value: &mut MaybeUninit, - optlen: &mut c::socklen_t, -) -> io::Result<()> { - unsafe { - ret(c::getsockopt( - borrowed_fd(fd), - level, - optname, - as_mut_ptr(value).cast(), - optlen, - )) - } -} - -#[inline] -fn setsockopt(fd: BorrowedFd<'_>, level: i32, optname: i32, value: T) -> io::Result<()> { - let optlen = size_of::().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - setsockopt_raw(fd, level, optname, &value, optlen) -} - -#[inline] -fn setsockopt_raw( - fd: BorrowedFd<'_>, - level: i32, - optname: i32, - ptr: *const T, - optlen: c::socklen_t, -) -> io::Result<()> { - unsafe { - ret(c::setsockopt( - borrowed_fd(fd), - level, - optname, - ptr.cast(), - optlen, - )) - } -} - -#[inline] -pub(crate) fn socket_type(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_TYPE) -} - -#[inline] -pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR, from_bool(reuseaddr)) -} - -#[inline] -pub(crate) fn socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST, from_bool(broadcast)) -} - -#[inline] -pub(crate) fn socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_linger(fd: BorrowedFd<'_>, linger: Option) -> io::Result<()> { - // Convert `linger` to seconds, rounding up. - let l_linger = if let Some(linger) = linger { - duration_to_secs(linger)? - } else { - 0 - }; - let linger = c::linger { - l_onoff: linger.is_some().into(), - l_linger, - }; - setsockopt(fd, c::SOL_SOCKET, c::SO_LINGER, linger) -} - -#[inline] -pub(crate) fn socket_linger(fd: BorrowedFd<'_>) -> io::Result> { - let linger: c::linger = getsockopt(fd, c::SOL_SOCKET, c::SO_LINGER)?; - Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED, from_bool(passcred)) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn socket_passcred(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option, -) -> io::Result<()> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO, - Timeout::Send => c::SO_SNDTIMEO, - }; - - #[cfg(not(windows))] - let timeout = match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // Rust's musl libc bindings deprecated `time_t` while they - // transition to 64-bit `time_t`. What we want here is just - // “whatever type `timeval`'s `tv_sec` is”, so we're ok using - // the deprecated type. - #[allow(deprecated)] - let tv_sec = timeout.as_secs().try_into().unwrap_or(c::time_t::MAX); - - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = c::timeval { - tv_sec, - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => c::timeval { - tv_sec: 0, - tv_usec: 0, - }, - }; - - #[cfg(windows)] - let timeout: u32 = match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // `as_millis` rounds down, so we use `as_nanos` and - // manually round up. - let mut timeout: u32 = ((timeout.as_nanos() + 999_999) / 1_000_000) - .try_into() - .map_err(|_convert_err| io::Errno::INVAL)?; - if timeout == 0 { - timeout = 1; - } - timeout - } - None => 0, - }; - - setsockopt(fd, c::SOL_SOCKET, optname, timeout) -} - -#[inline] -pub(crate) fn socket_timeout(fd: BorrowedFd<'_>, id: Timeout) -> io::Result> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO, - Timeout::Send => c::SO_SNDTIMEO, - }; - - #[cfg(not(windows))] - { - let timeout: c::timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - Ok(None) - } else { - Ok(Some( - Duration::from_secs(timeout.tv_sec as u64) - + Duration::from_micros(timeout.tv_usec as u64), - )) - } - } - - #[cfg(windows)] - { - let timeout: u32 = getsockopt(fd, c::SOL_SOCKET, optname)?; - if timeout == 0 { - Ok(None) - } else { - Ok(Some(Duration::from_millis(timeout as u64))) - } - } -} - -#[cfg(any(apple, freebsdlike, target_os = "netbsd"))] -#[inline] -pub(crate) fn socket_nosigpipe(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE).map(to_bool) -} - -#[cfg(any(apple, freebsdlike, target_os = "netbsd"))] -#[inline] -pub(crate) fn set_socket_nosigpipe(fd: BorrowedFd<'_>, val: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE, from_bool(val)) -} - -#[inline] -pub(crate) fn socket_error(fd: BorrowedFd<'_>) -> io::Result> { - let err: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_ERROR)?; - Ok(if err == 0 { - Ok(()) - } else { - Err(io::Errno::from_raw_os_error(err)) - }) -} - -#[inline] -pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE, from_bool(keepalive)) -} - -#[inline] -pub(crate) fn socket_keepalive(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF, size) -} - -#[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "redox"))] -#[inline] -pub(crate) fn set_socket_recv_buffer_size_force(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUFFORCE, size) -} - -#[inline] -pub(crate) fn socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF).map(|size: u32| size as usize) -} - -#[inline] -pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF, size) -} - -#[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "redox"))] -#[inline] -pub(crate) fn set_socket_send_buffer_size_force(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUFFORCE, size) -} - -#[inline] -pub(crate) fn socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF).map(|size: u32| size as usize) -} - -#[inline] -#[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", -)))] -pub(crate) fn socket_domain(fd: BorrowedFd<'_>) -> io::Result { - let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_DOMAIN)?; - Ok(AddressFamily( - domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, - )) -} - -#[inline] -#[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it. -pub(crate) fn socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_ACCEPTCONN).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE, from_bool(value)) -} - -#[inline] -pub(crate) fn socket_oobinline(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE).map(to_bool) -} - -#[cfg(not(any(solarish, windows, target_os = "cygwin")))] -#[inline] -pub(crate) fn set_socket_reuseport(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT, from_bool(value)) -} - -#[cfg(not(any(solarish, windows, target_os = "cygwin")))] -#[inline] -pub(crate) fn socket_reuseport(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT).map(to_bool) -} - -#[cfg(target_os = "freebsd")] -#[inline] -pub(crate) fn set_socket_reuseport_lb(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT_LB, from_bool(value)) -} - -#[cfg(target_os = "freebsd")] -#[inline] -pub(crate) fn socket_reuseport_lb(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT_LB).map(to_bool) -} - -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "openbsd", - target_os = "redox", - target_env = "newlib" -))] -#[inline] -pub(crate) fn socket_protocol(fd: BorrowedFd<'_>) -> io::Result> { - getsockopt(fd, c::SOL_SOCKET, c::SO_PROTOCOL) - .map(|raw| RawProtocol::new(raw).map(Protocol::from_raw)) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn socket_cookie(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_COOKIE) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn socket_incoming_cpu(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_socket_incoming_cpu(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU, value) -} - -#[inline] -pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_TTL, ttl) -} - -#[inline] -pub(crate) fn ip_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IP_TTL) -} - -#[inline] -pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY, from_bool(only_v6)) -} - -#[inline] -pub(crate) fn ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY).map(to_bool) -} - -#[cfg(any(linux_kernel, target_os = "cygwin"))] -#[inline] -pub(crate) fn ip_mtu(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IP_MTU) -} - -#[cfg(any(linux_kernel, target_os = "cygwin"))] -#[inline] -pub(crate) fn ipv6_mtu(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MTU) -} - -#[inline] -pub(crate) fn set_ip_multicast_if(fd: BorrowedFd<'_>, value: &Ipv4Addr) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_IF, to_imr_addr(value)) -} - -#[inline] -pub(crate) fn ip_multicast_if(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_IF).map(from_in_addr) -} - -#[cfg(any( - apple, - freebsdlike, - linux_like, - target_os = "fuchsia", - target_os = "openbsd" -))] -#[inline] -pub(crate) fn set_ip_multicast_if_with_ifindex( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - let mreqn = to_ip_mreqn(multiaddr, address, ifindex as i32); - setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_IF, mreqn) -} - -#[inline] -pub(crate) fn set_ipv6_multicast_if(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_IF, value as c::c_int) -} - -#[inline] -pub(crate) fn ipv6_multicast_if(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_IF) -} - -#[inline] -pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP, - c::IP_MULTICAST_LOOP, - from_bool(multicast_loop), - ) -} - -#[inline] -pub(crate) fn ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_LOOP).map(to_bool) -} - -#[inline] -pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl) -} - -#[inline] -pub(crate) fn ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL) -} - -#[inline] -pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IPV6, - c::IPV6_MULTICAST_LOOP, - from_bool(multicast_loop), - ) -} - -#[inline] -pub(crate) fn ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP).map(to_bool) -} - -#[inline] -pub(crate) fn set_ipv6_multicast_hops(fd: BorrowedFd<'_>, multicast_hops: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS, multicast_hops) -} - -#[inline] -pub(crate) fn ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS) -} - -#[inline] -pub(crate) fn set_ip_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, -) -> io::Result<()> { - let mreq = to_ip_mreq(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) -} - -#[cfg(any( - apple, - freebsdlike, - linux_like, - target_os = "fuchsia", - target_os = "openbsd" -))] -#[inline] -pub(crate) fn set_ip_add_membership_with_ifindex( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - let mreqn = to_ip_mreqn(multiaddr, address, ifindex as i32); - setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreqn) -} - -#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] -#[inline] -pub(crate) fn set_ip_add_source_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> io::Result<()> { - let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); - setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_SOURCE_MEMBERSHIP, mreq_source) -} - -#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] -#[inline] -pub(crate) fn set_ip_drop_source_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> io::Result<()> { - let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); - setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_SOURCE_MEMBERSHIP, mreq_source) -} - -#[inline] -pub(crate) fn set_ipv6_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, -) -> io::Result<()> { - #[cfg(not(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - )))] - use c::IPV6_ADD_MEMBERSHIP; - #[cfg(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - ))] - use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; - - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq) -} - -#[inline] -pub(crate) fn set_ip_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, -) -> io::Result<()> { - let mreq = to_ip_mreq(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) -} - -#[cfg(any( - apple, - freebsdlike, - linux_like, - target_os = "fuchsia", - target_os = "openbsd" -))] -#[inline] -pub(crate) fn set_ip_drop_membership_with_ifindex( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - let mreqn = to_ip_mreqn(multiaddr, address, ifindex as i32); - setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreqn) -} - -#[inline] -pub(crate) fn set_ipv6_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, -) -> io::Result<()> { - #[cfg(not(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - )))] - use c::IPV6_DROP_MEMBERSHIP; - #[cfg(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - ))] - use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; - - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq) -} - -#[inline] -pub(crate) fn ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) -} - -#[inline] -pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io::Result<()> { - let hops = match hops { - Some(hops) => hops as c::c_int, - None => -1, - }; - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS, hops) -} - -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "haiku", - target_os = "nto", - target_env = "newlib" -))] -#[inline] -pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, i32::from(value)) -} - -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "haiku", - target_os = "nto", - target_env = "newlib" -))] -#[inline] -pub(crate) fn ip_tos(fd: BorrowedFd<'_>) -> io::Result { - let value: i32 = getsockopt(fd, c::IPPROTO_IP, c::IP_TOS)?; - Ok(value as u8) -} - -#[cfg(any( - apple, - linux_like, - target_os = "cygwin", - target_os = "freebsd", - target_os = "fuchsia", -))] -#[inline] -pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, from_bool(value)) -} - -#[cfg(any( - apple, - linux_like, - target_os = "cygwin", - target_os = "freebsd", - target_os = "fuchsia", -))] -#[inline] -pub(crate) fn ip_recvtos(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) -} - -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "nto" -))] -#[inline] -pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, from_bool(value)) -} - -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "nto" -))] -#[inline] -pub(crate) fn ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(to_bool) -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn set_ip_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND, from_bool(value)) -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn ip_freebind(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND).map(to_bool) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn set_ipv6_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND, from_bool(value)) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn ipv6_freebind(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND).map(to_bool) -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn ip_original_dst(fd: BorrowedFd<'_>) -> io::Result { - let level = c::IPPROTO_IP; - let optname = c::SO_ORIGINAL_DST; - - let mut addr = crate::net::SocketAddrBuf::new(); - getsockopt_raw(fd, level, optname, &mut addr.storage, &mut addr.len)?; - Ok(unsafe { addr.into_any() }.try_into().unwrap()) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn ipv6_original_dst(fd: BorrowedFd<'_>) -> io::Result { - let level = c::IPPROTO_IPV6; - let optname = c::IP6T_SO_ORIGINAL_DST; - - let mut addr = crate::net::SocketAddrBuf::new(); - getsockopt_raw(fd, level, optname, &mut addr.storage, &mut addr.len)?; - Ok(unsafe { addr.into_any() }.try_into().unwrap()) -} - -#[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -#[inline] -pub(crate) fn set_ipv6_tclass(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS, value) -} - -#[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -#[inline] -pub(crate) fn ipv6_tclass(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS) -} - -#[inline] -pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY, from_bool(nodelay)) -} - -#[inline] -pub(crate) fn tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY).map(to_bool) -} - -#[inline] -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT, count) -} - -#[inline] -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -pub(crate) fn tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT) -} - -#[inline] -#[cfg(not(any(target_os = "haiku", target_os = "nto", target_os = "openbsd")))] -pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP, TCP_KEEPIDLE, secs) -} - -#[inline] -#[cfg(not(any(target_os = "haiku", target_os = "nto", target_os = "openbsd")))] -pub(crate) fn tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, TCP_KEEPIDLE)?; - Ok(Duration::from_secs(secs as u64)) -} - -#[inline] -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL, secs) -} - -#[inline] -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -pub(crate) fn tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL)?; - Ok(Duration::from_secs(secs as u64)) -} - -#[inline] -#[cfg(any(linux_like, target_os = "fuchsia"))] -pub(crate) fn set_tcp_user_timeout(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT, value) -} - -#[inline] -#[cfg(any(linux_like, target_os = "fuchsia"))] -pub(crate) fn tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT) -} - -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -pub(crate) fn set_tcp_quickack(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK, from_bool(value)) -} - -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -pub(crate) fn tcp_quickack(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK).map(to_bool) -} - -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -#[inline] -pub(crate) fn set_tcp_congestion(fd: BorrowedFd<'_>, value: &str) -> io::Result<()> { - let level = c::IPPROTO_TCP; - let optname = c::TCP_CONGESTION; - let optlen = value.len().try_into().unwrap(); - setsockopt_raw(fd, level, optname, value.as_ptr(), optlen) -} - -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -#[inline] -pub(crate) fn tcp_congestion(fd: BorrowedFd<'_>) -> io::Result { - const OPTLEN: c::socklen_t = 16; - - let level = c::IPPROTO_TCP; - let optname = c::TCP_CONGESTION; - let mut value = MaybeUninit::<[MaybeUninit; OPTLEN as usize]>::uninit(); - let mut optlen = OPTLEN; - getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; - unsafe { - let value = value.assume_init(); - let slice: &[u8] = core::mem::transmute(&value[..optlen as usize]); - assert!(slice.contains(&b'\0')); - Ok( - core::str::from_utf8(CStr::from_ptr(slice.as_ptr().cast()).to_bytes()) - .unwrap() - .to_owned(), - ) - } -} - -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -pub(crate) fn set_tcp_thin_linear_timeouts(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_TCP, - c::TCP_THIN_LINEAR_TIMEOUTS, - from_bool(value), - ) -} - -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -pub(crate) fn tcp_thin_linear_timeouts(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_THIN_LINEAR_TIMEOUTS).map(to_bool) -} - -#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] -#[inline] -pub(crate) fn set_tcp_cork(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK, from_bool(value)) -} - -#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] -#[inline] -pub(crate) fn tcp_cork(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK).map(to_bool) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn socket_peercred(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET, c::SO_PEERCRED) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_umem_reg(fd: BorrowedFd<'_>, value: XdpUmemReg) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_UMEM_REG, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_umem_fill_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_UMEM_FILL_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_umem_completion_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_UMEM_COMPLETION_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_tx_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_TX_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_rx_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_RX_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn xdp_mmap_offsets(fd: BorrowedFd<'_>) -> io::Result { - // The kernel will write `xdp_mmap_offsets` or `xdp_mmap_offsets_v1` to the - // supplied pointer, depending on the kernel version. Both structs only - // contain u64 values. By using the larger of both as the parameter, we can - // shuffle the values to the non-v1 version returned by - // `get_xdp_mmap_offsets` while keeping the return type unaffected by the - // kernel version. This works because C will layout all struct members one - // after the other. - - let mut optlen = size_of::().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - let mut value = MaybeUninit::::zeroed(); - getsockopt_raw(fd, c::SOL_XDP, c::XDP_MMAP_OFFSETS, &mut value, &mut optlen)?; - - if optlen as usize == size_of::() { - // SAFETY: All members of xdp_mmap_offsets are `u64` and thus are - // correctly initialized by `MaybeUninit::::zeroed()`. - let xpd_mmap_offsets = unsafe { value.assume_init() }; - Ok(XdpMmapOffsets { - rx: XdpRingOffset { - producer: xpd_mmap_offsets.rx.producer, - consumer: xpd_mmap_offsets.rx.consumer, - desc: xpd_mmap_offsets.rx.desc, - flags: None, - }, - tx: XdpRingOffset { - producer: xpd_mmap_offsets.rx.flags, - consumer: xpd_mmap_offsets.tx.producer, - desc: xpd_mmap_offsets.tx.consumer, - flags: None, - }, - fr: XdpRingOffset { - producer: xpd_mmap_offsets.tx.desc, - consumer: xpd_mmap_offsets.tx.flags, - desc: xpd_mmap_offsets.fr.producer, - flags: None, - }, - cr: XdpRingOffset { - producer: xpd_mmap_offsets.fr.consumer, - consumer: xpd_mmap_offsets.fr.desc, - desc: xpd_mmap_offsets.fr.flags, - flags: None, - }, - }) - } else { - assert_eq!( - optlen as usize, - size_of::(), - "unexpected getsockopt size" - ); - // SAFETY: All members of xdp_mmap_offsets are `u64` and thus are - // correctly initialized by `MaybeUninit::::zeroed()` - let xpd_mmap_offsets = unsafe { value.assume_init() }; - Ok(XdpMmapOffsets { - rx: XdpRingOffset { - producer: xpd_mmap_offsets.rx.producer, - consumer: xpd_mmap_offsets.rx.consumer, - desc: xpd_mmap_offsets.rx.desc, - flags: Some(xpd_mmap_offsets.rx.flags), - }, - tx: XdpRingOffset { - producer: xpd_mmap_offsets.tx.producer, - consumer: xpd_mmap_offsets.tx.consumer, - desc: xpd_mmap_offsets.tx.desc, - flags: Some(xpd_mmap_offsets.tx.flags), - }, - fr: XdpRingOffset { - producer: xpd_mmap_offsets.fr.producer, - consumer: xpd_mmap_offsets.fr.consumer, - desc: xpd_mmap_offsets.fr.desc, - flags: Some(xpd_mmap_offsets.fr.flags), - }, - cr: XdpRingOffset { - producer: xpd_mmap_offsets.cr.producer, - consumer: xpd_mmap_offsets.cr.consumer, - desc: xpd_mmap_offsets.cr.desc, - flags: Some(xpd_mmap_offsets.cr.flags), - }, - }) - } -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn xdp_statistics(fd: BorrowedFd<'_>) -> io::Result { - let mut optlen = size_of::().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - let mut value = MaybeUninit::::zeroed(); - getsockopt_raw(fd, c::SOL_XDP, c::XDP_STATISTICS, &mut value, &mut optlen)?; - - if optlen as usize == size_of::() { - // SAFETY: All members of xdp_statistics are `u64` and thus are - // correctly initialized by `MaybeUninit::::zeroed()`. - let xdp_statistics = unsafe { value.assume_init() }; - Ok(XdpStatistics { - rx_dropped: xdp_statistics.rx_dropped, - rx_invalid_descs: xdp_statistics.rx_dropped, - tx_invalid_descs: xdp_statistics.rx_dropped, - rx_ring_full: None, - rx_fill_ring_empty_descs: None, - tx_ring_empty_descs: None, - }) - } else { - assert_eq!( - optlen as usize, - size_of::(), - "unexpected getsockopt size" - ); - // SAFETY: All members of xdp_statistics are `u64` and thus are - // correctly initialized by `MaybeUninit::::zeroed()`. - let xdp_statistics = unsafe { value.assume_init() }; - Ok(XdpStatistics { - rx_dropped: xdp_statistics.rx_dropped, - rx_invalid_descs: xdp_statistics.rx_invalid_descs, - tx_invalid_descs: xdp_statistics.tx_invalid_descs, - rx_ring_full: Some(xdp_statistics.rx_ring_full), - rx_fill_ring_empty_descs: Some(xdp_statistics.rx_fill_ring_empty_descs), - tx_ring_empty_descs: Some(xdp_statistics.tx_ring_empty_descs), - }) - } -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn xdp_options(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_XDP, c::XDP_OPTIONS) -} - -#[inline] -fn to_ip_mreq(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { - c::ip_mreq { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - } -} - -#[cfg(not(windows))] -#[inline] -fn from_in_addr(in_addr: c::in_addr) -> Ipv4Addr { - Ipv4Addr::from(in_addr.s_addr.to_ne_bytes()) -} - -#[cfg(windows)] -fn from_in_addr(in_addr: c::in_addr) -> Ipv4Addr { - Ipv4Addr::from(unsafe { in_addr.S_un.S_addr.to_ne_bytes() }) -} - -#[cfg(any( - apple, - freebsdlike, - linux_like, - target_os = "fuchsia", - target_os = "openbsd" -))] -#[inline] -fn to_ip_mreqn(multiaddr: &Ipv4Addr, address: &Ipv4Addr, ifindex: i32) -> c::ip_mreqn { - c::ip_mreqn { - imr_multiaddr: to_imr_addr(multiaddr), - imr_address: to_imr_addr(address), - imr_ifindex: ifindex, - } -} - -#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] -#[inline] -fn to_imr_source( - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> c::ip_mreq_source { - c::ip_mreq_source { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - imr_sourceaddr: to_imr_addr(sourceaddr), - } -} - -#[inline] -fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { - in_addr_new(u32::from_ne_bytes(addr.octets())) -} - -#[inline] -fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { - c::ipv6_mreq { - ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), - ipv6mr_interface: to_ipv6mr_interface(interface), - } -} - -#[inline] -fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { - in6_addr_new(multiaddr.octets()) -} - -#[cfg(target_os = "android")] -#[inline] -fn to_ipv6mr_interface(interface: u32) -> c::c_int { - interface as c::c_int -} - -#[cfg(not(target_os = "android"))] -#[inline] -fn to_ipv6mr_interface(interface: u32) -> c::c_uint { - interface as c::c_uint -} - -// `getsockopt` and `setsockopt` represent boolean values as integers. -#[cfg(not(windows))] -type RawSocketBool = c::c_int; -#[cfg(windows)] -type RawSocketBool = BOOL; - -// Wrap `RawSocketBool` in a newtype to discourage misuse. -#[repr(transparent)] -#[derive(Copy, Clone)] -struct SocketBool(RawSocketBool); - -// Convert from a `bool` to a `SocketBool`. -#[inline] -fn from_bool(value: bool) -> SocketBool { - SocketBool(value.into()) -} - -// Convert from a `SocketBool` to a `bool`. -#[inline] -fn to_bool(value: SocketBool) -> bool { - value.0 != 0 -} - -/// Convert to seconds, rounding up if necessary. -#[inline] -fn duration_to_secs>(duration: Duration) -> io::Result { - let mut secs = duration.as_secs(); - if duration.subsec_nanos() != 0 { - secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; - } - T::try_from(secs).map_err(|_e| io::Errno::INVAL) -} diff --git a/vendor/rustix/src/backend/libc/net/syscalls.rs b/vendor/rustix/src/backend/libc/net/syscalls.rs deleted file mode 100644 index aafea002..00000000 --- a/vendor/rustix/src/backend/libc/net/syscalls.rs +++ /dev/null @@ -1,438 +0,0 @@ -//! libc syscalls supporting `rustix::net`. - -use super::read_sockaddr::initialize_family_to_unspec; -use super::send_recv::{RecvFlags, SendFlags}; -use crate::backend::c; -#[cfg(target_os = "linux")] -use crate::backend::conv::ret_u32; -use crate::backend::conv::{borrowed_fd, ret, ret_owned_fd, ret_send_recv, send_recv_len}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io; -use crate::net::addr::SocketAddrArg; -#[cfg(target_os = "linux")] -use crate::net::MMsgHdr; -use crate::net::{ - AddressFamily, Protocol, Shutdown, SocketAddrAny, SocketAddrBuf, SocketFlags, SocketType, -}; -use crate::utils::as_ptr; -use core::mem::{size_of, MaybeUninit}; -use core::ptr::null_mut; -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -use { - super::msghdr::{noaddr_msghdr, with_msghdr, with_recv_msghdr}, - super::send_recv::ReturnFlags, - crate::io::{IoSlice, IoSliceMut}, - crate::net::{RecvAncillaryBuffer, RecvMsg, SendAncillaryBuffer}, -}; - -pub(crate) unsafe fn recv( - fd: BorrowedFd<'_>, - buf: (*mut u8, usize), - flags: RecvFlags, -) -> io::Result { - ret_send_recv(c::recv( - borrowed_fd(fd), - buf.0.cast(), - send_recv_len(buf.1), - bitflags_bits!(flags), - )) -} - -pub(crate) fn send(fd: BorrowedFd<'_>, buf: &[u8], flags: SendFlags) -> io::Result { - unsafe { - ret_send_recv(c::send( - borrowed_fd(fd), - buf.as_ptr().cast(), - send_recv_len(buf.len()), - bitflags_bits!(flags), - )) - } -} - -pub(crate) unsafe fn recvfrom( - fd: BorrowedFd<'_>, - buf: (*mut u8, usize), - flags: RecvFlags, -) -> io::Result<(usize, Option)> { - let mut addr = SocketAddrBuf::new(); - - // `recvfrom` does not write to the storage if the socket is - // connection-oriented sockets, so we initialize the family field to - // `AF_UNSPEC` so that we can detect this case. - initialize_family_to_unspec(addr.storage.as_mut_ptr().cast::()); - - let nread = ret_send_recv(c::recvfrom( - borrowed_fd(fd), - buf.0.cast(), - send_recv_len(buf.1), - bitflags_bits!(flags), - addr.storage.as_mut_ptr().cast::(), - &mut addr.len, - ))?; - - Ok((nread, addr.into_any_option())) -} - -pub(crate) fn sendto( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &impl SocketAddrArg, -) -> io::Result { - unsafe { - addr.with_sockaddr(|addr_ptr, addr_len| { - ret_send_recv(c::sendto( - borrowed_fd(fd), - buf.as_ptr().cast(), - send_recv_len(buf.len()), - bitflags_bits!(flags), - addr_ptr.cast(), - bitcast!(addr_len), - )) - }) - } -} - -pub(crate) fn socket( - domain: AddressFamily, - type_: SocketType, - protocol: Option, -) -> io::Result { - let raw_protocol = match protocol { - Some(p) => p.0.get(), - None => 0, - }; - unsafe { - ret_owned_fd(c::socket( - domain.0 as c::c_int, - type_.0 as c::c_int, - raw_protocol as c::c_int, - )) - } -} - -pub(crate) fn socket_with( - domain: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option, -) -> io::Result { - let raw_protocol = match protocol { - Some(p) => p.0.get(), - None => 0, - }; - unsafe { - ret_owned_fd(c::socket( - domain.0 as c::c_int, - (type_.0 | flags.bits()) as c::c_int, - raw_protocol as c::c_int, - )) - } -} - -pub(crate) fn bind(sockfd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Result<()> { - unsafe { - addr.with_sockaddr(|addr_ptr, addr_len| { - ret(c::bind( - borrowed_fd(sockfd), - addr_ptr.cast(), - bitcast!(addr_len), - )) - }) - } -} - -pub(crate) fn connect(sockfd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Result<()> { - unsafe { - addr.with_sockaddr(|addr_ptr, addr_len| { - ret(c::connect( - borrowed_fd(sockfd), - addr_ptr.cast(), - bitcast!(addr_len), - )) - }) - } -} - -pub(crate) fn connect_unspec(sockfd: BorrowedFd<'_>) -> io::Result<()> { - debug_assert_eq!(c::AF_UNSPEC, 0); - let addr = MaybeUninit::::zeroed(); - unsafe { - ret(c::connect( - borrowed_fd(sockfd), - as_ptr(&addr).cast(), - size_of::() as c::socklen_t, - )) - } -} - -pub(crate) fn listen(sockfd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { - unsafe { ret(c::listen(borrowed_fd(sockfd), backlog)) } -} - -pub(crate) fn accept(sockfd: BorrowedFd<'_>) -> io::Result { - unsafe { - let owned_fd = ret_owned_fd(c::accept(borrowed_fd(sockfd), null_mut(), null_mut()))?; - Ok(owned_fd) - } -} - -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub(crate) fn recvmsg( - sockfd: BorrowedFd<'_>, - iov: &mut [IoSliceMut<'_>], - control: &mut RecvAncillaryBuffer<'_>, - msg_flags: RecvFlags, -) -> io::Result { - let mut addr = SocketAddrBuf::new(); - - // SAFETY: This passes the `msghdr` reference to the OS which reads the - // buffers only within the designated bounds. - let (bytes, flags) = unsafe { - with_recv_msghdr(&mut addr, iov, control, |msghdr| { - let bytes = ret_send_recv(c::recvmsg( - borrowed_fd(sockfd), - msghdr, - bitflags_bits!(msg_flags), - ))?; - Ok((bytes, msghdr.msg_flags)) - })? - }; - - Ok(RecvMsg { - bytes, - address: unsafe { addr.into_any_option() }, - flags: ReturnFlags::from_bits_retain(bitcast!(flags)), - }) -} - -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub(crate) fn sendmsg( - sockfd: BorrowedFd<'_>, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - msg_flags: SendFlags, -) -> io::Result { - let msghdr = noaddr_msghdr(iov, control); - unsafe { - ret_send_recv(c::sendmsg( - borrowed_fd(sockfd), - &msghdr, - bitflags_bits!(msg_flags), - )) - } -} - -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub(crate) fn sendmsg_addr( - sockfd: BorrowedFd<'_>, - addr: &impl SocketAddrArg, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - msg_flags: SendFlags, -) -> io::Result { - // SAFETY: This passes the `msghdr` reference to the OS which reads the - // buffers only within the designated bounds. - unsafe { - with_msghdr(addr, iov, control, |msghdr| { - ret_send_recv(c::sendmsg( - borrowed_fd(sockfd), - msghdr, - bitflags_bits!(msg_flags), - )) - }) - } -} - -#[cfg(target_os = "linux")] -pub(crate) fn sendmmsg( - sockfd: BorrowedFd<'_>, - msgs: &mut [MMsgHdr<'_>], - flags: SendFlags, -) -> io::Result { - unsafe { - ret_u32(c::sendmmsg( - borrowed_fd(sockfd), - msgs.as_mut_ptr() as _, - msgs.len().try_into().unwrap_or(c::c_uint::MAX), - bitflags_bits!(flags), - )) - .map(|ret| ret as usize) - } -} - -#[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -)))] -pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, flags: SocketFlags) -> io::Result { - unsafe { - let owned_fd = ret_owned_fd(c::accept4( - borrowed_fd(sockfd), - null_mut(), - null_mut(), - flags.bits() as c::c_int, - ))?; - Ok(owned_fd) - } -} - -pub(crate) fn acceptfrom(sockfd: BorrowedFd<'_>) -> io::Result<(OwnedFd, Option)> { - unsafe { - let mut addr = SocketAddrBuf::new(); - let owned_fd = ret_owned_fd(c::accept( - borrowed_fd(sockfd), - addr.storage.as_mut_ptr().cast::(), - &mut addr.len, - ))?; - Ok((owned_fd, addr.into_any_option())) - } -} - -#[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -)))] -pub(crate) fn acceptfrom_with( - sockfd: BorrowedFd<'_>, - flags: SocketFlags, -) -> io::Result<(OwnedFd, Option)> { - unsafe { - let mut addr = SocketAddrBuf::new(); - let owned_fd = ret_owned_fd(c::accept4( - borrowed_fd(sockfd), - addr.storage.as_mut_ptr().cast::(), - &mut addr.len, - flags.bits() as c::c_int, - ))?; - Ok((owned_fd, addr.into_any_option())) - } -} - -/// Darwin lacks `accept4`, but does have `accept`. We define `SocketFlags` to -/// have no flags, so we can discard it here. -#[cfg(any( - apple, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -))] -pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, _flags: SocketFlags) -> io::Result { - accept(sockfd) -} - -/// Darwin lacks `accept4`, but does have `accept`. We define `SocketFlags` to -/// have no flags, so we can discard it here. -#[cfg(any( - apple, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -))] -pub(crate) fn acceptfrom_with( - sockfd: BorrowedFd<'_>, - _flags: SocketFlags, -) -> io::Result<(OwnedFd, Option)> { - acceptfrom(sockfd) -} - -pub(crate) fn shutdown(sockfd: BorrowedFd<'_>, how: Shutdown) -> io::Result<()> { - unsafe { ret(c::shutdown(borrowed_fd(sockfd), how as c::c_int)) } -} - -pub(crate) fn getsockname(sockfd: BorrowedFd<'_>) -> io::Result { - unsafe { - let mut addr = SocketAddrBuf::new(); - ret(c::getsockname( - borrowed_fd(sockfd), - addr.storage.as_mut_ptr().cast::(), - &mut addr.len, - ))?; - Ok(addr.into_any()) - } -} - -pub(crate) fn getpeername(sockfd: BorrowedFd<'_>) -> io::Result> { - unsafe { - let mut addr = SocketAddrBuf::new(); - ret(c::getpeername( - borrowed_fd(sockfd), - addr.storage.as_mut_ptr().cast::(), - &mut addr.len, - ))?; - Ok(addr.into_any_option()) - } -} - -#[cfg(not(windows))] -pub(crate) fn socketpair( - domain: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option, -) -> io::Result<(OwnedFd, OwnedFd)> { - let raw_protocol = match protocol { - Some(p) => p.0.get(), - None => 0, - }; - unsafe { - let mut fds = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(c::socketpair( - c::c_int::from(domain.0), - (type_.0 | flags.bits()) as c::c_int, - raw_protocol as c::c_int, - fds.as_mut_ptr().cast::(), - ))?; - - let [fd0, fd1] = fds.assume_init(); - Ok((fd0, fd1)) - } -} diff --git a/vendor/rustix/src/backend/libc/net/write_sockaddr.rs b/vendor/rustix/src/backend/libc/net/write_sockaddr.rs deleted file mode 100644 index 08f04646..00000000 --- a/vendor/rustix/src/backend/libc/net/write_sockaddr.rs +++ /dev/null @@ -1,72 +0,0 @@ -//! The BSD sockets API requires us to read the `sa_family` field before we can -//! interpret the rest of a `sockaddr` produced by the kernel. - -use super::ext::{in6_addr_new, in_addr_new, sockaddr_in6_new}; -use crate::backend::c; -use crate::net::{SocketAddrV4, SocketAddrV6}; - -pub(crate) fn encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in { - c::sockaddr_in { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita", - ))] - sin_len: core::mem::size_of::() as _, - sin_family: c::AF_INET as _, - sin_port: u16::to_be(v4.port()), - sin_addr: in_addr_new(u32::from_ne_bytes(v4.ip().octets())), - #[cfg(not(any(target_os = "haiku", target_os = "vita")))] - sin_zero: [0; 8_usize], - #[cfg(target_os = "haiku")] - sin_zero: [0; 24_usize], - #[cfg(target_os = "vita")] - sin_zero: [0; 6_usize], - #[cfg(target_os = "vita")] - sin_vport: 0, - } -} - -pub(crate) fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - { - sockaddr_in6_new( - core::mem::size_of::() as _, - c::AF_INET6 as _, - u16::to_be(v6.port()), - u32::to_be(v6.flowinfo()), - in6_addr_new(v6.ip().octets()), - v6.scope_id(), - ) - } - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - )))] - { - sockaddr_in6_new( - c::AF_INET6 as _, - u16::to_be(v6.port()), - u32::to_be(v6.flowinfo()), - in6_addr_new(v6.ip().octets()), - v6.scope_id(), - ) - } -} -- cgit v1.2.3