summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/src/backend/linux_raw/net/syscalls.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/net/syscalls.rs')
-rw-r--r--vendor/rustix/src/backend/linux_raw/net/syscalls.rs219
1 files changed, 187 insertions, 32 deletions
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(),
},
}