diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
commit | dc0db358abe19481e475e10c32149b53370f1a1c (patch) | |
tree | ab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/rustix/src/backend/linux_raw/net | |
parent | Releasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff) | |
download | rustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip |
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/net')
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/addr.rs | 60 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/mod.rs | 2 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/msghdr.rs | 143 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs | 68 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/send_recv.rs | 6 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/syscalls.rs | 219 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/types.rs | 275 | ||||
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs | 4 |
8 files changed, 404 insertions, 373 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/net/addr.rs b/vendor/rustix/src/backend/linux_raw/net/addr.rs index b69c6deca..4a203ed16 100644 --- a/vendor/rustix/src/backend/linux_raw/net/addr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/addr.rs @@ -1,15 +1,17 @@ -//! IPv4, IPv6, and Socket addresses. +//! Socket address utilities. //! //! # Safety //! -//! Linux's IPv6 type contains a union. +//! This file uses `CStr::from_bytes_with_nul_unchecked` on a string it knows +//! to be NUL-terminated. #![allow(unsafe_code)] -use super::super::c; +use crate::backend::c; use crate::ffi::CStr; use crate::{io, path}; -use core::convert::TryInto; -use core::{fmt, slice}; +use core::cmp::Ordering; +use core::fmt; +use core::hash::{Hash, Hasher}; /// `struct sockaddr_un` #[derive(Clone)] @@ -34,7 +36,7 @@ impl SocketAddrUnix { return Err(io::Errno::NAMETOOLONG); } for (i, b) in bytes.iter().enumerate() { - unix.sun_path[i] = *b as c::c_char; + unix.sun_path[i] = *b; } let len = offsetof_sun_path() + bytes.len(); let len = len.try_into().unwrap(); @@ -45,19 +47,18 @@ impl SocketAddrUnix { #[inline] pub fn new_abstract_name(name: &[u8]) -> io::Result<Self> { let mut unix = Self::init(); - if 1 + name.len() > unix.sun_path.len() { - return Err(io::Errno::NAMETOOLONG); - } - unix.sun_path[0] = b'\0' as c::c_char; - for (i, b) in name.iter().enumerate() { - unix.sun_path[1 + i] = *b as c::c_char; + let id = &mut unix.sun_path[1..]; + 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) } - let len = offsetof_sun_path() + 1 + name.len(); - let len = len.try_into().unwrap(); - Ok(Self { unix, len }) } - fn init() -> c::sockaddr_un { + const fn init() -> c::sockaddr_un { c::sockaddr_un { sun_family: c::AF_UNIX as _, sun_path: [0; 108], @@ -68,17 +69,12 @@ impl SocketAddrUnix { #[inline] pub fn path(&self) -> Option<&CStr> { let len = self.len(); - if len != 0 && self.unix.sun_path[0] != b'\0' as c::c_char { + if len != 0 && self.unix.sun_path[0] != b'\0' { let end = len as usize - offsetof_sun_path(); let bytes = &self.unix.sun_path[..end]; - // SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. And - // `from_bytes_with_nul_unchecked` since the string is NUL-terminated. - unsafe { - Some(CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts( - bytes.as_ptr().cast(), - 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 } @@ -88,11 +84,9 @@ impl SocketAddrUnix { #[inline] pub fn abstract_name(&self) -> Option<&[u8]> { let len = self.len(); - if len != 0 && self.unix.sun_path[0] == b'\0' as c::c_char { + if len != 0 && self.unix.sun_path[0] == b'\0' { let end = len as usize - offsetof_sun_path(); - let bytes = &self.unix.sun_path[1..end]; - // SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. - unsafe { Some(slice::from_raw_parts(bytes.as_ptr().cast(), bytes.len())) } + Some(&self.unix.sun_path[1..end]) } else { None } @@ -122,7 +116,7 @@ impl Eq for SocketAddrUnix {} impl PartialOrd for SocketAddrUnix { #[inline] - fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { let self_len = self.len() - offsetof_sun_path(); let other_len = other.len() - offsetof_sun_path(); self.unix.sun_path[..self_len].partial_cmp(&other.unix.sun_path[..other_len]) @@ -131,16 +125,16 @@ impl PartialOrd for SocketAddrUnix { impl Ord for SocketAddrUnix { #[inline] - fn cmp(&self, other: &Self) -> core::cmp::Ordering { + 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 core::hash::Hash for SocketAddrUnix { +impl Hash for SocketAddrUnix { #[inline] - fn hash<H: core::hash::Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { let self_len = self.len() - offsetof_sun_path(); self.unix.sun_path[..self_len].hash(state) } diff --git a/vendor/rustix/src/backend/linux_raw/net/mod.rs b/vendor/rustix/src/backend/linux_raw/net/mod.rs index f2273db1b..2b6ab34ba 100644 --- a/vendor/rustix/src/backend/linux_raw/net/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/net/mod.rs @@ -1,6 +1,6 @@ pub(crate) mod addr; +pub(crate) mod msghdr; pub(crate) mod read_sockaddr; pub(crate) mod send_recv; pub(crate) mod syscalls; -pub(crate) mod types; 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 new file mode 100644 index 000000000..3c435bcfa --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/msghdr.rs @@ -0,0 +1,143 @@ +//! 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, zeroed, 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()), + + // Zero-initialize any padding bytes. + ..unsafe { zeroed() } + }; + + 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()), + + // Zero-initialize any padding bytes. + ..unsafe { zeroed() } + }) +} + +/// 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 = unsafe { 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()), + + // Zero-initialize any padding bytes. + ..unsafe { zeroed() } + }) +} + +/// 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 = unsafe { 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()), + + // Zero-initialize any padding bytes. + ..unsafe { zeroed() } + }) +} + +/// 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) 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()), + + // Zero-initialize any padding bytes. + ..unsafe { zeroed() } + }) +} diff --git a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs index b9bc09b96..f4b7d9914 100644 --- a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs @@ -2,10 +2,9 @@ //! we can interpret the rest of a `sockaddr` produced by the kernel. #![allow(unsafe_code)] -use super::super::c; +use crate::backend::c; use crate::io; use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; -use alloc::vec::Vec; use core::mem::size_of; // This must match the header of `sockaddr`. @@ -24,9 +23,9 @@ 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::general::__kernel_sockaddr_storage__bindgen_ty_1 { + __bindgen_anon_1: linux_raw_sys::net::__kernel_sockaddr_storage__bindgen_ty_1 { __bindgen_anon_1: - linux_raw_sys::general::__kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1 { + linux_raw_sys::net::__kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1 { ss_family: 0_u16, __data: [0; 126_usize], }, @@ -63,7 +62,7 @@ pub(crate) unsafe fn read_sockaddr( if len < size_of::<c::sockaddr_in>() { return Err(io::Errno::INVAL); } - let decode = *storage.cast::<c::sockaddr_in>(); + 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), @@ -73,7 +72,7 @@ pub(crate) unsafe fn read_sockaddr( if len < size_of::<c::sockaddr_in6>() { return Err(io::Errno::INVAL); } - let decode = *storage.cast::<c::sockaddr_in6>(); + 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), @@ -88,16 +87,22 @@ pub(crate) unsafe fn read_sockaddr( if len == offsetof_sun_path { Ok(SocketAddrAny::Unix(SocketAddrUnix::new(&[][..])?)) } else { - let decode = *storage.cast::<c::sockaddr_un>(); - assert_eq!( - decode.sun_path[len - 1 - offsetof_sun_path], - b'\0' as c::c_char - ); + 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 { + return SocketAddrUnix::new_abstract_name( + &decode.sun_path[1..len - offsetof_sun_path], + ) + .map(SocketAddrAny::Unix); + } + + // Otherwise we expect a NUL-terminated filesystem path. + assert_eq!(decode.sun_path[len - 1 - offsetof_sun_path], 0); Ok(SocketAddrAny::Unix(SocketAddrUnix::new( - decode.sun_path[..len - 1 - offsetof_sun_path] - .iter() - .map(|c| *c as u8) - .collect::<Vec<u8>>(), + &decode.sun_path[..len - 1 - offsetof_sun_path], )?)) } } @@ -133,7 +138,7 @@ pub(crate) unsafe fn read_sockaddr_os(storage: *const c::sockaddr, len: usize) - match read_ss_family(storage).into() { c::AF_INET => { assert!(len >= size_of::<c::sockaddr_in>()); - let decode = *storage.cast::<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), @@ -141,7 +146,7 @@ pub(crate) unsafe fn read_sockaddr_os(storage: *const c::sockaddr, len: usize) - } c::AF_INET6 => { assert!(len >= size_of::<c::sockaddr_in6>()); - let decode = *storage.cast::<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), @@ -154,19 +159,24 @@ pub(crate) unsafe fn read_sockaddr_os(storage: *const c::sockaddr, len: usize) - if len == offsetof_sun_path { SocketAddrAny::Unix(SocketAddrUnix::new(&[][..]).unwrap()) } else { - let decode = *storage.cast::<c::sockaddr_un>(); - assert_eq!( - decode.sun_path[len - 1 - offsetof_sun_path], - b'\0' as c::c_char - ); + 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 { + return SocketAddrAny::Unix( + SocketAddrUnix::new_abstract_name( + &decode.sun_path[1..len - offsetof_sun_path], + ) + .unwrap(), + ); + } + + // Otherwise we expect a NUL-terminated filesystem path. + assert_eq!(decode.sun_path[len - 1 - offsetof_sun_path], 0); SocketAddrAny::Unix( - SocketAddrUnix::new( - decode.sun_path[..len - 1 - offsetof_sun_path] - .iter() - .map(|c| *c as u8) - .collect::<Vec<u8>>(), - ) - .unwrap(), + SocketAddrUnix::new(&decode.sun_path[..len - 1 - offsetof_sun_path]).unwrap(), ) } } diff --git a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs index fb82eaef3..6e39a13aa 100644 --- a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs +++ b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs @@ -1,4 +1,4 @@ -use super::super::c; +use crate::backend::c; use bitflags::bitflags; bitflags! { @@ -6,6 +6,8 @@ bitflags! { /// /// [`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; @@ -29,6 +31,8 @@ bitflags! { /// /// [`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; diff --git a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs index 7fe9f0ef4..dca331783 100644 --- a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs @@ -6,29 +6,33 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] -use super::super::c; -use super::super::conv::{ - by_mut, by_ref, c_int, c_uint, ret, ret_owned_fd, ret_usize, size_of, slice, slice_mut, - socklen_t, zero, +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::types::{AddressFamily, Protocol, Shutdown, SocketFlags, SocketType}; 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, ret, ret_owned_fd, ret_usize, size_of, slice, slice_mut, + socklen_t, zero, +}; use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io; -use crate::net::{SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; +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::convert::TryInto; use core::mem::MaybeUninit; #[cfg(target_arch = "x86")] use { - super::super::conv::{slice_just_addr, x86_sys}, - super::super::reg::{ArgReg, SocketArg}, - linux_raw_sys::general::{ + 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_GETSOCKOPT, SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_SEND, SYS_SENDTO, SYS_SETSOCKOPT, - SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, + SYS_GETSOCKOPT, SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_RECVMSG, SYS_SEND, SYS_SENDMSG, + SYS_SENDTO, SYS_SETSOCKOPT, SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, }, }; @@ -36,7 +40,7 @@ use { pub(crate) fn socket( family: AddressFamily, type_: SocketType, - protocol: Protocol, + protocol: Option<Protocol>, ) -> io::Result<OwnedFd> { #[cfg(not(target_arch = "x86"))] unsafe { @@ -61,7 +65,7 @@ pub(crate) fn socket_with( family: AddressFamily, type_: SocketType, flags: SocketFlags, - protocol: Protocol, + protocol: Option<Protocol>, ) -> io::Result<OwnedFd> { #[cfg(not(target_arch = "x86"))] unsafe { @@ -91,7 +95,7 @@ pub(crate) fn socketpair( family: AddressFamily, type_: SocketType, flags: SocketFlags, - protocol: Protocol, + protocol: Option<Protocol>, ) -> io::Result<(OwnedFd, OwnedFd)> { #[cfg(not(target_arch = "x86"))] unsafe { @@ -240,6 +244,166 @@ pub(crate) fn acceptfrom_with( } #[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 { @@ -754,13 +918,9 @@ pub(crate) mod sockopt { use crate::net::sockopt::Timeout; use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; use c::{SO_RCVTIMEO_NEW, SO_RCVTIMEO_OLD, SO_SNDTIMEO_NEW, SO_SNDTIMEO_OLD}; - use core::convert::TryInto; use core::time::Duration; use linux_raw_sys::general::{__kernel_timespec, timeval}; - // TODO: With Rust 1.53 we can use `Duration::ZERO` instead. - const DURATION_ZERO: Duration = Duration::from_secs(0); - #[inline] fn getsockopt<T: Copy>(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result<T> { use super::*; @@ -910,12 +1070,7 @@ pub(crate) mod sockopt { #[inline] pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result<Option<Duration>> { let linger: c::linger = getsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER)?; - // TODO: With Rust 1.50, this could use `.then`. - Ok(if linger.l_onoff != 0 { - Some(Duration::from_secs(linger.l_linger as u64)) - } else { - None - }) + Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) } #[inline] @@ -1020,7 +1175,7 @@ pub(crate) mod sockopt { fn duration_to_linux(timeout: Option<Duration>) -> io::Result<__kernel_timespec> { Ok(match timeout { Some(timeout) => { - if timeout == DURATION_ZERO { + if timeout == Duration::ZERO { return Err(io::Errno::INVAL); } let mut timeout = __kernel_timespec { @@ -1043,7 +1198,7 @@ pub(crate) mod sockopt { fn duration_to_linux_old(timeout: Option<Duration>) -> io::Result<timeval> { Ok(match timeout { Some(timeout) => { - if timeout == DURATION_ZERO { + if timeout == Duration::ZERO { return Err(io::Errno::INVAL); } @@ -1186,14 +1341,14 @@ pub(crate) mod sockopt { setsockopt( fd, c::IPPROTO_IP as _, - c::IPV6_MULTICAST_LOOP, + c::IPV6_MULTICAST_HOPS, multicast_hops, ) } #[inline] pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_LOOP) + getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_HOPS) } #[inline] @@ -1244,7 +1399,7 @@ pub(crate) mod sockopt { #[inline] pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option<u8>) -> io::Result<()> { let hops = match hops { - Some(hops) => hops as c::c_int, + Some(hops) => hops.into(), None => -1, }; setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) @@ -1286,7 +1441,7 @@ pub(crate) mod sockopt { #[inline] fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { c::in6_addr { - in6_u: linux_raw_sys::general::in6_addr__bindgen_ty_1 { + in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { u6_addr8: multiaddr.octets(), }, } diff --git a/vendor/rustix/src/backend/linux_raw/net/types.rs b/vendor/rustix/src/backend/linux_raw/net/types.rs deleted file mode 100644 index 3f0b571a5..000000000 --- a/vendor/rustix/src/backend/linux_raw/net/types.rs +++ /dev/null @@ -1,275 +0,0 @@ -use super::super::c; -use bitflags::bitflags; - -/// A type for holding raw integer socket types. -#[doc(hidden)] -pub type RawSocketType = u32; - -/// `SOCK_*` constants for use with [`socket`]. -/// -/// [`socket`]: crate::net::socket -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct SocketType(pub(crate) RawSocketType); - -#[rustfmt::skip] -impl SocketType { - /// `SOCK_STREAM` - pub const STREAM: Self = Self(c::SOCK_STREAM); - - /// `SOCK_DGRAM` - pub const DGRAM: Self = Self(c::SOCK_DGRAM); - - /// `SOCK_SEQPACKET` - pub const SEQPACKET: Self = Self(c::SOCK_SEQPACKET); - - /// `SOCK_RAW` - pub const RAW: Self = Self(c::SOCK_RAW); - - /// `SOCK_RDM` - pub const RDM: Self = Self(c::SOCK_RDM); - - /// Constructs a `SocketType` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawSocketType) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `SocketType`. - #[inline] - pub const fn as_raw(self) -> RawSocketType { - self.0 - } -} - -/// A type for holding raw integer address families. -#[doc(hidden)] -pub type RawAddressFamily = c::sa_family_t; - -/// `AF_*` constants. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct AddressFamily(pub(crate) RawAddressFamily); - -#[rustfmt::skip] -#[allow(non_upper_case_globals)] -impl AddressFamily { - /// `AF_UNSPEC` - pub const UNSPEC: Self = Self(c::AF_UNSPEC as _); - /// `AF_INET` - pub const INET: Self = Self(c::AF_INET as _); - /// `AF_INET6` - pub const INET6: Self = Self(c::AF_INET6 as _); - /// `AF_NETLINK` - pub const NETLINK: Self = Self(c::AF_NETLINK as _); - /// `AF_UNIX`, aka `AF_LOCAL` - #[doc(alias = "LOCAL")] - pub const UNIX: Self = Self(c::AF_UNIX as _); - /// `AF_AX25` - pub const AX25: Self = Self(c::AF_AX25 as _); - /// `AF_IPX` - pub const IPX: Self = Self(c::AF_IPX as _); - /// `AF_APPLETALK` - pub const APPLETALK: Self = Self(c::AF_APPLETALK as _); - /// `AF_NETROM` - pub const NETROM: Self = Self(c::AF_NETROM as _); - /// `AF_BRIDGE` - pub const BRIDGE: Self = Self(c::AF_BRIDGE as _); - /// `AF_ATMPVC` - pub const ATMPVC: Self = Self(c::AF_ATMPVC as _); - /// `AF_X25` - pub const X25: Self = Self(c::AF_X25 as _); - /// `AF_ROSE` - pub const ROSE: Self = Self(c::AF_ROSE as _); - /// `AF_DECnet` - pub const DECnet: Self = Self(c::AF_DECnet as _); - /// `AF_NETBEUI` - pub const NETBEUI: Self = Self(c::AF_NETBEUI as _); - /// `AF_SECURITY` - pub const SECURITY: Self = Self(c::AF_SECURITY as _); - /// `AF_KEY` - pub const KEY: Self = Self(c::AF_KEY as _); - /// `AF_PACKET` - pub const PACKET: Self = Self(c::AF_PACKET as _); - /// `AF_ASH` - pub const ASH: Self = Self(c::AF_ASH as _); - /// `AF_ECONET` - pub const ECONET: Self = Self(c::AF_ECONET as _); - /// `AF_ATMSVC` - pub const ATMSVC: Self = Self(c::AF_ATMSVC as _); - /// `AF_RDS` - pub const RDS: Self = Self(c::AF_RDS as _); - /// `AF_SNA` - pub const SNA: Self = Self(c::AF_SNA as _); - /// `AF_IRDA` - pub const IRDA: Self = Self(c::AF_IRDA as _); - /// `AF_PPPOX` - pub const PPPOX: Self = Self(c::AF_PPPOX as _); - /// `AF_WANPIPE` - pub const WANPIPE: Self = Self(c::AF_WANPIPE as _); - /// `AF_LLC` - pub const LLC: Self = Self(c::AF_LLC as _); - /// `AF_CAN` - pub const CAN: Self = Self(c::AF_CAN as _); - /// `AF_TIPC` - pub const TIPC: Self = Self(c::AF_TIPC as _); - /// `AF_BLUETOOTH` - pub const BLUETOOTH: Self = Self(c::AF_BLUETOOTH as _); - /// `AF_IUCV` - pub const IUCV: Self = Self(c::AF_IUCV as _); - /// `AF_RXRPC` - pub const RXRPC: Self = Self(c::AF_RXRPC as _); - /// `AF_ISDN` - pub const ISDN: Self = Self(c::AF_ISDN as _); - /// `AF_PHONET` - pub const PHONET: Self = Self(c::AF_PHONET as _); - /// `AF_IEEE802154` - pub const IEEE802154: Self = Self(c::AF_IEEE802154 as _); - - /// Constructs a `AddressFamily` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawAddressFamily) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `AddressFamily`. - #[inline] - pub const fn as_raw(self) -> RawAddressFamily { - self.0 - } -} - -/// A type for holding raw integer protocols. -#[doc(hidden)] -pub type RawProtocol = u32; - -/// `IPPROTO_*` constants for use with [`socket`] and [`socket_with`]. -/// -/// [`socket`]: crate::net::socket -/// [`socket_with`]: crate::net::socket_with -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct Protocol(pub(crate) RawProtocol); - -#[rustfmt::skip] -impl Protocol { - /// `IPPROTO_IP` - pub const IP: Self = Self(c::IPPROTO_IP as _); - /// `IPPROTO_ICMP` - pub const ICMP: Self = Self(c::IPPROTO_ICMP as _); - /// `IPPROTO_IGMP` - pub const IGMP: Self = Self(c::IPPROTO_IGMP as _); - /// `IPPROTO_IPIP` - pub const IPIP: Self = Self(c::IPPROTO_IPIP as _); - /// `IPPROTO_TCP` - pub const TCP: Self = Self(c::IPPROTO_TCP as _); - /// `IPPROTO_EGP` - pub const EGP: Self = Self(c::IPPROTO_EGP as _); - /// `IPPROTO_PUP` - pub const PUP: Self = Self(c::IPPROTO_PUP as _); - /// `IPPROTO_UDP` - pub const UDP: Self = Self(c::IPPROTO_UDP as _); - /// `IPPROTO_IDP` - pub const IDP: Self = Self(c::IPPROTO_IDP as _); - /// `IPPROTO_TP` - pub const TP: Self = Self(c::IPPROTO_TP as _); - /// `IPPROTO_DCCP` - pub const DCCP: Self = Self(c::IPPROTO_DCCP as _); - /// `IPPROTO_IPV6` - pub const IPV6: Self = Self(c::IPPROTO_IPV6 as _); - /// `IPPROTO_RSVP` - pub const RSVP: Self = Self(c::IPPROTO_RSVP as _); - /// `IPPROTO_GRE` - pub const GRE: Self = Self(c::IPPROTO_GRE as _); - /// `IPPROTO_ESP` - pub const ESP: Self = Self(c::IPPROTO_ESP as _); - /// `IPPROTO_AH` - pub const AH: Self = Self(c::IPPROTO_AH as _); - /// `IPPROTO_MTP` - pub const MTP: Self = Self(c::IPPROTO_MTP as _); - /// `IPPROTO_BEETPH` - pub const BEETPH: Self = Self(c::IPPROTO_BEETPH as _); - /// `IPPROTO_ENCAP` - pub const ENCAP: Self = Self(c::IPPROTO_ENCAP as _); - /// `IPPROTO_PIM` - pub const PIM: Self = Self(c::IPPROTO_PIM as _); - /// `IPPROTO_COMP` - pub const COMP: Self = Self(c::IPPROTO_COMP as _); - /// `IPPROTO_SCTP` - pub const SCTP: Self = Self(c::IPPROTO_SCTP as _); - /// `IPPROTO_UDPLITE` - pub const UDPLITE: Self = Self(c::IPPROTO_UDPLITE as _); - /// `IPPROTO_MPLS` - pub const MPLS: Self = Self(c::IPPROTO_MPLS as _); - /// `IPPROTO_ETHERNET` - pub const ETHERNET: Self = Self(c::IPPROTO_ETHERNET as _); - /// `IPPROTO_RAW` - pub const RAW: Self = Self(c::IPPROTO_RAW as _); - /// `IPPROTO_MPTCP` - pub const MPTCP: Self = Self(c::IPPROTO_MPTCP as _); - /// `IPPROTO_FRAGMENT` - pub const FRAGMENT: Self = Self(c::IPPROTO_FRAGMENT as _); - /// `IPPROTO_ICMPV6` - pub const ICMPV6: Self = Self(c::IPPROTO_ICMPV6 as _); - /// `IPPROTO_MH` - pub const MH: Self = Self(c::IPPROTO_MH as _); - /// `IPPROTO_ROUTING` - pub const ROUTING: Self = Self(c::IPPROTO_ROUTING as _); - - /// Constructs a `Protocol` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawProtocol) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `Protocol`. - #[inline] - pub const fn as_raw(self) -> RawProtocol { - self.0 - } -} - -/// `SHUT_*` constants for use with [`shutdown`]. -/// -/// [`shutdown`]: crate::net::shutdown -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum Shutdown { - /// `SHUT_RD`—Disable further read operations. - Read = c::SHUT_RD, - /// `SHUT_WR`—Disable further write operations. - Write = c::SHUT_WR, - /// `SHUT_RDWR`—Disable further read and write operations. - ReadWrite = c::SHUT_RDWR, -} - -bitflags! { - /// `SOCK_*` constants for use with [`socket_with`], [`accept_with`] and - /// [`acceptfrom_with`]. - /// - /// [`socket_with`]: crate::net::socket_with - /// [`accept_with`]: crate::net::accept_with - /// [`acceptfrom_with`]: crate::net::acceptfrom_with - pub struct SocketFlags: c::c_uint { - /// `SOCK_NONBLOCK` - const NONBLOCK = c::O_NONBLOCK; - - /// `SOCK_CLOEXEC` - const CLOEXEC = c::O_CLOEXEC; - } -} - -/// Timeout identifier for use with [`set_socket_timeout`] and -/// [`get_socket_timeout`]. -/// -/// [`set_socket_timeout`]: crate::net::sockopt::set_socket_timeout. -/// [`get_socket_timeout`]: crate::net::sockopt::get_socket_timeout. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum Timeout { - /// `SO_RCVTIMEO`—Timeout for receiving. - Recv = c::SO_RCVTIMEO_NEW, - - /// `SO_SNDTIMEO`—Timeout for sending. - Send = c::SO_SNDTIMEO_NEW, -} diff --git a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs index 17abd96a0..28da05cd0 100644 --- a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs @@ -2,7 +2,7 @@ //! we can interpret the rest of a `sockaddr` produced by the kernel. #![allow(unsafe_code)] -use super::super::c; +use crate::backend::c; use crate::net::{SocketAddrAny, SocketAddrStorage, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; use core::mem::size_of; @@ -40,7 +40,7 @@ pub(crate) unsafe fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { sin6_port: u16::to_be(v6.port()), sin6_flowinfo: u32::to_be(v6.flowinfo()), sin6_addr: c::in6_addr { - in6_u: linux_raw_sys::general::in6_addr__bindgen_ty_1 { + in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { u6_addr8: v6.ip().octets(), }, }, |