diff options
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/net')
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/addr.rs | 178 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/mod.rs | 7 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/msghdr.rs | 146 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs | 195 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/send_recv.rs | 60 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/sockopt.rs | 879 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/syscalls.rs | 949 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs | 60 |
8 files changed, 0 insertions, 2474 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/net/addr.rs b/vendor/rustix/src/backend/linux_raw/net/addr.rs deleted file mode 100644 index 85ba875..0000000 --- a/vendor/rustix/src/backend/linux_raw/net/addr.rs +++ /dev/null @@ -1,178 +0,0 @@ -//! Socket address utilities. -//! -//! # Safety -//! -//! This file uses `CStr::from_bytes_with_nul_unchecked` on a string it knows -//! to be NUL-terminated. -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::ffi::CStr; -use crate::{io, path}; -use core::cmp::Ordering; -use core::fmt; -use core::hash::{Hash, Hasher}; -use core::slice; - -/// `struct sockaddr_un` -#[derive(Clone)] -#[doc(alias = "sockaddr_un")] -pub struct SocketAddrUnix { - pub(crate) unix: c::sockaddr_un, - len: c::socklen_t, -} - -impl SocketAddrUnix { - /// Construct a new Unix-domain address from a filesystem path. - #[inline] - pub fn new<P: path::Arg>(path: P) -> io::Result<Self> { - path.into_with_c_str(Self::_new) - } - - #[inline] - fn _new(path: &CStr) -> io::Result<Self> { - let mut unix = Self::init(); - let bytes = path.to_bytes_with_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 _; - } - let len = offsetof_sun_path() + bytes.len(); - let len = len.try_into().unwrap(); - Ok(Self { unix, len }) - } - - /// Construct a new abstract Unix-domain address from a byte slice. - #[inline] - pub fn new_abstract_name(name: &[u8]) -> io::Result<Self> { - let mut unix = Self::init(); - let id = &mut unix.sun_path[1..]; - - // SAFETY: Convert `&mut [c_char]` to `&mut [u8]`. - let id = unsafe { slice::from_raw_parts_mut(id.as_mut_ptr().cast::<u8>(), id.len()) }; - - if let Some(id) = id.get_mut(..name.len()) { - id.copy_from_slice(name); - let len = offsetof_sun_path() + 1 + name.len(); - let len = len.try_into().unwrap(); - Ok(Self { unix, len }) - } else { - Err(io::Errno::NAMETOOLONG) - } - } - - const fn init() -> c::sockaddr_un { - c::sockaddr_un { - sun_family: c::AF_UNIX as _, - sun_path: [0; 108], - } - } - - /// For a filesystem path address, return the path. - #[inline] - pub fn path(&self) -> Option<&CStr> { - let len = self.len(); - if len != 0 && self.unix.sun_path[0] as u8 != b'\0' { - let end = len as usize - offsetof_sun_path(); - let bytes = &self.unix.sun_path[..end]; - - // SAFETY: Convert `&[c_char]` to `&[u8]`. - let bytes = unsafe { slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len()) }; - - // SAFETY: `from_bytes_with_nul_unchecked` since the string is - // NUL-terminated. - unsafe { Some(CStr::from_bytes_with_nul_unchecked(bytes)) } - } else { - None - } - } - - /// For an abstract address, return the identifier. - #[inline] - pub fn abstract_name(&self) -> Option<&[u8]> { - let len = self.len(); - if len != 0 && self.unix.sun_path[0] as u8 == b'\0' { - let end = len as usize - offsetof_sun_path(); - let bytes = &self.unix.sun_path[1..end]; - - // SAFETY: Convert `&[c_char]` to `&[u8]`. - let bytes = unsafe { slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len()) }; - - Some(bytes) - } else { - None - } - } - - #[inline] - pub(crate) fn addr_len(&self) -> c::socklen_t { - self.len - } - - #[inline] - pub(crate) fn len(&self) -> usize { - self.addr_len() as usize - } -} - -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]) - } -} - -impl Eq for SocketAddrUnix {} - -impl PartialOrd for SocketAddrUnix { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -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]) - } -} - -impl Hash for SocketAddrUnix { - #[inline] - fn hash<H: Hasher>(&self, state: &mut H) { - let self_len = self.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].hash(state) - } -} - -impl fmt::Debug for SocketAddrUnix { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(path) = self.path() { - path.fmt(fmt) - } else if let Some(name) = self.abstract_name() { - name.fmt(fmt) - } else { - "(unnamed)".fmt(fmt) - } - } -} - -/// `struct sockaddr_storage` as a raw struct. -pub type SocketAddrStorage = c::sockaddr; - -/// Return the offset of the `sun_path` field of `sockaddr_un`. -#[inline] -pub(crate) fn offsetof_sun_path() -> usize { - let z = c::sockaddr_un { - sun_family: 0_u16, - sun_path: [0; 108], - }; - (crate::utils::as_ptr(&z.sun_path) as usize) - (crate::utils::as_ptr(&z) as usize) -} diff --git a/vendor/rustix/src/backend/linux_raw/net/mod.rs b/vendor/rustix/src/backend/linux_raw/net/mod.rs deleted file mode 100644 index f83c546..0000000 --- a/vendor/rustix/src/backend/linux_raw/net/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub(crate) mod addr; -pub(crate) mod msghdr; -pub(crate) mod read_sockaddr; -pub(crate) mod send_recv; -pub(crate) mod sockopt; -pub(crate) mod syscalls; -pub(crate) mod write_sockaddr; diff --git a/vendor/rustix/src/backend/linux_raw/net/msghdr.rs b/vendor/rustix/src/backend/linux_raw/net/msghdr.rs deleted file mode 100644 index 2b88bfb..0000000 --- a/vendor/rustix/src/backend/linux_raw/net/msghdr.rs +++ /dev/null @@ -1,146 +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. - -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::backend::net::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; - -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrV4, SocketAddrV6}; -use crate::utils::as_ptr; - -use core::mem::{size_of, MaybeUninit}; -use core::ptr::null_mut; - -fn msg_iov_len(len: usize) -> c::size_t { - // This cast cannot overflow. - len as c::size_t -} - -pub(crate) fn msg_control_len(len: usize) -> c::size_t { - // Same as above. - len as c::size_t -} - -/// Create a message header intended to receive a datagram. -pub(crate) fn with_recv_msghdr<R>( - name: &mut MaybeUninit<c::sockaddr_storage>, - iov: &mut [IoSliceMut<'_>], - control: &mut RecvAncillaryBuffer<'_>, - f: impl FnOnce(&mut c::msghdr) -> io::Result<R>, -) -> io::Result<R> { - control.clear(); - - let namelen = size_of::<c::sockaddr_storage>() as c::c_int; - let mut msghdr = c::msghdr { - msg_name: name.as_mut_ptr().cast(), - msg_namelen: namelen, - msg_iov: iov.as_mut_ptr().cast(), - msg_iovlen: msg_iov_len(iov.len()), - msg_control: control.as_control_ptr().cast(), - msg_controllen: msg_control_len(control.control_len()), - msg_flags: 0, - }; - - let res = f(&mut msghdr); - - // Reset the control length. - if res.is_ok() { - unsafe { - control.set_control_len(msghdr.msg_controllen.try_into().unwrap_or(usize::MAX)); - } - } - - res -} - -/// Create a message header intended to send without an address. -pub(crate) fn with_noaddr_msghdr<R>( - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - f: impl FnOnce(c::msghdr) -> R, -) -> R { - f(c::msghdr { - msg_name: null_mut(), - msg_namelen: 0, - msg_iov: iov.as_ptr() as _, - msg_iovlen: msg_iov_len(iov.len()), - msg_control: control.as_control_ptr().cast(), - msg_controllen: msg_control_len(control.control_len()), - msg_flags: 0, - }) -} - -/// Create a message header intended to send with an IPv4 address. -pub(crate) fn with_v4_msghdr<R>( - addr: &SocketAddrV4, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - f: impl FnOnce(c::msghdr) -> R, -) -> R { - let encoded = encode_sockaddr_v4(addr); - - f(c::msghdr { - msg_name: as_ptr(&encoded) as _, - msg_namelen: size_of::<SocketAddrV4>() as _, - msg_iov: iov.as_ptr() as _, - msg_iovlen: msg_iov_len(iov.len()), - msg_control: control.as_control_ptr().cast(), - msg_controllen: msg_control_len(control.control_len()), - msg_flags: 0, - }) -} - -/// Create a message header intended to send with an IPv6 address. -pub(crate) fn with_v6_msghdr<R>( - addr: &SocketAddrV6, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - f: impl FnOnce(c::msghdr) -> R, -) -> R { - let encoded = encode_sockaddr_v6(addr); - - f(c::msghdr { - msg_name: as_ptr(&encoded) as _, - msg_namelen: size_of::<SocketAddrV6>() as _, - msg_iov: iov.as_ptr() as _, - msg_iovlen: msg_iov_len(iov.len()), - msg_control: control.as_control_ptr().cast(), - msg_controllen: msg_control_len(control.control_len()), - msg_flags: 0, - }) -} - -/// Create a message header intended to send with a Unix address. -pub(crate) fn with_unix_msghdr<R>( - addr: &crate::net::SocketAddrUnix, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - f: impl FnOnce(c::msghdr) -> R, -) -> R { - f(c::msghdr { - msg_name: as_ptr(&addr.unix) as _, - msg_namelen: addr.addr_len() as _, - msg_iov: iov.as_ptr() as _, - msg_iovlen: msg_iov_len(iov.len()), - msg_control: control.as_control_ptr().cast(), - msg_controllen: msg_control_len(control.control_len()), - msg_flags: 0, - }) -} - -/// Create a zero-initialized message header struct value. -pub(crate) fn zero_msghdr() -> c::msghdr { - c::msghdr { - msg_name: null_mut(), - msg_namelen: 0, - msg_iov: null_mut(), - msg_iovlen: 0, - msg_control: null_mut(), - msg_controllen: 0, - msg_flags: 0, - } -} diff --git a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs deleted file mode 100644 index 5a91707..0000000 --- a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs +++ /dev/null @@ -1,195 +0,0 @@ -//! The BSD sockets API requires us to read the `ss_family` field before we can -//! interpret the rest of a `sockaddr` produced by the kernel. -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::io; -use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; -use core::mem::size_of; -use core::slice; - -// This must match the header of `sockaddr`. -#[repr(C)] -struct sockaddr_header { - ss_family: u16, -} - -/// Read the `ss_family` field from a socket address returned from the OS. -/// -/// # Safety -/// -/// `storage` must point to a valid socket address returned from the OS. -#[inline] -unsafe fn read_ss_family(storage: *const c::sockaddr) -> u16 { - // Assert that we know the layout of `sockaddr`. - let _ = c::sockaddr { - __storage: c::sockaddr_storage { - __bindgen_anon_1: linux_raw_sys::net::__kernel_sockaddr_storage__bindgen_ty_1 { - __bindgen_anon_1: - linux_raw_sys::net::__kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1 { - ss_family: 0_u16, - __data: [0; 126_usize], - }, - }, - }, - }; - - (*storage.cast::<sockaddr_header>()).ss_family -} - -/// Set the `ss_family` field of a socket address to `AF_UNSPEC`, so that we -/// can test for `AF_UNSPEC` to test whether it was stored to. -#[inline] -pub(crate) unsafe fn initialize_family_to_unspec(storage: *mut c::sockaddr) { - (*storage.cast::<sockaddr_header>()).ss_family = c::AF_UNSPEC as _; -} - -/// Read a socket address encoded in a platform-specific format. -/// -/// # Safety -/// -/// `storage` must point to valid socket address storage. -pub(crate) unsafe fn read_sockaddr( - storage: *const c::sockaddr, - len: usize, -) -> io::Result<SocketAddrAny> { - let offsetof_sun_path = super::addr::offsetof_sun_path(); - - if len < size_of::<c::sa_family_t>() { - return Err(io::Errno::INVAL); - } - match read_ss_family(storage).into() { - c::AF_INET => { - if len < size_of::<c::sockaddr_in>() { - return Err(io::Errno::INVAL); - } - let decode = &*storage.cast::<c::sockaddr_in>(); - Ok(SocketAddrAny::V4(SocketAddrV4::new( - Ipv4Addr::from(u32::from_be(decode.sin_addr.s_addr)), - u16::from_be(decode.sin_port), - ))) - } - c::AF_INET6 => { - if len < size_of::<c::sockaddr_in6>() { - return Err(io::Errno::INVAL); - } - let decode = &*storage.cast::<c::sockaddr_in6>(); - Ok(SocketAddrAny::V6(SocketAddrV6::new( - Ipv6Addr::from(decode.sin6_addr.in6_u.u6_addr8), - u16::from_be(decode.sin6_port), - u32::from_be(decode.sin6_flowinfo), - decode.sin6_scope_id, - ))) - } - c::AF_UNIX => { - if len < offsetof_sun_path { - return Err(io::Errno::INVAL); - } - if len == offsetof_sun_path { - Ok(SocketAddrAny::Unix(SocketAddrUnix::new(&[][..])?)) - } else { - let decode = &*storage.cast::<c::sockaddr_un>(); - - // On Linux check for Linux's [abstract namespace]. - // - // [abstract namespace]: https://man7.org/linux/man-pages/man7/unix.7.html - if decode.sun_path[0] == 0 { - let bytes = &decode.sun_path[1..len - offsetof_sun_path]; - - // SAFETY: Convert `&[c_char]` to `&[u8]`. - let bytes = slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len()); - - return SocketAddrUnix::new_abstract_name(bytes).map(SocketAddrAny::Unix); - } - - // Otherwise we expect a NUL-terminated filesystem path. - let bytes = &decode.sun_path[..len - 1 - offsetof_sun_path]; - - // SAFETY: Convert `&[c_char]` to `&[u8]`. - let bytes = slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len()); - - assert_eq!(decode.sun_path[len - 1 - offsetof_sun_path], 0); - Ok(SocketAddrAny::Unix(SocketAddrUnix::new(bytes)?)) - } - } - _ => Err(io::Errno::NOTSUP), - } -} - -/// Read an optional socket address returned from the OS. -/// -/// # Safety -/// -/// `storage` must point to a valid socket address returned from the OS. -pub(crate) unsafe fn maybe_read_sockaddr_os( - storage: *const c::sockaddr, - len: usize, -) -> Option<SocketAddrAny> { - if len == 0 { - None - } else { - Some(read_sockaddr_os(storage, len)) - } -} - -/// Read a socket address returned from the OS. -/// -/// # Safety -/// -/// `storage` must point to a valid socket address returned from the OS. -pub(crate) unsafe fn read_sockaddr_os(storage: *const c::sockaddr, len: usize) -> SocketAddrAny { - let offsetof_sun_path = super::addr::offsetof_sun_path(); - - assert!(len >= size_of::<c::sa_family_t>()); - match read_ss_family(storage).into() { - c::AF_INET => { - assert!(len >= size_of::<c::sockaddr_in>()); - let decode = &*storage.cast::<c::sockaddr_in>(); - SocketAddrAny::V4(SocketAddrV4::new( - Ipv4Addr::from(u32::from_be(decode.sin_addr.s_addr)), - u16::from_be(decode.sin_port), - )) - } - c::AF_INET6 => { - assert!(len >= size_of::<c::sockaddr_in6>()); - let decode = &*storage.cast::<c::sockaddr_in6>(); - SocketAddrAny::V6(SocketAddrV6::new( - Ipv6Addr::from(decode.sin6_addr.in6_u.u6_addr8), - u16::from_be(decode.sin6_port), - u32::from_be(decode.sin6_flowinfo), - decode.sin6_scope_id, - )) - } - c::AF_UNIX => { - assert!(len >= offsetof_sun_path); - if len == offsetof_sun_path { - SocketAddrAny::Unix(SocketAddrUnix::new(&[][..]).unwrap()) - } else { - let decode = &*storage.cast::<c::sockaddr_un>(); - - // On Linux check for Linux's [abstract namespace]. - // - // [abstract namespace]: https://man7.org/linux/man-pages/man7/unix.7.html - if decode.sun_path[0] == 0 { - let bytes = &decode.sun_path[1..len - offsetof_sun_path]; - - // SAFETY: Convert `&[c_char]` to `&[u8]`. - let bytes = slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len()); - - return SocketAddrAny::Unix(SocketAddrUnix::new_abstract_name(bytes).unwrap()); - } - - // Otherwise we expect a NUL-terminated filesystem path. - assert_eq!(decode.sun_path[len - 1 - offsetof_sun_path], 0); - - let bytes = &decode.sun_path[..len - 1 - offsetof_sun_path]; - - // SAFETY: Convert `&[c_char]` to `&[u8]`. - let bytes = slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len()); - - SocketAddrAny::Unix(SocketAddrUnix::new(bytes).unwrap()) - } - } - other => unimplemented!("{:?}", other), - } -} diff --git a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs deleted file mode 100644 index d5cdd07..0000000 --- a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs +++ /dev/null @@ -1,60 +0,0 @@ -use crate::backend::c; -use bitflags::bitflags; - -bitflags! { - /// `MSG_*` flags for use with [`send`], [`send_to`], 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` - const CONFIRM = c::MSG_CONFIRM; - /// `MSG_DONTROUTE` - const DONTROUTE = c::MSG_DONTROUTE; - /// `MSG_DONTWAIT` - const DONTWAIT = c::MSG_DONTWAIT; - /// `MSG_EOT` - const EOT = c::MSG_EOR; - /// `MSG_MORE` - const MORE = c::MSG_MORE; - /// `MSG_NOSIGNAL` - const NOSIGNAL = c::MSG_NOSIGNAL; - /// `MSG_OOB` - const OOB = c::MSG_OOB; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - 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` - const CMSG_CLOEXEC = c::MSG_CMSG_CLOEXEC; - /// `MSG_DONTWAIT` - const DONTWAIT = c::MSG_DONTWAIT; - /// `MSG_ERRQUEUE` - const ERRQUEUE = c::MSG_ERRQUEUE; - /// `MSG_OOB` - const OOB = c::MSG_OOB; - /// `MSG_PEEK` - const PEEK = c::MSG_PEEK; - /// `MSG_TRUNC` - const TRUNC = c::MSG_TRUNC; - /// `MSG_WAITALL` - const WAITALL = c::MSG_WAITALL; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/linux_raw/net/sockopt.rs b/vendor/rustix/src/backend/linux_raw/net/sockopt.rs deleted file mode 100644 index 6a740bb..0000000 --- a/vendor/rustix/src/backend/linux_raw/net/sockopt.rs +++ /dev/null @@ -1,879 +0,0 @@ -//! linux_raw syscalls supporting `rustix::net::sockopt`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::c; -use crate::backend::conv::{by_mut, c_uint, ret, socklen_t}; -use crate::fd::BorrowedFd; -#[cfg(feature = "alloc")] -use crate::ffi::CStr; -use crate::io; -use crate::net::sockopt::Timeout; -use crate::net::{ - AddressFamily, Ipv4Addr, Ipv6Addr, Protocol, RawProtocol, SocketAddrAny, SocketAddrStorage, - SocketAddrV4, SocketAddrV6, SocketType, UCred, -}; -#[cfg(feature = "alloc")] -use alloc::borrow::ToOwned; -#[cfg(feature = "alloc")] -use alloc::string::String; -use core::mem::MaybeUninit; -use core::time::Duration; -use linux_raw_sys::general::{__kernel_old_timeval, __kernel_sock_timeval}; -#[cfg(target_arch = "x86")] -use { - crate::backend::conv::{slice_just_addr, x86_sys}, - crate::backend::reg::{ArgReg, SocketArg}, - linux_raw_sys::net::{SYS_GETSOCKOPT, SYS_SETSOCKOPT}, -}; - -#[inline] -fn getsockopt<T: Copy>(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result<T> { - let mut optlen: c::socklen_t = core::mem::size_of::<T>().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - - let mut value = MaybeUninit::<T>::uninit(); - getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; - - assert_eq!( - optlen as usize, - core::mem::size_of::<T>(), - "unexpected getsockopt size" - ); - - unsafe { Ok(value.assume_init()) } -} - -#[inline] -fn getsockopt_raw<T>( - fd: BorrowedFd<'_>, - level: u32, - optname: u32, - value: &mut MaybeUninit<T>, - optlen: &mut c::socklen_t, -) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall!( - __NR_getsockopt, - fd, - c_uint(level), - c_uint(optname), - value, - by_mut(optlen) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETSOCKOPT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - value.into(), - by_mut(optlen), - ]) - )) - } -} - -#[inline] -fn setsockopt<T: Copy>(fd: BorrowedFd<'_>, level: u32, optname: u32, value: T) -> io::Result<()> { - let optlen = core::mem::size_of::<T>().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - setsockopt_raw(fd, level, optname, &value, optlen) -} - -#[inline] -fn setsockopt_raw<T>( - fd: BorrowedFd<'_>, - level: u32, - optname: u32, - ptr: *const T, - optlen: c::socklen_t, -) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_setsockopt, - fd, - c_uint(level), - c_uint(optname), - ptr, - socklen_t(optlen) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SETSOCKOPT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - ptr.into(), - socklen_t(optlen), - ]) - )) - } -} - -#[inline] -pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result<SocketType> { - 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 get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST, from_bool(broadcast)) -} - -#[inline] -pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_linger(fd: BorrowedFd<'_>, linger: Option<Duration>) -> io::Result<()> { - // Convert `linger` to seconds, rounding up. - let l_linger = if let Some(linger) = linger { - duration_to_secs(linger)? - } else { - 0 - }; - let linger = c::linger { - l_onoff: c::c_int::from(linger.is_some()), - l_linger, - }; - setsockopt(fd, c::SOL_SOCKET, c::SO_LINGER, linger) -} - -#[inline] -pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result<Option<Duration>> { - let linger: c::linger = getsockopt(fd, c::SOL_SOCKET, c::SO_LINGER)?; - Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) -} - -#[inline] -pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED, from_bool(passcred)) -} - -#[inline] -pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option<Duration>, -) -> io::Result<()> { - let time = duration_to_linux_sock_timeval(timeout)?; - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_NEW, - Timeout::Send => c::SO_SNDTIMEO_NEW, - }; - match setsockopt(fd, c::SOL_SOCKET, optname, time) { - Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { - set_socket_timeout_old(fd, id, timeout) - } - otherwise => otherwise, - } -} - -/// Same as `set_socket_timeout` but uses `__kernel_old_timeval` instead of -/// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. -fn set_socket_timeout_old( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option<Duration>, -) -> io::Result<()> { - let time = duration_to_linux_old_timeval(timeout)?; - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_OLD, - Timeout::Send => c::SO_SNDTIMEO_OLD, - }; - setsockopt(fd, c::SOL_SOCKET, optname, time) -} - -#[inline] -pub(crate) fn get_socket_timeout(fd: BorrowedFd<'_>, id: Timeout) -> io::Result<Option<Duration>> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_NEW, - Timeout::Send => c::SO_SNDTIMEO_NEW, - }; - let time: __kernel_sock_timeval = match getsockopt(fd, c::SOL_SOCKET, optname) { - Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { - return get_socket_timeout_old(fd, id) - } - otherwise => otherwise?, - }; - Ok(duration_from_linux_sock_timeval(time)) -} - -/// Same as `get_socket_timeout` but uses `__kernel_old_timeval` instead of -/// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. -fn get_socket_timeout_old(fd: BorrowedFd<'_>, id: Timeout) -> io::Result<Option<Duration>> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_OLD, - Timeout::Send => c::SO_SNDTIMEO_OLD, - }; - let time: __kernel_old_timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; - Ok(duration_from_linux_old_timeval(time)) -} - -/// Convert a `__linux_sock_timeval` to a Rust `Option<Duration>`. -#[inline] -fn duration_from_linux_sock_timeval(time: __kernel_sock_timeval) -> Option<Duration> { - if time.tv_sec == 0 && time.tv_usec == 0 { - None - } else { - Some(Duration::from_secs(time.tv_sec as u64) + Duration::from_micros(time.tv_usec as u64)) - } -} - -/// Like `duration_from_linux` but uses Linux's old 32-bit -/// `__kernel_old_timeval`. -fn duration_from_linux_old_timeval(time: __kernel_old_timeval) -> Option<Duration> { - if time.tv_sec == 0 && time.tv_usec == 0 { - None - } else { - Some(Duration::from_secs(time.tv_sec as u64) + Duration::from_micros(time.tv_usec as u64)) - } -} - -/// Convert a Rust `Option<Duration>` to a `__kernel_sock_timeval`. -#[inline] -fn duration_to_linux_sock_timeval(timeout: Option<Duration>) -> io::Result<__kernel_sock_timeval> { - Ok(match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = __kernel_sock_timeval { - tv_sec: timeout.as_secs().try_into().unwrap_or(i64::MAX), - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => __kernel_sock_timeval { - tv_sec: 0, - tv_usec: 0, - }, - }) -} - -/// Like `duration_to_linux` but uses Linux's old 32-bit -/// `__kernel_old_timeval`. -fn duration_to_linux_old_timeval(timeout: Option<Duration>) -> io::Result<__kernel_old_timeval> { - Ok(match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = __kernel_old_timeval { - tv_sec: timeout.as_secs().try_into().unwrap_or(c::c_long::MAX), - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => __kernel_old_timeval { - tv_sec: 0, - tv_usec: 0, - }, - }) -} - -#[inline] -pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result<Result<(), io::Errno>> { - 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 get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF, size) -} - -#[inline] -pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - getsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF).map(|size: u32| size as usize) -} - -#[inline] -pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF, size) -} - -#[inline] -pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - getsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF).map(|size: u32| size as usize) -} - -#[inline] -pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result<AddressFamily> { - let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_DOMAIN)?; - Ok(AddressFamily( - domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, - )) -} - -#[inline] -pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_ACCEPTCONN).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE, from_bool(value)) -} - -#[inline] -pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_reuseport(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT, from_bool(value)) -} - -#[inline] -pub(crate) fn get_socket_reuseport(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT).map(to_bool) -} - -#[inline] -pub(crate) fn get_socket_protocol(fd: BorrowedFd<'_>) -> io::Result<Option<Protocol>> { - getsockopt(fd, c::SOL_SOCKET, c::SO_PROTOCOL) - .map(|raw: u32| RawProtocol::new(raw).map(Protocol::from_raw)) -} - -#[inline] -pub(crate) fn get_socket_cookie(fd: BorrowedFd<'_>) -> io::Result<u64> { - getsockopt(fd, c::SOL_SOCKET, c::SO_COOKIE) -} - -#[inline] -pub(crate) fn get_socket_incoming_cpu(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU) -} - -#[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 get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { - 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 get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY).map(to_bool) -} - -#[inline] -pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP, - c::IP_MULTICAST_LOOP, - from_bool(multicast_loop), - ) -} - -#[inline] -pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_LOOP).map(to_bool) -} - -#[inline] -pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl) -} - -#[inline] -pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { - 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 get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP).map(to_bool) -} - -#[inline] -pub(crate) fn set_ipv6_multicast_hops(fd: BorrowedFd<'_>, multicast_hops: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS, multicast_hops) -} - -#[inline] -pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result<u32> { - 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) -} - -#[inline] -pub(crate) fn set_ip_add_membership_with_ifindex( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: i32, -) -> io::Result<()> { - let mreqn = to_ip_mreqn(multiaddr, address, ifindex); - setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreqn) -} - -#[inline] -pub(crate) fn set_ip_add_source_membership( - fd: BorrowedFd<'_>, - 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) -} - -#[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<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6, c::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) -} - -#[inline] -pub(crate) fn set_ip_drop_membership_with_ifindex( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: i32, -) -> io::Result<()> { - let mreqn = to_ip_mreqn(multiaddr, address, ifindex); - setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreqn) -} - -#[inline] -pub(crate) fn set_ipv6_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, -) -> io::Result<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_DROP_MEMBERSHIP, mreq) -} - -#[inline] -pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result<u8> { - 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<u8>) -> io::Result<()> { - let hops = match hops { - Some(hops) => hops.into(), - None => -1, - }; - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS, hops) -} - -#[inline] -pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, i32::from(value)) -} - -#[inline] -pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result<u8> { - let value: i32 = getsockopt(fd, c::IPPROTO_IP, c::IP_TOS)?; - Ok(value as u8) -} - -#[inline] -pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, from_bool(value)) -} - -#[inline] -pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) -} - -#[inline] -pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, from_bool(value)) -} - -#[inline] -pub(crate) fn get_ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(to_bool) -} - -#[inline] -pub(crate) fn set_ip_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND, from_bool(value)) -} - -#[inline] -pub(crate) fn get_ip_freebind(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND).map(to_bool) -} - -#[inline] -pub(crate) fn set_ipv6_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND, from_bool(value)) -} - -#[inline] -pub(crate) fn get_ipv6_freebind(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND).map(to_bool) -} - -#[inline] -pub(crate) fn get_ip_original_dst(fd: BorrowedFd<'_>) -> io::Result<SocketAddrV4> { - let level = c::IPPROTO_IP; - let optname = c::SO_ORIGINAL_DST; - let mut value = MaybeUninit::<SocketAddrStorage>::uninit(); - let mut optlen = core::mem::size_of_val(&value).try_into().unwrap(); - - getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; - - let any = unsafe { SocketAddrAny::read(value.as_ptr(), optlen as usize)? }; - match any { - SocketAddrAny::V4(v4) => Ok(v4), - _ => unreachable!(), - } -} - -#[inline] -pub(crate) fn get_ipv6_original_dst(fd: BorrowedFd<'_>) -> io::Result<SocketAddrV6> { - let level = c::IPPROTO_IPV6; - let optname = c::IP6T_SO_ORIGINAL_DST; - let mut value = MaybeUninit::<SocketAddrStorage>::uninit(); - let mut optlen = core::mem::size_of_val(&value).try_into().unwrap(); - - getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; - - let any = unsafe { SocketAddrAny::read(value.as_ptr(), optlen as usize)? }; - match any { - SocketAddrAny::V6(v6) => Ok(v6), - _ => unreachable!(), - } -} - -#[inline] -pub(crate) fn set_ipv6_tclass(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS, value) -} - -#[inline] -pub(crate) fn get_ipv6_tclass(fd: BorrowedFd<'_>) -> io::Result<u32> { - 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 get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY).map(to_bool) -} - -#[inline] -pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT, count) -} - -#[inline] -pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT) -} - -#[inline] -pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPIDLE, secs) -} - -#[inline] -pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result<Duration> { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPIDLE)?; - Ok(Duration::from_secs(secs as u64)) -} - -#[inline] -pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL, secs) -} - -#[inline] -pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result<Duration> { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL)?; - Ok(Duration::from_secs(secs as u64)) -} - -#[inline] -pub(crate) fn set_tcp_user_timeout(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT, value) -} - -#[inline] -pub(crate) fn get_tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT) -} - -#[inline] -pub(crate) fn set_tcp_quickack(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK, from_bool(value)) -} - -#[inline] -pub(crate) fn get_tcp_quickack(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK).map(to_bool) -} - -#[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")] -#[inline] -pub(crate) fn get_tcp_congestion(fd: BorrowedFd<'_>) -> io::Result<String> { - let level = c::IPPROTO_TCP; - let optname = c::TCP_CONGESTION; - const OPTLEN: c::socklen_t = 16; - let mut value = MaybeUninit::<[MaybeUninit<u8>; 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.iter().any(|b| *b == b'\0')); - Ok( - core::str::from_utf8(CStr::from_ptr(slice.as_ptr().cast()).to_bytes()) - .unwrap() - .to_owned(), - ) - } -} - -#[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), - ) -} - -#[inline] -pub(crate) fn get_tcp_thin_linear_timeouts(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_THIN_LINEAR_TIMEOUTS).map(to_bool) -} - -#[inline] -pub(crate) fn set_tcp_cork(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK, from_bool(value)) -} - -#[inline] -pub(crate) fn get_tcp_cork(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK).map(to_bool) -} - -#[inline] -pub(crate) fn get_socket_peercred(fd: BorrowedFd<'_>) -> io::Result<UCred> { - getsockopt(fd, c::SOL_SOCKET, linux_raw_sys::net::SO_PEERCRED) -} - -#[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), - } -} - -#[inline] -fn to_ip_mreqn(multiaddr: &Ipv4Addr, address: &Ipv4Addr, ifindex: i32) -> c::ip_mreqn { - c::ip_mreqn { - imr_multiaddr: to_imr_addr(multiaddr), - imr_address: to_imr_addr(address), - imr_ifindex: ifindex, - } -} - -#[inline] -fn to_imr_source( - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> c::ip_mreq_source { - c::ip_mreq_source { - imr_multiaddr: to_imr_addr(multiaddr).s_addr, - imr_interface: to_imr_addr(interface).s_addr, - imr_sourceaddr: to_imr_addr(sourceaddr).s_addr, - } -} - -#[inline] -fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { - c::in_addr { - s_addr: u32::from_ne_bytes(addr.octets()), - } -} - -#[inline] -fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { - c::ipv6_mreq { - ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), - ipv6mr_ifindex: to_ipv6mr_interface(interface), - } -} - -#[inline] -fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { - c::in6_addr { - in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { - u6_addr8: multiaddr.octets(), - }, - } -} - -#[inline] -fn to_ipv6mr_interface(interface: u32) -> c::c_int { - interface as c::c_int -} - -#[inline] -fn from_bool(value: bool) -> c::c_uint { - c::c_uint::from(value) -} - -#[inline] -fn to_bool(value: c::c_uint) -> bool { - value != 0 -} - -/// Convert to seconds, rounding up if necessary. -#[inline] -fn duration_to_secs<T: TryFrom<u64>>(duration: Duration) -> io::Result<T> { - 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/linux_raw/net/syscalls.rs b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs deleted file mode 100644 index 726f022..0000000 --- a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs +++ /dev/null @@ -1,949 +0,0 @@ -//! linux_raw syscalls supporting `rustix::net`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use super::msghdr::{ - with_noaddr_msghdr, with_recv_msghdr, with_unix_msghdr, with_v4_msghdr, with_v6_msghdr, -}; -use super::read_sockaddr::{initialize_family_to_unspec, maybe_read_sockaddr_os, read_sockaddr_os}; -use super::send_recv::{RecvFlags, SendFlags}; -use super::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; -use crate::backend::c; -use crate::backend::conv::{ - by_mut, by_ref, c_int, c_uint, pass_usize, ret, ret_owned_fd, ret_usize, size_of, slice, - socklen_t, zero, -}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::net::{ - AddressFamily, Protocol, RecvAncillaryBuffer, RecvMsgReturn, SendAncillaryBuffer, Shutdown, - SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6, SocketFlags, SocketType, -}; -use c::{sockaddr, sockaddr_in, sockaddr_in6, socklen_t}; -use core::mem::MaybeUninit; -#[cfg(target_arch = "x86")] -use { - crate::backend::conv::{slice_just_addr, x86_sys}, - crate::backend::reg::{ArgReg, SocketArg}, - linux_raw_sys::net::{ - SYS_ACCEPT, SYS_ACCEPT4, SYS_BIND, SYS_CONNECT, SYS_GETPEERNAME, SYS_GETSOCKNAME, - SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_RECVMSG, SYS_SEND, SYS_SENDMSG, SYS_SENDTO, - SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, - }, -}; - -#[inline] -pub(crate) fn socket( - family: AddressFamily, - type_: SocketType, - protocol: Option<Protocol>, -) -> io::Result<OwnedFd> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_owned_fd(syscall_readonly!(__NR_socket, family, type_, protocol)) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SOCKET), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - family.into(), - type_.into(), - protocol.into(), - ]) - )) - } -} - -#[inline] -pub(crate) fn socket_with( - family: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option<Protocol>, -) -> io::Result<OwnedFd> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_socket, - family, - (type_, flags), - protocol - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SOCKET), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - family.into(), - (type_, flags).into(), - protocol.into(), - ]) - )) - } -} - -#[inline] -pub(crate) fn socketpair( - family: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option<Protocol>, -) -> io::Result<(OwnedFd, OwnedFd)> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(syscall!( - __NR_socketpair, - family, - (type_, flags), - protocol, - &mut result - ))?; - let [fd0, fd1] = result.assume_init(); - Ok((fd0, fd1)) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_SOCKETPAIR), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - family.into(), - (type_, flags).into(), - protocol.into(), - (&mut result).into(), - ]) - ))?; - let [fd0, fd1] = result.assume_init(); - Ok((fd0, fd1)) - } -} - -#[inline] -pub(crate) fn accept(fd: BorrowedFd<'_>) -> io::Result<OwnedFd> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let fd = ret_owned_fd(syscall_readonly!(__NR_accept, fd, zero(), zero()))?; - Ok(fd) - } - #[cfg(target_arch = "x86")] - unsafe { - let fd = ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_ACCEPT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[fd.into(), zero(), zero()]) - ))?; - Ok(fd) - } -} - -#[inline] -pub(crate) fn accept_with(fd: BorrowedFd<'_>, flags: SocketFlags) -> io::Result<OwnedFd> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let fd = ret_owned_fd(syscall_readonly!(__NR_accept4, fd, zero(), zero(), flags))?; - Ok(fd) - } - #[cfg(target_arch = "x86")] - unsafe { - let fd = ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_ACCEPT4), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[fd.into(), zero(), zero(), flags.into()]) - ))?; - Ok(fd) - } -} - -#[inline] -pub(crate) fn acceptfrom(fd: BorrowedFd<'_>) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut addrlen = core::mem::size_of::<sockaddr>() as socklen_t; - let mut storage = MaybeUninit::<sockaddr>::uninit(); - let fd = ret_owned_fd(syscall!( - __NR_accept, - fd, - &mut storage, - by_mut(&mut addrlen) - ))?; - Ok(( - fd, - maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), - )) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addrlen = core::mem::size_of::<sockaddr>() as socklen_t; - let mut storage = MaybeUninit::<sockaddr>::uninit(); - let fd = ret_owned_fd(syscall!( - __NR_socketcall, - x86_sys(SYS_ACCEPT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - (&mut storage).into(), - by_mut(&mut addrlen), - ]) - ))?; - Ok(( - fd, - maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), - )) - } -} - -#[inline] -pub(crate) fn acceptfrom_with( - fd: BorrowedFd<'_>, - flags: SocketFlags, -) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut addrlen = core::mem::size_of::<sockaddr>() as socklen_t; - let mut storage = MaybeUninit::<sockaddr>::uninit(); - let fd = ret_owned_fd(syscall!( - __NR_accept4, - fd, - &mut storage, - by_mut(&mut addrlen), - flags - ))?; - Ok(( - fd, - maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), - )) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addrlen = core::mem::size_of::<sockaddr>() as socklen_t; - let mut storage = MaybeUninit::<sockaddr>::uninit(); - let fd = ret_owned_fd(syscall!( - __NR_socketcall, - x86_sys(SYS_ACCEPT4), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - (&mut storage).into(), - by_mut(&mut addrlen), - flags.into(), - ]) - ))?; - Ok(( - fd, - maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), - )) - } -} - -#[inline] -pub(crate) fn recvmsg( - sockfd: BorrowedFd<'_>, - iov: &mut [IoSliceMut<'_>], - control: &mut RecvAncillaryBuffer<'_>, - msg_flags: RecvFlags, -) -> io::Result<RecvMsgReturn> { - let mut storage = MaybeUninit::<c::sockaddr_storage>::uninit(); - - with_recv_msghdr(&mut storage, iov, control, |msghdr| { - #[cfg(not(target_arch = "x86"))] - let result = - unsafe { ret_usize(syscall!(__NR_recvmsg, sockfd, by_mut(msghdr), msg_flags)) }; - - #[cfg(target_arch = "x86")] - let result = unsafe { - ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_RECVMSG), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - sockfd.into(), - by_mut(msghdr), - msg_flags.into(), - ]) - )) - }; - - result.map(|bytes| { - // Get the address of the sender, if any. - let addr = - unsafe { maybe_read_sockaddr_os(msghdr.msg_name as _, msghdr.msg_namelen as _) }; - - RecvMsgReturn { - bytes, - address: addr, - flags: RecvFlags::from_bits_retain(msghdr.msg_flags), - } - }) - }) -} - -#[inline] -pub(crate) fn sendmsg( - sockfd: BorrowedFd<'_>, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - msg_flags: SendFlags, -) -> io::Result<usize> { - with_noaddr_msghdr(iov, control, |msghdr| { - #[cfg(not(target_arch = "x86"))] - let result = - unsafe { ret_usize(syscall!(__NR_sendmsg, sockfd, by_ref(&msghdr), msg_flags)) }; - - #[cfg(target_arch = "x86")] - let result = unsafe { - ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_SENDMSG), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - sockfd.into(), - by_ref(&msghdr), - msg_flags.into() - ]) - )) - }; - - result - }) -} - -#[inline] -pub(crate) fn sendmsg_v4( - sockfd: BorrowedFd<'_>, - addr: &SocketAddrV4, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - msg_flags: SendFlags, -) -> io::Result<usize> { - with_v4_msghdr(addr, iov, control, |msghdr| { - #[cfg(not(target_arch = "x86"))] - let result = - unsafe { ret_usize(syscall!(__NR_sendmsg, sockfd, by_ref(&msghdr), msg_flags)) }; - - #[cfg(target_arch = "x86")] - let result = unsafe { - ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_SENDMSG), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - sockfd.into(), - by_ref(&msghdr), - msg_flags.into(), - ]) - )) - }; - - result - }) -} - -#[inline] -pub(crate) fn sendmsg_v6( - sockfd: BorrowedFd<'_>, - addr: &SocketAddrV6, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - msg_flags: SendFlags, -) -> io::Result<usize> { - with_v6_msghdr(addr, iov, control, |msghdr| { - #[cfg(not(target_arch = "x86"))] - let result = - unsafe { ret_usize(syscall!(__NR_sendmsg, sockfd, by_ref(&msghdr), msg_flags)) }; - - #[cfg(target_arch = "x86")] - let result = unsafe { - ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_SENDMSG), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - sockfd.into(), - by_ref(&msghdr), - msg_flags.into() - ]) - )) - }; - - result - }) -} - -#[inline] -pub(crate) fn sendmsg_unix( - sockfd: BorrowedFd<'_>, - addr: &SocketAddrUnix, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - msg_flags: SendFlags, -) -> io::Result<usize> { - with_unix_msghdr(addr, iov, control, |msghdr| { - #[cfg(not(target_arch = "x86"))] - let result = - unsafe { ret_usize(syscall!(__NR_sendmsg, sockfd, by_ref(&msghdr), msg_flags)) }; - - #[cfg(target_arch = "x86")] - let result = unsafe { - ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_SENDMSG), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - sockfd.into(), - by_ref(&msghdr), - msg_flags.into() - ]) - )) - }; - - result - }) -} - -#[inline] -pub(crate) fn shutdown(fd: BorrowedFd<'_>, how: Shutdown) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_shutdown, - fd, - c_uint(how as c::c_uint) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SHUTDOWN), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[fd.into(), c_uint(how as c::c_uint)]) - )) - } -} - -#[inline] -pub(crate) fn send(fd: BorrowedFd<'_>, buf: &[u8], flags: SendFlags) -> io::Result<usize> { - let (buf_addr, buf_len) = slice(buf); - - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv64", - target_arch = "x86", - target_arch = "x86_64", - )))] - unsafe { - ret_usize(syscall_readonly!(__NR_send, fd, buf_addr, buf_len, flags)) - } - #[cfg(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv64", - target_arch = "x86_64", - ))] - unsafe { - ret_usize(syscall_readonly!( - __NR_sendto, - fd, - buf_addr, - buf_len, - flags, - zero(), - zero() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_usize(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SEND), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - buf_addr, - buf_len, - flags.into() - ]) - )) - } -} - -#[inline] -pub(crate) fn sendto_v4( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &SocketAddrV4, -) -> io::Result<usize> { - let (buf_addr, buf_len) = slice(buf); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_usize(syscall_readonly!( - __NR_sendto, - fd, - buf_addr, - buf_len, - flags, - by_ref(&encode_sockaddr_v4(addr)), - size_of::<sockaddr_in, _>() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_usize(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SENDTO), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - buf_addr, - buf_len, - flags.into(), - by_ref(&encode_sockaddr_v4(addr)), - size_of::<sockaddr_in, _>(), - ]) - )) - } -} - -#[inline] -pub(crate) fn sendto_v6( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &SocketAddrV6, -) -> io::Result<usize> { - let (buf_addr, buf_len) = slice(buf); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_usize(syscall_readonly!( - __NR_sendto, - fd, - buf_addr, - buf_len, - flags, - by_ref(&encode_sockaddr_v6(addr)), - size_of::<sockaddr_in6, _>() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_usize(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SENDTO), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - buf_addr, - buf_len, - flags.into(), - by_ref(&encode_sockaddr_v6(addr)), - size_of::<sockaddr_in6, _>(), - ]) - )) - } -} - -#[inline] -pub(crate) fn sendto_unix( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &SocketAddrUnix, -) -> io::Result<usize> { - let (buf_addr, buf_len) = slice(buf); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_usize(syscall_readonly!( - __NR_sendto, - fd, - buf_addr, - buf_len, - flags, - by_ref(&addr.unix), - socklen_t(addr.addr_len()) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_usize(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SENDTO), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - buf_addr, - buf_len, - flags.into(), - by_ref(&addr.unix), - socklen_t(addr.addr_len()), - ]) - )) - } -} - -#[inline] -pub(crate) unsafe fn recv( - fd: BorrowedFd<'_>, - buf: *mut u8, - len: usize, - flags: RecvFlags, -) -> io::Result<usize> { - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv64", - target_arch = "x86", - target_arch = "x86_64", - )))] - { - ret_usize(syscall!(__NR_recv, fd, buf, pass_usize(len), flags)) - } - #[cfg(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv64", - target_arch = "x86_64", - ))] - { - ret_usize(syscall!( - __NR_recvfrom, - fd, - buf, - pass_usize(len), - flags, - zero(), - zero() - )) - } - #[cfg(target_arch = "x86")] - { - ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_RECV), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - buf.into(), - pass_usize(len), - flags.into(), - ]) - )) - } -} - -#[inline] -pub(crate) unsafe fn recvfrom( - fd: BorrowedFd<'_>, - buf: *mut u8, - len: usize, - flags: RecvFlags, -) -> io::Result<(usize, Option<SocketAddrAny>)> { - let mut addrlen = core::mem::size_of::<sockaddr>() as socklen_t; - let mut storage = MaybeUninit::<sockaddr>::uninit(); - - // `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(storage.as_mut_ptr()); - - #[cfg(not(target_arch = "x86"))] - let nread = ret_usize(syscall!( - __NR_recvfrom, - fd, - buf, - pass_usize(len), - flags, - &mut storage, - by_mut(&mut addrlen) - ))?; - #[cfg(target_arch = "x86")] - let nread = ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_RECVFROM), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - buf.into(), - pass_usize(len), - flags.into(), - (&mut storage).into(), - by_mut(&mut addrlen), - ]) - ))?; - - Ok(( - nread, - maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), - )) -} - -#[inline] -pub(crate) fn getpeername(fd: BorrowedFd<'_>) -> io::Result<Option<SocketAddrAny>> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut addrlen = core::mem::size_of::<sockaddr>() as socklen_t; - let mut storage = MaybeUninit::<sockaddr>::uninit(); - ret(syscall!( - __NR_getpeername, - fd, - &mut storage, - by_mut(&mut addrlen) - ))?; - Ok(maybe_read_sockaddr_os( - &storage.assume_init(), - addrlen.try_into().unwrap(), - )) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addrlen = core::mem::size_of::<sockaddr>() as socklen_t; - let mut storage = MaybeUninit::<sockaddr>::uninit(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETPEERNAME), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - (&mut storage).into(), - by_mut(&mut addrlen), - ]) - ))?; - Ok(maybe_read_sockaddr_os( - &storage.assume_init(), - addrlen.try_into().unwrap(), - )) - } -} - -#[inline] -pub(crate) fn getsockname(fd: BorrowedFd<'_>) -> io::Result<SocketAddrAny> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut addrlen = core::mem::size_of::<sockaddr>() as socklen_t; - let mut storage = MaybeUninit::<sockaddr>::uninit(); - ret(syscall!( - __NR_getsockname, - fd, - &mut storage, - by_mut(&mut addrlen) - ))?; - Ok(read_sockaddr_os( - &storage.assume_init(), - addrlen.try_into().unwrap(), - )) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addrlen = core::mem::size_of::<sockaddr>() as socklen_t; - let mut storage = MaybeUninit::<sockaddr>::uninit(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETSOCKNAME), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - (&mut storage).into(), - by_mut(&mut addrlen), - ]) - ))?; - Ok(read_sockaddr_os( - &storage.assume_init(), - addrlen.try_into().unwrap(), - )) - } -} - -#[inline] -pub(crate) fn bind_v4(fd: BorrowedFd<'_>, addr: &SocketAddrV4) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_bind, - fd, - by_ref(&encode_sockaddr_v4(addr)), - size_of::<sockaddr_in, _>() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_BIND), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - by_ref(&encode_sockaddr_v4(addr)), - size_of::<sockaddr_in, _>(), - ]) - )) - } -} - -#[inline] -pub(crate) fn bind_v6(fd: BorrowedFd<'_>, addr: &SocketAddrV6) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_bind, - fd, - by_ref(&encode_sockaddr_v6(addr)), - size_of::<sockaddr_in6, _>() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_BIND), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - by_ref(&encode_sockaddr_v6(addr)), - size_of::<sockaddr_in6, _>(), - ]) - )) - } -} - -#[inline] -pub(crate) fn bind_unix(fd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_bind, - fd, - by_ref(&addr.unix), - socklen_t(addr.addr_len()) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_BIND), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - by_ref(&addr.unix), - socklen_t(addr.addr_len()), - ]) - )) - } -} - -#[inline] -pub(crate) fn connect_v4(fd: BorrowedFd<'_>, addr: &SocketAddrV4) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_connect, - fd, - by_ref(&encode_sockaddr_v4(addr)), - size_of::<sockaddr_in, _>() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_CONNECT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - by_ref(&encode_sockaddr_v4(addr)), - size_of::<sockaddr_in, _>(), - ]) - )) - } -} - -#[inline] -pub(crate) fn connect_v6(fd: BorrowedFd<'_>, addr: &SocketAddrV6) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_connect, - fd, - by_ref(&encode_sockaddr_v6(addr)), - size_of::<sockaddr_in6, _>() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_CONNECT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - by_ref(&encode_sockaddr_v6(addr)), - size_of::<sockaddr_in6, _>(), - ]) - )) - } -} - -#[inline] -pub(crate) fn connect_unix(fd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_connect, - fd, - by_ref(&addr.unix), - socklen_t(addr.addr_len()) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_CONNECT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - by_ref(&addr.unix), - socklen_t(addr.addr_len()), - ]) - )) - } -} - -#[inline] -pub(crate) fn connect_unspec(fd: BorrowedFd<'_>) -> io::Result<()> { - debug_assert_eq!(c::AF_UNSPEC, 0); - let addr = MaybeUninit::<c::sockaddr_storage>::zeroed(); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_connect, - fd, - by_ref(&addr), - size_of::<c::sockaddr_storage, _>() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_CONNECT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - by_ref(&addr), - size_of::<c::sockaddr_storage, _>(), - ]) - )) - } -} - -#[inline] -pub(crate) fn listen(fd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!(__NR_listen, fd, c_int(backlog))) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_LISTEN), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[fd.into(), c_int(backlog)]) - )) - } -} diff --git a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs deleted file mode 100644 index 24edd49..0000000 --- a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! The BSD sockets API requires us to read the `ss_family` field before we can -//! interpret the rest of a `sockaddr` produced by the kernel. -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::net::{SocketAddrAny, SocketAddrStorage, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; -use core::mem::size_of; - -pub(crate) unsafe fn write_sockaddr( - addr: &SocketAddrAny, - storage: *mut SocketAddrStorage, -) -> usize { - match addr { - SocketAddrAny::V4(v4) => write_sockaddr_v4(v4, storage), - SocketAddrAny::V6(v6) => write_sockaddr_v6(v6, storage), - SocketAddrAny::Unix(unix) => write_sockaddr_unix(unix, storage), - } -} - -pub(crate) fn encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in { - c::sockaddr_in { - sin_family: c::AF_INET as _, - sin_port: u16::to_be(v4.port()), - sin_addr: c::in_addr { - s_addr: u32::from_ne_bytes(v4.ip().octets()), - }, - __pad: [0_u8; 8], - } -} - -unsafe fn write_sockaddr_v4(v4: &SocketAddrV4, storage: *mut SocketAddrStorage) -> usize { - let encoded = encode_sockaddr_v4(v4); - core::ptr::write(storage.cast(), encoded); - size_of::<c::sockaddr_in>() -} - -pub(crate) fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { - c::sockaddr_in6 { - sin6_family: c::AF_INET6 as _, - sin6_port: u16::to_be(v6.port()), - sin6_flowinfo: u32::to_be(v6.flowinfo()), - sin6_addr: c::in6_addr { - in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { - u6_addr8: v6.ip().octets(), - }, - }, - sin6_scope_id: v6.scope_id(), - } -} - -unsafe fn write_sockaddr_v6(v6: &SocketAddrV6, storage: *mut SocketAddrStorage) -> usize { - let encoded = encode_sockaddr_v6(v6); - core::ptr::write(storage.cast(), encoded); - size_of::<c::sockaddr_in6>() -} - -unsafe fn write_sockaddr_unix(unix: &SocketAddrUnix, storage: *mut SocketAddrStorage) -> usize { - core::ptr::write(storage.cast(), unix.unix); - unix.len() -} |