mirror of
https://gitee.com/openharmony/third_party_rust_nix
synced 2025-01-05 23:09:03 +00:00
Relax assertions in sockaddr_storage_to_addr to match the documentation.
Fixes #1479
This commit is contained in:
parent
5ed5bb634f
commit
d133d3db76
@ -1780,21 +1780,21 @@ pub fn sockaddr_storage_to_addr(
|
||||
addr: &sockaddr_storage,
|
||||
len: usize) -> Result<SockAddr> {
|
||||
|
||||
assert!(len <= mem::size_of::<sockaddr_un>());
|
||||
assert!(len <= mem::size_of::<sockaddr_storage>());
|
||||
if len < mem::size_of_val(&addr.ss_family) {
|
||||
return Err(Error::from(Errno::ENOTCONN));
|
||||
}
|
||||
|
||||
match c_int::from(addr.ss_family) {
|
||||
libc::AF_INET => {
|
||||
assert_eq!(len as usize, mem::size_of::<sockaddr_in>());
|
||||
assert!(len as usize >= mem::size_of::<sockaddr_in>());
|
||||
let sin = unsafe {
|
||||
*(addr as *const sockaddr_storage as *const sockaddr_in)
|
||||
};
|
||||
Ok(SockAddr::Inet(InetAddr::V4(sin)))
|
||||
}
|
||||
libc::AF_INET6 => {
|
||||
assert_eq!(len as usize, mem::size_of::<sockaddr_in6>());
|
||||
assert!(len as usize >= mem::size_of::<sockaddr_in6>());
|
||||
let sin6 = unsafe {
|
||||
*(addr as *const _ as *const sockaddr_in6)
|
||||
};
|
||||
@ -1810,10 +1810,10 @@ pub fn sockaddr_storage_to_addr(
|
||||
#[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
|
||||
assert!(len as usize <= mem::size_of::<sockaddr_ll>());
|
||||
let sll = unsafe {
|
||||
*(addr as *const _ as *const sockaddr_ll)
|
||||
};
|
||||
|
@ -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::<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;
|
||||
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user