@@ -17,14 +17,100 @@ use crate::time::Duration;
1717
1818use core:: ffi:: { c_int, c_long, c_ulong, c_ushort} ;
1919
20+ #[ allow( non_camel_case_types) ]
2021pub type wrlen_t = i32 ;
2122
2223pub mod netc {
23- pub use crate :: sys:: c:: ADDRESS_FAMILY as sa_family_t;
24- pub use crate :: sys:: c:: ADDRINFOA as addrinfo;
25- pub use crate :: sys:: c:: SOCKADDR as sockaddr;
26- pub use crate :: sys:: c:: SOCKADDR_STORAGE_LH as sockaddr_storage;
27- pub use crate :: sys:: c:: * ;
24+ //! BSD socket compatibility shim
25+ //!
26+ //! Some Windows API types are not quite what's expected by our cross-platform
27+ //! net code. E.g. naming differences or different pointer types.
28+ use crate :: sys:: c:: { self , ADDRESS_FAMILY , ADDRINFOA , SOCKADDR , SOCKET } ;
29+ use core:: ffi:: { c_char, c_int, c_uint, c_ulong, c_ushort, c_void} ;
30+
31+ // re-exports from Windows API bindings.
32+ pub use crate :: sys:: c:: {
33+ bind, connect, freeaddrinfo, getpeername, getsockname, getsockopt, listen, setsockopt,
34+ ADDRESS_FAMILY as sa_family_t, ADDRINFOA as addrinfo, IPPROTO_IP , IPPROTO_IPV6 ,
35+ IPV6_ADD_MEMBERSHIP , IPV6_DROP_MEMBERSHIP , IPV6_MULTICAST_LOOP , IPV6_V6ONLY ,
36+ IP_ADD_MEMBERSHIP , IP_DROP_MEMBERSHIP , IP_MULTICAST_LOOP , IP_MULTICAST_TTL , IP_TTL ,
37+ SOCKADDR as sockaddr, SOCKADDR_STORAGE as sockaddr_storage, SOCK_DGRAM , SOCK_STREAM ,
38+ SOL_SOCKET , SO_BROADCAST , SO_RCVTIMEO , SO_SNDTIMEO ,
39+ } ;
40+
41+ #[ allow( non_camel_case_types) ]
42+ pub type socklen_t = c_int ;
43+
44+ pub const AF_INET : i32 = c:: AF_INET as i32 ;
45+ pub const AF_INET6 : i32 = c:: AF_INET6 as i32 ;
46+
47+ // The following two structs use a union in the generated bindings but
48+ // our cross-platform code expects a normal field so it's redefined here.
49+ // As a consequence, we also need to redefine other structs that use this struct.
50+ #[ repr( C ) ]
51+ #[ derive( Copy , Clone ) ]
52+ pub struct in_addr {
53+ pub s_addr : u32 ,
54+ }
55+
56+ #[ repr( C ) ]
57+ #[ derive( Copy , Clone ) ]
58+ pub struct in6_addr {
59+ pub s6_addr : [ u8 ; 16 ] ,
60+ }
61+
62+ #[ repr( C ) ]
63+ pub struct ip_mreq {
64+ pub imr_multiaddr : in_addr ,
65+ pub imr_interface : in_addr ,
66+ }
67+
68+ #[ repr( C ) ]
69+ pub struct ipv6_mreq {
70+ pub ipv6mr_multiaddr : in6_addr ,
71+ pub ipv6mr_interface : c_uint ,
72+ }
73+
74+ #[ repr( C ) ]
75+ #[ derive( Copy , Clone ) ]
76+ pub struct sockaddr_in {
77+ pub sin_family : ADDRESS_FAMILY ,
78+ pub sin_port : c_ushort ,
79+ pub sin_addr : in_addr ,
80+ pub sin_zero : [ c_char ; 8 ] ,
81+ }
82+
83+ #[ repr( C ) ]
84+ #[ derive( Copy , Clone ) ]
85+ pub struct sockaddr_in6 {
86+ pub sin6_family : ADDRESS_FAMILY ,
87+ pub sin6_port : c_ushort ,
88+ pub sin6_flowinfo : c_ulong ,
89+ pub sin6_addr : in6_addr ,
90+ pub sin6_scope_id : c_ulong ,
91+ }
92+
93+ pub unsafe fn send ( socket : SOCKET , buf : * const c_void , len : c_int , flags : c_int ) -> c_int {
94+ unsafe { c:: send ( socket, buf. cast :: < u8 > ( ) , len, flags) }
95+ }
96+ pub unsafe fn sendto (
97+ socket : SOCKET ,
98+ buf : * const c_void ,
99+ len : c_int ,
100+ flags : c_int ,
101+ addr : * const SOCKADDR ,
102+ addrlen : c_int ,
103+ ) -> c_int {
104+ unsafe { c:: sendto ( socket, buf. cast :: < u8 > ( ) , len, flags, addr, addrlen) }
105+ }
106+ pub unsafe fn getaddrinfo (
107+ node : * const c_char ,
108+ service : * const c_char ,
109+ hints : * const ADDRINFOA ,
110+ res : * mut * mut ADDRINFOA ,
111+ ) -> c_int {
112+ unsafe { c:: getaddrinfo ( node. cast :: < u8 > ( ) , service. cast :: < u8 > ( ) , hints, res) }
113+ }
28114}
29115
30116pub struct Socket ( OwnedSocket ) ;
@@ -102,8 +188,8 @@ where
102188impl Socket {
103189 pub fn new ( addr : & SocketAddr , ty : c_int ) -> io:: Result < Socket > {
104190 let family = match * addr {
105- SocketAddr :: V4 ( ..) => c :: AF_INET ,
106- SocketAddr :: V6 ( ..) => c :: AF_INET6 ,
191+ SocketAddr :: V4 ( ..) => netc :: AF_INET ,
192+ SocketAddr :: V6 ( ..) => netc :: AF_INET6 ,
107193 } ;
108194 let socket = unsafe {
109195 c:: WSASocketW (
@@ -157,7 +243,7 @@ impl Socket {
157243 return Err ( io:: Error :: ZERO_TIMEOUT ) ;
158244 }
159245
160- let mut timeout = c:: timeval {
246+ let mut timeout = c:: TIMEVAL {
161247 tv_sec : cmp:: min ( timeout. as_secs ( ) , c_long:: MAX as u64 ) as c_long ,
162248 tv_usec : timeout. subsec_micros ( ) as c_long ,
163249 } ;
@@ -167,7 +253,7 @@ impl Socket {
167253 }
168254
169255 let fds = {
170- let mut fds = unsafe { mem:: zeroed :: < c:: fd_set > ( ) } ;
256+ let mut fds = unsafe { mem:: zeroed :: < c:: FD_SET > ( ) } ;
171257 fds. fd_count = 1 ;
172258 fds. fd_array [ 0 ] = self . as_raw ( ) ;
173259 fds
@@ -295,8 +381,8 @@ impl Socket {
295381 buf : & mut [ u8 ] ,
296382 flags : c_int ,
297383 ) -> io:: Result < ( usize , SocketAddr ) > {
298- let mut storage = unsafe { mem:: zeroed :: < c:: SOCKADDR_STORAGE_LH > ( ) } ;
299- let mut addrlen = mem:: size_of_val ( & storage) as c :: socklen_t ;
384+ let mut storage = unsafe { mem:: zeroed :: < c:: SOCKADDR_STORAGE > ( ) } ;
385+ let mut addrlen = mem:: size_of_val ( & storage) as netc :: socklen_t ;
300386 let length = cmp:: min ( buf. len ( ) , <wrlen_t >:: MAX as usize ) as wrlen_t ;
301387
302388 // On unix when a socket is shut down all further reads return 0, so we
@@ -399,7 +485,7 @@ impl Socket {
399485 }
400486
401487 pub fn set_linger ( & self , linger : Option < Duration > ) -> io:: Result < ( ) > {
402- let linger = c:: linger {
488+ let linger = c:: LINGER {
403489 l_onoff : linger. is_some ( ) as c_ushort ,
404490 l_linger : linger. unwrap_or_default ( ) . as_secs ( ) as c_ushort ,
405491 } ;
@@ -408,7 +494,7 @@ impl Socket {
408494 }
409495
410496 pub fn linger ( & self ) -> io:: Result < Option < Duration > > {
411- let val: c:: linger = net:: getsockopt ( self , c:: SOL_SOCKET , c:: SO_LINGER ) ?;
497+ let val: c:: LINGER = net:: getsockopt ( self , c:: SOL_SOCKET , c:: SO_LINGER ) ?;
412498
413499 Ok ( ( val. l_onoff != 0 ) . then ( || Duration :: from_secs ( val. l_linger as u64 ) ) )
414500 }
0 commit comments