diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
commit | 8dd16259287f58f9273002717ec4d27e97127719 (patch) | |
tree | 3863e62a53829a84037444beab3abd4ed9dfc7d0 /third_party/rust/nix/src/sys/socket/mod.rs | |
parent | Releasing progress-linux version 126.0.1-1~progress7.99u1. (diff) | |
download | firefox-8dd16259287f58f9273002717ec4d27e97127719.tar.xz firefox-8dd16259287f58f9273002717ec4d27e97127719.zip |
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/nix/src/sys/socket/mod.rs')
-rw-r--r-- | third_party/rust/nix/src/sys/socket/mod.rs | 943 |
1 files changed, 388 insertions, 555 deletions
diff --git a/third_party/rust/nix/src/sys/socket/mod.rs b/third_party/rust/nix/src/sys/socket/mod.rs index 78dd617c55..3d1651bd3f 100644 --- a/third_party/rust/nix/src/sys/socket/mod.rs +++ b/third_party/rust/nix/src/sys/socket/mod.rs @@ -1,7 +1,7 @@ //! Socket interface functions //! //! [Further reading](https://man7.org/linux/man-pages/man7/socket.7.html) -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(any(target_os = "freebsd", linux_android))] #[cfg(feature = "uio")] use crate::sys::time::TimeSpec; #[cfg(not(target_os = "redox"))] @@ -9,16 +9,16 @@ use crate::sys::time::TimeSpec; use crate::sys::time::TimeVal; use crate::{errno::Errno, Result}; use cfg_if::cfg_if; -use libc::{self, c_int, c_void, size_t, socklen_t}; +use libc::{self, c_int, size_t, socklen_t}; #[cfg(all(feature = "uio", not(target_os = "redox")))] use libc::{ - iovec, CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_NXTHDR, CMSG_SPACE, + c_void, iovec, CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_NXTHDR, CMSG_SPACE, }; #[cfg(not(target_os = "redox"))] use std::io::{IoSlice, IoSliceMut}; #[cfg(feature = "net")] use std::net; -use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, RawFd, OwnedFd}; +use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, OwnedFd, RawFd}; use std::{mem, ptr}; #[deny(missing_docs)] @@ -34,35 +34,25 @@ pub mod sockopt; pub use self::addr::{SockaddrLike, SockaddrStorage}; -#[cfg(any(target_os = "illumos", target_os = "solaris"))] +#[cfg(solarish)] pub use self::addr::{AddressFamily, UnixAddr}; -#[cfg(not(any(target_os = "illumos", target_os = "solaris")))] +#[cfg(not(solarish))] pub use self::addr::{AddressFamily, UnixAddr}; -#[cfg(not(any( - target_os = "illumos", - target_os = "solaris", - target_os = "haiku", - target_os = "redox", -)))] +#[cfg(not(any(solarish, target_os = "haiku", target_os = "hurd", target_os = "redox")))] #[cfg(feature = "net")] pub use self::addr::{LinkAddr, SockaddrIn, SockaddrIn6}; -#[cfg(any( - target_os = "illumos", - target_os = "solaris", - target_os = "haiku", - target_os = "redox", -))] +#[cfg(any(solarish, target_os = "haiku", target_os = "hurd", target_os = "redox"))] #[cfg(feature = "net")] pub use self::addr::{SockaddrIn, SockaddrIn6}; -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_android)] pub use crate::sys::socket::addr::alg::AlgAddr; -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_android)] pub use crate::sys::socket::addr::netlink::NetlinkAddr; -#[cfg(any(target_os = "ios", target_os = "macos"))] +#[cfg(apple_targets)] #[cfg(feature = "ioctl")] pub use crate::sys::socket::addr::sys_control::SysControlAddr; -#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))] +#[cfg(any(linux_android, apple_targets))] pub use crate::sys::socket::addr::vsock::VsockAddr; #[cfg(all(feature = "uio", not(target_os = "redox")))] @@ -132,121 +122,108 @@ pub enum SockProtocol { Udp = libc::IPPROTO_UDP, /// Raw sockets ([raw(7)](https://man7.org/linux/man-pages/man7/raw.7.html)) Raw = libc::IPPROTO_RAW, - /// Allows applications and other KEXTs to be notified when certain kernel events occur - /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html)) - #[cfg(any(target_os = "ios", target_os = "macos"))] - #[cfg_attr(docsrs, doc(cfg(all())))] - KextEvent = libc::SYSPROTO_EVENT, /// Allows applications to configure and control a KEXT /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html)) - #[cfg(any(target_os = "ios", target_os = "macos"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(apple_targets)] KextControl = libc::SYSPROTO_CONTROL, /// Receives routing and link updates and may be used to modify the routing tables (both IPv4 and IPv6), IP addresses, link // parameters, neighbor setups, queueing disciplines, traffic classes and packet classifiers /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkRoute = libc::NETLINK_ROUTE, /// Reserved for user-mode socket protocols /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkUserSock = libc::NETLINK_USERSOCK, /// Query information about sockets of various protocol families from the kernel /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkSockDiag = libc::NETLINK_SOCK_DIAG, /// Netfilter/iptables ULOG. /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkNFLOG = libc::NETLINK_NFLOG, /// SELinux event notifications. /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkSELinux = libc::NETLINK_SELINUX, /// Open-iSCSI /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkISCSI = libc::NETLINK_ISCSI, /// Auditing /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkAudit = libc::NETLINK_AUDIT, /// Access to FIB lookup from user space /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkFIBLookup = libc::NETLINK_FIB_LOOKUP, /// Netfilter subsystem /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkNetFilter = libc::NETLINK_NETFILTER, /// SCSI Transports /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkSCSITransport = libc::NETLINK_SCSITRANSPORT, /// Infiniband RDMA /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkRDMA = libc::NETLINK_RDMA, /// Transport IPv6 packets from netfilter to user space. Used by ip6_queue kernel module. /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkIPv6Firewall = libc::NETLINK_IP6_FW, /// DECnet routing messages /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkDECNetRoutingMessage = libc::NETLINK_DNRTMSG, /// Kernel messages to user space /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkKObjectUEvent = libc::NETLINK_KOBJECT_UEVENT, /// Generic netlink family for simplified netlink usage. /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkGeneric = libc::NETLINK_GENERIC, /// Netlink interface to request information about ciphers registered with the kernel crypto API as well as allow /// configuration of the kernel crypto API. /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] NetlinkCrypto = libc::NETLINK_CRYPTO, /// Non-DIX type protocol number defined for the Ethernet IEEE 802.3 interface that allows packets of all protocols /// defined in the interface to be received. /// ([ref](https://man7.org/linux/man-pages/man7/packet.7.html)) // The protocol number is fed into the socket syscall in network byte order. - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] EthAll = (libc::ETH_P_ALL as u16).to_be() as i32, + /// ICMP protocol ([icmp(7)](https://man7.org/linux/man-pages/man7/icmp.7.html)) + Icmp = libc::IPPROTO_ICMP, + /// ICMPv6 protocol (ICMP over IPv6) + IcmpV6 = libc::IPPROTO_ICMPV6, +} + +impl SockProtocol { /// The Controller Area Network raw socket protocol /// ([ref](https://docs.kernel.org/networking/can.html#how-to-use-socketcan)) #[cfg(target_os = "linux")] - #[cfg_attr(docsrs, doc(cfg(all())))] - CanRaw = libc::CAN_RAW, -} + #[allow(non_upper_case_globals)] + pub const CanRaw: SockProtocol = SockProtocol::Icmp; // Matches libc::CAN_RAW -impl SockProtocol { /// The Controller Area Network broadcast manager protocol /// ([ref](https://docs.kernel.org/networking/can.html#how-to-use-socketcan)) #[cfg(target_os = "linux")] - #[cfg_attr(docsrs, doc(cfg(all())))] #[allow(non_upper_case_globals)] pub const CanBcm: SockProtocol = SockProtocol::NetlinkUserSock; // Matches libc::CAN_BCM + + /// Allows applications and other KEXTs to be notified when certain kernel events occur + /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html)) + #[cfg(apple_targets)] + #[allow(non_upper_case_globals)] + pub const KextEvent: SockProtocol = SockProtocol::Icmp; // Matches libc::SYSPROTO_EVENT } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_android)] libc_bitflags! { /// Configuration flags for `SO_TIMESTAMPING` interface /// @@ -276,33 +253,23 @@ libc_bitflags! { /// Additional socket options pub struct SockFlag: c_int { /// Set non-blocking mode on the new socket - #[cfg(any(target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(any(linux_android, + freebsdlike, + netbsdlike, + solarish))] SOCK_NONBLOCK; /// Set close-on-exec on the new descriptor - #[cfg(any(target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(any(linux_android, + freebsdlike, + netbsdlike, + solarish))] SOCK_CLOEXEC; /// Return `EPIPE` instead of raising `SIGPIPE` #[cfg(target_os = "netbsd")] - #[cfg_attr(docsrs, doc(cfg(all())))] SOCK_NOSIGPIPE; /// For domains `AF_INET(6)`, only allow `connect(2)`, `sendto(2)`, or `sendmsg(2)` /// to the DNS port (typically 53) #[cfg(target_os = "openbsd")] - #[cfg_attr(docsrs, doc(cfg(all())))] SOCK_DNS; } } @@ -333,7 +300,6 @@ libc_bitflags! { /// the calling process and as well as other processes that hold /// file descriptors referring to the same open file description. #[cfg(not(target_os = "aix"))] - #[cfg_attr(docsrs, doc(cfg(all())))] MSG_DONTWAIT; /// Receive flags: Control Data was discarded (buffer too small) MSG_CTRUNC; @@ -352,8 +318,7 @@ libc_bitflags! { /// This flag specifies that queued errors should be received from /// the socket error queue. (For more details, see /// [recvfrom(2)](https://linux.die.net/man/2/recvfrom)) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] MSG_ERRQUEUE; /// Set the `close-on-exec` flag for the file descriptor received via a UNIX domain /// file descriptor using the `SCM_RIGHTS` operation (described in @@ -362,44 +327,48 @@ libc_bitflags! { /// [open(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html). /// /// Only used in [`recvmsg`](fn.recvmsg.html) function. - #[cfg(any(target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(any(linux_android, freebsdlike, netbsdlike))] MSG_CMSG_CLOEXEC; /// Requests not to send `SIGPIPE` errors when the other end breaks the connection. /// (For more details, see [send(2)](https://linux.die.net/man/2/send)). - #[cfg(any(target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", + #[cfg(any(linux_android, + freebsdlike, + solarish, + netbsdlike, target_os = "fuchsia", - target_os = "haiku", - target_os = "illumos", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "solaris"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + target_os = "haiku"))] MSG_NOSIGNAL; /// Turns on [`MSG_DONTWAIT`] after the first message has been received (only for /// `recvmmsg()`). - #[cfg(any(target_os = "android", + #[cfg(any(linux_android, + netbsdlike, target_os = "fuchsia", - target_os = "linux", - target_os = "netbsd", - target_os = "freebsd", - target_os = "openbsd", - target_os = "solaris"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + target_os = "freebsd"))] MSG_WAITFORONE; } } +#[cfg(target_os = "freebsd")] +libc_enum! { + /// A selector for which clock to use when generating packet timestamps. + /// Used when setting [`TsClock`](crate::sys::socket::sockopt::TsClock) on a socket. + /// (For more details, see [setsockopt(2)](https://man.freebsd.org/cgi/man.cgi?setsockopt)). + #[repr(i32)] + #[non_exhaustive] + pub enum SocketTimestamp { + /// Microsecond resolution, realtime. This is the default. + SO_TS_REALTIME_MICRO, + /// Sub-nanosecond resolution, realtime. + SO_TS_BINTIME, + /// Nanosecond resolution, realtime. + SO_TS_REALTIME, + /// Nanosecond resolution, monotonic. + SO_TS_MONOTONIC, + } +} + cfg_if! { - if #[cfg(any(target_os = "android", target_os = "linux"))] { + if #[cfg(linux_android)] { /// Unix credentials of the sending process. /// /// This struct is used with the `SO_PEERCRED` ancillary message @@ -454,7 +423,7 @@ cfg_if! { uc.0 } } - } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] { + } else if #[cfg(freebsdlike)] { /// Unix credentials of the sending process. /// /// This struct is used with the `SCM_CREDS` ancillary message for UNIX sockets. @@ -487,7 +456,7 @@ cfg_if! { pub fn groups(&self) -> &[libc::gid_t] { unsafe { std::slice::from_raw_parts( - self.0.cmcred_groups.as_ptr() as *const libc::gid_t, + self.0.cmcred_groups.as_ptr(), self.0.cmcred_ngroups as _ ) } @@ -503,12 +472,7 @@ cfg_if! { } cfg_if! { - if #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "macos", - target_os = "ios" - ))] { + if #[cfg(any(freebsdlike, apple_targets))] { /// Return type of [`LocalPeerCred`](crate::sys::socket::sockopt::LocalPeerCred) #[repr(transparent)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -603,8 +567,6 @@ feature! { /// let _ = cmsg_space!(RawFd, TimeVal); /// # } /// ``` -// Unfortunately, CMSG_SPACE isn't a const_fn, or else we could return a -// stack-allocated array. #[macro_export] macro_rules! cmsg_space { ( $( $x:ty ),* ) => { @@ -617,7 +579,7 @@ macro_rules! cmsg_space { #[inline] #[doc(hidden)] -pub fn cmsg_space<T>() -> usize { +pub const fn cmsg_space<T>() -> usize { // SAFETY: CMSG_SPACE is always safe unsafe { libc::CMSG_SPACE(mem::size_of::<T>() as libc::c_uint) as usize } } @@ -677,7 +639,7 @@ impl<'a> Iterator for CmsgIterator<'a> { } /// A type-safe wrapper around a single control message, as used with -/// [`recvmsg`](#fn.recvmsg). +/// [`recvmsg`]. /// /// [Further reading](https://man7.org/linux/man-pages/man3/cmsg.3.html) // Nix version 0.13.0 and earlier used ControlMessage for both recvmsg and @@ -692,12 +654,10 @@ pub enum ControlMessageOwned { /// Received version of [`ControlMessage::ScmRights`] ScmRights(Vec<RawFd>), /// Received version of [`ControlMessage::ScmCredentials`] - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] ScmCredentials(UnixCredentials), /// Received version of [`ControlMessage::ScmCreds`] - #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(freebsdlike)] ScmCreds(UnixCredentials), /// A message of type `SCM_TIMESTAMP`, containing the time the /// packet was received by the kernel. @@ -760,62 +720,44 @@ pub enum ControlMessageOwned { /// A set of nanosecond resolution timestamps /// /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ScmTimestampsns(Timestamps), /// Nanoseconds resolution timestamp /// /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] ScmTimestampns(TimeSpec), - #[cfg(any( - target_os = "android", - target_os = "ios", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - ))] + /// Realtime clock timestamp + /// + /// [Further reading](https://man.freebsd.org/cgi/man.cgi?setsockopt) + #[cfg(target_os = "freebsd")] + ScmRealtime(TimeSpec), + /// Monotonic clock timestamp + /// + /// [Further reading](https://man.freebsd.org/cgi/man.cgi?setsockopt) + #[cfg(target_os = "freebsd")] + ScmMonotonic(TimeSpec), + #[cfg(any(linux_android, apple_targets, target_os = "netbsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4PacketInfo(libc::in_pktinfo), - #[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "linux", - target_os = "macos", - target_os = "openbsd", - target_os = "netbsd", - ))] + #[cfg(any(linux_android, bsd))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv6PacketInfo(libc::in6_pktinfo), - #[cfg(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] + #[cfg(bsd)] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4RecvIf(libc::sockaddr_dl), - #[cfg(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] + #[cfg(bsd)] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4RecvDstAddr(libc::in_addr), - #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4OrigDstAddr(libc::sockaddr_in), - #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv6OrigDstAddr(libc::sockaddr_in6), @@ -841,28 +783,31 @@ pub enum ControlMessageOwned { /// /// `RxqOvfl` socket option should be enabled on a socket /// to allow receiving the drop counter. - #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(any(linux_android, target_os = "fuchsia"))] RxqOvfl(u32), /// Socket error queue control messages read with the `MSG_ERRQUEUE` flag. - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4RecvErr(libc::sock_extended_err, Option<sockaddr_in>), /// Socket error queue control messages read with the `MSG_ERRQUEUE` flag. - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv6RecvErr(libc::sock_extended_err, Option<sockaddr_in6>), + /// `SOL_TLS` messages of type `TLS_GET_RECORD_TYPE` + #[cfg(any(target_os = "linux"))] + TlsGetRecordType(TlsGetRecordType), + /// Catch-all variant for unimplemented cmsg types. #[doc(hidden)] Unknown(UnknownCmsg), } /// For representing packet timestamps via `SO_TIMESTAMPING` interface -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_android)] #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct Timestamps { /// software based timestamp, usually one containing data @@ -873,6 +818,33 @@ pub struct Timestamps { pub hw_raw: TimeSpec, } +/// These constants correspond to TLS 1.2 message types, as defined in +/// RFC 5246, Appendix A.1 +#[cfg(any(target_os = "linux"))] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[repr(u8)] +#[non_exhaustive] +pub enum TlsGetRecordType { + ChangeCipherSpec , + Alert, + Handshake, + ApplicationData, + Unknown(u8), +} + +#[cfg(any(target_os = "linux"))] +impl From<u8> for TlsGetRecordType { + fn from(x: u8) -> Self { + match x { + 20 => TlsGetRecordType::ChangeCipherSpec, + 21 => TlsGetRecordType::Alert, + 22 => TlsGetRecordType::Handshake, + 23 => TlsGetRecordType::ApplicationData, + _ => TlsGetRecordType::Unknown(x), + } + } +} + impl ControlMessageOwned { /// Decodes a `ControlMessageOwned` from raw bytes. /// @@ -885,7 +857,7 @@ impl ControlMessageOwned { #[allow(clippy::cast_ptr_alignment)] unsafe fn decode_from(header: &cmsghdr) -> ControlMessageOwned { - let p = CMSG_DATA(header); + let p = unsafe { CMSG_DATA(header) }; // The cast is not unnecessary on all platforms. #[allow(clippy::unnecessary_cast)] let len = header as *const _ as usize + header.cmsg_len as usize @@ -895,158 +867,151 @@ impl ControlMessageOwned { let n = len / mem::size_of::<RawFd>(); let mut fds = Vec::with_capacity(n); for i in 0..n { - let fdp = (p as *const RawFd).add(i); - fds.push(ptr::read_unaligned(fdp)); + unsafe { + let fdp = (p as *const RawFd).add(i); + fds.push(ptr::read_unaligned(fdp)); + } } ControlMessageOwned::ScmRights(fds) }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] (libc::SOL_SOCKET, libc::SCM_CREDENTIALS) => { - let cred: libc::ucred = ptr::read_unaligned(p as *const _); + let cred: libc::ucred = unsafe { ptr::read_unaligned(p as *const _) }; ControlMessageOwned::ScmCredentials(cred.into()) } - #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg(freebsdlike)] (libc::SOL_SOCKET, libc::SCM_CREDS) => { - let cred: libc::cmsgcred = ptr::read_unaligned(p as *const _); + let cred: libc::cmsgcred = unsafe { ptr::read_unaligned(p as *const _) }; ControlMessageOwned::ScmCreds(cred.into()) } #[cfg(not(any(target_os = "aix", target_os = "haiku")))] (libc::SOL_SOCKET, libc::SCM_TIMESTAMP) => { - let tv: libc::timeval = ptr::read_unaligned(p as *const _); + let tv: libc::timeval = unsafe { ptr::read_unaligned(p as *const _) }; ControlMessageOwned::ScmTimestamp(TimeVal::from(tv)) }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] (libc::SOL_SOCKET, libc::SCM_TIMESTAMPNS) => { - let ts: libc::timespec = ptr::read_unaligned(p as *const _); + let ts: libc::timespec = unsafe { ptr::read_unaligned(p as *const _) }; ControlMessageOwned::ScmTimestampns(TimeSpec::from(ts)) } - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(target_os = "freebsd")] + (libc::SOL_SOCKET, libc::SCM_REALTIME) => { + let ts: libc::timespec = unsafe { ptr::read_unaligned(p as *const _) }; + ControlMessageOwned::ScmRealtime(TimeSpec::from(ts)) + } + #[cfg(target_os = "freebsd")] + (libc::SOL_SOCKET, libc::SCM_MONOTONIC) => { + let ts: libc::timespec = unsafe { ptr::read_unaligned(p as *const _) }; + ControlMessageOwned::ScmMonotonic(TimeSpec::from(ts)) + } + #[cfg(linux_android)] (libc::SOL_SOCKET, libc::SCM_TIMESTAMPING) => { let tp = p as *const libc::timespec; - let ts: libc::timespec = ptr::read_unaligned(tp); + let ts: libc::timespec = unsafe { ptr::read_unaligned(tp) }; let system = TimeSpec::from(ts); - let ts: libc::timespec = ptr::read_unaligned(tp.add(1)); + let ts: libc::timespec = unsafe { ptr::read_unaligned(tp.add(1)) }; let hw_trans = TimeSpec::from(ts); - let ts: libc::timespec = ptr::read_unaligned(tp.add(2)); + let ts: libc::timespec = unsafe { ptr::read_unaligned(tp.add(2)) }; let hw_raw = TimeSpec::from(ts); let timestamping = Timestamps { system, hw_trans, hw_raw }; ControlMessageOwned::ScmTimestampsns(timestamping) } - #[cfg(any( - target_os = "android", - target_os = "freebsd", - target_os = "ios", - target_os = "linux", - target_os = "macos" - ))] + #[cfg(any(target_os = "freebsd", linux_android, apple_targets))] #[cfg(feature = "net")] (libc::IPPROTO_IPV6, libc::IPV6_PKTINFO) => { - let info = ptr::read_unaligned(p as *const libc::in6_pktinfo); + let info = unsafe { ptr::read_unaligned(p as *const libc::in6_pktinfo) }; ControlMessageOwned::Ipv6PacketInfo(info) } - #[cfg(any( - target_os = "android", - target_os = "ios", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - ))] + #[cfg(any(linux_android, apple_targets, target_os = "netbsd"))] #[cfg(feature = "net")] (libc::IPPROTO_IP, libc::IP_PKTINFO) => { - let info = ptr::read_unaligned(p as *const libc::in_pktinfo); + let info = unsafe { ptr::read_unaligned(p as *const libc::in_pktinfo) }; ControlMessageOwned::Ipv4PacketInfo(info) } - #[cfg(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] + #[cfg(bsd)] #[cfg(feature = "net")] (libc::IPPROTO_IP, libc::IP_RECVIF) => { - let dl = ptr::read_unaligned(p as *const libc::sockaddr_dl); + let dl = unsafe { ptr::read_unaligned(p as *const libc::sockaddr_dl) }; ControlMessageOwned::Ipv4RecvIf(dl) }, - #[cfg(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] + #[cfg(bsd)] #[cfg(feature = "net")] (libc::IPPROTO_IP, libc::IP_RECVDSTADDR) => { - let dl = ptr::read_unaligned(p as *const libc::in_addr); + let dl = unsafe { ptr::read_unaligned(p as *const libc::in_addr) }; ControlMessageOwned::Ipv4RecvDstAddr(dl) }, - #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] (libc::IPPROTO_IP, libc::IP_ORIGDSTADDR) => { - let dl = ptr::read_unaligned(p as *const libc::sockaddr_in); + let dl = unsafe { ptr::read_unaligned(p as *const libc::sockaddr_in) }; ControlMessageOwned::Ipv4OrigDstAddr(dl) }, #[cfg(target_os = "linux")] #[cfg(feature = "net")] (libc::SOL_UDP, libc::UDP_GRO) => { - let gso_size: u16 = ptr::read_unaligned(p as *const _); + let gso_size: u16 = unsafe { ptr::read_unaligned(p as *const _) }; ControlMessageOwned::UdpGroSegments(gso_size) }, - #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any(linux_android, target_os = "fuchsia"))] (libc::SOL_SOCKET, libc::SO_RXQ_OVFL) => { - let drop_counter = ptr::read_unaligned(p as *const u32); + let drop_counter = unsafe { ptr::read_unaligned(p as *const u32) }; ControlMessageOwned::RxqOvfl(drop_counter) }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] #[cfg(feature = "net")] (libc::IPPROTO_IP, libc::IP_RECVERR) => { - let (err, addr) = Self::recv_err_helper::<sockaddr_in>(p, len); + let (err, addr) = unsafe { Self::recv_err_helper::<sockaddr_in>(p, len) }; ControlMessageOwned::Ipv4RecvErr(err, addr) }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] #[cfg(feature = "net")] (libc::IPPROTO_IPV6, libc::IPV6_RECVERR) => { - let (err, addr) = Self::recv_err_helper::<sockaddr_in6>(p, len); + let (err, addr) = unsafe { Self::recv_err_helper::<sockaddr_in6>(p, len) }; ControlMessageOwned::Ipv6RecvErr(err, addr) }, - #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] (libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR) => { - let dl = ptr::read_unaligned(p as *const libc::sockaddr_in6); + let dl = unsafe { ptr::read_unaligned(p as *const libc::sockaddr_in6) }; ControlMessageOwned::Ipv6OrigDstAddr(dl) }, + #[cfg(any(target_os = "linux"))] + (libc::SOL_TLS, libc::TLS_GET_RECORD_TYPE) => { + let content_type = unsafe { ptr::read_unaligned(p as *const u8) }; + ControlMessageOwned::TlsGetRecordType(content_type.into()) + }, (_, _) => { - let sl = std::slice::from_raw_parts(p, len); + let sl = unsafe { std::slice::from_raw_parts(p, len) }; let ucmsg = UnknownCmsg(*header, Vec::<u8>::from(sl)); ControlMessageOwned::Unknown(ucmsg) } } } - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] #[cfg(feature = "net")] #[allow(clippy::cast_ptr_alignment)] // False positive unsafe fn recv_err_helper<T>(p: *mut libc::c_uchar, len: usize) -> (libc::sock_extended_err, Option<T>) { let ee = p as *const libc::sock_extended_err; - let err = ptr::read_unaligned(ee); + let err = unsafe { ptr::read_unaligned(ee) }; // For errors originating on the network, SO_EE_OFFENDER(ee) points inside the p[..len] // CMSG_DATA buffer. For local errors, there is no address included in the control // message, and SO_EE_OFFENDER(ee) points beyond the end of the buffer. So, we need to // validate that the address object is in-bounds before we attempt to copy it. - let addrp = libc::SO_EE_OFFENDER(ee) as *const T; + let addrp = unsafe { libc::SO_EE_OFFENDER(ee) as *const T }; - if addrp.offset(1) as usize - (p as usize) > len { + if unsafe { addrp.offset(1) } as usize - (p as usize) > len { (err, None) } else { - (err, Some(ptr::read_unaligned(addrp))) + (err, Some(unsafe { ptr::read_unaligned(addrp) })) } } } -/// A type-safe zero-copy wrapper around a single control message, as used wih -/// [`sendmsg`](#fn.sendmsg). More types may be added to this enum; do not -/// exhaustively pattern-match it. +/// A type-safe zero-copy wrapper around a single control message, as used with +/// [`sendmsg`]. More types may be added to this enum; do not exhaustively +/// pattern-match it. /// /// [Further reading](https://man7.org/linux/man-pages/man3/cmsg.3.html) #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -1074,8 +1039,7 @@ pub enum ControlMessage<'a> { /// /// For further information, please refer to the /// [`unix(7)`](https://man7.org/linux/man-pages/man7/unix.7.html) man page. - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] ScmCredentials(&'a UnixCredentials), /// A message of type `SCM_CREDS`, containing the pid, uid, euid, gid and groups of /// a process connected to the socket. @@ -1089,41 +1053,28 @@ pub enum ControlMessage<'a> { /// /// For further information, please refer to the /// [`unix(4)`](https://www.freebsd.org/cgi/man.cgi?query=unix) man page. - #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(freebsdlike)] ScmCreds, /// Set IV for `AF_ALG` crypto API. /// /// For further information, please refer to the /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html) - #[cfg(any( - target_os = "android", - target_os = "linux", - ))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] AlgSetIv(&'a [u8]), /// Set crypto operation for `AF_ALG` crypto API. It may be one of /// `ALG_OP_ENCRYPT` or `ALG_OP_DECRYPT` /// /// For further information, please refer to the /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html) - #[cfg(any( - target_os = "android", - target_os = "linux", - ))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] AlgSetOp(&'a libc::c_int), /// Set the length of associated authentication data (AAD) (applicable only to AEAD algorithms) /// for `AF_ALG` crypto API. /// /// For further information, please refer to the /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html) - #[cfg(any( - target_os = "android", - target_os = "linux", - ))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(linux_android)] AlgSetAeadAssoclen(&'a u32), /// UDP GSO makes it possible for applications to generate network packets @@ -1139,51 +1090,52 @@ pub enum ControlMessage<'a> { #[cfg_attr(docsrs, doc(cfg(feature = "net")))] UdpGsoSegments(&'a u16), - /// Configure the sending addressing and interface for v4 + /// Configure the sending addressing and interface for v4. /// /// For further information, please refer to the /// [`ip(7)`](https://man7.org/linux/man-pages/man7/ip.7.html) man page. - #[cfg(any(target_os = "linux", - target_os = "macos", - target_os = "netbsd", - target_os = "android", - target_os = "ios",))] + #[cfg(any(linux_android, target_os = "netbsd", apple_targets))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4PacketInfo(&'a libc::in_pktinfo), - /// Configure the sending addressing and interface for v6 + /// Configure the sending addressing and interface for v6. /// /// For further information, please refer to the /// [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html) man page. - #[cfg(any(target_os = "linux", - target_os = "macos", + #[cfg(any(linux_android, target_os = "netbsd", target_os = "freebsd", - target_os = "android", - target_os = "ios",))] + apple_targets))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv6PacketInfo(&'a libc::in6_pktinfo), /// Configure the IPv4 source address with `IP_SENDSRCADDR`. - #[cfg(any( - target_os = "netbsd", - target_os = "freebsd", - target_os = "openbsd", - target_os = "dragonfly", - ))] + #[cfg(any(freebsdlike, netbsdlike))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4SendSrcAddr(&'a libc::in_addr), + /// Configure the hop limit for v6 multicast traffic. + /// + /// Set the IPv6 hop limit for this message. The argument is an integer + /// between 0 and 255. A value of -1 will set the hop limit to the route + /// default if possible on the interface. Without this cmsg, packets sent + /// with sendmsg have a hop limit of 1 and will not leave the local network. + /// For further information, please refer to the + /// [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html) man page. + #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv6HopLimit(&'a libc::c_int), + /// SO_RXQ_OVFL indicates that an unsigned 32 bit value /// ancilliary msg (cmsg) should be attached to recieved /// skbs indicating the number of packets dropped by the /// socket between the last recieved packet and this /// received packet. - #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all())))] + #[cfg(any(linux_android, target_os = "fuchsia"))] RxqOvfl(&'a u32), /// Configure the transmission time of packets. @@ -1227,18 +1179,18 @@ impl<'a> ControlMessage<'a> { ControlMessage::ScmRights(fds) => { fds as *const _ as *const u8 }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::ScmCredentials(creds) => { &creds.0 as *const libc::ucred as *const u8 } - #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg(freebsdlike)] ControlMessage::ScmCreds => { // The kernel overwrites the data, we just zero it // to make sure it's not uninitialized memory unsafe { ptr::write_bytes(cmsg_data, 0, self.len()) }; return } - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::AlgSetIv(iv) => { #[allow(deprecated)] // https://github.com/rust-lang/libc/issues/1501 let af_alg_iv = libc::af_alg_iv { @@ -1263,11 +1215,11 @@ impl<'a> ControlMessage<'a> { return }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::AlgSetOp(op) => { op as *const _ as *const u8 }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::AlgSetAeadAssoclen(len) => { len as *const _ as *const u8 }, @@ -1276,21 +1228,20 @@ impl<'a> ControlMessage<'a> { ControlMessage::UdpGsoSegments(gso_size) => { gso_size as *const _ as *const u8 }, - #[cfg(any(target_os = "linux", target_os = "macos", - target_os = "netbsd", target_os = "android", - target_os = "ios",))] + #[cfg(any(linux_android, target_os = "netbsd", apple_targets))] #[cfg(feature = "net")] ControlMessage::Ipv4PacketInfo(info) => info as *const _ as *const u8, - #[cfg(any(target_os = "linux", target_os = "macos", - target_os = "netbsd", target_os = "freebsd", - target_os = "android", target_os = "ios",))] + #[cfg(any(linux_android, target_os = "netbsd", + target_os = "freebsd", apple_targets))] #[cfg(feature = "net")] ControlMessage::Ipv6PacketInfo(info) => info as *const _ as *const u8, - #[cfg(any(target_os = "netbsd", target_os = "freebsd", - target_os = "openbsd", target_os = "dragonfly"))] + #[cfg(any(freebsdlike, netbsdlike))] #[cfg(feature = "net")] ControlMessage::Ipv4SendSrcAddr(addr) => addr as *const _ as *const u8, - #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(feature = "net")] + ControlMessage::Ipv6HopLimit(limit) => limit as *const _ as *const u8, + #[cfg(any(linux_android, target_os = "fuchsia"))] ControlMessage::RxqOvfl(drop_count) => { drop_count as *const _ as *const u8 }, @@ -1314,23 +1265,23 @@ impl<'a> ControlMessage<'a> { ControlMessage::ScmRights(fds) => { mem::size_of_val(fds) }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::ScmCredentials(creds) => { mem::size_of_val(creds) } - #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg(freebsdlike)] ControlMessage::ScmCreds => { mem::size_of::<libc::cmsgcred>() } - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::AlgSetIv(iv) => { mem::size_of::<&[u8]>() + iv.len() }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::AlgSetOp(op) => { mem::size_of_val(op) }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::AlgSetAeadAssoclen(len) => { mem::size_of_val(len) }, @@ -1339,21 +1290,22 @@ impl<'a> ControlMessage<'a> { ControlMessage::UdpGsoSegments(gso_size) => { mem::size_of_val(gso_size) }, - #[cfg(any(target_os = "linux", target_os = "macos", - target_os = "netbsd", target_os = "android", - target_os = "ios",))] + #[cfg(any(linux_android, target_os = "netbsd", apple_targets))] #[cfg(feature = "net")] ControlMessage::Ipv4PacketInfo(info) => mem::size_of_val(info), - #[cfg(any(target_os = "linux", target_os = "macos", - target_os = "netbsd", target_os = "freebsd", - target_os = "android", target_os = "ios",))] + #[cfg(any(linux_android, target_os = "netbsd", + target_os = "freebsd", apple_targets))] #[cfg(feature = "net")] ControlMessage::Ipv6PacketInfo(info) => mem::size_of_val(info), - #[cfg(any(target_os = "netbsd", target_os = "freebsd", - target_os = "openbsd", target_os = "dragonfly"))] + #[cfg(any(freebsdlike, netbsdlike))] #[cfg(feature = "net")] ControlMessage::Ipv4SendSrcAddr(addr) => mem::size_of_val(addr), - #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(feature = "net")] + ControlMessage::Ipv6HopLimit(limit) => { + mem::size_of_val(limit) + }, + #[cfg(any(linux_android, target_os = "fuchsia"))] ControlMessage::RxqOvfl(drop_count) => { mem::size_of_val(drop_count) }, @@ -1368,31 +1320,30 @@ impl<'a> ControlMessage<'a> { fn cmsg_level(&self) -> libc::c_int { match *self { ControlMessage::ScmRights(_) => libc::SOL_SOCKET, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::ScmCredentials(_) => libc::SOL_SOCKET, - #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg(freebsdlike)] ControlMessage::ScmCreds => libc::SOL_SOCKET, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::AlgSetIv(_) | ControlMessage::AlgSetOp(_) | ControlMessage::AlgSetAeadAssoclen(_) => libc::SOL_ALG, #[cfg(target_os = "linux")] #[cfg(feature = "net")] ControlMessage::UdpGsoSegments(_) => libc::SOL_UDP, - #[cfg(any(target_os = "linux", target_os = "macos", - target_os = "netbsd", target_os = "android", - target_os = "ios",))] + #[cfg(any(linux_android, target_os = "netbsd", apple_targets))] #[cfg(feature = "net")] ControlMessage::Ipv4PacketInfo(_) => libc::IPPROTO_IP, - #[cfg(any(target_os = "linux", target_os = "macos", - target_os = "netbsd", target_os = "freebsd", - target_os = "android", target_os = "ios",))] + #[cfg(any(linux_android, target_os = "netbsd", + target_os = "freebsd", apple_targets))] #[cfg(feature = "net")] ControlMessage::Ipv6PacketInfo(_) => libc::IPPROTO_IPV6, - #[cfg(any(target_os = "netbsd", target_os = "freebsd", - target_os = "openbsd", target_os = "dragonfly"))] + #[cfg(any(freebsdlike, netbsdlike))] #[cfg(feature = "net")] ControlMessage::Ipv4SendSrcAddr(_) => libc::IPPROTO_IP, - #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(feature = "net")] + ControlMessage::Ipv6HopLimit(_) => libc::IPPROTO_IPV6, + #[cfg(any(linux_android, target_os = "fuchsia"))] ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET, #[cfg(target_os = "linux")] ControlMessage::TxTime(_) => libc::SOL_SOCKET, @@ -1403,19 +1354,19 @@ impl<'a> ControlMessage<'a> { fn cmsg_type(&self) -> libc::c_int { match *self { ControlMessage::ScmRights(_) => libc::SCM_RIGHTS, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::ScmCredentials(_) => libc::SCM_CREDENTIALS, - #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg(freebsdlike)] ControlMessage::ScmCreds => libc::SCM_CREDS, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::AlgSetIv(_) => { libc::ALG_SET_IV }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::AlgSetOp(_) => { libc::ALG_SET_OP }, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_android)] ControlMessage::AlgSetAeadAssoclen(_) => { libc::ALG_SET_AEAD_ASSOCLEN }, @@ -1424,21 +1375,20 @@ impl<'a> ControlMessage<'a> { ControlMessage::UdpGsoSegments(_) => { libc::UDP_SEGMENT }, - #[cfg(any(target_os = "linux", target_os = "macos", - target_os = "netbsd", target_os = "android", - target_os = "ios",))] + #[cfg(any(linux_android, target_os = "netbsd", apple_targets))] #[cfg(feature = "net")] ControlMessage::Ipv4PacketInfo(_) => libc::IP_PKTINFO, - #[cfg(any(target_os = "linux", target_os = "macos", - target_os = "netbsd", target_os = "freebsd", - target_os = "android", target_os = "ios",))] + #[cfg(any(linux_android, target_os = "netbsd", + target_os = "freebsd", apple_targets))] #[cfg(feature = "net")] ControlMessage::Ipv6PacketInfo(_) => libc::IPV6_PKTINFO, - #[cfg(any(target_os = "netbsd", target_os = "freebsd", - target_os = "openbsd", target_os = "dragonfly"))] + #[cfg(any(freebsdlike, netbsdlike))] #[cfg(feature = "net")] ControlMessage::Ipv4SendSrcAddr(_) => libc::IP_SENDSRCADDR, - #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(feature = "net")] + ControlMessage::Ipv6HopLimit(_) => libc::IPV6_HOPLIMIT, + #[cfg(any(linux_android, target_os = "fuchsia"))] ControlMessage::RxqOvfl(_) => { libc::SO_RXQ_OVFL }, @@ -1452,10 +1402,12 @@ impl<'a> ControlMessage<'a> { // Unsafe: cmsg must point to a valid cmsghdr with enough space to // encode self. unsafe fn encode_into(&self, cmsg: *mut cmsghdr) { - (*cmsg).cmsg_level = self.cmsg_level(); - (*cmsg).cmsg_type = self.cmsg_type(); - (*cmsg).cmsg_len = self.cmsg_len(); - self.copy_to_cmsg_data(CMSG_DATA(cmsg)); + unsafe { + (*cmsg).cmsg_level = self.cmsg_level(); + (*cmsg).cmsg_type = self.cmsg_type(); + (*cmsg).cmsg_len = self.cmsg_len(); + self.copy_to_cmsg_data( CMSG_DATA(cmsg) ); + } } } @@ -1479,7 +1431,7 @@ impl<'a> ControlMessage<'a> { /// let (r, w) = pipe().unwrap(); /// /// let iov = [IoSlice::new(b"hello")]; -/// let fds = [r]; +/// let fds = [r.as_raw_fd()]; /// let cmsg = ControlMessage::ScmRights(&fds); /// sendmsg::<()>(fd1.as_raw_fd(), &iov, &[cmsg], MsgFlags::empty(), None).unwrap(); /// ``` @@ -1496,7 +1448,7 @@ impl<'a> ControlMessage<'a> { /// let (r, w) = pipe().unwrap(); /// /// let iov = [IoSlice::new(b"hello")]; -/// let fds = [r]; +/// let fds = [r.as_raw_fd()]; /// let cmsg = ControlMessage::ScmRights(&fds); /// sendmsg(fd.as_raw_fd(), &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap(); /// ``` @@ -1535,12 +1487,7 @@ pub fn sendmsg<S>(fd: RawFd, iov: &[IoSlice<'_>], cmsgs: &[ControlMessage], /// /// # References /// [`sendmsg`](fn.sendmsg.html) -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "freebsd", - target_os = "netbsd", -))] +#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))] pub fn sendmmsg<'a, XS, AS, C, I, S>( fd: RawFd, data: &'a mut MultiHeaders<S>, @@ -1556,7 +1503,7 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>( AS: AsRef<[Option<S>]>, I: AsRef<[IoSlice<'a>]> + 'a, C: AsRef<[ControlMessage<'a>]> + 'a, - S: SockaddrLike + 'a + S: SockaddrLike + 'a, { let mut count = 0; @@ -1564,11 +1511,11 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>( for (i, ((slice, addr), mmsghdr)) in slices.into_iter().zip(addrs.as_ref()).zip(data.items.iter_mut() ).enumerate() { let p = &mut mmsghdr.msg_hdr; - p.msg_iov = slice.as_ref().as_ptr() as *mut libc::iovec; + p.msg_iov = slice.as_ref().as_ptr().cast_mut().cast(); p.msg_iovlen = slice.as_ref().len() as _; p.msg_namelen = addr.as_ref().map_or(0, S::len); - p.msg_name = addr.as_ref().map_or(ptr::null(), S::as_ptr) as _; + p.msg_name = addr.as_ref().map_or(ptr::null(), S::as_ptr).cast_mut().cast(); // Encode each cmsg. This must happen after initializing the header because // CMSG_NEXT_HDR and friends read the msg_control and msg_controllen fields. @@ -1583,9 +1530,16 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>( pmhdr = unsafe { CMSG_NXTHDR(p, pmhdr) }; } - count = i+1; + // Doing an unchecked addition is alright here, as the only way to obtain an instance of `MultiHeaders` + // is through the `preallocate` function, which takes an `usize` as an argument to define its size, + // which also provides an upper bound for the size of this zipped iterator. Thus, `i < usize::MAX` or in + // other words: `count` doesn't overflow + count = i + 1; } + // SAFETY: all pointers are guaranteed to be valid for the scope of this function. `count` does represent the + // maximum number of messages that can be sent safely (i.e. `count` is the minimum of the sizes of `slices`, + // `data.items` and `addrs`) let sent = Errno::result(unsafe { libc::sendmmsg( fd, @@ -1604,12 +1558,7 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>( } -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "freebsd", - target_os = "netbsd", -))] +#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))] #[derive(Debug)] /// Preallocated structures needed for [`recvmmsg`] and [`sendmmsg`] functions pub struct MultiHeaders<S> { @@ -1622,12 +1571,7 @@ pub struct MultiHeaders<S> { msg_controllen: usize, } -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "freebsd", - target_os = "netbsd", -))] +#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))] impl<S> MultiHeaders<S> { /// Preallocate structure used by [`recvmmsg`] and [`sendmmsg`] takes number of headers to preallocate /// @@ -1652,7 +1596,7 @@ impl<S> MultiHeaders<S> { .enumerate() .map(|(ix, address)| { let (ptr, cap) = match &mut cmsg_buffers { - Some(v) => ((&mut v[ix * msg_controllen] as *mut u8), msg_controllen), + Some(v) => (&mut v[ix * msg_controllen] as *mut u8, msg_controllen), None => (std::ptr::null_mut(), 0), }; let msg_hdr = unsafe { pack_mhdr_to_receive(std::ptr::null_mut(), 0, ptr, cap, address.as_mut_ptr()) }; @@ -1697,12 +1641,7 @@ impl<S> MultiHeaders<S> { // always produce the desired results - see https://github.com/nix-rust/nix/pull/1744 for more // details -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "freebsd", - target_os = "netbsd", -))] +#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))] pub fn recvmmsg<'a, XS, S, I>( fd: RawFd, data: &'a mut MultiHeaders<S>, @@ -1711,14 +1650,19 @@ pub fn recvmmsg<'a, XS, S, I>( mut timeout: Option<crate::sys::time::TimeSpec>, ) -> crate::Result<MultiResults<'a, S>> where - XS: IntoIterator<Item = &'a I>, - I: AsRef<[IoSliceMut<'a>]> + 'a, + XS: IntoIterator<Item = &'a mut I>, + I: AsMut<[IoSliceMut<'a>]> + 'a, { let mut count = 0; for (i, (slice, mmsghdr)) in slices.into_iter().zip(data.items.iter_mut()).enumerate() { let p = &mut mmsghdr.msg_hdr; - p.msg_iov = slice.as_ref().as_ptr() as *mut libc::iovec; - p.msg_iovlen = slice.as_ref().len() as _; + p.msg_iov = slice.as_mut().as_mut_ptr().cast(); + p.msg_iovlen = slice.as_mut().len() as _; + + // Doing an unchecked addition is alright here, as the only way to obtain an instance of `MultiHeaders` + // is through the `preallocate` function, which takes an `usize` as an argument to define its size, + // which also provides an upper bound for the size of this zipped iterator. Thus, `i < usize::MAX` or in + // other words: `count` doesn't overflow count = i + 1; } @@ -1726,6 +1670,8 @@ where .as_mut() .map_or_else(std::ptr::null_mut, |t| t as *mut _ as *mut libc::timespec); + // SAFETY: all pointers are guaranteed to be valid for the scope of this function. `count` does represent the + // maximum number of messages that can be received safely (i.e. `count` is the minimum of the sizes of `slices` and `data.items`) let received = Errno::result(unsafe { libc::recvmmsg( fd, @@ -1743,16 +1689,9 @@ where }) } -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "freebsd", - target_os = "netbsd", -))] -#[derive(Debug)] /// Iterator over results of [`recvmmsg`]/[`sendmmsg`] -/// -/// +#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))] +#[derive(Debug)] pub struct MultiResults<'a, S> { // preallocated structures rmm: &'a MultiHeaders<S>, @@ -1760,12 +1699,7 @@ pub struct MultiResults<'a, S> { received: usize, } -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "freebsd", - target_os = "netbsd", -))] +#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))] impl<'a, S> Iterator for MultiResults<'a, S> where S: Copy + SockaddrLike, @@ -1838,108 +1772,6 @@ impl<'a> Iterator for IoSliceIterator<'a> { } } -// test contains both recvmmsg and timestaping which is linux only -// there are existing tests for recvmmsg only in tests/ -#[cfg(target_os = "linux")] -#[cfg(test)] -mod test { - use crate::sys::socket::{AddressFamily, ControlMessageOwned}; - use crate::*; - use std::str::FromStr; - use std::os::unix::io::AsRawFd; - - #[cfg_attr(qemu, ignore)] - #[test] - fn test_recvmm2() -> crate::Result<()> { - use crate::sys::socket::{ - sendmsg, setsockopt, socket, sockopt::Timestamping, MsgFlags, SockFlag, SockType, - SockaddrIn, TimestampingFlag, - }; - use std::io::{IoSlice, IoSliceMut}; - - let sock_addr = SockaddrIn::from_str("127.0.0.1:6790").unwrap(); - - let ssock = socket( - AddressFamily::Inet, - SockType::Datagram, - SockFlag::empty(), - None, - )?; - - let rsock = socket( - AddressFamily::Inet, - SockType::Datagram, - SockFlag::SOCK_NONBLOCK, - None, - )?; - - crate::sys::socket::bind(rsock.as_raw_fd(), &sock_addr)?; - - setsockopt(&rsock, Timestamping, &TimestampingFlag::all())?; - - let sbuf = (0..400).map(|i| i as u8).collect::<Vec<_>>(); - - let mut recv_buf = vec![0; 1024]; - - let mut recv_iovs = Vec::new(); - let mut pkt_iovs = Vec::new(); - - for (ix, chunk) in recv_buf.chunks_mut(256).enumerate() { - pkt_iovs.push(IoSliceMut::new(chunk)); - if ix % 2 == 1 { - recv_iovs.push(pkt_iovs); - pkt_iovs = Vec::new(); - } - } - drop(pkt_iovs); - - let flags = MsgFlags::empty(); - let iov1 = [IoSlice::new(&sbuf)]; - - let cmsg = cmsg_space!(crate::sys::socket::Timestamps); - sendmsg(ssock.as_raw_fd(), &iov1, &[], flags, Some(&sock_addr)).unwrap(); - - let mut data = super::MultiHeaders::<()>::preallocate(recv_iovs.len(), Some(cmsg)); - - let t = sys::time::TimeSpec::from_duration(std::time::Duration::from_secs(10)); - - let recv = super::recvmmsg(rsock.as_raw_fd(), &mut data, recv_iovs.iter(), flags, Some(t))?; - - for rmsg in recv { - #[cfg(not(any(qemu, target_arch = "aarch64")))] - let mut saw_time = false; - let mut recvd = 0; - for cmsg in rmsg.cmsgs() { - if let ControlMessageOwned::ScmTimestampsns(timestamps) = cmsg { - let ts = timestamps.system; - - let sys_time = - crate::time::clock_gettime(crate::time::ClockId::CLOCK_REALTIME)?; - let diff = if ts > sys_time { - ts - sys_time - } else { - sys_time - ts - }; - assert!(std::time::Duration::from(diff).as_secs() < 60); - #[cfg(not(any(qemu, target_arch = "aarch64")))] - { - saw_time = true; - } - } - } - - #[cfg(not(any(qemu, target_arch = "aarch64")))] - assert!(saw_time); - - for iov in rmsg.iovs() { - recvd += iov.len(); - } - assert_eq!(recvd, 400); - } - - Ok(()) - } -} unsafe fn read_mhdr<'a, 'i, S>( mhdr: msghdr, r: isize, @@ -1951,19 +1783,23 @@ unsafe fn read_mhdr<'a, 'i, S>( // The cast is not unnecessary on all platforms. #[allow(clippy::unnecessary_cast)] let cmsghdr = { - if mhdr.msg_controllen > 0 { + let ptr = if mhdr.msg_controllen > 0 { debug_assert!(!mhdr.msg_control.is_null()); debug_assert!(msg_controllen >= mhdr.msg_controllen as usize); - CMSG_FIRSTHDR(&mhdr as *const msghdr) + unsafe { CMSG_FIRSTHDR(&mhdr as *const msghdr) } } else { ptr::null() - }.as_ref() + }; + + unsafe { + ptr.as_ref() + } }; // Ignore errors if this socket address has statically-known length // // This is to ensure that unix socket addresses have their length set appropriately. - let _ = address.set_length(mhdr.msg_namelen as usize); + let _ = unsafe { address.set_length(mhdr.msg_namelen as usize) }; RecvMsg { bytes: r as usize, @@ -2000,14 +1836,16 @@ unsafe fn pack_mhdr_to_receive<S>( // initialize it. let mut mhdr = mem::MaybeUninit::<msghdr>::zeroed(); let p = mhdr.as_mut_ptr(); - (*p).msg_name = address as *mut c_void; - (*p).msg_namelen = S::size(); - (*p).msg_iov = iov_buffer as *mut iovec; - (*p).msg_iovlen = iov_buffer_len as _; - (*p).msg_control = cmsg_buffer as *mut c_void; - (*p).msg_controllen = cmsg_capacity as _; - (*p).msg_flags = 0; - mhdr.assume_init() + unsafe { + (*p).msg_name = address as *mut c_void; + (*p).msg_namelen = S::size(); + (*p).msg_iov = iov_buffer as *mut iovec; + (*p).msg_iovlen = iov_buffer_len as _; + (*p).msg_control = cmsg_buffer as *mut c_void; + (*p).msg_controllen = cmsg_capacity as _; + (*p).msg_flags = 0; + mhdr.assume_init() + } } fn pack_mhdr_to_send<'a, I, C, S>( @@ -2025,7 +1863,7 @@ fn pack_mhdr_to_send<'a, I, C, S>( // The message header must be initialized before the individual cmsgs. let cmsg_ptr = if capacity > 0 { - cmsg_buffer.as_mut_ptr() as *mut c_void + cmsg_buffer.as_mut_ptr().cast() } else { ptr::null_mut() }; @@ -2035,11 +1873,11 @@ fn pack_mhdr_to_send<'a, I, C, S>( // initialize it. let mut mhdr = mem::MaybeUninit::<msghdr>::zeroed(); let p = mhdr.as_mut_ptr(); - (*p).msg_name = addr.map(S::as_ptr).unwrap_or(ptr::null()) as *mut _; + (*p).msg_name = addr.map(S::as_ptr).unwrap_or(ptr::null()).cast_mut().cast(); (*p).msg_namelen = addr.map(S::len).unwrap_or(0); // transmute iov into a mutable pointer. sendmsg doesn't really mutate // the buffer, but the standard says that it takes a mutable pointer - (*p).msg_iov = iov.as_ref().as_ptr() as *mut _; + (*p).msg_iov = iov.as_ref().as_ptr().cast_mut().cast(); (*p).msg_iovlen = iov.as_ref().len() as _; (*p).msg_control = cmsg_ptr; (*p).msg_controllen = capacity as _; @@ -2166,17 +2004,51 @@ pub fn socketpair<T: Into<Option<SockProtocol>>>( Errno::result(res)?; // Safe because socketpair returned success. - unsafe { - Ok((OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1]))) + unsafe { Ok((OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1]))) } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Backlog(i32); + +impl Backlog { + /// Sets the listen queue size to system `SOMAXCONN` value + pub const MAXCONN: Self = Self(libc::SOMAXCONN); + /// Sets the listen queue size to -1 for system supporting it + #[cfg(any(target_os = "linux", target_os = "freebsd"))] + pub const MAXALLOWABLE: Self = Self(-1); + + /// Create a `Backlog`, an `EINVAL` will be returned if `val` is invalid. + pub fn new<I: Into<i32>>(val: I) -> Result<Self> { + cfg_if! { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { + const MIN: i32 = -1; + } else { + const MIN: i32 = 0; + } + } + + let val = val.into(); + + if !(MIN..Self::MAXCONN.0).contains(&val) { + return Err(Errno::EINVAL); + } + + Ok(Self(val)) + } +} + +impl From<Backlog> for i32 { + fn from(backlog: Backlog) -> Self { + backlog.0 } } /// Listen for connections on a socket /// /// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html) -pub fn listen<F: AsFd>(sock: &F, backlog: usize) -> Result<()> { +pub fn listen<F: AsFd>(sock: &F, backlog: Backlog) -> Result<()> { let fd = sock.as_fd().as_raw_fd(); - let res = unsafe { libc::listen(fd, backlog as c_int) }; + let res = unsafe { libc::listen(fd, backlog.into()) }; Errno::result(res).map(drop) } @@ -2211,14 +2083,12 @@ pub fn accept(sockfd: RawFd) -> Result<RawFd> { target_arch = "x86_64" ) ), - target_os = "dragonfly", + freebsdlike, + netbsdlike, target_os = "emscripten", - target_os = "freebsd", target_os = "fuchsia", - target_os = "illumos", + solarish, target_os = "linux", - target_os = "netbsd", - target_os = "openbsd" ))] pub fn accept4(sockfd: RawFd, flags: SockFlag) -> Result<RawFd> { let res = unsafe { @@ -2245,7 +2115,7 @@ pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: MsgFlags) -> Result<usize> { unsafe { let ret = libc::recv( sockfd, - buf.as_mut_ptr() as *mut c_void, + buf.as_mut_ptr().cast(), buf.len() as size_t, flags.bits(), ); @@ -2269,20 +2139,14 @@ pub fn recvfrom<T: SockaddrLike>( let ret = Errno::result(libc::recvfrom( sockfd, - buf.as_mut_ptr() as *mut c_void, + buf.as_mut_ptr().cast(), buf.len() as size_t, 0, - addr.as_mut_ptr() as *mut sockaddr, + addr.as_mut_ptr().cast(), &mut len as *mut socklen_t, ))? as usize; - Ok(( - ret, - T::from_raw( - addr.assume_init().as_ptr(), - Some(len), - ), - )) + Ok((ret, T::from_raw(addr.assume_init().as_ptr(), Some(len)))) } } @@ -2298,7 +2162,7 @@ pub fn sendto( let ret = unsafe { libc::sendto( fd, - buf.as_ptr() as *const c_void, + buf.as_ptr().cast(), buf.len() as size_t, flags.bits(), addr.as_ptr(), @@ -2314,12 +2178,7 @@ pub fn sendto( /// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html) pub fn send(fd: RawFd, buf: &[u8], flags: MsgFlags) -> Result<usize> { let ret = unsafe { - libc::send( - fd, - buf.as_ptr() as *const c_void, - buf.len() as size_t, - flags.bits(), - ) + libc::send(fd, buf.as_ptr().cast(), buf.len() as size_t, flags.bits()) }; Errno::result(ret).map(|r| r as usize) @@ -2386,8 +2245,7 @@ pub fn getpeername<T: SockaddrLike>(fd: RawFd) -> Result<T> { let mut addr = mem::MaybeUninit::<T>::uninit(); let mut len = T::size(); - let ret = - libc::getpeername(fd, addr.as_mut_ptr() as *mut sockaddr, &mut len); + let ret = libc::getpeername(fd, addr.as_mut_ptr().cast(), &mut len); Errno::result(ret)?; @@ -2403,8 +2261,7 @@ pub fn getsockname<T: SockaddrLike>(fd: RawFd) -> Result<T> { let mut addr = mem::MaybeUninit::<T>::uninit(); let mut len = T::size(); - let ret = - libc::getsockname(fd, addr.as_mut_ptr() as *mut sockaddr, &mut len); + let ret = libc::getsockname(fd, addr.as_mut_ptr().cast(), &mut len); Errno::result(ret)?; @@ -2439,27 +2296,3 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> { } } -#[cfg(test)] -mod tests { - #[cfg(not(target_os = "redox"))] - #[test] - fn can_use_cmsg_space() { - let _ = cmsg_space!(u8); - } - - #[cfg(not(any( - target_os = "redox", - target_os = "linux", - target_os = "android" - )))] - #[test] - fn can_open_routing_socket() { - let _ = super::socket( - super::AddressFamily::Route, - super::SockType::Raw, - super::SockFlag::empty(), - None, - ) - .expect("Failed to open routing socket"); - } -} |