diff options
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/net/syscalls.rs')
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/net/syscalls.rs | 949 |
1 files changed, 949 insertions, 0 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs new file mode 100644 index 0000000..726f022 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs @@ -0,0 +1,949 @@ +//! 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)]) + )) + } +} |