summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorKyle Huey <khuey@kylehuey.com>2021-08-09 22:45:54 -0700
committerKyle Huey <khuey@kylehuey.com>2021-08-17 19:26:12 -0700
commitd133d3db7699bdf61441764d4278533539208ee1 (patch)
tree10ba7a8d3258d38c1f982e150af30276e57ae340 /test
parent5ed5bb634fbef82c5dcd6e64e9b609dff08e378d (diff)
downloadnix-d133d3db7699bdf61441764d4278533539208ee1.zip
Relax assertions in sockaddr_storage_to_addr to match the documentation.
Fixes #1479
Diffstat (limited to 'test')
-rw-r--r--test/sys/test_socket.rs56
1 files changed, 53 insertions, 3 deletions
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::*;
@@ -34,6 +35,29 @@ pub fn test_inetv4_addr_to_sock_addr() {
}
#[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::<sockaddr_storage>::zeroed();
+ let storage_ptr = storage.as_mut_ptr().cast::<sockaddr>();
+ let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair();
+ assert_eq!(mem::size_of::<sockaddr>(), 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::<sockaddr_storage>()).unwrap();
+ assert_eq!(from_storage, sockaddr);
+}
+
+#[test]
pub fn test_inetv6_addr_to_sock_addr() {
let port: u16 = 3000;
let flowinfo: u32 = 1;
@@ -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::<sockaddr_storage>::zeroed();
+ let storage_ptr = storage.as_mut_ptr().cast::<sockaddr_in6>();
+ let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair();
+ assert_eq!(mem::size_of::<sockaddr_in6>(), ffi_size as usize);
+ unsafe {
+ storage_ptr.copy_from_nonoverlapping((ffi_ptr as *const sockaddr).cast::<sockaddr_in6>(), 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::<sockaddr_storage>()).unwrap();
+ assert_eq!(from_storage, sockaddr);
+}
#[test]
pub fn test_path_to_sock_addr() {
@@ -1169,7 +1220,6 @@ fn loopback_address(family: AddressFamily) -> Option<nix::ifaddrs::InterfaceAddr
use std::io;
use std::io::Write;
use nix::ifaddrs::getifaddrs;
- use nix::sys::socket::SockAddr;
use nix::net::if_::*;
let addrs = match getifaddrs() {