Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
33
third-party/vendor/rustix/src/net/mod.rs
vendored
Normal file
33
third-party/vendor/rustix/src/net/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
//! Network-related operations.
|
||||
//!
|
||||
//! On Windows, one must call [`wsa_startup`] in the process before calling any
|
||||
//! of these APIs. [`wsa_cleanup`] may be used in the process if these APIs are
|
||||
//! no longer needed.
|
||||
//!
|
||||
//! [`wsa_startup`]: https://docs.rs/rustix/*/x86_64-pc-windows-msvc/rustix/net/fn.wsa_startup.html
|
||||
//! [`wsa_cleanup`]: https://docs.rs/rustix/*/x86_64-pc-windows-msvc/rustix/net/fn.wsa_cleanup.html
|
||||
|
||||
mod send_recv;
|
||||
mod socket;
|
||||
mod socket_addr_any;
|
||||
#[cfg(not(any(windows, target_os = "wasi")))]
|
||||
mod socketpair;
|
||||
mod types;
|
||||
#[cfg(windows)]
|
||||
mod wsa;
|
||||
|
||||
#[cfg(linux_kernel)]
|
||||
pub mod netdevice;
|
||||
pub mod sockopt;
|
||||
|
||||
pub use crate::maybe_polyfill::net::{
|
||||
IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6,
|
||||
};
|
||||
pub use send_recv::*;
|
||||
pub use socket::*;
|
||||
pub use socket_addr_any::{SocketAddrAny, SocketAddrStorage};
|
||||
#[cfg(not(any(windows, target_os = "wasi")))]
|
||||
pub use socketpair::socketpair;
|
||||
pub use types::*;
|
||||
#[cfg(windows)]
|
||||
pub use wsa::{wsa_cleanup, wsa_startup};
|
||||
99
third-party/vendor/rustix/src/net/netdevice.rs
vendored
Normal file
99
third-party/vendor/rustix/src/net/netdevice.rs
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
//! Low-level Linux network device access
|
||||
//!
|
||||
//! The methods in this module take a socket's file descriptor to communicate with
|
||||
//! the kernel in their ioctl call:
|
||||
//! - glibc uses an `AF_UNIX`, `AF_INET`, or `AF_INET6` socket.
|
||||
//! The address family itself does not matter and glibc tries the next address family if socket creation with one fails.
|
||||
//! - Android (bionic) uses an `AF_INET` socket.
|
||||
//! - Both create the socket with `SOCK_DGRAM|SOCK_CLOEXEC` type/flag.
|
||||
//! - The [man-pages] specify, that the ioctl calls "can be used on any socket's file descriptor regardless of the
|
||||
//! family or type".
|
||||
//!
|
||||
//! # References
|
||||
//! - [Linux]
|
||||
//!
|
||||
//! [man-pages]: https://man7.org/linux/man-pages/man7/netdevice.7.html
|
||||
//! [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::alloc::string::String;
|
||||
use crate::fd::AsFd;
|
||||
use crate::io;
|
||||
|
||||
/// `ioctl(fd, SIOCGIFINDEX, ifreq)`—Returns the interface index for a given name.
|
||||
///
|
||||
/// See the [module-level documentation] for information about `fd` usage.
|
||||
///
|
||||
/// # References
|
||||
/// - [Linux]
|
||||
///
|
||||
/// [module-level documentation]: self
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html
|
||||
#[inline]
|
||||
#[doc(alias = "SIOCGIFINDEX")]
|
||||
pub fn name_to_index(fd: impl AsFd, if_name: &str) -> io::Result<u32> {
|
||||
crate::backend::net::netdevice::name_to_index(fd, if_name)
|
||||
}
|
||||
|
||||
/// `ioctl(fd, SIOCGIFNAME, ifreq)`—Returns the interface name for a given index.
|
||||
///
|
||||
/// See the [module-level documentation] for information about `fd` usage.
|
||||
///
|
||||
/// # References
|
||||
/// - [Linux]
|
||||
///
|
||||
/// [module-level documentation]: self
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html
|
||||
#[inline]
|
||||
#[doc(alias = "SIOCGIFNAME")]
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn index_to_name(fd: impl AsFd, index: u32) -> io::Result<String> {
|
||||
crate::backend::net::netdevice::index_to_name(fd, index)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::backend::net::netdevice::{index_to_name, name_to_index};
|
||||
use crate::net::{AddressFamily, SocketFlags, SocketType};
|
||||
|
||||
#[test]
|
||||
fn test_name_to_index() {
|
||||
let fd = crate::net::socket_with(
|
||||
AddressFamily::INET,
|
||||
SocketType::DGRAM,
|
||||
SocketFlags::CLOEXEC,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let loopback_index = std::fs::read_to_string("/sys/class/net/lo/ifindex")
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.split_at(1)
|
||||
.0
|
||||
.parse::<u32>()
|
||||
.unwrap();
|
||||
assert_eq!(Ok(loopback_index), name_to_index(fd, "lo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "alloc")]
|
||||
fn test_index_to_name() {
|
||||
let fd = crate::net::socket_with(
|
||||
AddressFamily::INET,
|
||||
SocketType::DGRAM,
|
||||
SocketFlags::CLOEXEC,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let loopback_index = std::fs::read_to_string("/sys/class/net/lo/ifindex")
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.split_at(1)
|
||||
.0
|
||||
.parse::<u32>()
|
||||
.unwrap();
|
||||
assert_eq!(Ok("lo".to_owned()), index_to_name(fd, loopback_index));
|
||||
}
|
||||
}
|
||||
403
third-party/vendor/rustix/src/net/send_recv/mod.rs
vendored
Normal file
403
third-party/vendor/rustix/src/net/send_recv/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
//! `recv`, `send`, and variants.
|
||||
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use crate::buffer::split_init;
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::net::xdp::SocketAddrXdp;
|
||||
#[cfg(unix)]
|
||||
use crate::net::SocketAddrUnix;
|
||||
use crate::net::{SocketAddr, SocketAddrAny, SocketAddrV4, SocketAddrV6};
|
||||
use crate::{backend, io};
|
||||
use backend::fd::{AsFd, BorrowedFd};
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
pub use backend::net::send_recv::{RecvFlags, SendFlags};
|
||||
|
||||
#[cfg(not(any(
|
||||
windows,
|
||||
target_os = "espidf",
|
||||
target_os = "redox",
|
||||
target_os = "vita",
|
||||
target_os = "wasi"
|
||||
)))]
|
||||
mod msg;
|
||||
|
||||
#[cfg(not(any(
|
||||
windows,
|
||||
target_os = "espidf",
|
||||
target_os = "redox",
|
||||
target_os = "vita",
|
||||
target_os = "wasi"
|
||||
)))]
|
||||
pub use msg::*;
|
||||
|
||||
/// `recv(fd, buf, flags)`—Reads data from a socket.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendrecv
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/recv.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recv.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recv
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=recv&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/recv.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/recv.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=recv§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/recv
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Receiving-Data.html
|
||||
#[inline]
|
||||
pub fn recv<Fd: AsFd>(fd: Fd, buf: &mut [u8], flags: RecvFlags) -> io::Result<usize> {
|
||||
unsafe { backend::net::syscalls::recv(fd.as_fd(), buf.as_mut_ptr(), buf.len(), flags) }
|
||||
}
|
||||
|
||||
/// `recv(fd, buf, flags)`—Reads data from a socket.
|
||||
///
|
||||
/// This is equivalent to [`recv`], except that it can read into uninitialized
|
||||
/// memory. It returns the slice that was initialized by this function and the
|
||||
/// slice that remains uninitialized.
|
||||
#[inline]
|
||||
pub fn recv_uninit<Fd: AsFd>(
|
||||
fd: Fd,
|
||||
buf: &mut [MaybeUninit<u8>],
|
||||
flags: RecvFlags,
|
||||
) -> io::Result<(&mut [u8], &mut [MaybeUninit<u8>])> {
|
||||
let length = unsafe {
|
||||
backend::net::syscalls::recv(fd.as_fd(), buf.as_mut_ptr() as *mut u8, buf.len(), flags)
|
||||
};
|
||||
|
||||
Ok(unsafe { split_init(buf, length?) })
|
||||
}
|
||||
|
||||
/// `send(fd, buf, flags)`—Writes data to a socket.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendrecv
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/send.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/send.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=send&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/send.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/send.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=send§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/send
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Sending-Data.html
|
||||
#[inline]
|
||||
pub fn send<Fd: AsFd>(fd: Fd, buf: &[u8], flags: SendFlags) -> io::Result<usize> {
|
||||
backend::net::syscalls::send(fd.as_fd(), buf, flags)
|
||||
}
|
||||
|
||||
/// `recvfrom(fd, buf, flags, addr, len)`—Reads data from a socket and
|
||||
/// returns the sender address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/recvfrom.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recvfrom.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recvfrom
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=recvfrom&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/recvfrom.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/recvfrom.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=recvfrom§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/recvfrom
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Receiving-Datagrams.html
|
||||
#[inline]
|
||||
pub fn recvfrom<Fd: AsFd>(
|
||||
fd: Fd,
|
||||
buf: &mut [u8],
|
||||
flags: RecvFlags,
|
||||
) -> io::Result<(usize, Option<SocketAddrAny>)> {
|
||||
unsafe { backend::net::syscalls::recvfrom(fd.as_fd(), buf.as_mut_ptr(), buf.len(), flags) }
|
||||
}
|
||||
|
||||
/// `recvfrom(fd, buf, flags, addr, len)`—Reads data from a socket and
|
||||
/// returns the sender address.
|
||||
///
|
||||
/// This is equivalent to [`recvfrom`], except that it can read into
|
||||
/// uninitialized memory. It returns the slice that was initialized by this
|
||||
/// function and the slice that remains uninitialized.
|
||||
#[allow(clippy::type_complexity)]
|
||||
#[inline]
|
||||
pub fn recvfrom_uninit<Fd: AsFd>(
|
||||
fd: Fd,
|
||||
buf: &mut [MaybeUninit<u8>],
|
||||
flags: RecvFlags,
|
||||
) -> io::Result<(&mut [u8], &mut [MaybeUninit<u8>], Option<SocketAddrAny>)> {
|
||||
let (length, addr) = unsafe {
|
||||
backend::net::syscalls::recvfrom(fd.as_fd(), buf.as_mut_ptr() as *mut u8, buf.len(), flags)?
|
||||
};
|
||||
let (init, uninit) = unsafe { split_init(buf, length) };
|
||||
Ok((init, uninit, addr))
|
||||
}
|
||||
|
||||
/// `sendto(fd, buf, flags, addr)`—Writes data to a socket to a specific IP
|
||||
/// address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendto&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/sendto.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/sendto.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendto§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/sendto
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Sending-Datagrams.html
|
||||
pub fn sendto<Fd: AsFd>(
|
||||
fd: Fd,
|
||||
buf: &[u8],
|
||||
flags: SendFlags,
|
||||
addr: &SocketAddr,
|
||||
) -> io::Result<usize> {
|
||||
_sendto(fd.as_fd(), buf, flags, addr)
|
||||
}
|
||||
|
||||
fn _sendto(
|
||||
fd: BorrowedFd<'_>,
|
||||
buf: &[u8],
|
||||
flags: SendFlags,
|
||||
addr: &SocketAddr,
|
||||
) -> io::Result<usize> {
|
||||
match addr {
|
||||
SocketAddr::V4(v4) => backend::net::syscalls::sendto_v4(fd, buf, flags, v4),
|
||||
SocketAddr::V6(v6) => backend::net::syscalls::sendto_v6(fd, buf, flags, v6),
|
||||
}
|
||||
}
|
||||
|
||||
/// `sendto(fd, buf, flags, addr)`—Writes data to a socket to a specific
|
||||
/// address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendto&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/sendto.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/sendto.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendto§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/sendto
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Sending-Datagrams.html
|
||||
pub fn sendto_any<Fd: AsFd>(
|
||||
fd: Fd,
|
||||
buf: &[u8],
|
||||
flags: SendFlags,
|
||||
addr: &SocketAddrAny,
|
||||
) -> io::Result<usize> {
|
||||
_sendto_any(fd.as_fd(), buf, flags, addr)
|
||||
}
|
||||
|
||||
fn _sendto_any(
|
||||
fd: BorrowedFd<'_>,
|
||||
buf: &[u8],
|
||||
flags: SendFlags,
|
||||
addr: &SocketAddrAny,
|
||||
) -> io::Result<usize> {
|
||||
match addr {
|
||||
SocketAddrAny::V4(v4) => backend::net::syscalls::sendto_v4(fd, buf, flags, v4),
|
||||
SocketAddrAny::V6(v6) => backend::net::syscalls::sendto_v6(fd, buf, flags, v6),
|
||||
#[cfg(unix)]
|
||||
SocketAddrAny::Unix(unix) => backend::net::syscalls::sendto_unix(fd, buf, flags, unix),
|
||||
#[cfg(target_os = "linux")]
|
||||
SocketAddrAny::Xdp(xdp) => backend::net::syscalls::sendto_xdp(fd, buf, flags, xdp),
|
||||
}
|
||||
}
|
||||
|
||||
/// `sendto(fd, buf, flags, addr, sizeof(struct sockaddr_in))`—Writes data to
|
||||
/// a socket to a specific IPv4 address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendto&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/sendto.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/sendto.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendto§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/sendto
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Sending-Datagrams.html
|
||||
#[inline]
|
||||
#[doc(alias = "sendto")]
|
||||
pub fn sendto_v4<Fd: AsFd>(
|
||||
fd: Fd,
|
||||
buf: &[u8],
|
||||
flags: SendFlags,
|
||||
addr: &SocketAddrV4,
|
||||
) -> io::Result<usize> {
|
||||
backend::net::syscalls::sendto_v4(fd.as_fd(), buf, flags, addr)
|
||||
}
|
||||
|
||||
/// `sendto(fd, buf, flags, addr, sizeof(struct sockaddr_in6))`—Writes data
|
||||
/// to a socket to a specific IPv6 address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendto&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/sendto.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/sendto.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendto§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/sendto
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Sending-Datagrams.html
|
||||
#[inline]
|
||||
#[doc(alias = "sendto")]
|
||||
pub fn sendto_v6<Fd: AsFd>(
|
||||
fd: Fd,
|
||||
buf: &[u8],
|
||||
flags: SendFlags,
|
||||
addr: &SocketAddrV6,
|
||||
) -> io::Result<usize> {
|
||||
backend::net::syscalls::sendto_v6(fd.as_fd(), buf, flags, addr)
|
||||
}
|
||||
|
||||
/// `sendto(fd, buf, flags, addr, sizeof(struct sockaddr_un))`—Writes data to
|
||||
/// a socket to a specific Unix-domain socket address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendto&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/sendto.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/sendto.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendto§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/sendto
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Sending-Datagrams.html
|
||||
#[cfg(unix)]
|
||||
#[inline]
|
||||
#[doc(alias = "sendto")]
|
||||
pub fn sendto_unix<Fd: AsFd>(
|
||||
fd: Fd,
|
||||
buf: &[u8],
|
||||
flags: SendFlags,
|
||||
addr: &SocketAddrUnix,
|
||||
) -> io::Result<usize> {
|
||||
backend::net::syscalls::sendto_unix(fd.as_fd(), buf, flags, addr)
|
||||
}
|
||||
|
||||
/// `sendto(fd, buf, flags, addr, sizeof(struct sockaddr_xdp))`—Writes data
|
||||
/// to a socket to a specific XDP address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Linux]
|
||||
///
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
|
||||
#[cfg(target_os = "linux")]
|
||||
#[inline]
|
||||
#[doc(alias = "sendto")]
|
||||
pub fn sendto_xdp<Fd: AsFd>(
|
||||
fd: Fd,
|
||||
buf: &[u8],
|
||||
flags: SendFlags,
|
||||
addr: &SocketAddrXdp,
|
||||
) -> io::Result<usize> {
|
||||
backend::net::syscalls::sendto_xdp(fd.as_fd(), buf, flags, addr)
|
||||
}
|
||||
988
third-party/vendor/rustix/src/net/send_recv/msg.rs
vendored
Normal file
988
third-party/vendor/rustix/src/net/send_recv/msg.rs
vendored
Normal file
|
|
@ -0,0 +1,988 @@
|
|||
//! [`recvmsg`], [`sendmsg`], and related functions.
|
||||
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use crate::backend::{self, c};
|
||||
use crate::fd::{AsFd, BorrowedFd, OwnedFd};
|
||||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
#[cfg(linux_kernel)]
|
||||
use crate::net::UCred;
|
||||
|
||||
use core::iter::FusedIterator;
|
||||
use core::marker::PhantomData;
|
||||
use core::mem::{align_of, size_of, size_of_val, take};
|
||||
#[cfg(linux_kernel)]
|
||||
use core::ptr::addr_of;
|
||||
use core::{ptr, slice};
|
||||
|
||||
use super::{RecvFlags, SendFlags, SocketAddrAny, SocketAddrV4, SocketAddrV6};
|
||||
|
||||
/// Macro for defining the amount of space to allocate in a buffer for use with
|
||||
/// [`RecvAncillaryBuffer::new`] and [`SendAncillaryBuffer::new`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Allocate a buffer for a single file descriptor:
|
||||
/// ```
|
||||
/// # use rustix::cmsg_space;
|
||||
/// let mut space = [0; rustix::cmsg_space!(ScmRights(1))];
|
||||
/// ```
|
||||
///
|
||||
/// Allocate a buffer for credentials:
|
||||
/// ```
|
||||
/// # #[cfg(linux_kernel)]
|
||||
/// # {
|
||||
/// # use rustix::cmsg_space;
|
||||
/// let mut space = [0; rustix::cmsg_space!(ScmCredentials(1))];
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// Allocate a buffer for two file descriptors and credentials:
|
||||
/// ```
|
||||
/// # #[cfg(linux_kernel)]
|
||||
/// # {
|
||||
/// # use rustix::cmsg_space;
|
||||
/// let mut space = [0; rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))];
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! cmsg_space {
|
||||
// Base Rules
|
||||
(ScmRights($len:expr)) => {
|
||||
$crate::net::__cmsg_space(
|
||||
$len * ::core::mem::size_of::<$crate::fd::BorrowedFd<'static>>(),
|
||||
)
|
||||
};
|
||||
(ScmCredentials($len:expr)) => {
|
||||
$crate::net::__cmsg_space(
|
||||
$len * ::core::mem::size_of::<$crate::net::UCred>(),
|
||||
)
|
||||
};
|
||||
|
||||
// Combo Rules
|
||||
($firstid:ident($firstex:expr), $($restid:ident($restex:expr)),*) => {{
|
||||
// We only have to add `cmsghdr` alignment once; all other times we can
|
||||
// use `cmsg_aligned_space`.
|
||||
let sum = $crate::cmsg_space!($firstid($firstex));
|
||||
$(
|
||||
let sum = sum + $crate::cmsg_aligned_space!($restid($restex));
|
||||
)*
|
||||
sum
|
||||
}};
|
||||
}
|
||||
|
||||
/// Like `cmsg_space`, but doesn't add padding for `cmsghdr` alignment.
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! cmsg_aligned_space {
|
||||
// Base Rules
|
||||
(ScmRights($len:expr)) => {
|
||||
$crate::net::__cmsg_aligned_space(
|
||||
$len * ::core::mem::size_of::<$crate::fd::BorrowedFd<'static>>(),
|
||||
)
|
||||
};
|
||||
(ScmCredentials($len:expr)) => {
|
||||
$crate::net::__cmsg_aligned_space(
|
||||
$len * ::core::mem::size_of::<$crate::net::UCred>(),
|
||||
)
|
||||
};
|
||||
|
||||
// Combo Rules
|
||||
($firstid:ident($firstex:expr), $($restid:ident($restex:expr)),*) => {{
|
||||
let sum = cmsg_aligned_space!($firstid($firstex));
|
||||
$(
|
||||
let sum = sum + cmsg_aligned_space!($restid($restex));
|
||||
)*
|
||||
sum
|
||||
}};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub const fn __cmsg_space(len: usize) -> usize {
|
||||
// Add `align_of::<c::cmsghdr>()` so that we can align the user-provided
|
||||
// `&[u8]` to the required alignment boundary.
|
||||
let len = len + align_of::<c::cmsghdr>();
|
||||
|
||||
__cmsg_aligned_space(len)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub const fn __cmsg_aligned_space(len: usize) -> usize {
|
||||
// Convert `len` to `u32` for `CMSG_SPACE`. This would be `try_into()` if
|
||||
// we could call that in a `const fn`.
|
||||
let converted_len = len as u32;
|
||||
if converted_len as usize != len {
|
||||
unreachable!(); // `CMSG_SPACE` size overflow
|
||||
}
|
||||
|
||||
unsafe { c::CMSG_SPACE(converted_len) as usize }
|
||||
}
|
||||
|
||||
/// Ancillary message for [`sendmsg`], [`sendmsg_v4`], [`sendmsg_v6`],
|
||||
/// [`sendmsg_unix`], and [`sendmsg_any`].
|
||||
#[non_exhaustive]
|
||||
pub enum SendAncillaryMessage<'slice, 'fd> {
|
||||
/// Send file descriptors.
|
||||
#[doc(alias = "SCM_RIGHTS")]
|
||||
ScmRights(&'slice [BorrowedFd<'fd>]),
|
||||
/// Send process credentials.
|
||||
#[cfg(linux_kernel)]
|
||||
#[doc(alias = "SCM_CREDENTIAL")]
|
||||
ScmCredentials(UCred),
|
||||
}
|
||||
|
||||
impl SendAncillaryMessage<'_, '_> {
|
||||
/// Get the maximum size of an ancillary message.
|
||||
///
|
||||
/// This can be helpful in determining the size of the buffer you allocate.
|
||||
pub const fn size(&self) -> usize {
|
||||
match self {
|
||||
Self::ScmRights(slice) => cmsg_space!(ScmRights(slice.len())),
|
||||
#[cfg(linux_kernel)]
|
||||
Self::ScmCredentials(_) => cmsg_space!(ScmCredentials(1)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Ancillary message for [`recvmsg`].
|
||||
#[non_exhaustive]
|
||||
pub enum RecvAncillaryMessage<'a> {
|
||||
/// Received file descriptors.
|
||||
#[doc(alias = "SCM_RIGHTS")]
|
||||
ScmRights(AncillaryIter<'a, OwnedFd>),
|
||||
/// Received process credentials.
|
||||
#[cfg(linux_kernel)]
|
||||
#[doc(alias = "SCM_CREDENTIALS")]
|
||||
ScmCredentials(UCred),
|
||||
}
|
||||
|
||||
/// Buffer for sending ancillary messages with [`sendmsg`], [`sendmsg_v4`],
|
||||
/// [`sendmsg_v6`], [`sendmsg_unix`], and [`sendmsg_any`].
|
||||
///
|
||||
/// Use the [`push`] function to add messages to send.
|
||||
///
|
||||
/// [`push`]: SendAncillaryBuffer::push
|
||||
pub struct SendAncillaryBuffer<'buf, 'slice, 'fd> {
|
||||
/// Raw byte buffer for messages.
|
||||
buffer: &'buf mut [u8],
|
||||
|
||||
/// The amount of the buffer that is used.
|
||||
length: usize,
|
||||
|
||||
/// Phantom data for lifetime of `&'slice [BorrowedFd<'fd>]`.
|
||||
_phantom: PhantomData<&'slice [BorrowedFd<'fd>]>,
|
||||
}
|
||||
|
||||
impl<'buf> From<&'buf mut [u8]> for SendAncillaryBuffer<'buf, '_, '_> {
|
||||
fn from(buffer: &'buf mut [u8]) -> Self {
|
||||
Self::new(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SendAncillaryBuffer<'_, '_, '_> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
buffer: &mut [],
|
||||
length: 0,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'buf, 'slice, 'fd> SendAncillaryBuffer<'buf, 'slice, 'fd> {
|
||||
/// Create a new, empty `SendAncillaryBuffer` from a raw byte buffer.
|
||||
///
|
||||
/// The buffer size may be computed with [`cmsg_space`], or it may be
|
||||
/// zero for an empty buffer, however in that case, consider `default()`
|
||||
/// instead, or even using [`send`] instead of `sendmsg`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Allocate a buffer for a single file descriptor:
|
||||
/// ```
|
||||
/// # use rustix::cmsg_space;
|
||||
/// # use rustix::net::SendAncillaryBuffer;
|
||||
/// let mut space = [0; rustix::cmsg_space!(ScmRights(1))];
|
||||
/// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space);
|
||||
/// ```
|
||||
///
|
||||
/// Allocate a buffer for credentials:
|
||||
/// ```
|
||||
/// # #[cfg(linux_kernel)]
|
||||
/// # {
|
||||
/// # use rustix::cmsg_space;
|
||||
/// # use rustix::net::SendAncillaryBuffer;
|
||||
/// let mut space = [0; rustix::cmsg_space!(ScmCredentials(1))];
|
||||
/// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space);
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// Allocate a buffer for two file descriptors and credentials:
|
||||
/// ```
|
||||
/// # #[cfg(linux_kernel)]
|
||||
/// # {
|
||||
/// # use rustix::cmsg_space;
|
||||
/// # use rustix::net::SendAncillaryBuffer;
|
||||
/// let mut space = [0; rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))];
|
||||
/// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space);
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`send`]: crate::net::send
|
||||
#[inline]
|
||||
pub fn new(buffer: &'buf mut [u8]) -> Self {
|
||||
Self {
|
||||
buffer: align_for_cmsghdr(buffer),
|
||||
length: 0,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a pointer to the message data.
|
||||
pub(crate) fn as_control_ptr(&mut self) -> *mut u8 {
|
||||
// When the length is zero, we may be using a `&[]` address, which may
|
||||
// be an invalid but non-null pointer, and on some platforms, that
|
||||
// causes `sendmsg` to fail with `EFAULT` or `EINVAL`
|
||||
#[cfg(not(linux_kernel))]
|
||||
if self.length == 0 {
|
||||
return core::ptr::null_mut();
|
||||
}
|
||||
|
||||
self.buffer.as_mut_ptr()
|
||||
}
|
||||
|
||||
/// Returns the length of the message data.
|
||||
pub(crate) fn control_len(&self) -> usize {
|
||||
self.length
|
||||
}
|
||||
|
||||
/// Delete all messages from the buffer.
|
||||
pub fn clear(&mut self) {
|
||||
self.length = 0;
|
||||
}
|
||||
|
||||
/// Add an ancillary message to the buffer.
|
||||
///
|
||||
/// Returns `true` if the message was added successfully.
|
||||
pub fn push(&mut self, msg: SendAncillaryMessage<'slice, 'fd>) -> bool {
|
||||
match msg {
|
||||
SendAncillaryMessage::ScmRights(fds) => {
|
||||
let fds_bytes =
|
||||
unsafe { slice::from_raw_parts(fds.as_ptr().cast::<u8>(), size_of_val(fds)) };
|
||||
self.push_ancillary(fds_bytes, c::SOL_SOCKET as _, c::SCM_RIGHTS as _)
|
||||
}
|
||||
#[cfg(linux_kernel)]
|
||||
SendAncillaryMessage::ScmCredentials(ucred) => {
|
||||
let ucred_bytes = unsafe {
|
||||
slice::from_raw_parts(addr_of!(ucred).cast::<u8>(), size_of_val(&ucred))
|
||||
};
|
||||
self.push_ancillary(ucred_bytes, c::SOL_SOCKET as _, c::SCM_CREDENTIALS as _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pushes an ancillary message to the buffer.
|
||||
fn push_ancillary(&mut self, source: &[u8], cmsg_level: c::c_int, cmsg_type: c::c_int) -> bool {
|
||||
macro_rules! leap {
|
||||
($e:expr) => {{
|
||||
match ($e) {
|
||||
Some(x) => x,
|
||||
None => return false,
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
// Calculate the length of the message.
|
||||
let source_len = leap!(u32::try_from(source.len()).ok());
|
||||
|
||||
// Calculate the new length of the buffer.
|
||||
let additional_space = unsafe { c::CMSG_SPACE(source_len) };
|
||||
let new_length = leap!(self.length.checked_add(additional_space as usize));
|
||||
let buffer = leap!(self.buffer.get_mut(..new_length));
|
||||
|
||||
// Fill the new part of the buffer with zeroes.
|
||||
buffer[self.length..new_length].fill(0);
|
||||
self.length = new_length;
|
||||
|
||||
// Get the last header in the buffer.
|
||||
let last_header = leap!(messages::Messages::new(buffer).last());
|
||||
|
||||
// Set the header fields.
|
||||
last_header.cmsg_len = unsafe { c::CMSG_LEN(source_len) } as _;
|
||||
last_header.cmsg_level = cmsg_level;
|
||||
last_header.cmsg_type = cmsg_type;
|
||||
|
||||
// Get the pointer to the payload and copy the data.
|
||||
unsafe {
|
||||
let payload = c::CMSG_DATA(last_header);
|
||||
ptr::copy_nonoverlapping(source.as_ptr(), payload, source_len as _);
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<'slice, 'fd> Extend<SendAncillaryMessage<'slice, 'fd>>
|
||||
for SendAncillaryBuffer<'_, 'slice, 'fd>
|
||||
{
|
||||
fn extend<T: IntoIterator<Item = SendAncillaryMessage<'slice, 'fd>>>(&mut self, iter: T) {
|
||||
// TODO: This could be optimized to add every message in one go.
|
||||
iter.into_iter().all(|msg| self.push(msg));
|
||||
}
|
||||
}
|
||||
|
||||
/// Buffer for receiving ancillary messages with [`recvmsg`].
|
||||
///
|
||||
/// Use the [`drain`] function to iterate over the received messages.
|
||||
///
|
||||
/// [`drain`]: RecvAncillaryBuffer::drain
|
||||
#[derive(Default)]
|
||||
pub struct RecvAncillaryBuffer<'buf> {
|
||||
/// Raw byte buffer for messages.
|
||||
buffer: &'buf mut [u8],
|
||||
|
||||
/// The portion of the buffer we've read from already.
|
||||
read: usize,
|
||||
|
||||
/// The amount of the buffer that is used.
|
||||
length: usize,
|
||||
}
|
||||
|
||||
impl<'buf> From<&'buf mut [u8]> for RecvAncillaryBuffer<'buf> {
|
||||
fn from(buffer: &'buf mut [u8]) -> Self {
|
||||
Self::new(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'buf> RecvAncillaryBuffer<'buf> {
|
||||
/// Create a new, empty `RecvAncillaryBuffer` from a raw byte buffer.
|
||||
///
|
||||
/// The buffer size may be computed with [`cmsg_space`], or it may be
|
||||
/// zero for an empty buffer, however in that case, consider `default()`
|
||||
/// instead, or even using [`recv`] instead of `recvmsg`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Allocate a buffer for a single file descriptor:
|
||||
/// ```
|
||||
/// # use rustix::cmsg_space;
|
||||
/// # use rustix::net::RecvAncillaryBuffer;
|
||||
/// let mut space = [0; rustix::cmsg_space!(ScmRights(1))];
|
||||
/// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space);
|
||||
/// ```
|
||||
///
|
||||
/// Allocate a buffer for credentials:
|
||||
/// ```
|
||||
/// # #[cfg(linux_kernel)]
|
||||
/// # {
|
||||
/// # use rustix::cmsg_space;
|
||||
/// # use rustix::net::RecvAncillaryBuffer;
|
||||
/// let mut space = [0; rustix::cmsg_space!(ScmCredentials(1))];
|
||||
/// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space);
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// Allocate a buffer for two file descriptors and credentials:
|
||||
/// ```
|
||||
/// # #[cfg(linux_kernel)]
|
||||
/// # {
|
||||
/// # use rustix::cmsg_space;
|
||||
/// # use rustix::net::RecvAncillaryBuffer;
|
||||
/// let mut space = [0; rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))];
|
||||
/// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space);
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`recv`]: crate::net::recv
|
||||
#[inline]
|
||||
pub fn new(buffer: &'buf mut [u8]) -> Self {
|
||||
Self {
|
||||
buffer: align_for_cmsghdr(buffer),
|
||||
read: 0,
|
||||
length: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a pointer to the message data.
|
||||
pub(crate) fn as_control_ptr(&mut self) -> *mut u8 {
|
||||
// When the length is zero, we may be using a `&[]` address, which may
|
||||
// be an invalid but non-null pointer, and on some platforms, that
|
||||
// causes `sendmsg` to fail with `EFAULT` or `EINVAL`
|
||||
#[cfg(not(linux_kernel))]
|
||||
if self.buffer.is_empty() {
|
||||
return core::ptr::null_mut();
|
||||
}
|
||||
|
||||
self.buffer.as_mut_ptr()
|
||||
}
|
||||
|
||||
/// Returns the length of the message data.
|
||||
pub(crate) fn control_len(&self) -> usize {
|
||||
self.buffer.len()
|
||||
}
|
||||
|
||||
/// Set the length of the message data.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The buffer must be filled with valid message data.
|
||||
pub(crate) unsafe fn set_control_len(&mut self, len: usize) {
|
||||
self.length = len;
|
||||
self.read = 0;
|
||||
}
|
||||
|
||||
/// Delete all messages from the buffer.
|
||||
pub(crate) fn clear(&mut self) {
|
||||
self.drain().for_each(drop);
|
||||
}
|
||||
|
||||
/// Drain all messages from the buffer.
|
||||
pub fn drain(&mut self) -> AncillaryDrain<'_> {
|
||||
AncillaryDrain {
|
||||
messages: messages::Messages::new(&mut self.buffer[self.read..][..self.length]),
|
||||
read: &mut self.read,
|
||||
length: &mut self.length,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for RecvAncillaryBuffer<'_> {
|
||||
fn drop(&mut self) {
|
||||
self.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a slice of `buffer` starting at the first `cmsghdr` alignment
|
||||
/// boundary.
|
||||
#[inline]
|
||||
fn align_for_cmsghdr(buffer: &mut [u8]) -> &mut [u8] {
|
||||
// If the buffer is empty, we won't be writing anything into it, so it
|
||||
// doesn't need to be aligned.
|
||||
if buffer.is_empty() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
let align = align_of::<c::cmsghdr>();
|
||||
let addr = buffer.as_ptr() as usize;
|
||||
let adjusted = (addr + (align - 1)) & align.wrapping_neg();
|
||||
&mut buffer[adjusted - addr..]
|
||||
}
|
||||
|
||||
/// An iterator that drains messages from a [`RecvAncillaryBuffer`].
|
||||
pub struct AncillaryDrain<'buf> {
|
||||
/// Inner iterator over messages.
|
||||
messages: messages::Messages<'buf>,
|
||||
|
||||
/// Increment the number of messages we've read.
|
||||
read: &'buf mut usize,
|
||||
|
||||
/// Decrement the total length.
|
||||
length: &'buf mut usize,
|
||||
}
|
||||
|
||||
impl<'buf> AncillaryDrain<'buf> {
|
||||
/// A closure that converts a message into a [`RecvAncillaryMessage`].
|
||||
fn cvt_msg(
|
||||
read: &mut usize,
|
||||
length: &mut usize,
|
||||
msg: &c::cmsghdr,
|
||||
) -> Option<RecvAncillaryMessage<'buf>> {
|
||||
unsafe {
|
||||
// Advance the `read` pointer.
|
||||
let msg_len = msg.cmsg_len as usize;
|
||||
*read += msg_len;
|
||||
*length -= msg_len;
|
||||
|
||||
// Get a pointer to the payload.
|
||||
let payload = c::CMSG_DATA(msg);
|
||||
let payload_len = msg.cmsg_len as usize - c::CMSG_LEN(0) as usize;
|
||||
|
||||
// Get a mutable slice of the payload.
|
||||
let payload: &'buf mut [u8] = slice::from_raw_parts_mut(payload, payload_len);
|
||||
|
||||
// Determine what type it is.
|
||||
let (level, msg_type) = (msg.cmsg_level, msg.cmsg_type);
|
||||
match (level as _, msg_type as _) {
|
||||
(c::SOL_SOCKET, c::SCM_RIGHTS) => {
|
||||
// Create an iterator that reads out the file descriptors.
|
||||
let fds = AncillaryIter::new(payload);
|
||||
|
||||
Some(RecvAncillaryMessage::ScmRights(fds))
|
||||
}
|
||||
#[cfg(linux_kernel)]
|
||||
(c::SOL_SOCKET, c::SCM_CREDENTIALS) => {
|
||||
if payload_len >= size_of::<UCred>() {
|
||||
let ucred = payload.as_ptr().cast::<UCred>().read_unaligned();
|
||||
Some(RecvAncillaryMessage::ScmCredentials(ucred))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'buf> Iterator for AncillaryDrain<'buf> {
|
||||
type Item = RecvAncillaryMessage<'buf>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let read = &mut self.read;
|
||||
let length = &mut self.length;
|
||||
self.messages.find_map(|ev| Self::cvt_msg(read, length, ev))
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let (_, max) = self.messages.size_hint();
|
||||
(0, max)
|
||||
}
|
||||
|
||||
fn fold<B, F>(self, init: B, f: F) -> B
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(B, Self::Item) -> B,
|
||||
{
|
||||
let read = self.read;
|
||||
let length = self.length;
|
||||
self.messages
|
||||
.filter_map(|ev| Self::cvt_msg(read, length, ev))
|
||||
.fold(init, f)
|
||||
}
|
||||
|
||||
fn count(self) -> usize {
|
||||
let read = self.read;
|
||||
let length = self.length;
|
||||
self.messages
|
||||
.filter_map(|ev| Self::cvt_msg(read, length, ev))
|
||||
.count()
|
||||
}
|
||||
|
||||
fn last(self) -> Option<Self::Item>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let read = self.read;
|
||||
let length = self.length;
|
||||
self.messages
|
||||
.filter_map(|ev| Self::cvt_msg(read, length, ev))
|
||||
.last()
|
||||
}
|
||||
|
||||
fn collect<B: FromIterator<Self::Item>>(self) -> B
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let read = self.read;
|
||||
let length = self.length;
|
||||
self.messages
|
||||
.filter_map(|ev| Self::cvt_msg(read, length, ev))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl FusedIterator for AncillaryDrain<'_> {}
|
||||
|
||||
/// `sendmsg(msghdr)`—Sends a message on a socket.
|
||||
///
|
||||
/// # References
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
///
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendmsg.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendmsg.2.html
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendmsg&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/sendmsg.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/sendmsg.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendmsg§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/sendmsg
|
||||
#[inline]
|
||||
pub fn sendmsg(
|
||||
socket: impl AsFd,
|
||||
iov: &[IoSlice<'_>],
|
||||
control: &mut SendAncillaryBuffer<'_, '_, '_>,
|
||||
flags: SendFlags,
|
||||
) -> io::Result<usize> {
|
||||
backend::net::syscalls::sendmsg(socket.as_fd(), iov, control, flags)
|
||||
}
|
||||
|
||||
/// `sendmsg(msghdr)`—Sends a message on a socket to a specific IPv4 address.
|
||||
///
|
||||
/// # References
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
///
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendmsg.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendmsg.2.html
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendmsg&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/sendmsg.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/sendmsg.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendmsg§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/sendmsg
|
||||
#[inline]
|
||||
pub fn sendmsg_v4(
|
||||
socket: impl AsFd,
|
||||
addr: &SocketAddrV4,
|
||||
iov: &[IoSlice<'_>],
|
||||
control: &mut SendAncillaryBuffer<'_, '_, '_>,
|
||||
flags: SendFlags,
|
||||
) -> io::Result<usize> {
|
||||
backend::net::syscalls::sendmsg_v4(socket.as_fd(), addr, iov, control, flags)
|
||||
}
|
||||
|
||||
/// `sendmsg(msghdr)`—Sends a message on a socket to a specific IPv6 address.
|
||||
///
|
||||
/// # References
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
///
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendmsg.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendmsg.2.html
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendmsg&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/sendmsg.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/sendmsg.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendmsg§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/sendmsg
|
||||
#[inline]
|
||||
pub fn sendmsg_v6(
|
||||
socket: impl AsFd,
|
||||
addr: &SocketAddrV6,
|
||||
iov: &[IoSlice<'_>],
|
||||
control: &mut SendAncillaryBuffer<'_, '_, '_>,
|
||||
flags: SendFlags,
|
||||
) -> io::Result<usize> {
|
||||
backend::net::syscalls::sendmsg_v6(socket.as_fd(), addr, iov, control, flags)
|
||||
}
|
||||
|
||||
/// `sendmsg(msghdr)`—Sends a message on a socket to a specific Unix-domain
|
||||
/// address.
|
||||
///
|
||||
/// # References
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
///
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendmsg.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendmsg.2.html
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendmsg&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/sendmsg.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/sendmsg.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendmsg§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/sendmsg
|
||||
#[inline]
|
||||
#[cfg(unix)]
|
||||
pub fn sendmsg_unix(
|
||||
socket: impl AsFd,
|
||||
addr: &super::SocketAddrUnix,
|
||||
iov: &[IoSlice<'_>],
|
||||
control: &mut SendAncillaryBuffer<'_, '_, '_>,
|
||||
flags: SendFlags,
|
||||
) -> io::Result<usize> {
|
||||
backend::net::syscalls::sendmsg_unix(socket.as_fd(), addr, iov, control, flags)
|
||||
}
|
||||
|
||||
/// `sendmsg(msghdr)`—Sends a message on a socket to a specific XDP address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Linux]
|
||||
///
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendmsg.2.html
|
||||
#[inline]
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn sendmsg_xdp(
|
||||
socket: impl AsFd,
|
||||
addr: &super::SocketAddrXdp,
|
||||
iov: &[IoSlice<'_>],
|
||||
control: &mut SendAncillaryBuffer<'_, '_, '_>,
|
||||
flags: SendFlags,
|
||||
) -> io::Result<usize> {
|
||||
backend::net::syscalls::sendmsg_xdp(socket.as_fd(), addr, iov, control, flags)
|
||||
}
|
||||
|
||||
/// `sendmsg(msghdr)`—Sends a message on a socket to a specific address.
|
||||
///
|
||||
/// # References
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
///
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/sendmsg.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendmsg.2.html
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendmsg&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/sendmsg.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/sendmsg.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendmsg§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/sendmsg
|
||||
#[inline]
|
||||
pub fn sendmsg_any(
|
||||
socket: impl AsFd,
|
||||
addr: Option<&SocketAddrAny>,
|
||||
iov: &[IoSlice<'_>],
|
||||
control: &mut SendAncillaryBuffer<'_, '_, '_>,
|
||||
flags: SendFlags,
|
||||
) -> io::Result<usize> {
|
||||
match addr {
|
||||
None => backend::net::syscalls::sendmsg(socket.as_fd(), iov, control, flags),
|
||||
Some(SocketAddrAny::V4(addr)) => {
|
||||
backend::net::syscalls::sendmsg_v4(socket.as_fd(), addr, iov, control, flags)
|
||||
}
|
||||
Some(SocketAddrAny::V6(addr)) => {
|
||||
backend::net::syscalls::sendmsg_v6(socket.as_fd(), addr, iov, control, flags)
|
||||
}
|
||||
#[cfg(unix)]
|
||||
Some(SocketAddrAny::Unix(addr)) => {
|
||||
backend::net::syscalls::sendmsg_unix(socket.as_fd(), addr, iov, control, flags)
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
Some(SocketAddrAny::Xdp(addr)) => {
|
||||
backend::net::syscalls::sendmsg_xdp(socket.as_fd(), addr, iov, control, flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `recvmsg(msghdr)`—Receives a message from a socket.
|
||||
///
|
||||
/// # References
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
///
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/recvmsg.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recvmsg.2.html
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=recvmsg&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/recvmsg.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/recvmsg.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=recvmsg§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/recvmsg
|
||||
#[inline]
|
||||
pub fn recvmsg(
|
||||
socket: impl AsFd,
|
||||
iov: &mut [IoSliceMut<'_>],
|
||||
control: &mut RecvAncillaryBuffer<'_>,
|
||||
flags: RecvFlags,
|
||||
) -> io::Result<RecvMsgReturn> {
|
||||
backend::net::syscalls::recvmsg(socket.as_fd(), iov, control, flags)
|
||||
}
|
||||
|
||||
/// The result of a successful [`recvmsg`] call.
|
||||
pub struct RecvMsgReturn {
|
||||
/// The number of bytes received.
|
||||
pub bytes: usize,
|
||||
|
||||
/// The flags received.
|
||||
pub flags: RecvFlags,
|
||||
|
||||
/// The address of the socket we received from, if any.
|
||||
pub address: Option<SocketAddrAny>,
|
||||
}
|
||||
|
||||
/// An iterator over data in an ancillary buffer.
|
||||
pub struct AncillaryIter<'data, T> {
|
||||
/// The data we're iterating over.
|
||||
data: &'data mut [u8],
|
||||
|
||||
/// The raw data we're removing.
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'data, T> AncillaryIter<'data, T> {
|
||||
/// Create a new iterator over data in an ancillary buffer.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The buffer must contain valid ancillary data.
|
||||
unsafe fn new(data: &'data mut [u8]) -> Self {
|
||||
assert_eq!(data.len() % size_of::<T>(), 0);
|
||||
|
||||
Self {
|
||||
data,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'data, T> Drop for AncillaryIter<'data, T> {
|
||||
fn drop(&mut self) {
|
||||
self.for_each(drop);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Iterator for AncillaryIter<'_, T> {
|
||||
type Item = T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// See if there is a next item.
|
||||
if self.data.len() < size_of::<T>() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Get the next item.
|
||||
let item = unsafe { self.data.as_ptr().cast::<T>().read_unaligned() };
|
||||
|
||||
// Move forward.
|
||||
let data = take(&mut self.data);
|
||||
self.data = &mut data[size_of::<T>()..];
|
||||
|
||||
Some(item)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = self.len();
|
||||
(len, Some(len))
|
||||
}
|
||||
|
||||
fn count(self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
|
||||
fn last(mut self) -> Option<Self::Item> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FusedIterator for AncillaryIter<'_, T> {}
|
||||
|
||||
impl<T> ExactSizeIterator for AncillaryIter<'_, T> {
|
||||
fn len(&self) -> usize {
|
||||
self.data.len() / size_of::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DoubleEndedIterator for AncillaryIter<'_, T> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
// See if there is a next item.
|
||||
if self.data.len() < size_of::<T>() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Get the next item.
|
||||
let item = unsafe {
|
||||
let ptr = self.data.as_ptr().add(self.data.len() - size_of::<T>());
|
||||
ptr.cast::<T>().read_unaligned()
|
||||
};
|
||||
|
||||
// Move forward.
|
||||
let len = self.data.len();
|
||||
let data = take(&mut self.data);
|
||||
self.data = &mut data[..len - size_of::<T>()];
|
||||
|
||||
Some(item)
|
||||
}
|
||||
}
|
||||
|
||||
mod messages {
|
||||
use crate::backend::c;
|
||||
use crate::backend::net::msghdr;
|
||||
use core::iter::FusedIterator;
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr::NonNull;
|
||||
|
||||
/// An iterator over the messages in an ancillary buffer.
|
||||
pub(super) struct Messages<'buf> {
|
||||
/// The message header we're using to iterate over the messages.
|
||||
msghdr: c::msghdr,
|
||||
|
||||
/// The current pointer to the next message header to return.
|
||||
///
|
||||
/// This has a lifetime of `'buf`.
|
||||
header: Option<NonNull<c::cmsghdr>>,
|
||||
|
||||
/// Capture the original lifetime of the buffer.
|
||||
_buffer: PhantomData<&'buf mut [u8]>,
|
||||
}
|
||||
|
||||
impl<'buf> Messages<'buf> {
|
||||
/// Create a new iterator over messages from a byte buffer.
|
||||
pub(super) fn new(buf: &'buf mut [u8]) -> Self {
|
||||
let msghdr = {
|
||||
let mut h = msghdr::zero_msghdr();
|
||||
h.msg_control = buf.as_mut_ptr().cast();
|
||||
h.msg_controllen = buf.len().try_into().expect("buffer too large for msghdr");
|
||||
h
|
||||
};
|
||||
|
||||
// Get the first header.
|
||||
let header = NonNull::new(unsafe { c::CMSG_FIRSTHDR(&msghdr) });
|
||||
|
||||
Self {
|
||||
msghdr,
|
||||
header,
|
||||
_buffer: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Messages<'a> {
|
||||
type Item = &'a mut c::cmsghdr;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// Get the current header.
|
||||
let header = self.header?;
|
||||
|
||||
// Get the next header.
|
||||
self.header = NonNull::new(unsafe { c::CMSG_NXTHDR(&self.msghdr, header.as_ptr()) });
|
||||
|
||||
// If the headers are equal, we're done.
|
||||
if Some(header) == self.header {
|
||||
self.header = None;
|
||||
}
|
||||
|
||||
// SAFETY: The lifetime of `header` is tied to this.
|
||||
Some(unsafe { &mut *header.as_ptr() })
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
if self.header.is_some() {
|
||||
// The remaining buffer *could* be filled with zero-length
|
||||
// messages.
|
||||
let max_size = unsafe { c::CMSG_LEN(0) } as usize;
|
||||
let remaining_count = self.msghdr.msg_controllen as usize / max_size;
|
||||
(1, Some(remaining_count))
|
||||
} else {
|
||||
(0, Some(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FusedIterator for Messages<'_> {}
|
||||
}
|
||||
769
third-party/vendor/rustix/src/net/socket.rs
vendored
Normal file
769
third-party/vendor/rustix/src/net/socket.rs
vendored
Normal file
|
|
@ -0,0 +1,769 @@
|
|||
use crate::fd::OwnedFd;
|
||||
use crate::net::{SocketAddr, SocketAddrAny, SocketAddrV4, SocketAddrV6};
|
||||
use crate::{backend, io};
|
||||
use backend::fd::{AsFd, BorrowedFd};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::net::xdp::SocketAddrXdp;
|
||||
pub use crate::net::{AddressFamily, Protocol, Shutdown, SocketFlags, SocketType};
|
||||
#[cfg(unix)]
|
||||
pub use backend::net::addr::SocketAddrUnix;
|
||||
|
||||
/// `socket(domain, type_, protocol)`—Creates a socket.
|
||||
///
|
||||
/// POSIX guarantees that `socket` will use the lowest unused file descriptor,
|
||||
/// however it is not safe in general to rely on this, as file descriptors may
|
||||
/// be unexpectedly allocated on other threads or in libraries.
|
||||
///
|
||||
/// To pass extra flags such as [`SocketFlags::CLOEXEC`] or
|
||||
/// [`SocketFlags::NONBLOCK`], use [`socket_with`].
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#socket
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/socket.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socket.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/socket.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/socket.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socket§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/socket
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Creating-a-Socket.html
|
||||
#[inline]
|
||||
pub fn socket(
|
||||
domain: AddressFamily,
|
||||
type_: SocketType,
|
||||
protocol: Option<Protocol>,
|
||||
) -> io::Result<OwnedFd> {
|
||||
backend::net::syscalls::socket(domain, type_, protocol)
|
||||
}
|
||||
|
||||
/// `socket_with(domain, type_ | flags, protocol)`—Creates a socket, with
|
||||
/// flags.
|
||||
///
|
||||
/// POSIX guarantees that `socket` will use the lowest unused file descriptor,
|
||||
/// however it is not safe in general to rely on this, as file descriptors may
|
||||
/// be unexpectedly allocated on other threads or in libraries.
|
||||
///
|
||||
/// `socket_with` is the same as [`socket`] but adds an additional flags
|
||||
/// operand.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#socket
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/socket.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socket.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/socket.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/socket.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socket§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/socket
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Creating-a-Socket.html
|
||||
#[doc(alias("socket"))]
|
||||
#[inline]
|
||||
pub fn socket_with(
|
||||
domain: AddressFamily,
|
||||
type_: SocketType,
|
||||
flags: SocketFlags,
|
||||
protocol: Option<Protocol>,
|
||||
) -> io::Result<OwnedFd> {
|
||||
backend::net::syscalls::socket_with(domain, type_, flags, protocol)
|
||||
}
|
||||
|
||||
/// `bind(sockfd, addr)`—Binds a socket to an IP address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/bind.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/bind.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/bind
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Setting-Address.html
|
||||
pub fn bind<Fd: AsFd>(sockfd: Fd, addr: &SocketAddr) -> io::Result<()> {
|
||||
_bind(sockfd.as_fd(), addr)
|
||||
}
|
||||
|
||||
fn _bind(sockfd: BorrowedFd<'_>, addr: &SocketAddr) -> io::Result<()> {
|
||||
match addr {
|
||||
SocketAddr::V4(v4) => backend::net::syscalls::bind_v4(sockfd, v4),
|
||||
SocketAddr::V6(v6) => backend::net::syscalls::bind_v6(sockfd, v6),
|
||||
}
|
||||
}
|
||||
|
||||
/// `bind(sockfd, addr)`—Binds a socket to an address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/bind.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/bind.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/bind
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Setting-Address.html
|
||||
#[doc(alias = "bind")]
|
||||
pub fn bind_any<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrAny) -> io::Result<()> {
|
||||
_bind_any(sockfd.as_fd(), addr)
|
||||
}
|
||||
|
||||
fn _bind_any(sockfd: BorrowedFd<'_>, addr: &SocketAddrAny) -> io::Result<()> {
|
||||
match addr {
|
||||
SocketAddrAny::V4(v4) => backend::net::syscalls::bind_v4(sockfd, v4),
|
||||
SocketAddrAny::V6(v6) => backend::net::syscalls::bind_v6(sockfd, v6),
|
||||
#[cfg(unix)]
|
||||
SocketAddrAny::Unix(unix) => backend::net::syscalls::bind_unix(sockfd, unix),
|
||||
#[cfg(target_os = "linux")]
|
||||
SocketAddrAny::Xdp(xdp) => backend::net::syscalls::bind_xdp(sockfd, xdp),
|
||||
}
|
||||
}
|
||||
|
||||
/// `bind(sockfd, addr, sizeof(struct sockaddr_in))`—Binds a socket to an
|
||||
/// IPv4 address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/bind.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/bind.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/bind
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Setting-Address.html
|
||||
#[inline]
|
||||
#[doc(alias = "bind")]
|
||||
pub fn bind_v4<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV4) -> io::Result<()> {
|
||||
backend::net::syscalls::bind_v4(sockfd.as_fd(), addr)
|
||||
}
|
||||
|
||||
/// `bind(sockfd, addr, sizeof(struct sockaddr_in6))`—Binds a socket to an
|
||||
/// IPv6 address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/bind.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/bind.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/bind
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Setting-Address.html
|
||||
#[inline]
|
||||
#[doc(alias = "bind")]
|
||||
pub fn bind_v6<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV6) -> io::Result<()> {
|
||||
backend::net::syscalls::bind_v6(sockfd.as_fd(), addr)
|
||||
}
|
||||
|
||||
/// `bind(sockfd, addr, sizeof(struct sockaddr_un))`—Binds a socket to a
|
||||
/// Unix-domain address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/bind.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/bind.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/bind
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Setting-Address.html
|
||||
#[cfg(unix)]
|
||||
#[inline]
|
||||
#[doc(alias = "bind")]
|
||||
pub fn bind_unix<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrUnix) -> io::Result<()> {
|
||||
backend::net::syscalls::bind_unix(sockfd.as_fd(), addr)
|
||||
}
|
||||
|
||||
/// `bind(sockfd, addr, sizeof(struct sockaddr_un))`—Binds a socket to a XDP address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Linux]
|
||||
///
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
|
||||
#[cfg(target_os = "linux")]
|
||||
#[inline]
|
||||
#[doc(alias = "bind")]
|
||||
pub fn bind_xdp<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrXdp) -> io::Result<()> {
|
||||
backend::net::syscalls::bind_xdp(sockfd.as_fd(), addr)
|
||||
}
|
||||
|
||||
/// `connect(sockfd, addr)`—Initiates a connection to an IP address.
|
||||
///
|
||||
/// On Windows, a non-blocking socket returns [`Errno::WOULDBLOCK`] if the
|
||||
/// connection cannot be completed immediately, rather than
|
||||
/// `Errno::INPROGRESS`.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/connect.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/connect.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/connect
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
|
||||
/// [`Errno::WOULDBLOCK`]: io::Errno::WOULDBLOCK
|
||||
pub fn connect<Fd: AsFd>(sockfd: Fd, addr: &SocketAddr) -> io::Result<()> {
|
||||
_connect(sockfd.as_fd(), addr)
|
||||
}
|
||||
|
||||
fn _connect(sockfd: BorrowedFd<'_>, addr: &SocketAddr) -> io::Result<()> {
|
||||
match addr {
|
||||
SocketAddr::V4(v4) => backend::net::syscalls::connect_v4(sockfd, v4),
|
||||
SocketAddr::V6(v6) => backend::net::syscalls::connect_v6(sockfd, v6),
|
||||
}
|
||||
}
|
||||
|
||||
/// `connect(sockfd, addr)`—Initiates a connection.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/connect.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/connect.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/connect
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
|
||||
#[doc(alias = "connect")]
|
||||
pub fn connect_any<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrAny) -> io::Result<()> {
|
||||
_connect_any(sockfd.as_fd(), addr)
|
||||
}
|
||||
|
||||
fn _connect_any(sockfd: BorrowedFd<'_>, addr: &SocketAddrAny) -> io::Result<()> {
|
||||
match addr {
|
||||
SocketAddrAny::V4(v4) => backend::net::syscalls::connect_v4(sockfd, v4),
|
||||
SocketAddrAny::V6(v6) => backend::net::syscalls::connect_v6(sockfd, v6),
|
||||
#[cfg(unix)]
|
||||
SocketAddrAny::Unix(unix) => backend::net::syscalls::connect_unix(sockfd, unix),
|
||||
#[cfg(target_os = "linux")]
|
||||
SocketAddrAny::Xdp(_) => Err(io::Errno::OPNOTSUPP),
|
||||
}
|
||||
}
|
||||
|
||||
/// `connect(sockfd, addr, sizeof(struct sockaddr_in))`—Initiates a
|
||||
/// connection to an IPv4 address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/connect.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/connect.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/connect
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
|
||||
#[inline]
|
||||
#[doc(alias = "connect")]
|
||||
pub fn connect_v4<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV4) -> io::Result<()> {
|
||||
backend::net::syscalls::connect_v4(sockfd.as_fd(), addr)
|
||||
}
|
||||
|
||||
/// `connect(sockfd, addr, sizeof(struct sockaddr_in6))`—Initiates a
|
||||
/// connection to an IPv6 address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/connect.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/connect.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/connect
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
|
||||
#[inline]
|
||||
#[doc(alias = "connect")]
|
||||
pub fn connect_v6<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV6) -> io::Result<()> {
|
||||
backend::net::syscalls::connect_v6(sockfd.as_fd(), addr)
|
||||
}
|
||||
|
||||
/// `connect(sockfd, addr, sizeof(struct sockaddr_un))`—Initiates a
|
||||
/// connection to a Unix-domain address.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/connect.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/connect.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/connect
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
|
||||
#[cfg(unix)]
|
||||
#[inline]
|
||||
#[doc(alias = "connect")]
|
||||
pub fn connect_unix<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrUnix) -> io::Result<()> {
|
||||
backend::net::syscalls::connect_unix(sockfd.as_fd(), addr)
|
||||
}
|
||||
|
||||
/// `connect(sockfd, {.sa_family = AF_UNSPEC}, sizeof(struct sockaddr))`
|
||||
/// — Dissolve the socket's association.
|
||||
///
|
||||
/// On UDP sockets, BSD platforms report [`Errno::AFNOSUPPORT`] or
|
||||
/// [`Errno::INVAL`] even if the disconnect was successful.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/connect.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/connect.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/connect
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
|
||||
/// [`Errno::AFNOSUPPORT`]: io::Errno::AFNOSUPPORT
|
||||
/// [`Errno::INVAL`]: io::Errno::INVAL
|
||||
#[inline]
|
||||
#[doc(alias = "connect")]
|
||||
pub fn connect_unspec<Fd: AsFd>(sockfd: Fd) -> io::Result<()> {
|
||||
backend::net::syscalls::connect_unspec(sockfd.as_fd())
|
||||
}
|
||||
|
||||
/// `listen(fd, backlog)`—Enables listening for incoming connections.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#listen
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/listen.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/listen.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=listen&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/listen.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/listen.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=listen§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/listen
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Listening.html
|
||||
#[inline]
|
||||
pub fn listen<Fd: AsFd>(sockfd: Fd, backlog: i32) -> io::Result<()> {
|
||||
backend::net::syscalls::listen(sockfd.as_fd(), backlog)
|
||||
}
|
||||
|
||||
/// `accept(fd, NULL, NULL)`—Accepts an incoming connection.
|
||||
///
|
||||
/// Use [`acceptfrom`] to retrieve the peer address.
|
||||
///
|
||||
/// POSIX guarantees that `accept` will use the lowest unused file descriptor,
|
||||
/// however it is not safe in general to rely on this, as file descriptors may
|
||||
/// be unexpectedly allocated on other threads or in libraries.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#acceptthank-you-for-calling-port-3490.
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/accept.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/accept.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/accept.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/accept.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/accept
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Accepting-Connections.html
|
||||
#[inline]
|
||||
pub fn accept<Fd: AsFd>(sockfd: Fd) -> io::Result<OwnedFd> {
|
||||
backend::net::syscalls::accept(sockfd.as_fd())
|
||||
}
|
||||
|
||||
/// `accept4(fd, NULL, NULL, flags)`—Accepts an incoming connection, with
|
||||
/// flags.
|
||||
///
|
||||
/// Use [`acceptfrom_with`] to retrieve the peer address.
|
||||
///
|
||||
/// Even though POSIX guarantees that this will use the lowest unused file
|
||||
/// descriptor, it is not safe in general to rely on this, as file descriptors
|
||||
/// may be unexpectedly allocated on other threads or in libraries.
|
||||
///
|
||||
/// `accept_with` is the same as [`accept`] but adds an additional flags
|
||||
/// operand.
|
||||
///
|
||||
/// # References
|
||||
/// - [Linux]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
///
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/accept4.2.html
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept4&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/accept4.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/accept4.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept4§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/accept4
|
||||
#[inline]
|
||||
#[doc(alias = "accept4")]
|
||||
pub fn accept_with<Fd: AsFd>(sockfd: Fd, flags: SocketFlags) -> io::Result<OwnedFd> {
|
||||
backend::net::syscalls::accept_with(sockfd.as_fd(), flags)
|
||||
}
|
||||
|
||||
/// `accept(fd, &addr, &len)`—Accepts an incoming connection and returns the
|
||||
/// peer address.
|
||||
///
|
||||
/// Use [`accept`] if the peer address isn't needed.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#acceptthank-you-for-calling-port-3490.
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/accept.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/accept.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/accept.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/accept.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/accept
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Accepting-Connections.html
|
||||
#[inline]
|
||||
#[doc(alias = "accept")]
|
||||
pub fn acceptfrom<Fd: AsFd>(sockfd: Fd) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> {
|
||||
backend::net::syscalls::acceptfrom(sockfd.as_fd())
|
||||
}
|
||||
|
||||
/// `accept4(fd, &addr, &len, flags)`—Accepts an incoming connection and
|
||||
/// returns the peer address, with flags.
|
||||
///
|
||||
/// Use [`accept_with`] if the peer address isn't needed.
|
||||
///
|
||||
/// `acceptfrom_with` is the same as [`acceptfrom`] but adds an additional
|
||||
/// flags operand.
|
||||
///
|
||||
/// # References
|
||||
/// - [Linux]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
///
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/accept4.2.html
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept4&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/accept4.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/accept4.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept4§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/accept4
|
||||
#[inline]
|
||||
#[doc(alias = "accept4")]
|
||||
pub fn acceptfrom_with<Fd: AsFd>(
|
||||
sockfd: Fd,
|
||||
flags: SocketFlags,
|
||||
) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> {
|
||||
backend::net::syscalls::acceptfrom_with(sockfd.as_fd(), flags)
|
||||
}
|
||||
|
||||
/// `shutdown(fd, how)`—Closes the read and/or write sides of a stream.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#close-and-shutdownget-outta-my-face
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/shutdown.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/shutdown.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-shutdown
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=shutdown&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/shutdown.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/shutdown.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=shutdown§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/shutdown
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Closing-a-Socket.html
|
||||
#[inline]
|
||||
pub fn shutdown<Fd: AsFd>(sockfd: Fd, how: Shutdown) -> io::Result<()> {
|
||||
backend::net::syscalls::shutdown(sockfd.as_fd(), how)
|
||||
}
|
||||
|
||||
/// `getsockname(fd, addr, len)`—Returns the address a socket is bound to.
|
||||
///
|
||||
/// # References
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/getsockname.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockname.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockname
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockname&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/getsockname.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/getsockname.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockname§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/getsockname
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Reading-Address.html
|
||||
#[inline]
|
||||
pub fn getsockname<Fd: AsFd>(sockfd: Fd) -> io::Result<SocketAddrAny> {
|
||||
backend::net::syscalls::getsockname(sockfd.as_fd())
|
||||
}
|
||||
|
||||
/// `getpeername(fd, addr, len)`—Returns the address a socket is connected
|
||||
/// to.
|
||||
///
|
||||
/// # References
|
||||
/// - [Beej's Guide to Network Programming]
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [Winsock]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#getpeernamewho-are-you
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/getpeername.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getpeername.2.html
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getpeername
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/getpeername.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/getpeername.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getpeername§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/getpeername
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Who-is-Connected.html
|
||||
#[inline]
|
||||
pub fn getpeername<Fd: AsFd>(sockfd: Fd) -> io::Result<Option<SocketAddrAny>> {
|
||||
backend::net::syscalls::getpeername(sockfd.as_fd())
|
||||
}
|
||||
122
third-party/vendor/rustix/src/net/socket_addr_any.rs
vendored
Normal file
122
third-party/vendor/rustix/src/net/socket_addr_any.rs
vendored
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
//! A socket address for any kind of socket.
|
||||
//!
|
||||
//! This is similar to [`std::net::SocketAddr`], but also supports Unix-domain
|
||||
//! socket addresses on Unix.
|
||||
//!
|
||||
//! # Safety
|
||||
//!
|
||||
//! The `read` and `write` functions allow decoding and encoding from and to
|
||||
//! OS-specific socket address representations in memory.
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::net::xdp::SocketAddrXdp;
|
||||
#[cfg(unix)]
|
||||
use crate::net::SocketAddrUnix;
|
||||
use crate::net::{AddressFamily, SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||
use crate::{backend, io};
|
||||
#[cfg(feature = "std")]
|
||||
use core::fmt;
|
||||
|
||||
pub use backend::net::addr::SocketAddrStorage;
|
||||
|
||||
/// `struct sockaddr_storage` as a Rust enum.
|
||||
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[doc(alias = "sockaddr")]
|
||||
#[non_exhaustive]
|
||||
pub enum SocketAddrAny {
|
||||
/// `struct sockaddr_in`
|
||||
V4(SocketAddrV4),
|
||||
/// `struct sockaddr_in6`
|
||||
V6(SocketAddrV6),
|
||||
/// `struct sockaddr_un`
|
||||
#[cfg(unix)]
|
||||
Unix(SocketAddrUnix),
|
||||
/// `struct sockaddr_xdp`
|
||||
#[cfg(target_os = "linux")]
|
||||
Xdp(SocketAddrXdp),
|
||||
}
|
||||
|
||||
impl From<SocketAddr> for SocketAddrAny {
|
||||
#[inline]
|
||||
fn from(from: SocketAddr) -> Self {
|
||||
match from {
|
||||
SocketAddr::V4(v4) => Self::V4(v4),
|
||||
SocketAddr::V6(v6) => Self::V6(v6),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SocketAddrV4> for SocketAddrAny {
|
||||
#[inline]
|
||||
fn from(from: SocketAddrV4) -> Self {
|
||||
Self::V4(from)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SocketAddrV6> for SocketAddrAny {
|
||||
#[inline]
|
||||
fn from(from: SocketAddrV6) -> Self {
|
||||
Self::V6(from)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl From<SocketAddrUnix> for SocketAddrAny {
|
||||
#[inline]
|
||||
fn from(from: SocketAddrUnix) -> Self {
|
||||
Self::Unix(from)
|
||||
}
|
||||
}
|
||||
|
||||
impl SocketAddrAny {
|
||||
/// Return the address family of this socket address.
|
||||
#[inline]
|
||||
pub const fn address_family(&self) -> AddressFamily {
|
||||
match self {
|
||||
Self::V4(_) => AddressFamily::INET,
|
||||
Self::V6(_) => AddressFamily::INET6,
|
||||
#[cfg(unix)]
|
||||
Self::Unix(_) => AddressFamily::UNIX,
|
||||
#[cfg(target_os = "linux")]
|
||||
Self::Xdp(_) => AddressFamily::XDP,
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes a platform-specific encoding of this socket address to
|
||||
/// the memory pointed to by `storage`, and returns the number of
|
||||
/// bytes used.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `storage` must point to valid memory for encoding the socket
|
||||
/// address.
|
||||
pub unsafe fn write(&self, storage: *mut SocketAddrStorage) -> usize {
|
||||
backend::net::write_sockaddr::write_sockaddr(self, storage)
|
||||
}
|
||||
|
||||
/// Reads a platform-specific encoding of a socket address from
|
||||
/// the memory pointed to by `storage`, which uses `len` bytes.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `storage` must point to valid memory for decoding a socket
|
||||
/// address.
|
||||
pub unsafe fn read(storage: *const SocketAddrStorage, len: usize) -> io::Result<Self> {
|
||||
backend::net::read_sockaddr::read_sockaddr(storage, len)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl fmt::Debug for SocketAddrAny {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::V4(v4) => v4.fmt(fmt),
|
||||
Self::V6(v6) => v6.fmt(fmt),
|
||||
#[cfg(unix)]
|
||||
Self::Unix(unix) => unix.fmt(fmt),
|
||||
#[cfg(target_os = "linux")]
|
||||
Self::Xdp(xdp) => xdp.fmt(fmt),
|
||||
}
|
||||
}
|
||||
}
|
||||
36
third-party/vendor/rustix/src/net/socketpair.rs
vendored
Normal file
36
third-party/vendor/rustix/src/net/socketpair.rs
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
use crate::fd::OwnedFd;
|
||||
use crate::net::{AddressFamily, Protocol, SocketFlags, SocketType};
|
||||
use crate::{backend, io};
|
||||
|
||||
/// `socketpair(domain, type_ | accept_flags, protocol)`—Create a pair of
|
||||
/// sockets that are connected to each other.
|
||||
///
|
||||
/// # References
|
||||
/// - [POSIX]
|
||||
/// - [Linux]
|
||||
/// - [Apple]
|
||||
/// - [FreeBSD]
|
||||
/// - [NetBSD]
|
||||
/// - [OpenBSD]
|
||||
/// - [DragonFly BSD]
|
||||
/// - [illumos]
|
||||
/// - [glibc]
|
||||
///
|
||||
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/socketpair.html
|
||||
/// [Linux]: https://man7.org/linux/man-pages/man2/socketpair.2.html
|
||||
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socketpair.2.html
|
||||
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socketpair&sektion=2
|
||||
/// [NetBSD]: https://man.netbsd.org/socketpair.2
|
||||
/// [OpenBSD]: https://man.openbsd.org/socketpair.2
|
||||
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socketpair§ion=2
|
||||
/// [illumos]: https://illumos.org/man/3SOCKET/socketpair
|
||||
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Socket-Pairs.html
|
||||
#[inline]
|
||||
pub fn socketpair(
|
||||
domain: AddressFamily,
|
||||
type_: SocketType,
|
||||
flags: SocketFlags,
|
||||
protocol: Option<Protocol>,
|
||||
) -> io::Result<(OwnedFd, OwnedFd)> {
|
||||
backend::net::syscalls::socketpair(domain, type_, flags, protocol)
|
||||
}
|
||||
1482
third-party/vendor/rustix/src/net/sockopt.rs
vendored
Normal file
1482
third-party/vendor/rustix/src/net/sockopt.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
1788
third-party/vendor/rustix/src/net/types.rs
vendored
Normal file
1788
third-party/vendor/rustix/src/net/types.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
49
third-party/vendor/rustix/src/net/wsa.rs
vendored
Normal file
49
third-party/vendor/rustix/src/net/wsa.rs
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
use crate::io;
|
||||
use core::mem::MaybeUninit;
|
||||
use windows_sys::Win32::Networking::WinSock::{WSACleanup, WSAGetLastError, WSAStartup, WSADATA};
|
||||
|
||||
/// `WSAStartup()`—Initialize process-wide Windows support for sockets.
|
||||
///
|
||||
/// On Windows, it's necessary to initialize the sockets subsystem before
|
||||
/// using sockets APIs. The function performs the necessary initialization.
|
||||
///
|
||||
/// # References
|
||||
/// - [Winsock]
|
||||
///
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastartup
|
||||
pub fn wsa_startup() -> io::Result<WSADATA> {
|
||||
// Request version 2.2, which has been the latest version since far older
|
||||
// versions of Windows than we support here. For more information about
|
||||
// the version, see [here].
|
||||
//
|
||||
// [here]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastartup#remarks
|
||||
let version = 0x202;
|
||||
let mut data = MaybeUninit::uninit();
|
||||
unsafe {
|
||||
let ret = WSAStartup(version, data.as_mut_ptr());
|
||||
if ret == 0 {
|
||||
Ok(data.assume_init())
|
||||
} else {
|
||||
Err(io::Errno::from_raw_os_error(WSAGetLastError()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `WSACleanup()`—Clean up process-wide Windows support for sockets.
|
||||
///
|
||||
/// In a program where `init` is called, if sockets are no longer necessary,
|
||||
/// this function releases associated resources.
|
||||
///
|
||||
/// # References
|
||||
/// - [Winsock]
|
||||
///
|
||||
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsacleanup
|
||||
pub fn wsa_cleanup() -> io::Result<()> {
|
||||
unsafe {
|
||||
if WSACleanup() == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(io::Errno::from_raw_os_error(WSAGetLastError()))
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue