1
- use nix:: sys:: socket:: { AddressFamily , InetAddr , UnixAddr , getsockname} ;
1
+ use nix:: sys:: socket:: { AddressFamily , InetAddr , SockAddr , UnixAddr , getsockname, sockaddr , sockaddr_in6 , sockaddr_storage_to_addr } ;
2
2
use std:: collections:: hash_map:: DefaultHasher ;
3
3
use std:: hash:: { Hash , Hasher } ;
4
+ use std:: mem:: { self , MaybeUninit } ;
4
5
use std:: net:: { self , Ipv6Addr , SocketAddr , SocketAddrV6 } ;
5
6
use std:: os:: unix:: io:: RawFd ;
6
7
use std:: path:: Path ;
7
8
use std:: slice;
8
9
use std:: str:: FromStr ;
9
- use libc:: c_char;
10
+ use libc:: { c_char, sockaddr_storage } ;
10
11
#[ cfg( any( target_os = "linux" , target_os= "android" ) ) ]
11
12
use crate :: * ;
12
13
13
14
#[ test]
14
15
pub fn test_inetv4_addr_to_sock_addr ( ) {
15
16
let actual: net:: SocketAddr = FromStr :: from_str ( "127.0.0.1:3000" ) . unwrap ( ) ;
16
17
let addr = InetAddr :: from_std ( & actual) ;
18
+ let sockaddr = SockAddr :: new_inet ( addr) ;
17
19
18
20
match addr {
19
21
InetAddr :: V4 ( addr) => {
@@ -31,6 +33,22 @@ pub fn test_inetv4_addr_to_sock_addr() {
31
33
32
34
let inet = addr. to_std ( ) ;
33
35
assert_eq ! ( actual, inet) ;
36
+
37
+ let ( storage, ffi_size) = {
38
+ let mut storage = MaybeUninit :: < sockaddr_storage > :: zeroed ( ) ;
39
+ let storage_ptr = storage. as_mut_ptr ( ) . cast :: < sockaddr > ( ) ;
40
+ let ( ffi_ptr, ffi_size) = sockaddr. as_ffi_pair ( ) ;
41
+ assert_eq ! ( mem:: size_of:: <sockaddr>( ) , ffi_size as usize ) ;
42
+ unsafe {
43
+ storage_ptr. copy_from_nonoverlapping ( ffi_ptr as * const sockaddr , 1 ) ;
44
+ ( storage. assume_init ( ) , ffi_size)
45
+ }
46
+ } ;
47
+
48
+ let from_storage = sockaddr_storage_to_addr ( & storage, ffi_size as usize ) . unwrap ( ) ;
49
+ assert_eq ! ( from_storage, sockaddr) ;
50
+ let from_storage = sockaddr_storage_to_addr ( & storage, mem:: size_of :: < sockaddr_storage > ( ) ) . unwrap ( ) ;
51
+ assert_eq ! ( from_storage, sockaddr) ;
34
52
}
35
53
36
54
#[ test]
@@ -42,6 +60,7 @@ pub fn test_inetv6_addr_to_sock_addr() {
42
60
43
61
let actual = SocketAddr :: V6 ( SocketAddrV6 :: new ( ip, port, flowinfo, scope_id) ) ;
44
62
let addr = InetAddr :: from_std ( & actual) ;
63
+ let sockaddr = SockAddr :: new_inet ( addr) ;
45
64
46
65
match addr {
47
66
InetAddr :: V6 ( addr) => {
@@ -53,6 +72,24 @@ pub fn test_inetv6_addr_to_sock_addr() {
53
72
}
54
73
55
74
assert_eq ! ( actual, addr. to_std( ) ) ;
75
+
76
+ let ( storage, ffi_size) = {
77
+ let mut storage = MaybeUninit :: < sockaddr_storage > :: zeroed ( ) ;
78
+ let storage_ptr = storage. as_mut_ptr ( ) . cast :: < sockaddr_in6 > ( ) ;
79
+ let ( ffi_ptr, ffi_size) = sockaddr. as_ffi_pair ( ) ;
80
+ // XXX this does not pass.
81
+ // assert_eq!(mem::size_of::<sockaddr>(), ffi_size as usize);
82
+ assert_eq ! ( mem:: size_of:: <sockaddr_in6>( ) , ffi_size as usize ) ;
83
+ unsafe {
84
+ storage_ptr. copy_from_nonoverlapping ( ( ffi_ptr as * const sockaddr ) . cast :: < sockaddr_in6 > ( ) , 1 ) ;
85
+ ( storage. assume_init ( ) , ffi_size)
86
+ }
87
+ } ;
88
+
89
+ let from_storage = sockaddr_storage_to_addr ( & storage, ffi_size as usize ) . unwrap ( ) ;
90
+ assert_eq ! ( from_storage, sockaddr) ;
91
+ let from_storage = sockaddr_storage_to_addr ( & storage, mem:: size_of :: < sockaddr_storage > ( ) ) . unwrap ( ) ;
92
+ assert_eq ! ( from_storage, sockaddr) ;
56
93
}
57
94
58
95
#[ test]
@@ -1169,7 +1206,6 @@ fn loopback_address(family: AddressFamily) -> Option<nix::ifaddrs::InterfaceAddr
1169
1206
use std:: io;
1170
1207
use std:: io:: Write ;
1171
1208
use nix:: ifaddrs:: getifaddrs;
1172
- use nix:: sys:: socket:: SockAddr ;
1173
1209
use nix:: net:: if_:: * ;
1174
1210
1175
1211
let addrs = match getifaddrs ( ) {
0 commit comments