From e53cee34b9f15abb37c447e8008d81403c912ad9 Mon Sep 17 00:00:00 2001 From: Noa <33094578+coolreader18@users.noreply.github.com> Date: Tue, 24 Aug 2021 22:15:25 -0500 Subject: [PATCH] Merge sockaddr_storage_to_addr and SockAddr::from_raw_sockaddr --- src/ifaddrs.rs | 40 +++++-- src/sys/socket/addr.rs | 228 +++++++++++++++++++++++----------------- src/sys/socket/mod.rs | 112 +++----------------- test/sys/test_socket.rs | 24 ++--- 4 files changed, 186 insertions(+), 218 deletions(-) diff --git a/src/ifaddrs.rs b/src/ifaddrs.rs index 74f340505e..8abf2174fd 100644 --- a/src/ifaddrs.rs +++ b/src/ifaddrs.rs @@ -9,9 +9,9 @@ use std::iter::Iterator; use std::mem; use std::option::Option; -use crate::{Result, Errno}; -use crate::sys::socket::SockAddr; use crate::net::if_::*; +use crate::sys::socket::SockAddr; +use crate::{Errno, Result}; /// Describes a single address for an interface as returned by `getifaddrs`. #[derive(Clone, Debug, Eq, Hash, PartialEq)] @@ -46,8 +46,31 @@ impl InterfaceAddress { /// Create an `InterfaceAddress` from the libc struct. fn from_libc_ifaddrs(info: &libc::ifaddrs) -> InterfaceAddress { let ifname = unsafe { ffi::CStr::from_ptr(info.ifa_name) }; - let address = unsafe { SockAddr::from_raw_sockaddr(info.ifa_addr) }; - let netmask = unsafe { SockAddr::from_raw_sockaddr(info.ifa_netmask) }; + let get_sockaddr = |sa: *const libc::sockaddr| { + if sa.is_null() { + return None; + } + // TODO: there's gotta be a better way to do this but this is basically + // what the man pages recommend + let len = match unsafe { (*sa).sa_family } as _ { + libc::AF_INET => mem::size_of::(), + libc::AF_INET6 => mem::size_of::(), + #[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "illumos", + target_os = "fuchsia", + target_os = "solaris" + ))] + libc::AF_PACKET => mem::size_of::(), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_NETLINK => mem::size_of::(), + _ => return None, + }; + unsafe { SockAddr::from_raw_sockaddr(sa, len) }.ok() + }; + let address = get_sockaddr(info.ifa_addr); + let netmask = get_sockaddr(info.ifa_netmask); let mut addr = InterfaceAddress { interface_name: ifname.to_string_lossy().to_string(), flags: InterfaceFlags::from_bits_truncate(info.ifa_flags as i32), @@ -59,9 +82,9 @@ impl InterfaceAddress { let ifu = get_ifu_from_sockaddr(info); if addr.flags.contains(InterfaceFlags::IFF_POINTOPOINT) { - addr.destination = unsafe { SockAddr::from_raw_sockaddr(ifu) }; + addr.destination = get_sockaddr(ifu); } else if addr.flags.contains(InterfaceFlags::IFF_BROADCAST) { - addr.broadcast = unsafe { SockAddr::from_raw_sockaddr(ifu) }; + addr.broadcast = get_sockaddr(ifu); } addr @@ -127,9 +150,10 @@ pub fn getifaddrs() -> Result { let mut addrs = mem::MaybeUninit::<*mut libc::ifaddrs>::uninit(); unsafe { Errno::result(libc::getifaddrs(addrs.as_mut_ptr())).map(|_| { + let addrs = addrs.assume_init(); InterfaceAddressIterator { - base: addrs.assume_init(), - next: addrs.assume_init(), + base: addrs, + next: addrs, } }) } diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs index 832a153f2a..cf7ba66ef1 100644 --- a/src/sys/socket/addr.rs +++ b/src/sys/socket/addr.rs @@ -29,12 +29,41 @@ pub use self::datalink::LinkAddr; #[cfg(any(target_os = "android", target_os = "linux"))] pub use self::vsock::VsockAddr; -/// These constants specify the protocol family to be used -/// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html) -#[repr(i32)] -#[non_exhaustive] -#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] -pub enum AddressFamily { +macro_rules! address_family_enum { + ($($(#[doc = $doc:tt])* $(#[cfg($cfg:meta)])* $Variant:ident = $constant:path),* $(,)?) => { + /// These constants specify the protocol family to be used + /// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html) + #[repr(i32)] + #[non_exhaustive] + #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] + pub enum AddressFamily { + $( + $(#[doc = $doc])* + $(#[cfg($cfg)])* + $Variant = $constant, + )* + } + + impl AddressFamily { + /// Create a new `AddressFamily` from an integer value retrieved from `libc`, usually from + /// the `sa_family` field of a `sockaddr`. + /// + /// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink, Link/Packet + /// and System. Returns None for unsupported or unknown address families. + pub const fn from_i32(family: i32) -> Option { + match family { + $( + $(#[cfg($cfg)])* + $constant => Some(AddressFamily::$Variant), + )* + _ => None + } + } + } + }; +} + +address_family_enum! { /// Local communication (see [`unix(7)`](https://man7.org/linux/man-pages/man7/unix.7.html)) Unix = libc::AF_UNIX, /// IPv4 Internet protocols (see [`ip(7)`](https://man7.org/linux/man-pages/man7/ip.7.html)) @@ -231,38 +260,6 @@ pub enum AddressFamily { Unspec = libc::AF_UNSPEC, } -impl AddressFamily { - /// Create a new `AddressFamily` from an integer value retrieved from `libc`, usually from - /// the `sa_family` field of a `sockaddr`. - /// - /// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink, Link/Packet - /// and System. Returns None for unsupported or unknown address families. - pub const fn from_i32(family: i32) -> Option { - match family { - 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"))] - libc::AF_NETLINK => Some(AddressFamily::Netlink), - #[cfg(any(target_os = "macos", target_os = "macos"))] - libc::AF_SYSTEM => Some(AddressFamily::System), - #[cfg(any(target_os = "android", target_os = "linux"))] - 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"))] - libc::AF_LINK => Some(AddressFamily::Link), - #[cfg(any(target_os = "android", target_os = "linux"))] - libc::AF_VSOCK => Some(AddressFamily::Vsock), - _ => None - } - } -} - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum InetAddr { V4(libc::sockaddr_in), @@ -517,7 +514,7 @@ impl fmt::Display for Ipv6Addr { } /// A wrapper around `sockaddr_un`. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy)] pub struct UnixAddr { // INVARIANT: sun & path_len are valid as defined by docs for from_raw_parts sun: libc::sockaddr_un, @@ -680,6 +677,17 @@ fn fmt_abstract(abs: &[u8], f: &mut fmt::Formatter) -> fmt::Result { Ok(()) } +impl fmt::Debug for UnixAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.kind() { + UnixAddrKind::Pathname(path) => path.fmt(f), + UnixAddrKind::Unnamed => f.pad(""), + #[cfg(any(target_os = "android", target_os = "linux"))] + UnixAddrKind::Abstract(name) => fmt_abstract(name, f), + } + } +} + impl fmt::Display for UnixAddr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.kind() { @@ -792,58 +800,86 @@ impl SockAddr { format!("{}", self) } - /// Creates a `SockAddr` struct from libc's sockaddr. + /// Return the appropriate `SockAddr` type from a `sockaddr` of a certain size. /// - /// Supports only the following address families: Unix, Inet (v4 & v6), Netlink and System. - /// Returns None for unsupported families. + /// In C this would usually be done by casting. The `len` argument + /// should be the number of bytes in the `sockaddr` that are actually + /// allocated and valid. It must be at least as large as all the useful parts + /// of the structure. Note that in the case of a `sockaddr_un`, `len` need not + /// include the terminating null. /// /// # Safety - /// - /// unsafe because it takes a raw pointer as argument. The caller must - /// ensure that the pointer is valid. - #[cfg(not(target_os = "fuchsia"))] - pub unsafe fn from_raw_sockaddr(addr: *const libc::sockaddr) -> Option { - if addr.is_null() { - None - } else { - match AddressFamily::from_i32(i32::from((*addr).sa_family)) { - Some(AddressFamily::Unix) => None, - Some(AddressFamily::Inet) => Some(SockAddr::Inet( - InetAddr::V4(*(addr as *const libc::sockaddr_in)))), - Some(AddressFamily::Inet6) => Some(SockAddr::Inet( - InetAddr::V6(*(addr as *const libc::sockaddr_in6)))), - #[cfg(any(target_os = "android", target_os = "linux"))] - Some(AddressFamily::Netlink) => Some(SockAddr::Netlink( - NetlinkAddr(*(addr as *const libc::sockaddr_nl)))), - #[cfg(any(target_os = "ios", target_os = "macos"))] - Some(AddressFamily::System) => Some(SockAddr::SysControl( - SysControlAddr(*(addr as *const libc::sockaddr_ctl)))), - #[cfg(any(target_os = "android", target_os = "linux"))] - Some(AddressFamily::Packet) => Some(SockAddr::Link( - LinkAddr(*(addr as *const libc::sockaddr_ll)))), - #[cfg(any(target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "illumos", - target_os = "openbsd"))] - Some(AddressFamily::Link) => { - let ether_addr = LinkAddr(*(addr as *const libc::sockaddr_dl)); - if ether_addr.is_empty() { - None - } else { - Some(SockAddr::Link(ether_addr)) - } - }, - #[cfg(any(target_os = "android", target_os = "linux"))] - Some(AddressFamily::Vsock) => Some(SockAddr::Vsock( - VsockAddr(*(addr as *const libc::sockaddr_vm)))), - // Other address families are currently not supported and simply yield a None - // entry instead of a proper conversion to a `SockAddr`. - Some(_) | None => None, + /// `addr` must be a valid, non-null pointer, and `len` should describe the + /// number of bytes within `*addr` that are initialized and represent data. + pub unsafe fn from_raw_sockaddr(addr: *const libc::sockaddr, len: usize) -> Result { + let af = (*addr).sa_family; + if len < mem::size_of_val(&af) { + return Err(Errno::ENOTCONN); + } + + let af = AddressFamily::from_i32(af.into()).ok_or(Errno::EAFNOSUPPORT)?; + match af { + AddressFamily::Inet => { + use libc::sockaddr_in; + assert!(len as usize >= mem::size_of::()); + let sin = *(addr as *const sockaddr_in); + Ok(SockAddr::Inet(InetAddr::V4(sin))) + } + AddressFamily::Inet6 => { + use libc::sockaddr_in6; + assert!(len as usize >= mem::size_of::()); + let sin6 = *(addr as *const sockaddr_in6); + Ok(SockAddr::Inet(InetAddr::V6(sin6))) + } + AddressFamily::Unix => { + use libc::sockaddr_un; + let pathlen = len - offset_of!(sockaddr_un, sun_path); + let sun = *(addr as *const sockaddr_un); + Ok(SockAddr::Unix(UnixAddr::from_raw_parts(sun, pathlen))) + } + #[cfg(any(target_os = "android", target_os = "linux"))] + AddressFamily::Packet => { + // Don't assert anything about the size. + // Apparently the Linux kernel can return smaller sizes when + // the value in the last element of sockaddr_ll (`sll_addr`) is + // smaller than the declared size of that field + let sll = *(addr as *const libc::sockaddr_ll); + Ok(SockAddr::Link(LinkAddr(sll))) + } + #[cfg(any(target_os = "android", target_os = "linux"))] + AddressFamily::Netlink => { + let snl = *(addr as *const libc::sockaddr_nl); + Ok(SockAddr::Netlink(NetlinkAddr(snl))) + } + #[cfg(any(target_os = "android", target_os = "linux"))] + AddressFamily::Alg => { + let salg = *(addr as *const libc::sockaddr_alg); + Ok(SockAddr::Alg(AlgAddr(salg))) + } + #[cfg(any(target_os = "android", target_os = "linux"))] + AddressFamily::Vsock => { + let svm = *(addr as *const libc::sockaddr_vm); + Ok(SockAddr::Vsock(VsockAddr(svm))) + } + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "illumos", + target_os = "openbsd"))] + AddressFamily::Link => { + let ether_addr = LinkAddr(*(addr as *const libc::sockaddr_dl)); + Ok(SockAddr::Link(ether_addr)) + } + #[cfg(any(target_os = "ios", target_os = "macos"))] + AddressFamily::System => { + let sctl = SysControlAddr(*(addr as *const libc::sockaddr_ctl)); + Ok(SockAddr::SysControl(sctl)) } + _ => Err(Errno::EAFNOSUPPORT), } + } /// Conversion from nix's SockAddr type to the underlying libc sockaddr type. @@ -1381,8 +1417,12 @@ mod tests { fn test_macos_loopback_datalink_addr() { 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 _sock_addr = unsafe { SockAddr::from_raw_sockaddr(sa) }; - assert!(_sock_addr.is_none()); + let sock_addr = unsafe { SockAddr::from_raw_sockaddr(sa, bytes.len()).unwrap() }; + if let SockAddr::Link(link_addr) = sock_addr { + assert!(link_addr.is_empty()) + } else { + panic!("bad family") + } } #[cfg(any(target_os = "dragonfly", @@ -1396,11 +1436,7 @@ mod tests { let bytes = [20i8, 18, 7, 0, 6, 3, 6, 0, 101, 110, 48, 24, 101, -112, -35, 76, -80]; let ptr = bytes.as_ptr(); let sa = ptr as *const libc::sockaddr; - let _sock_addr = unsafe { SockAddr::from_raw_sockaddr(sa) }; - - assert!(_sock_addr.is_some()); - - let sock_addr = _sock_addr.unwrap(); + let sock_addr = unsafe { SockAddr::from_raw_sockaddr(sa, bytes.len()).unwrap() }; assert_eq!(sock_addr.family(), AddressFamily::Link); @@ -1418,11 +1454,7 @@ mod tests { 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; - let _sock_addr = unsafe { SockAddr::from_raw_sockaddr(sa) }; - - assert!(_sock_addr.is_some()); - - let sock_addr = _sock_addr.unwrap(); + let sock_addr = unsafe { SockAddr::from_raw_sockaddr(sa, bytes.len()).unwrap() }; assert_eq!(sock_addr.family(), AddressFamily::Link); diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 97eea3dcb1..5bc44bb6a5 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -5,7 +5,6 @@ use cfg_if::cfg_if; use crate::{Result, errno::Errno}; use libc::{self, c_void, c_int, iovec, socklen_t, size_t, CMSG_FIRSTHDR, CMSG_NXTHDR, CMSG_DATA, CMSG_LEN}; -use memoffset::offset_of; use std::{mem, ptr, slice}; use std::os::unix::io::RawFd; #[cfg(all(target_os = "linux"))] @@ -1320,7 +1319,7 @@ pub fn recvmmsg<'a, I>( // Addresses should be pre-allocated. pack_mhdr_to_receive will store them // as raw pointers, so we may not move them. Turn the vec into a boxed // slice so we won't inadvertently reallocate the vec. - let mut addresses = vec![mem::MaybeUninit::uninit(); num_messages] + let mut addresses = vec![mem::MaybeUninit::::uninit(); num_messages] .into_boxed_slice(); let results: Vec<_> = iter.enumerate().map(|(i, d)| { @@ -1355,7 +1354,7 @@ pub fn recvmmsg<'a, I>( Ok(output .into_iter() .take(ret as usize) - .zip(addresses.iter().map(|addr| unsafe{addr.assume_init()})) + .zip(addresses.iter()) .zip(results.into_iter()) .map(|((mmsghdr, address), (msg_controllen, cmsg_buffer))| { unsafe { @@ -1363,7 +1362,7 @@ pub fn recvmmsg<'a, I>( mmsghdr.msg_hdr, mmsghdr.msg_len as isize, msg_controllen, - address, + address.as_ptr() as *const sockaddr, cmsg_buffer ) } @@ -1375,7 +1374,7 @@ unsafe fn read_mhdr<'a, 'b>( mhdr: msghdr, r: isize, msg_controllen: usize, - address: sockaddr_storage, + address: *const sockaddr, cmsg_buffer: &'a mut Option<&'b mut Vec> ) -> RecvMsg<'b> { let cmsghdr = { @@ -1393,10 +1392,7 @@ unsafe fn read_mhdr<'a, 'b>( }.as_ref() }; - let address = sockaddr_storage_to_addr( - &address , - mhdr.msg_namelen as usize - ).ok(); + let address = SockAddr::from_raw_sockaddr(address, mhdr.msg_namelen as usize).ok(); RecvMsg { bytes: r as usize, @@ -1516,7 +1512,7 @@ pub fn recvmsg<'a>(fd: RawFd, iov: &[IoVec<&mut [u8]>], mut cmsg_buffer: Option<&'a mut Vec>, flags: MsgFlags) -> Result> { - let mut address = mem::MaybeUninit::uninit(); + let mut address = mem::MaybeUninit::::uninit(); let (msg_controllen, mut mhdr) = unsafe { pack_mhdr_to_receive(&iov, &mut cmsg_buffer, address.as_mut_ptr()) @@ -1526,7 +1522,7 @@ pub fn recvmsg<'a>(fd: RawFd, iov: &[IoVec<&mut [u8]>], let r = Errno::result(ret)?; - Ok(unsafe { read_mhdr(mhdr, r, msg_controllen, address.assume_init(), &mut cmsg_buffer) }) + Ok(unsafe { read_mhdr(mhdr, r, msg_controllen, address.as_ptr() as *const sockaddr, &mut cmsg_buffer) }) } @@ -1668,7 +1664,7 @@ pub fn recvfrom(sockfd: RawFd, buf: &mut [u8]) -> Result<(usize, Option)> { unsafe { - let mut addr: sockaddr_storage = mem::zeroed(); + let mut addr = mem::MaybeUninit::::uninit(); let mut len = mem::size_of::() as socklen_t; let ret = Errno::result(libc::recvfrom( @@ -1676,10 +1672,10 @@ pub fn recvfrom(sockfd: RawFd, buf: &mut [u8]) buf.as_ptr() as *mut c_void, buf.len() as size_t, 0, - &mut addr as *mut libc::sockaddr_storage as *mut libc::sockaddr, + addr.as_mut_ptr() as *mut libc::sockaddr, &mut len as *mut socklen_t))? as usize; - match sockaddr_storage_to_addr(&addr, len as usize) { + match SockAddr::from_raw_sockaddr(addr.as_ptr() as _, len as usize) { Err(Errno::ENOTCONN) => Ok((ret, None)), Ok(addr) => Ok((ret, Some(addr))), Err(e) => Err(e) @@ -1765,7 +1761,7 @@ pub fn setsockopt(fd: RawFd, opt: O, val: &O::Val) -> Result<()> /// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html) pub fn getpeername(fd: RawFd) -> Result { unsafe { - let mut addr = mem::MaybeUninit::uninit(); + let mut addr = mem::MaybeUninit::::uninit(); let mut len = mem::size_of::() as socklen_t; let ret = libc::getpeername( @@ -1776,7 +1772,7 @@ pub fn getpeername(fd: RawFd) -> Result { Errno::result(ret)?; - sockaddr_storage_to_addr(&addr.assume_init(), len as usize) + SockAddr::from_raw_sockaddr(addr.as_ptr() as _, len as usize) } } @@ -1785,7 +1781,7 @@ pub fn getpeername(fd: RawFd) -> Result { /// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html) pub fn getsockname(fd: RawFd) -> Result { unsafe { - let mut addr = mem::MaybeUninit::uninit(); + let mut addr = mem::MaybeUninit::::uninit(); let mut len = mem::size_of::() as socklen_t; let ret = libc::getsockname( @@ -1796,90 +1792,10 @@ pub fn getsockname(fd: RawFd) -> Result { Errno::result(ret)?; - sockaddr_storage_to_addr(&addr.assume_init(), len as usize) + SockAddr::from_raw_sockaddr(addr.as_ptr() as _, len as usize) } } -/// Return the appropriate `SockAddr` type from a `sockaddr_storage` of a -/// certain size. -/// -/// In C this would usually be done by casting. The `len` argument -/// should be the number of bytes in the `sockaddr_storage` that are actually -/// allocated and valid. It must be at least as large as all the useful parts -/// of the structure. Note that in the case of a `sockaddr_un`, `len` need not -/// include the terminating null. -pub fn sockaddr_storage_to_addr( - addr: &sockaddr_storage, - len: usize) -> Result { - - assert!(len <= mem::size_of::()); - if len < mem::size_of_val(&addr.ss_family) { - return Err(Errno::ENOTCONN); - } - - match c_int::from(addr.ss_family) { - libc::AF_INET => { - assert!(len as usize >= mem::size_of::()); - let sin = unsafe { - *(addr as *const sockaddr_storage as *const sockaddr_in) - }; - Ok(SockAddr::Inet(InetAddr::V4(sin))) - } - libc::AF_INET6 => { - assert!(len as usize >= mem::size_of::()); - let sin6 = unsafe { - *(addr as *const _ as *const sockaddr_in6) - }; - Ok(SockAddr::Inet(InetAddr::V6(sin6))) - } - libc::AF_UNIX => { - let pathlen = len - offset_of!(sockaddr_un, sun_path); - unsafe { - let sun = *(addr as *const _ as *const sockaddr_un); - Ok(SockAddr::Unix(UnixAddr::from_raw_parts(sun, pathlen))) - } - } - #[cfg(any(target_os = "android", target_os = "linux"))] - libc::AF_PACKET => { - use libc::sockaddr_ll; - // Don't assert anything about the size. - // Apparently the Linux kernel can return smaller sizes when - // the value in the last element of sockaddr_ll (`sll_addr`) is - // smaller than the declared size of that field - let sll = unsafe { - *(addr as *const _ as *const sockaddr_ll) - }; - Ok(SockAddr::Link(LinkAddr(sll))) - } - #[cfg(any(target_os = "android", target_os = "linux"))] - libc::AF_NETLINK => { - use libc::sockaddr_nl; - let snl = unsafe { - *(addr as *const _ as *const sockaddr_nl) - }; - Ok(SockAddr::Netlink(NetlinkAddr(snl))) - } - #[cfg(any(target_os = "android", target_os = "linux"))] - libc::AF_ALG => { - use libc::sockaddr_alg; - let salg = unsafe { - *(addr as *const _ as *const sockaddr_alg) - }; - Ok(SockAddr::Alg(AlgAddr(salg))) - } - #[cfg(any(target_os = "android", target_os = "linux"))] - libc::AF_VSOCK => { - use libc::sockaddr_vm; - let svm = unsafe { - *(addr as *const _ as *const sockaddr_vm) - }; - Ok(SockAddr::Vsock(VsockAddr(svm))) - } - af => panic!("unexpected address family {}", af), - } -} - - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum Shutdown { /// Further receptions will be disallowed. diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 0f6fac6664..0adb457a88 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -1,4 +1,4 @@ -use nix::sys::socket::{AddressFamily, InetAddr, SockAddr, UnixAddr, getsockname, sockaddr, sockaddr_in6, sockaddr_storage_to_addr}; +use nix::sys::socket::{AddressFamily, InetAddr, SockAddr, UnixAddr, getsockname, sockaddr, sockaddr_in6}; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; use std::mem::{self, MaybeUninit}; @@ -35,7 +35,7 @@ pub fn test_inetv4_addr_to_sock_addr() { } #[test] -pub fn test_inetv4_addr_roundtrip_sockaddr_storage_to_addr() { +pub fn test_inetv4_addr_roundtrip_sockaddr_from_raw() { let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap(); let addr = InetAddr::from_std(&actual); let sockaddr = SockAddr::new_inet(addr); @@ -47,13 +47,13 @@ pub fn test_inetv4_addr_roundtrip_sockaddr_storage_to_addr() { assert_eq!(mem::size_of::(), ffi_size as usize); unsafe { storage_ptr.copy_from_nonoverlapping(ffi_ptr as *const sockaddr, 1); - (storage.assume_init(), ffi_size) + (storage, ffi_size) } }; - let from_storage = sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap(); + let from_storage = unsafe { SockAddr::from_raw_sockaddr(storage.as_ptr() as _, ffi_size as usize).unwrap() }; assert_eq!(from_storage, sockaddr); - let from_storage = sockaddr_storage_to_addr(&storage, mem::size_of::()).unwrap(); + let from_storage = unsafe { SockAddr::from_raw_sockaddr(storage.as_ptr() as _, mem::size_of::()).unwrap() }; assert_eq!(from_storage, sockaddr); } @@ -79,7 +79,7 @@ pub fn test_inetv6_addr_to_sock_addr() { assert_eq!(actual, addr.to_std()); } #[test] -pub fn test_inetv6_addr_roundtrip_sockaddr_storage_to_addr() { +pub fn test_inetv6_addr_roundtrip_sockaddr_from_raw() { let port: u16 = 3000; let flowinfo: u32 = 1; let scope_id: u32 = 2; @@ -96,13 +96,13 @@ pub fn test_inetv6_addr_roundtrip_sockaddr_storage_to_addr() { assert_eq!(mem::size_of::(), ffi_size as usize); unsafe { storage_ptr.copy_from_nonoverlapping((ffi_ptr as *const sockaddr).cast::(), 1); - (storage.assume_init(), ffi_size) + (storage, ffi_size) } }; - let from_storage = sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap(); + let from_storage = unsafe { SockAddr::from_raw_sockaddr(storage.as_ptr() as _, ffi_size as usize).unwrap() }; assert_eq!(from_storage, sockaddr); - let from_storage = sockaddr_storage_to_addr(&storage, mem::size_of::()).unwrap(); + let from_storage = unsafe { SockAddr::from_raw_sockaddr(storage.as_ptr() as _, mem::size_of::()).unwrap() }; assert_eq!(from_storage, sockaddr); } @@ -1218,17 +1218,13 @@ pub fn test_syscontrol() { target_os = "openbsd", ))] fn loopback_address(family: AddressFamily) -> Option { - use std::io; - use std::io::Write; use nix::ifaddrs::getifaddrs; use nix::net::if_::*; let addrs = match getifaddrs() { Ok(iter) => iter, Err(e) => { - let stdioerr = io::stderr(); - let mut handle = stdioerr.lock(); - writeln!(handle, "getifaddrs: {:?}", e).unwrap(); + eprintln!("getifaddrs: {:?}", e); return None; }, };