summaryrefslogtreecommitdiffstats
path: root/third_party/rust/nix/src/sys/socket
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/nix/src/sys/socket')
-rw-r--r--third_party/rust/nix/src/sys/socket/addr.rs873
-rw-r--r--third_party/rust/nix/src/sys/socket/mod.rs943
-rw-r--r--third_party/rust/nix/src/sys/socket/sockopt.rs454
3 files changed, 959 insertions, 1311 deletions
diff --git a/third_party/rust/nix/src/sys/socket/addr.rs b/third_party/rust/nix/src/sys/socket/addr.rs
index 1783531d49..f6800aa5d0 100644
--- a/third_party/rust/nix/src/sys/socket/addr.rs
+++ b/third_party/rust/nix/src/sys/socket/addr.rs
@@ -1,31 +1,22 @@
#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd",
+ bsd,
+ linux_android,
+ solarish,
target_os = "haiku",
target_os = "fuchsia",
target_os = "aix",
))]
#[cfg(feature = "net")]
pub use self::datalink::LinkAddr;
-#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
+#[cfg(any(linux_android, apple_targets))]
pub use self::vsock::VsockAddr;
use super::sa_family_t;
use crate::errno::Errno;
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
use crate::sys::socket::addr::alg::AlgAddr;
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
use crate::sys::socket::addr::netlink::NetlinkAddr;
-#[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
-))]
+#[cfg(all(feature = "ioctl", apple_targets))]
use crate::sys::socket::addr::sys_control::SysControlAddr;
use crate::{NixPath, Result};
use cfg_if::cfg_if;
@@ -33,6 +24,7 @@ use memoffset::offset_of;
use std::convert::TryInto;
use std::ffi::OsStr;
use std::hash::{Hash, Hasher};
+use std::net::{Ipv4Addr, Ipv6Addr};
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use std::{fmt, mem, net, ptr, slice};
@@ -41,7 +33,7 @@ use std::{fmt, mem, net, ptr, slice};
#[cfg(feature = "net")]
pub(crate) const fn ipv4addr_to_libc(addr: net::Ipv4Addr) -> libc::in_addr {
libc::in_addr {
- s_addr: u32::from_ne_bytes(addr.octets())
+ s_addr: u32::from_ne_bytes(addr.octets()),
}
}
@@ -49,7 +41,7 @@ pub(crate) const fn ipv4addr_to_libc(addr: net::Ipv4Addr) -> libc::in_addr {
#[cfg(feature = "net")]
pub(crate) const fn ipv6addr_to_libc(addr: &net::Ipv6Addr) -> libc::in6_addr {
libc::in6_addr {
- s6_addr: addr.octets()
+ s6_addr: addr.octets(),
}
}
@@ -71,346 +63,188 @@ pub enum AddressFamily {
/// IPv6 Internet protocols (see [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html))
Inet6 = libc::AF_INET6,
/// Kernel user interface device (see [`netlink(7)`](https://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)]
Netlink = libc::AF_NETLINK,
/// Kernel interface for interacting with the routing table
- #[cfg(not(any(
- target_os = "redox",
- target_os = "linux",
- target_os = "android"
- )))]
+ #[cfg(not(any(linux_android, target_os = "redox")))]
Route = libc::PF_ROUTE,
/// Low level packet interface (see [`packet(7)`](https://man7.org/linux/man-pages/man7/packet.7.html))
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "illumos",
- target_os = "fuchsia",
- target_os = "solaris"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, solarish, target_os = "fuchsia"))]
Packet = libc::AF_PACKET,
/// KEXT Controls and Notifications
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
System = libc::AF_SYSTEM,
/// Amateur radio AX.25 protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Ax25 = libc::AF_AX25,
/// IPX - Novell protocols
#[cfg(not(any(target_os = "aix", target_os = "redox")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Ipx = libc::AF_IPX,
/// AppleTalk
#[cfg(not(target_os = "redox"))]
AppleTalk = libc::AF_APPLETALK,
/// AX.25 packet layer protocol.
/// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetRom = libc::AF_NETROM,
/// Can't be used for creating sockets; mostly used for bridge
/// links in
/// [rtnetlink(7)](https://man7.org/linux/man-pages/man7/rtnetlink.7.html)
/// protocol commands.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Bridge = libc::AF_BRIDGE,
/// Access to raw ATM PVCs
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
AtmPvc = libc::AF_ATMPVC,
/// ITU-T X.25 / ISO-8208 protocol (see [`x25(7)`](https://man7.org/linux/man-pages/man7/x25.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
X25 = libc::AF_X25,
/// RATS (Radio Amateur Telecommunications Society) Open
/// Systems environment (ROSE) AX.25 packet layer protocol.
/// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Rose = libc::AF_ROSE,
/// DECet protocol sockets.
#[cfg(not(any(target_os = "haiku", target_os = "redox")))]
Decnet = libc::AF_DECnet,
/// Reserved for "802.2LLC project"; never used.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
NetBeui = libc::AF_NETBEUI,
/// This was a short-lived (between Linux 2.1.30 and
/// 2.1.99pre2) protocol family for firewall upcalls.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Security = libc::AF_SECURITY,
/// Key management protocol.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Key = libc::AF_KEY,
#[allow(missing_docs)] // Not documented anywhere that I can find
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Ash = libc::AF_ASH,
/// Acorn Econet protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Econet = libc::AF_ECONET,
/// Access to ATM Switched Virtual Circuits
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
AtmSvc = libc::AF_ATMSVC,
/// Reliable Datagram Sockets (RDS) protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Rds = libc::AF_RDS,
/// IBM SNA
#[cfg(not(any(target_os = "haiku", target_os = "redox")))]
Sna = libc::AF_SNA,
/// Socket interface over IrDA
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Irda = libc::AF_IRDA,
/// Generic PPP transport layer, for setting up L2 tunnels (L2TP and PPPoE)
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Pppox = libc::AF_PPPOX,
/// Legacy protocol for wide area network (WAN) connectivity that was used
/// by Sangoma WAN cards
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Wanpipe = libc::AF_WANPIPE,
/// Logical link control (IEEE 802.2 LLC) protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Llc = libc::AF_LLC,
/// InfiniBand native addressing
#[cfg(all(target_os = "linux", not(target_env = "uclibc")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Ib = libc::AF_IB,
/// Multiprotocol Label Switching
#[cfg(all(target_os = "linux", not(target_env = "uclibc")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Mpls = libc::AF_MPLS,
/// Controller Area Network automotive bus protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Can = libc::AF_CAN,
/// TIPC, "cluster domain sockets" protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Tipc = libc::AF_TIPC,
/// Bluetooth low-level socket protocol
#[cfg(not(any(
target_os = "aix",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "solaris",
+ solarish,
+ apple_targets,
+ target_os = "hurd",
target_os = "redox",
)))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Bluetooth = libc::AF_BLUETOOTH,
/// IUCV (inter-user communication vehicle) z/VM protocol for
/// hypervisor-guest interaction
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Iucv = libc::AF_IUCV,
/// Rx, Andrew File System remote procedure call protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
RxRpc = libc::AF_RXRPC,
/// New "modular ISDN" driver interface protocol
#[cfg(not(any(
target_os = "aix",
- target_os = "illumos",
- target_os = "solaris",
+ solarish,
target_os = "haiku",
+ target_os = "hurd",
target_os = "redox",
)))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Isdn = libc::AF_ISDN,
/// Nokia cellular modem IPC/RPC interface
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Phonet = libc::AF_PHONET,
/// IEEE 802.15.4 WPAN (wireless personal area network) raw packet protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Ieee802154 = libc::AF_IEEE802154,
/// Ericsson's Communication CPU to Application CPU interface (CAIF)
/// protocol.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Caif = libc::AF_CAIF,
/// Interface to kernel crypto API
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Alg = libc::AF_ALG,
/// Near field communication
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
Nfc = libc::AF_NFC,
/// VMWare VSockets protocol for hypervisor-guest interaction.
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, apple_targets))]
Vsock = libc::AF_VSOCK,
/// ARPANet IMP addresses
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
ImpLink = libc::AF_IMPLINK,
/// PUP protocols, e.g. BSP
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Pup = libc::AF_PUP,
/// MIT CHAOS protocols
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Chaos = libc::AF_CHAOS,
/// Novell and Xerox protocol
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(apple_targets, netbsdlike))]
Ns = libc::AF_NS,
#[allow(missing_docs)] // Not documented anywhere that I can find
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Iso = libc::AF_ISO,
/// Bell Labs virtual circuit switch ?
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Datakit = libc::AF_DATAKIT,
/// CCITT protocols, X.25 etc
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Ccitt = libc::AF_CCITT,
/// DEC Direct data link interface
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Dli = libc::AF_DLI,
#[allow(missing_docs)] // Not documented anywhere that I can find
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Lat = libc::AF_LAT,
/// NSC Hyperchannel
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Hylink = libc::AF_HYLINK,
/// Link layer interface
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(bsd, solarish))]
Link = libc::AF_LINK,
/// connection-oriented IP, aka ST II
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Coip = libc::AF_COIP,
/// Computer Network Technology
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Cnt = libc::AF_CNT,
/// Native ATM access
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(bsd)]
Natm = libc::AF_NATM,
/// Unspecified address family, (see [`getaddrinfo(3)`](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
Unspec = libc::AF_UNSPEC,
}
@@ -425,29 +259,17 @@ impl AddressFamily {
libc::AF_UNIX => Some(AddressFamily::Unix),
libc::AF_INET => Some(AddressFamily::Inet),
libc::AF_INET6 => Some(AddressFamily::Inet6),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_NETLINK => Some(AddressFamily::Netlink),
- #[cfg(any(target_os = "macos", target_os = "macos"))]
+ #[cfg(apple_targets)]
libc::AF_SYSTEM => Some(AddressFamily::System),
- #[cfg(not(any(
- target_os = "redox",
- target_os = "linux",
- target_os = "android"
- )))]
+ #[cfg(not(any(linux_android, target_os = "redox")))]
libc::PF_ROUTE => Some(AddressFamily::Route),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_PACKET => Some(AddressFamily::Packet),
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, solarish))]
libc::AF_LINK => Some(AddressFamily::Link),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
+ #[cfg(any(linux_android, apple_targets))]
libc::AF_VSOCK => Some(AddressFamily::Vsock),
_ => None,
}
@@ -463,13 +285,7 @@ pub struct UnixAddr {
/// The length of the valid part of `sun`, including the sun_family field
/// but excluding any trailing nul.
// On the BSDs, this field is built into sun
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux",
- target_os = "redox",
- ))]
+ #[cfg(not(any(bsd, target_os = "haiku", target_os = "hurd")))]
sun_len: u8,
}
@@ -483,12 +299,12 @@ pub struct UnixAddr {
enum UnixAddrKind<'a> {
Pathname(&'a Path),
Unnamed,
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
Abstract(&'a [u8]),
}
impl<'a> UnixAddrKind<'a> {
/// Safety: sun & sun_len must be valid
- #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
+ #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
unsafe fn get(sun: &'a libc::sockaddr_un, sun_len: u8) -> Self {
assert!(sun_len as usize >= offset_of!(libc::sockaddr_un, sun_path));
let path_len =
@@ -496,16 +312,19 @@ impl<'a> UnixAddrKind<'a> {
if path_len == 0 {
return Self::Unnamed;
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
if sun.sun_path[0] == 0 {
- let name = slice::from_raw_parts(
- sun.sun_path.as_ptr().add(1) as *const u8,
- path_len - 1,
- );
+ let name = unsafe {
+ slice::from_raw_parts(
+ sun.sun_path.as_ptr().add(1).cast(),
+ path_len - 1,
+ )
+ };
return Self::Abstract(name);
}
- let pathname =
- slice::from_raw_parts(sun.sun_path.as_ptr() as *const u8, path_len);
+ let pathname = unsafe {
+ slice::from_raw_parts(sun.sun_path.as_ptr().cast(), path_len)
+ };
if pathname.last() == Some(&0) {
// A trailing NUL is not considered part of the path, and it does
// not need to be included in the addrlen passed to functions like
@@ -525,7 +344,7 @@ impl<'a> UnixAddrKind<'a> {
impl UnixAddr {
/// Create a new sockaddr_un representing a filesystem path.
- #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
+ #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
pub fn new<P: ?Sized + NixPath>(path: &P) -> Result<UnixAddr> {
path.with_nix_path(|cstr| unsafe {
let mut ret = libc::sockaddr_un {
@@ -544,20 +363,13 @@ impl UnixAddr {
.try_into()
.unwrap();
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, target_os = "haiku", target_os = "hurd"))]
{
ret.sun_len = sun_len;
}
ptr::copy_nonoverlapping(
bytes.as_ptr(),
- ret.sun_path.as_mut_ptr() as *mut u8,
+ ret.sun_path.as_mut_ptr().cast(),
bytes.len(),
);
@@ -571,9 +383,8 @@ impl UnixAddr {
/// thus the input `path` is expected to be the bare name, not NUL-prefixed.
/// This is a Linux-specific extension, primarily used to allow chrooted
/// processes to communicate with processes having a different filesystem view.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
+ #[cfg(linux_android)]
+ #[allow(clippy::unnecessary_cast)] // Not unnecessary on all platforms
pub fn new_abstract(path: &[u8]) -> Result<UnixAddr> {
unsafe {
let mut ret = libc::sockaddr_un {
@@ -593,7 +404,7 @@ impl UnixAddr {
// b'\0', so copy starting one byte in.
ptr::copy_nonoverlapping(
path.as_ptr(),
- ret.sun_path.as_mut_ptr().offset(1) as *mut u8,
+ ret.sun_path.as_mut_ptr().offset(1).cast(),
path.len(),
);
@@ -602,8 +413,7 @@ impl UnixAddr {
}
/// Create a new `sockaddr_un` representing an "unnamed" unix socket address.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
pub fn new_unnamed() -> UnixAddr {
let ret = libc::sockaddr_un {
sun_family: AddressFamily::Unix as sa_family_t,
@@ -632,10 +442,9 @@ impl UnixAddr {
sun_len: u8,
) -> UnixAddr {
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux",
+ solarish,
target_os = "redox",
))]
{
@@ -664,8 +473,7 @@ impl UnixAddr {
///
/// For abstract sockets only the bare name is returned, without the
/// leading NUL byte. `None` is returned for unnamed or path-backed sockets.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
pub fn as_abstract(&self) -> Option<&[u8]> {
match self.kind() {
UnixAddrKind::Abstract(name) => Some(name),
@@ -674,8 +482,7 @@ impl UnixAddr {
}
/// Check if this address is an "unnamed" unix socket address.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
#[inline]
pub fn is_unnamed(&self) -> bool {
matches!(self.kind(), UnixAddrKind::Unnamed)
@@ -699,10 +506,9 @@ impl UnixAddr {
fn sun_len(&self) -> u8 {
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux",
+ solarish,
target_os = "redox",
))]
{
@@ -717,10 +523,10 @@ impl UnixAddr {
impl private::SockaddrLikePriv for UnixAddr {}
impl SockaddrLike for UnixAddr {
#[cfg(any(
- target_os = "android",
+ linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
+ solarish,
+ target_os = "redox"
))]
fn len(&self) -> libc::socklen_t {
self.sun_len.into()
@@ -740,27 +546,26 @@ impl SockaddrLike for UnixAddr {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_UNIX {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_UNIX } {
return None;
}
- let mut su: libc::sockaddr_un = mem::zeroed();
+ let mut su: libc::sockaddr_un = unsafe { mem::zeroed() };
let sup = &mut su as *mut libc::sockaddr_un as *mut u8;
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux",
+ solarish,
target_os = "redox",
))] {
let su_len = len.unwrap_or(
mem::size_of::<libc::sockaddr_un>() as libc::socklen_t
);
} else {
- let su_len = len.unwrap_or((*addr).sa_len as libc::socklen_t);
+ let su_len = unsafe { len.unwrap_or((*addr).sa_len as libc::socklen_t) };
}
- };
- ptr::copy(addr as *const u8, sup, su_len as usize);
- Some(Self::from_raw_parts(su, su_len as u8))
+ }
+ unsafe { ptr::copy(addr as *const u8, sup, su_len as usize) };
+ Some(unsafe { Self::from_raw_parts(su, su_len as u8) })
}
fn size() -> libc::socklen_t
@@ -770,14 +575,16 @@ impl SockaddrLike for UnixAddr {
mem::size_of::<libc::sockaddr_un>() as libc::socklen_t
}
- unsafe fn set_length(&mut self, new_length: usize) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
+ unsafe fn set_length(
+ &mut self,
+ new_length: usize,
+ ) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
// `new_length` is only used on some platforms, so it must be provided even when not used
#![allow(unused_variables)]
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux",
+ solarish,
target_os = "redox",
))] {
self.sun_len = new_length as u8;
@@ -793,7 +600,7 @@ impl AsRef<libc::sockaddr_un> for UnixAddr {
}
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
fn fmt_abstract(abs: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
use fmt::Write;
f.write_str("@\"")?;
@@ -810,7 +617,7 @@ impl fmt::Display for UnixAddr {
match self.kind() {
UnixAddrKind::Pathname(path) => path.display().fmt(f),
UnixAddrKind::Unnamed => f.pad("<unbound UNIX socket>"),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
UnixAddrKind::Abstract(name) => fmt_abstract(name, f),
}
}
@@ -894,12 +701,7 @@ pub trait SockaddrLike: private::SockaddrLikePriv {
}
cfg_if! {
- if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))] {
+ if #[cfg(bsd)] {
/// Return the length of valid data in the sockaddr structure.
///
/// For fixed-size sockaddrs, this should be the size of the
@@ -946,7 +748,10 @@ pub trait SockaddrLike: private::SockaddrLikePriv {
/// `new_length` must be a valid length for this type of address. Specifically, reads of that
/// length from `self` must be valid.
#[doc(hidden)]
- unsafe fn set_length(&mut self, _new_length: usize) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
+ unsafe fn set_length(
+ &mut self,
+ _new_length: usize,
+ ) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
Err(SocketAddressLengthNotDynamic)
}
}
@@ -1006,22 +811,20 @@ pub struct SockaddrIn(libc::sockaddr_in);
impl SockaddrIn {
/// Returns the IP address associated with this socket address, in native
/// endian.
- pub const fn ip(&self) -> libc::in_addr_t {
- u32::from_be(self.0.sin_addr.s_addr)
+ pub const fn ip(&self) -> net::Ipv4Addr {
+ let bytes = self.0.sin_addr.s_addr.to_ne_bytes();
+ let (a, b, c, d) = (bytes[0], bytes[1], bytes[2], bytes[3]);
+ Ipv4Addr::new(a, b, c, d)
}
/// Creates a new socket address from IPv4 octets and a port number.
pub fn new(a: u8, b: u8, c: u8, d: u8, port: u16) -> Self {
Self(libc::sockaddr_in {
#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
+ bsd,
target_os = "aix",
target_os = "haiku",
- target_os = "openbsd"
+ target_os = "hurd"
))]
sin_len: Self::size() as u8,
sin_family: AddressFamily::Inet as sa_family_t,
@@ -1056,10 +859,10 @@ impl SockaddrLike for SockaddrIn {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_INET {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_INET } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -1092,14 +895,10 @@ impl From<net::SocketAddrV4> for SockaddrIn {
fn from(addr: net::SocketAddrV4) -> Self {
Self(libc::sockaddr_in {
#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
+ bsd,
target_os = "haiku",
target_os = "hermit",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
+ target_os = "hurd"
))]
sin_len: mem::size_of::<libc::sockaddr_in>() as u8,
sin_family: AddressFamily::Inet as sa_family_t,
@@ -1143,8 +942,19 @@ impl SockaddrIn6 {
}
/// Returns the IP address associated with this socket address.
- pub fn ip(&self) -> net::Ipv6Addr {
- net::Ipv6Addr::from(self.0.sin6_addr.s6_addr)
+ pub const fn ip(&self) -> net::Ipv6Addr {
+ let bytes = self.0.sin6_addr.s6_addr;
+ let (a, b, c, d, e, f, g, h) = (
+ ((bytes[0] as u16) << 8) | bytes[1] as u16,
+ ((bytes[2] as u16) << 8) | bytes[3] as u16,
+ ((bytes[4] as u16) << 8) | bytes[5] as u16,
+ ((bytes[6] as u16) << 8) | bytes[7] as u16,
+ ((bytes[8] as u16) << 8) | bytes[9] as u16,
+ ((bytes[10] as u16) << 8) | bytes[11] as u16,
+ ((bytes[12] as u16) << 8) | bytes[13] as u16,
+ ((bytes[14] as u16) << 8) | bytes[15] as u16,
+ );
+ Ipv6Addr::new(a, b, c, d, e, f, g, h)
}
/// Returns the port number associated with this socket address, in native
@@ -1175,10 +985,10 @@ impl SockaddrLike for SockaddrIn6 {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_INET6 {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_INET6 } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -1210,14 +1020,10 @@ impl From<net::SocketAddrV6> for SockaddrIn6 {
#[allow(clippy::needless_update)] // It isn't needless on Illumos
Self(libc::sockaddr_in6 {
#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
+ bsd,
target_os = "haiku",
target_os = "hermit",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
+ target_os = "hurd"
))]
sin6_len: mem::size_of::<libc::sockaddr_in6>() as u8,
sin6_family: AddressFamily::Inet6 as sa_family_t,
@@ -1273,18 +1079,17 @@ impl std::str::FromStr for SockaddrIn6 {
#[derive(Clone, Copy, Eq)]
#[repr(C)]
pub union SockaddrStorage {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
alg: AlgAddr,
- #[cfg(all(feature = "net", not(target_os = "redox")))]
+ #[cfg(all(
+ feature = "net",
+ not(any(target_os = "hurd", target_os = "redox"))
+ ))]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
dl: LinkAddr,
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
nl: NetlinkAddr,
- #[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
- ))]
+ #[cfg(all(feature = "ioctl", apple_targets))]
#[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))]
sctl: SysControlAddr,
#[cfg(feature = "net")]
@@ -1293,8 +1098,7 @@ pub union SockaddrStorage {
sin6: SockaddrIn6,
ss: libc::sockaddr_storage,
su: UnixAddr,
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos" ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, apple_targets))]
vsock: VsockAddr,
}
impl private::SockaddrLikePriv for SockaddrStorage {}
@@ -1316,21 +1120,22 @@ impl SockaddrLike for SockaddrStorage {
{
None
} else {
- let mut ss: libc::sockaddr_storage = mem::zeroed();
+ let mut ss: libc::sockaddr_storage = unsafe { mem::zeroed() };
let ssp = &mut ss as *mut libc::sockaddr_storage as *mut u8;
- ptr::copy(addr as *const u8, ssp, len as usize);
+ unsafe { ptr::copy(addr as *const u8, ssp, len as usize) };
#[cfg(any(
- target_os = "android",
+ linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
+ solarish,
))]
if i32::from(ss.ss_family) == libc::AF_UNIX {
// Safe because we UnixAddr is strictly smaller than
// SockaddrStorage, and we just initialized the structure.
- (*(&mut ss as *mut libc::sockaddr_storage
- as *mut UnixAddr))
- .sun_len = len as u8;
+ unsafe {
+ (*(&mut ss as *mut libc::sockaddr_storage
+ as *mut UnixAddr))
+ .sun_len = len as u8;
+ }
}
Some(Self { ss })
}
@@ -1338,68 +1143,47 @@ impl SockaddrLike for SockaddrStorage {
// If length is not available and addr is of a fixed-length type,
// copy it. If addr is of a variable length type and len is not
// available, then there's nothing we can do.
- match (*addr).sa_family as i32 {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_ALG => {
+ match unsafe { (*addr).sa_family as i32 } {
+ #[cfg(linux_android)]
+ libc::AF_ALG => unsafe {
AlgAddr::from_raw(addr, l).map(|alg| Self { alg })
- }
+ },
#[cfg(feature = "net")]
- libc::AF_INET => {
+ libc::AF_INET => unsafe {
SockaddrIn::from_raw(addr, l).map(|sin| Self { sin })
- }
+ },
#[cfg(feature = "net")]
- libc::AF_INET6 => {
+ libc::AF_INET6 => unsafe {
SockaddrIn6::from_raw(addr, l).map(|sin6| Self { sin6 })
- }
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "haiku",
- target_os = "openbsd"
- ))]
+ },
+ #[cfg(any(bsd, solarish, target_os = "haiku"))]
#[cfg(feature = "net")]
- libc::AF_LINK => {
+ libc::AF_LINK => unsafe {
LinkAddr::from_raw(addr, l).map(|dl| Self { dl })
- }
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_NETLINK => {
+ },
+ #[cfg(linux_android)]
+ libc::AF_NETLINK => unsafe {
NetlinkAddr::from_raw(addr, l).map(|nl| Self { nl })
- }
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
+ },
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
- libc::AF_PACKET => {
+ libc::AF_PACKET => unsafe {
LinkAddr::from_raw(addr, l).map(|dl| Self { dl })
- }
- #[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
- ))]
- libc::AF_SYSTEM => {
+ },
+ #[cfg(all(feature = "ioctl", apple_targets))]
+ libc::AF_SYSTEM => unsafe {
SysControlAddr::from_raw(addr, l).map(|sctl| Self { sctl })
- }
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos" ))]
- libc::AF_VSOCK => {
+ },
+ #[cfg(any(linux_android, apple_targets))]
+ libc::AF_VSOCK => unsafe {
VsockAddr::from_raw(addr, l).map(|vsock| Self { vsock })
- }
+ },
_ => None,
}
}
}
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia", solarish))]
fn len(&self) -> libc::socklen_t {
match self.as_unix_addr() {
// The UnixAddr type knows its own length
@@ -1409,11 +1193,12 @@ impl SockaddrLike for SockaddrStorage {
}
}
- unsafe fn set_length(&mut self, new_length: usize) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
+ unsafe fn set_length(
+ &mut self,
+ new_length: usize,
+ ) -> std::result::Result<(), SocketAddressLengthNotDynamic> {
match self.as_unix_addr_mut() {
- Some(addr) => {
- addr.set_length(new_length)
- },
+ Some(addr) => unsafe { addr.set_length(new_length) },
None => Err(SocketAddressLengthNotDynamic),
}
}
@@ -1457,10 +1242,9 @@ impl SockaddrStorage {
/// Downcast to an immutable `[UnixAddr]` reference.
pub fn as_unix_addr(&self) -> Option<&UnixAddr> {
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
+ solarish,
))]
{
let p = unsafe{ &self.ss as *const libc::sockaddr_storage };
@@ -1487,10 +1271,9 @@ impl SockaddrStorage {
/// Downcast to a mutable `[UnixAddr]` reference.
pub fn as_unix_addr_mut(&mut self) -> Option<&mut UnixAddr> {
cfg_if! {
- if #[cfg(any(target_os = "android",
+ if #[cfg(any(linux_android,
target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
+ solarish,
))]
{
let p = unsafe{ &self.ss as *const libc::sockaddr_storage };
@@ -1514,29 +1297,17 @@ impl SockaddrStorage {
}
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
accessors! {as_alg_addr, as_alg_addr_mut, AlgAddr,
AddressFamily::Alg, libc::sockaddr_alg, alg}
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
accessors! {
as_link_addr, as_link_addr_mut, LinkAddr,
AddressFamily::Packet, libc::sockaddr_ll, dl}
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, solarish))]
#[cfg(feature = "net")]
accessors! {
as_link_addr, as_link_addr_mut, LinkAddr,
@@ -1552,17 +1323,16 @@ impl SockaddrStorage {
as_sockaddr_in6, as_sockaddr_in6_mut, SockaddrIn6,
AddressFamily::Inet6, libc::sockaddr_in6, sin6}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
accessors! {as_netlink_addr, as_netlink_addr_mut, NetlinkAddr,
AddressFamily::Netlink, libc::sockaddr_nl, nl}
- #[cfg(all(feature = "ioctl", any(target_os = "ios", target_os = "macos")))]
+ #[cfg(all(feature = "ioctl", apple_targets))]
#[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))]
accessors! {as_sys_control_addr, as_sys_control_addr_mut, SysControlAddr,
AddressFamily::System, libc::sockaddr_ctl, sctl}
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, apple_targets))]
accessors! {as_vsock_addr, as_vsock_addr_mut, VsockAddr,
AddressFamily::Vsock, libc::sockaddr_vm, vsock}
}
@@ -1581,37 +1351,25 @@ impl fmt::Display for SockaddrStorage {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
unsafe {
match self.ss.ss_family as i32 {
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_ALG => self.alg.fmt(f),
#[cfg(feature = "net")]
libc::AF_INET => self.sin.fmt(f),
#[cfg(feature = "net")]
libc::AF_INET6 => self.sin6.fmt(f),
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, solarish))]
#[cfg(feature = "net")]
libc::AF_LINK => self.dl.fmt(f),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_NETLINK => self.nl.fmt(f),
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "fuchsia"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
libc::AF_PACKET => self.dl.fmt(f),
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
#[cfg(feature = "ioctl")]
libc::AF_SYSTEM => self.sctl.fmt(f),
libc::AF_UNIX => self.su.fmt(f),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
+ #[cfg(any(linux_android, apple_targets))]
libc::AF_VSOCK => self.vsock.fmt(f),
_ => "<Address family unspecified>".fmt(f),
}
@@ -1655,37 +1413,25 @@ impl Hash for SockaddrStorage {
fn hash<H: Hasher>(&self, s: &mut H) {
unsafe {
match self.ss.ss_family as i32 {
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_ALG => self.alg.hash(s),
#[cfg(feature = "net")]
libc::AF_INET => self.sin.hash(s),
#[cfg(feature = "net")]
libc::AF_INET6 => self.sin6.hash(s),
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, solarish))]
#[cfg(feature = "net")]
libc::AF_LINK => self.dl.hash(s),
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
libc::AF_NETLINK => self.nl.hash(s),
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "fuchsia"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
libc::AF_PACKET => self.dl.hash(s),
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
#[cfg(feature = "ioctl")]
libc::AF_SYSTEM => self.sctl.hash(s),
libc::AF_UNIX => self.su.hash(s),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
+ #[cfg(any(linux_android, apple_targets))]
libc::AF_VSOCK => self.vsock.hash(s),
_ => self.ss.hash(s),
}
@@ -1697,37 +1443,25 @@ impl PartialEq for SockaddrStorage {
fn eq(&self, other: &Self) -> bool {
unsafe {
match (self.ss.ss_family as i32, other.ss.ss_family as i32) {
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
(libc::AF_ALG, libc::AF_ALG) => self.alg == other.alg,
#[cfg(feature = "net")]
(libc::AF_INET, libc::AF_INET) => self.sin == other.sin,
#[cfg(feature = "net")]
(libc::AF_INET6, libc::AF_INET6) => self.sin6 == other.sin6,
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(any(bsd, solarish))]
#[cfg(feature = "net")]
(libc::AF_LINK, libc::AF_LINK) => self.dl == other.dl,
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
(libc::AF_NETLINK, libc::AF_NETLINK) => self.nl == other.nl,
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
(libc::AF_PACKET, libc::AF_PACKET) => self.dl == other.dl,
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
#[cfg(feature = "ioctl")]
(libc::AF_SYSTEM, libc::AF_SYSTEM) => self.sctl == other.sctl,
(libc::AF_UNIX, libc::AF_UNIX) => self.su == other.su,
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
+ #[cfg(any(linux_android, apple_targets))]
(libc::AF_VSOCK, libc::AF_VSOCK) => self.vsock == other.vsock,
_ => false,
}
@@ -1751,8 +1485,7 @@ pub(super) mod private {
}
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(linux_android)]
pub mod netlink {
use super::*;
use crate::sys::socket::addr::AddressFamily;
@@ -1805,10 +1538,10 @@ pub mod netlink {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_NETLINK {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_NETLINK } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -1825,11 +1558,10 @@ pub mod netlink {
}
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(linux_android)]
pub mod alg {
use super::*;
- use libc::{c_char, sockaddr_alg, AF_ALG};
+ use libc::{sockaddr_alg, AF_ALG};
use std::ffi::CStr;
use std::hash::{Hash, Hasher};
use std::{fmt, mem, str};
@@ -1854,10 +1586,10 @@ pub mod alg {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_ALG {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_ALG } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -1918,16 +1650,12 @@ pub mod alg {
/// Return the socket's cipher type, for example `hash` or `aead`.
pub fn alg_type(&self) -> &CStr {
- unsafe {
- CStr::from_ptr(self.0.salg_type.as_ptr() as *const c_char)
- }
+ unsafe { CStr::from_ptr(self.0.salg_type.as_ptr().cast()) }
}
/// Return the socket's cipher name, for example `sha1`.
pub fn alg_name(&self) -> &CStr {
- unsafe {
- CStr::from_ptr(self.0.salg_name.as_ptr() as *const c_char)
- }
+ unsafe { CStr::from_ptr(self.0.salg_name.as_ptr().cast()) }
}
}
@@ -1951,7 +1679,7 @@ pub mod alg {
feature! {
#![feature = "ioctl"]
-#[cfg(any(target_os = "ios", target_os = "macos"))]
+#[cfg(apple_targets)]
pub mod sys_control {
use crate::sys::socket::addr::AddressFamily;
use libc::{self, c_uchar};
@@ -1994,10 +1722,10 @@ pub mod sys_control {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_SYSTEM {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_SYSTEM } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) } ))
}
}
@@ -2058,8 +1786,7 @@ pub mod sys_control {
}
}
-#[cfg(any(target_os = "android", target_os = "linux", target_os = "fuchsia"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(any(linux_android, target_os = "fuchsia"))]
mod datalink {
feature! {
#![feature = "net"]
@@ -2136,10 +1863,10 @@ mod datalink {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_PACKET {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_PACKET } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -2152,18 +1879,7 @@ mod datalink {
}
}
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "haiku",
- target_os = "aix",
- target_os = "openbsd"
-))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(any(bsd, solarish, target_os = "haiku", target_os = "aix"))]
mod datalink {
feature! {
#![feature = "net"]
@@ -2261,10 +1977,10 @@ mod datalink {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_LINK {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_LINK } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ Some(Self(unsafe { ptr::read_unaligned(addr as *const _) }))
}
}
@@ -2276,8 +1992,7 @@ mod datalink {
}
}
-#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
+#[cfg(any(linux_android, apple_targets))]
pub mod vsock {
use super::*;
use crate::sys::socket::addr::AddressFamily;
@@ -2308,10 +2023,10 @@ pub mod vsock {
return None;
}
}
- if (*addr).sa_family as i32 != libc::AF_VSOCK {
+ if unsafe { (*addr).sa_family as i32 != libc::AF_VSOCK } {
return None;
}
- Some(Self(ptr::read_unaligned(addr as *const _)))
+ unsafe { Some(Self(ptr::read_unaligned(addr as *const _))) }
}
}
@@ -2322,32 +2037,47 @@ pub mod vsock {
}
impl PartialEq for VsockAddr {
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
fn eq(&self, other: &Self) -> bool {
let (inner, other) = (self.0, other.0);
(inner.svm_family, inner.svm_cid, inner.svm_port)
== (other.svm_family, other.svm_cid, other.svm_port)
}
- #[cfg(target_os = "macos")]
+ #[cfg(apple_targets)]
fn eq(&self, other: &Self) -> bool {
let (inner, other) = (self.0, other.0);
- (inner.svm_family, inner.svm_cid, inner.svm_port, inner.svm_len)
- == (other.svm_family, other.svm_cid, other.svm_port, inner.svm_len)
+ (
+ inner.svm_family,
+ inner.svm_cid,
+ inner.svm_port,
+ inner.svm_len,
+ ) == (
+ other.svm_family,
+ other.svm_cid,
+ other.svm_port,
+ inner.svm_len,
+ )
}
}
impl Eq for VsockAddr {}
impl Hash for VsockAddr {
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
fn hash<H: Hasher>(&self, s: &mut H) {
let inner = self.0;
(inner.svm_family, inner.svm_cid, inner.svm_port).hash(s);
}
- #[cfg(target_os = "macos")]
+ #[cfg(apple_targets)]
fn hash<H: Hasher>(&self, s: &mut H) {
let inner = self.0;
- (inner.svm_family, inner.svm_cid, inner.svm_port, inner.svm_len).hash(s);
+ (
+ inner.svm_family,
+ inner.svm_cid,
+ inner.svm_port,
+ inner.svm_len,
+ )
+ .hash(s);
}
}
@@ -2363,9 +2093,9 @@ pub mod vsock {
addr.svm_cid = cid;
addr.svm_port = port;
- #[cfg(target_os = "macos")]
+ #[cfg(apple_targets)]
{
- addr.svm_len = std::mem::size_of::<sockaddr_vm>() as u8;
+ addr.svm_len = std::mem::size_of::<sockaddr_vm>() as u8;
}
VsockAddr(addr)
}
@@ -2419,27 +2149,16 @@ mod tests {
}
}
- #[cfg(not(target_os = "redox"))]
+ #[cfg(not(any(target_os = "hurd", target_os = "redox")))]
mod link {
#![allow(clippy::cast_ptr_alignment)]
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos"
- ))]
+ #[cfg(any(apple_targets, solarish))]
use super::super::super::socklen_t;
use super::*;
/// Don't panic when trying to display an empty datalink address
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
+ #[cfg(bsd)]
#[test]
fn test_datalink_display() {
use super::super::LinkAddr;
@@ -2459,11 +2178,7 @@ mod tests {
}
#[cfg(all(
- any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ),
+ any(linux_android, target_os = "fuchsia"),
target_endian = "little"
))]
#[test]
@@ -2474,7 +2189,7 @@ mod tests {
let bytes = Raw([
17u8, 0, 0, 0, 1, 0, 0, 0, 4, 3, 0, 6, 1, 2, 3, 4, 5, 6, 0, 0,
]);
- let sa = bytes.0.as_ptr() as *const libc::sockaddr;
+ let sa = bytes.0.as_ptr().cast();
let len = None;
let sock_addr =
unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap();
@@ -2485,12 +2200,12 @@ mod tests {
}
}
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
#[test]
fn macos_loopback() {
let bytes =
[20i8, 18, 1, 0, 24, 3, 0, 0, 108, 111, 48, 0, 0, 0, 0, 0];
- let sa = bytes.as_ptr() as *const libc::sockaddr;
+ let sa = bytes.as_ptr().cast();
let len = Some(bytes.len() as socklen_t);
let sock_addr =
unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap();
@@ -2503,7 +2218,7 @@ mod tests {
}
}
- #[cfg(any(target_os = "ios", target_os = "macos"))]
+ #[cfg(apple_targets)]
#[test]
fn macos_tap() {
let bytes = [
@@ -2525,9 +2240,9 @@ mod tests {
}
}
- #[cfg(target_os = "illumos")]
+ #[cfg(solarish)]
#[test]
- fn illumos_tap() {
+ fn solarish_tap() {
let bytes = [25u8, 0, 0, 0, 6, 0, 6, 0, 24, 101, 144, 221, 76, 176];
let ptr = bytes.as_ptr();
let sa = ptr as *const libc::sockaddr;
@@ -2548,23 +2263,9 @@ mod tests {
#[test]
fn size() {
- #[cfg(any(
- target_os = "aix",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd",
- target_os = "haiku"
- ))]
+ #[cfg(any(bsd, target_os = "aix", solarish, target_os = "haiku"))]
let l = mem::size_of::<libc::sockaddr_dl>();
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
let l = mem::size_of::<libc::sockaddr_ll>();
assert_eq!(LinkAddr::size() as usize, l);
}
@@ -2588,6 +2289,13 @@ mod tests {
SockaddrIn::size() as usize
);
}
+
+ #[test]
+ fn ip() {
+ let s = "127.0.0.1:8082";
+ let ip = SockaddrIn::from_str(s).unwrap().ip();
+ assert_eq!("127.0.0.1", format!("{ip}"));
+ }
}
mod sockaddr_in6 {
@@ -2610,6 +2318,13 @@ mod tests {
}
#[test]
+ fn ip() {
+ let s = "[1234:5678:90ab:cdef::1111:2222]:8080";
+ let ip = SockaddrIn6::from_str(s).unwrap().ip();
+ assert_eq!("1234:5678:90ab:cdef::1111:2222", format!("{ip}"));
+ }
+
+ #[test]
// Ensure that we can convert to-and-from std::net variants without change.
fn to_and_from() {
let s = "[1234:5678:90ab:cdef::1111:2222]:8080";
@@ -2628,28 +2343,28 @@ mod tests {
#[test]
fn from_sockaddr_un_named() {
let ua = UnixAddr::new("/var/run/mysock").unwrap();
- let ptr = ua.as_ptr() as *const libc::sockaddr;
+ let ptr = ua.as_ptr().cast();
let ss = unsafe { SockaddrStorage::from_raw(ptr, Some(ua.len())) }
.unwrap();
assert_eq!(ss.len(), ua.len());
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[test]
fn from_sockaddr_un_abstract_named() {
let name = String::from("nix\0abstract\0test");
let ua = UnixAddr::new_abstract(name.as_bytes()).unwrap();
- let ptr = ua.as_ptr() as *const libc::sockaddr;
+ let ptr = ua.as_ptr().cast();
let ss = unsafe { SockaddrStorage::from_raw(ptr, Some(ua.len())) }
.unwrap();
assert_eq!(ss.len(), ua.len());
}
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[test]
fn from_sockaddr_un_abstract_unnamed() {
let ua = UnixAddr::new_unnamed();
- let ptr = ua.as_ptr() as *const libc::sockaddr;
+ let ptr = ua.as_ptr().cast();
let ss = unsafe { SockaddrStorage::from_raw(ptr, Some(ua.len())) }
.unwrap();
assert_eq!(ss.len(), ua.len());
@@ -2659,7 +2374,7 @@ mod tests {
mod unixaddr {
use super::*;
- #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[cfg(linux_android)]
#[test]
fn abstract_sun_path() {
let name = String::from("nix\0abstract\0test");
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");
- }
-}
diff --git a/third_party/rust/nix/src/sys/socket/sockopt.rs b/third_party/rust/nix/src/sys/socket/sockopt.rs
index 44f3ebbc1d..4357695f56 100644
--- a/third_party/rust/nix/src/sys/socket/sockopt.rs
+++ b/third_party/rust/nix/src/sys/socket/sockopt.rs
@@ -7,7 +7,6 @@ use cfg_if::cfg_if;
use libc::{self, c_int, c_void, socklen_t};
use std::ffi::{OsStr, OsString};
use std::mem::{self, MaybeUninit};
-#[cfg(target_family = "unix")]
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::{AsFd, AsRawFd};
@@ -128,7 +127,7 @@ macro_rules! getsockopt_impl {
/// both of them.
/// * `$name:ident`: name of type `GetSockOpt`/`SetSockOpt` will be implemented for.
/// * `$level:expr` : socket layer, or a `protocol level`: could be *raw sockets*
-/// (`lic::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
+/// (`libc::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
/// and more. Please refer to your system manual for more options. Will be passed as the second
/// argument (`level`) to the `getsockopt`/`setsockopt` call.
/// * `$flag:path`: a flag name to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`,
@@ -261,7 +260,7 @@ sockopt_impl!(
libc::SO_REUSEADDR,
bool
);
-#[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
+#[cfg(not(solarish))]
sockopt_impl!(
/// Permits multiple AF_INET or AF_INET6 sockets to be bound to an
/// identical socket address.
@@ -318,7 +317,7 @@ sockopt_impl!(
super::IpMembershipRequest
);
cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
+ if #[cfg(linux_android)] {
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -329,14 +328,7 @@ cfg_if! {
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
/// Leave an IPv6 multicast group.
Ipv6DropMembership, SetOnly, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::Ipv6MembershipRequest);
- } else if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))] {
+ } else if #[cfg(any(bsd, solarish))] {
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -365,6 +357,17 @@ sockopt_impl!(
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
+ /// Set or read the hop limit value of outgoing IPv6 multicast packets for
+ /// this socket.
+ Ipv6MulticastHops,
+ Both,
+ libc::IPPROTO_IPV6,
+ libc::IPV6_MULTICAST_HOPS,
+ libc::c_int
+);
+#[cfg(feature = "net")]
+sockopt_impl!(
+ #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
/// Set or read a boolean integer argument that determines whether sent
/// multicast packets should be looped back to the local sockets.
IpMulticastLoop,
@@ -408,7 +411,7 @@ sockopt_impl!(
libc::IPV6_TCLASS,
libc::c_int
);
-#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -420,6 +423,20 @@ sockopt_impl!(
libc::IP_FREEBIND,
bool
);
+#[cfg(linux_android)]
+#[cfg(feature = "net")]
+sockopt_impl!(
+ #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
+ /// If enabled, the kernel will not reserve an ephemeral port when binding
+ /// socket with a port number of 0. The port will later be automatically
+ /// chosen at connect time, in a way that allows sharing a source port as
+ /// long as the 4-tuple is unique.
+ IpBindAddressNoPort,
+ Both,
+ libc::IPPROTO_IP,
+ libc::IP_BIND_ADDRESS_NO_PORT,
+ bool
+);
sockopt_impl!(
/// Specify the receiving timeout until reporting an error.
ReceiveTimeout,
@@ -477,12 +494,7 @@ sockopt_impl!(
libc::SO_KEEPALIVE,
bool
);
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "ios"
-))]
+#[cfg(any(freebsdlike, apple_targets))]
sockopt_impl!(
/// Get the credentials of the peer process of a connected unix domain
/// socket.
@@ -492,7 +504,7 @@ sockopt_impl!(
libc::LOCAL_PEERCRED,
super::XuCred
);
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(apple_targets)]
sockopt_impl!(
/// Get the PID of the peer process of a connected unix domain socket.
LocalPeerPid,
@@ -501,7 +513,7 @@ sockopt_impl!(
libc::LOCAL_PEERPID,
libc::c_int
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Return the credentials of the foreign process connected to this socket.
PeerCredentials,
@@ -510,7 +522,18 @@ sockopt_impl!(
libc::SO_PEERCRED,
super::UnixCredentials
);
-#[cfg(any(target_os = "ios", target_os = "macos"))]
+#[cfg(target_os = "freebsd")]
+#[cfg(feature = "net")]
+sockopt_impl!(
+ #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
+ /// Get backlog limit of the socket
+ ListenQLimit,
+ GetOnly,
+ libc::SOL_SOCKET,
+ libc::SO_LISTENQLIMIT,
+ u32
+);
+#[cfg(apple_targets)]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -522,12 +545,7 @@ sockopt_impl!(
libc::TCP_KEEPALIVE,
u32
);
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux"
-))]
+#[cfg(any(freebsdlike, linux_android))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -540,7 +558,7 @@ sockopt_impl!(
u32
);
cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
+ if #[cfg(linux_android)] {
sockopt_impl!(
/// The maximum segment size for outgoing TCP packets.
TcpMaxSeg, Both, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32);
@@ -550,7 +568,11 @@ cfg_if! {
TcpMaxSeg, GetOnly, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32);
}
}
-#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "redox")))]
+#[cfg(not(any(
+ target_os = "openbsd",
+ target_os = "haiku",
+ target_os = "redox"
+)))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -562,7 +584,7 @@ sockopt_impl!(
libc::TCP_KEEPCNT,
u32
);
-#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "fuchsia"))]
sockopt_impl!(
#[allow(missing_docs)]
// Not documented by Linux!
@@ -572,7 +594,11 @@ sockopt_impl!(
libc::TCP_REPAIR,
u32
);
-#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "redox")))]
+#[cfg(not(any(
+ target_os = "openbsd",
+ target_os = "haiku",
+ target_os = "redox"
+)))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -596,6 +622,26 @@ sockopt_impl!(
libc::TCP_USER_TIMEOUT,
u32
);
+#[cfg(linux_android)]
+#[cfg(feature = "net")]
+sockopt_impl!(
+ #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
+ /// Enables TCP Fast Open (RFC 7413) on a connecting socket. If a fast open
+ /// cookie is not available (first attempt to connect), `connect` syscall
+ /// will behave as usual, except for internally trying to solicit a cookie
+ /// from remote peer. When cookie is available, the next `connect` syscall
+ /// will immediately succeed without actually establishing TCP connection.
+ /// The connection establishment will be defered till the next `write` or
+ /// `sendmsg` syscalls on the socket, allowing TCP prtocol to establish
+ /// connection and send data in the same packets. Note: calling `read` right
+ /// after `connect` without `write` on the socket will cause the blocking
+ /// socket to be blocked forever.
+ TcpFastOpenConnect,
+ Both,
+ libc::IPPROTO_TCP,
+ libc::TCP_FASTOPEN_CONNECT,
+ bool
+);
sockopt_impl!(
/// Sets or gets the maximum socket receive buffer in bytes.
RcvBuf,
@@ -612,7 +658,7 @@ sockopt_impl!(
libc::SO_SNDBUF,
usize
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can
/// perform the same task as `SO_RCVBUF`, but the `rmem_max limit` can be
@@ -623,7 +669,7 @@ sockopt_impl!(
libc::SO_RCVBUFFORCE,
usize
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can
/// perform the same task as `SO_SNDBUF`, but the `wmem_max` limit can be
@@ -652,7 +698,7 @@ sockopt_impl!(
libc::SO_ACCEPTCONN,
bool
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Bind this socket to a particular device like “eth0”.
BindToDevice,
@@ -661,7 +707,7 @@ sockopt_impl!(
libc::SO_BINDTODEVICE,
OsString<[u8; libc::IFNAMSIZ]>
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -673,7 +719,7 @@ sockopt_impl!(
libc::SO_ORIGINAL_DST,
libc::sockaddr_in
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
#[allow(missing_docs)]
// Not documented by Linux!
@@ -683,7 +729,7 @@ sockopt_impl!(
libc::IP6T_SO_ORIGINAL_DST,
libc::sockaddr_in6
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Specifies exact type of timestamping information collected by the kernel
/// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
@@ -693,7 +739,7 @@ sockopt_impl!(
libc::SO_TIMESTAMPING,
super::TimestampingFlag
);
-#[cfg(not(any(target_os = "aix", target_os = "haiku", target_os = "redox")))]
+#[cfg(not(any(target_os = "aix", target_os = "haiku", target_os = "hurd", target_os = "redox")))]
sockopt_impl!(
/// Enable or disable the receiving of the `SO_TIMESTAMP` control message.
ReceiveTimestamp,
@@ -702,7 +748,7 @@ sockopt_impl!(
libc::SO_TIMESTAMP,
bool
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Enable or disable the receiving of the `SO_TIMESTAMPNS` control message.
ReceiveTimestampns,
@@ -719,9 +765,9 @@ sockopt_impl!(
Both,
libc::SOL_SOCKET,
libc::SO_TS_CLOCK,
- i32
+ super::SocketTimestamp
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -806,7 +852,7 @@ sockopt_impl!(
libc::SO_MARK,
u32
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Enable or disable the receiving of the `SCM_CREDENTIALS` control
/// message.
@@ -828,13 +874,7 @@ sockopt_impl!(
libc::TCP_CONGESTION,
OsString<[u8; TCP_CA_NAME_MAX]>
);
-#[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")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -846,15 +886,7 @@ sockopt_impl!(
libc::IP_PKTINFO,
bool
);
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(any(linux_android, target_os = "freebsd", apple_targets, netbsdlike))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -866,13 +898,7 @@ sockopt_impl!(
libc::IPV6_RECVPKTINFO,
bool
);
-#[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(bsd)]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -884,13 +910,7 @@ sockopt_impl!(
libc::IP_RECVIF,
bool
);
-#[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(bsd)]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -902,7 +922,7 @@ sockopt_impl!(
libc::IP_RECVDSTADDR,
bool
);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "freebsd"))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -948,7 +968,7 @@ sockopt_impl!(
libc::SO_TXTIME,
libc::sock_txtime
);
-#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "fuchsia"))]
sockopt_impl!(
/// Indicates that an unsigned 32-bit value ancillary message (cmsg) should
/// be attached to received skbs indicating the number of packets dropped by
@@ -969,7 +989,7 @@ sockopt_impl!(
libc::IPV6_V6ONLY,
bool
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Enable extended reliable error message passing.
Ipv4RecvErr,
@@ -978,7 +998,7 @@ sockopt_impl!(
libc::IP_RECVERR,
bool
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Control receiving of asynchronous error options.
Ipv6RecvErr,
@@ -987,7 +1007,7 @@ sockopt_impl!(
libc::IPV6_RECVERR,
bool
);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
sockopt_impl!(
/// Fetch the current system-estimated Path MTU.
IpMtu,
@@ -996,7 +1016,7 @@ sockopt_impl!(
libc::IP_MTU,
libc::c_int
);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "freebsd"))]
sockopt_impl!(
/// Set or retrieve the current time-to-live field that is used in every
/// packet sent from this socket.
@@ -1006,7 +1026,7 @@ sockopt_impl!(
libc::IP_TTL,
libc::c_int
);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "freebsd"))]
sockopt_impl!(
/// Set the unicast hop limit for the socket.
Ipv6Ttl,
@@ -1015,7 +1035,7 @@ sockopt_impl!(
libc::IPV6_UNICAST_HOPS,
libc::c_int
);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
+#[cfg(any(linux_android, target_os = "freebsd"))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -1027,7 +1047,7 @@ sockopt_impl!(
libc::IPV6_ORIGDSTADDR,
bool
);
-#[cfg(any(target_os = "ios", target_os = "macos"))]
+#[cfg(apple_targets)]
sockopt_impl!(
/// Set "don't fragment packet" flag on the IP packet.
IpDontFrag,
@@ -1036,12 +1056,7 @@ sockopt_impl!(
libc::IP_DONTFRAG,
bool
);
-#[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
-))]
+#[cfg(any(linux_android, apple_targets))]
sockopt_impl!(
/// Set "don't fragment packet" flag on the IPv6 packet.
Ipv6DontFrag,
@@ -1053,13 +1068,13 @@ sockopt_impl!(
#[allow(missing_docs)]
// Not documented by Linux!
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
#[derive(Copy, Clone, Debug)]
pub struct AlgSetAeadAuthSize;
// ALG_SET_AEAD_AUTH_SIZE read the length from passed `option_len`
// See https://elixir.bootlin.com/linux/v4.4/source/crypto/af_alg.c#L222
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
impl SetSockOpt for AlgSetAeadAuthSize {
type Val = usize;
@@ -1079,18 +1094,18 @@ impl SetSockOpt for AlgSetAeadAuthSize {
#[allow(missing_docs)]
// Not documented by Linux!
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
#[derive(Clone, Debug)]
pub struct AlgSetKey<T>(::std::marker::PhantomData<T>);
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
impl<T> Default for AlgSetKey<T> {
fn default() -> Self {
AlgSetKey(Default::default())
}
}
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(linux_android)]
impl<T> SetSockOpt for AlgSetKey<T>
where
T: AsRef<[u8]> + Clone,
@@ -1103,7 +1118,54 @@ where
fd.as_fd().as_raw_fd(),
libc::SOL_ALG,
libc::ALG_SET_KEY,
- val.as_ref().as_ptr() as *const _,
+ val.as_ref().as_ptr().cast(),
+ val.as_ref().len() as libc::socklen_t,
+ );
+ Errno::result(res).map(drop)
+ }
+ }
+}
+
+/// Set the Upper Layer Protocol (ULP) on the TCP socket.
+///
+/// For example, to enable the TLS ULP on a socket, the C function call would be:
+///
+/// ```c
+/// setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));
+/// ```
+///
+/// ... and the `nix` equivalent is:
+///
+/// ```ignore,rust
+/// setsockopt(sock, TcpUlp::default(), b"tls");
+/// ```
+///
+/// Note that the ULP name does not need a trailing NUL terminator (`\0`).
+#[cfg(linux_android)]
+#[derive(Clone, Debug)]
+pub struct TcpUlp<T>(::std::marker::PhantomData<T>);
+
+#[cfg(linux_android)]
+impl<T> Default for TcpUlp<T> {
+ fn default() -> Self {
+ TcpUlp(Default::default())
+ }
+}
+
+#[cfg(linux_android)]
+impl<T> SetSockOpt for TcpUlp<T>
+where
+ T: AsRef<[u8]> + Clone,
+{
+ type Val = T;
+
+ fn set<F: AsFd>(&self, fd: &F, val: &Self::Val) -> Result<()> {
+ unsafe {
+ let res = libc::setsockopt(
+ fd.as_fd().as_raw_fd(),
+ libc::SOL_TCP,
+ libc::TCP_ULP,
+ val.as_ref().as_ptr().cast(),
val.as_ref().len() as libc::socklen_t,
);
Errno::result(res).map(drop)
@@ -1111,6 +1173,113 @@ where
}
}
+/// Value used with the [`TcpTlsTx`] and [`TcpTlsRx`] socket options.
+#[cfg(target_os = "linux")]
+#[derive(Copy, Clone, Debug)]
+pub enum TlsCryptoInfo {
+ /// AES-128-GCM
+ Aes128Gcm(libc::tls12_crypto_info_aes_gcm_128),
+
+ /// AES-256-GCM
+ Aes256Gcm(libc::tls12_crypto_info_aes_gcm_256),
+
+ /// CHACHA20-POLY1305
+ Chacha20Poly1305(libc::tls12_crypto_info_chacha20_poly1305),
+}
+
+/// Set the Kernel TLS write parameters on the TCP socket.
+///
+/// For example, the C function call would be:
+///
+/// ```c
+/// setsockopt(sock, SOL_TLS, TLS_TX, &crypto_info, sizeof(crypto_info));
+/// ```
+///
+/// ... and the `nix` equivalent is:
+///
+/// ```ignore,rust
+/// setsockopt(sock, TcpTlsTx, &crypto_info);
+/// ```
+#[cfg(target_os = "linux")]
+#[derive(Copy, Clone, Debug)]
+pub struct TcpTlsTx;
+
+#[cfg(target_os = "linux")]
+impl SetSockOpt for TcpTlsTx {
+ type Val = TlsCryptoInfo;
+
+ fn set<F: AsFd>(&self, fd: &F, val: &Self::Val) -> Result<()> {
+ let (ffi_ptr, ffi_len) = match val {
+ TlsCryptoInfo::Aes128Gcm(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ TlsCryptoInfo::Aes256Gcm(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ TlsCryptoInfo::Chacha20Poly1305(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ };
+ unsafe {
+ let res = libc::setsockopt(
+ fd.as_fd().as_raw_fd(),
+ libc::SOL_TLS,
+ libc::TLS_TX,
+ ffi_ptr,
+ ffi_len as libc::socklen_t,
+ );
+ Errno::result(res).map(drop)
+ }
+ }
+}
+
+/// Set the Kernel TLS read parameters on the TCP socket.
+///
+/// For example, the C function call would be:
+///
+/// ```c
+/// setsockopt(sock, SOL_TLS, TLS_RX, &crypto_info, sizeof(crypto_info));
+/// ```
+///
+/// ... and the `nix` equivalent is:
+///
+/// ```ignore,rust
+/// setsockopt(sock, TcpTlsRx, &crypto_info);
+/// ```
+#[cfg(target_os = "linux")]
+#[derive(Copy, Clone, Debug)]
+pub struct TcpTlsRx;
+
+#[cfg(target_os = "linux")]
+impl SetSockOpt for TcpTlsRx {
+ type Val = TlsCryptoInfo;
+
+ fn set<F: AsFd>(&self, fd: &F, val: &Self::Val) -> Result<()> {
+ let (ffi_ptr, ffi_len) = match val {
+ TlsCryptoInfo::Aes128Gcm(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ TlsCryptoInfo::Aes256Gcm(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ TlsCryptoInfo::Chacha20Poly1305(crypto_info) => {
+ (<*const _>::cast(crypto_info), mem::size_of_val(crypto_info))
+ }
+ };
+ unsafe {
+ let res = libc::setsockopt(
+ fd.as_fd().as_raw_fd(),
+ libc::SOL_TLS,
+ libc::TLS_RX,
+ ffi_ptr,
+ ffi_len as libc::socklen_t,
+ );
+ Errno::result(res).map(drop)
+ }
+ }
+}
+
+
/*
*
* ===== Accessor helpers =====
@@ -1158,7 +1327,7 @@ impl<T> Get<T> for GetStruct<T> {
}
fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
+ self.val.as_mut_ptr().cast()
}
fn ffi_len(&mut self) -> *mut socklen_t {
@@ -1171,7 +1340,7 @@ impl<T> Get<T> for GetStruct<T> {
mem::size_of::<T>(),
"invalid getsockopt implementation"
);
- self.val.assume_init()
+ unsafe { self.val.assume_init() }
}
}
@@ -1209,7 +1378,7 @@ impl Get<bool> for GetBool {
}
fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
+ self.val.as_mut_ptr().cast()
}
fn ffi_len(&mut self) -> *mut socklen_t {
@@ -1222,7 +1391,7 @@ impl Get<bool> for GetBool {
mem::size_of::<c_int>(),
"invalid getsockopt implementation"
);
- self.val.assume_init() != 0
+ unsafe { self.val.assume_init() != 0 }
}
}
@@ -1243,7 +1412,7 @@ impl<'a> Set<'a, bool> for SetBool {
}
fn ffi_len(&self) -> socklen_t {
- mem::size_of::<c_int>() as socklen_t
+ mem::size_of_val(&self.val) as socklen_t
}
}
@@ -1262,7 +1431,7 @@ impl Get<u8> for GetU8 {
}
fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
+ self.val.as_mut_ptr().cast()
}
fn ffi_len(&mut self) -> *mut socklen_t {
@@ -1275,7 +1444,7 @@ impl Get<u8> for GetU8 {
mem::size_of::<u8>(),
"invalid getsockopt implementation"
);
- self.val.assume_init()
+ unsafe { self.val.assume_init() }
}
}
@@ -1294,7 +1463,7 @@ impl<'a> Set<'a, u8> for SetU8 {
}
fn ffi_len(&self) -> socklen_t {
- mem::size_of::<c_int>() as socklen_t
+ mem::size_of_val(&self.val) as socklen_t
}
}
@@ -1313,7 +1482,7 @@ impl Get<usize> for GetUsize {
}
fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
+ self.val.as_mut_ptr().cast()
}
fn ffi_len(&mut self) -> *mut socklen_t {
@@ -1326,7 +1495,7 @@ impl Get<usize> for GetUsize {
mem::size_of::<c_int>(),
"invalid getsockopt implementation"
);
- self.val.assume_init() as usize
+ unsafe { self.val.assume_init() as usize }
}
}
@@ -1345,7 +1514,7 @@ impl<'a> Set<'a, usize> for SetUsize {
}
fn ffi_len(&self) -> socklen_t {
- mem::size_of::<c_int>() as socklen_t
+ mem::size_of_val(&self.val) as socklen_t
}
}
@@ -1364,7 +1533,7 @@ impl<T: AsMut<[u8]>> Get<OsString> for GetOsString<T> {
}
fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
+ self.val.as_mut_ptr().cast()
}
fn ffi_len(&mut self) -> *mut socklen_t {
@@ -1373,7 +1542,7 @@ impl<T: AsMut<[u8]>> Get<OsString> for GetOsString<T> {
unsafe fn assume_init(self) -> OsString {
let len = self.len as usize;
- let mut v = self.val.assume_init();
+ let mut v = unsafe { self.val.assume_init() };
OsStr::from_bytes(&v.as_mut()[0..len]).to_owned()
}
}
@@ -1391,7 +1560,7 @@ impl<'a> Set<'a, OsString> for SetOsString<'a> {
}
fn ffi_ptr(&self) -> *const c_void {
- self.val.as_bytes().as_ptr() as *const c_void
+ self.val.as_bytes().as_ptr().cast()
}
fn ffi_len(&self) -> socklen_t {
@@ -1399,72 +1568,3 @@ impl<'a> Set<'a, OsString> for SetOsString<'a> {
}
}
-#[cfg(test)]
-mod test {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[test]
- fn can_get_peercred_on_unix_socket() {
- use super::super::*;
-
- let (a, b) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let a_cred = getsockopt(&a, super::PeerCredentials).unwrap();
- let b_cred = getsockopt(&b, super::PeerCredentials).unwrap();
- assert_eq!(a_cred, b_cred);
- assert_ne!(a_cred.pid(), 0);
- }
-
- #[test]
- fn is_socket_type_unix() {
- use super::super::*;
-
- let (a, _b) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let a_type = getsockopt(&a, super::SockType).unwrap();
- assert_eq!(a_type, SockType::Stream);
- }
-
- #[test]
- fn is_socket_type_dgram() {
- use super::super::*;
-
- let s = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- let s_type = getsockopt(&s, super::SockType).unwrap();
- assert_eq!(s_type, SockType::Datagram);
- }
-
- #[cfg(any(target_os = "freebsd", target_os = "linux"))]
- #[test]
- fn can_get_listen_on_tcp_socket() {
- use super::super::*;
-
- let s = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- let s_listening = getsockopt(&s, super::AcceptConn).unwrap();
- assert!(!s_listening);
- listen(&s, 10).unwrap();
- let s_listening2 = getsockopt(&s, super::AcceptConn).unwrap();
- assert!(s_listening2);
- }
-}