summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/src/backend/linux_raw/net
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/rustix/src/backend/linux_raw/net
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-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.rs60
-rw-r--r--vendor/rustix/src/backend/linux_raw/net/mod.rs2
-rw-r--r--vendor/rustix/src/backend/linux_raw/net/msghdr.rs143
-rw-r--r--vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs68
-rw-r--r--vendor/rustix/src/backend/linux_raw/net/send_recv.rs6
-rw-r--r--vendor/rustix/src/backend/linux_raw/net/syscalls.rs219
-rw-r--r--vendor/rustix/src/backend/linux_raw/net/types.rs275
-rw-r--r--vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs4
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(),
},
},