From d133d3db7699bdf61441764d4278533539208ee1 Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Mon, 9 Aug 2021 22:45:54 -0700 Subject: Relax assertions in sockaddr_storage_to_addr to match the documentation. Fixes #1479 --- test/sys/test_socket.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 5471afe3..c43d0672 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -1,12 +1,13 @@ -use nix::sys::socket::{AddressFamily, InetAddr, UnixAddr, getsockname}; +use nix::sys::socket::{AddressFamily, InetAddr, SockAddr, UnixAddr, getsockname, sockaddr, sockaddr_in6, sockaddr_storage_to_addr}; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; +use std::mem::{self, MaybeUninit}; use std::net::{self, Ipv6Addr, SocketAddr, SocketAddrV6}; use std::os::unix::io::RawFd; use std::path::Path; use std::slice; use std::str::FromStr; -use libc::c_char; +use libc::{c_char, sockaddr_storage}; #[cfg(any(target_os = "linux", target_os= "android"))] use crate::*; @@ -33,6 +34,29 @@ pub fn test_inetv4_addr_to_sock_addr() { assert_eq!(actual, inet); } +#[test] +pub fn test_inetv4_addr_roundtrip_sockaddr_storage_to_addr() { + 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); + + let (storage, ffi_size) = { + let mut storage = MaybeUninit::::zeroed(); + let storage_ptr = storage.as_mut_ptr().cast::(); + let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair(); + 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) + } + }; + + let from_storage = sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap(); + assert_eq!(from_storage, sockaddr); + let from_storage = sockaddr_storage_to_addr(&storage, mem::size_of::()).unwrap(); + assert_eq!(from_storage, sockaddr); +} + #[test] pub fn test_inetv6_addr_to_sock_addr() { let port: u16 = 3000; @@ -54,6 +78,33 @@ 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() { + let port: u16 = 3000; + let flowinfo: u32 = 1; + let scope_id: u32 = 2; + let ip: Ipv6Addr = "fe80::1".parse().unwrap(); + + let actual = SocketAddr::V6(SocketAddrV6::new(ip, port, flowinfo, scope_id)); + let addr = InetAddr::from_std(&actual); + let sockaddr = SockAddr::new_inet(addr); + + let (storage, ffi_size) = { + let mut storage = MaybeUninit::::zeroed(); + let storage_ptr = storage.as_mut_ptr().cast::(); + let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair(); + 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) + } + }; + + let from_storage = sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap(); + assert_eq!(from_storage, sockaddr); + let from_storage = sockaddr_storage_to_addr(&storage, mem::size_of::()).unwrap(); + assert_eq!(from_storage, sockaddr); +} #[test] pub fn test_path_to_sock_addr() { @@ -1169,7 +1220,6 @@ fn loopback_address(family: AddressFamily) -> Option