@@ -17,14 +17,101 @@ 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+
29+ use crate :: sys:: c:: { self , ADDRESS_FAMILY , ADDRINFOA , SOCKADDR , SOCKET } ;
30+ use core:: ffi:: { c_char, c_int, c_uint, c_ulong, c_ushort, c_void} ;
31+
32+ // re-exports from Windows API bindings.
33+ pub use crate :: sys:: c:: {
34+ bind, connect, freeaddrinfo, getpeername, getsockname, getsockopt, listen, setsockopt,
35+ ADDRESS_FAMILY as sa_family_t, ADDRINFOA as addrinfo, IPPROTO_IP , IPPROTO_IPV6 ,
36+ IPV6_ADD_MEMBERSHIP , IPV6_DROP_MEMBERSHIP , IPV6_MULTICAST_LOOP , IPV6_V6ONLY ,
37+ IP_ADD_MEMBERSHIP , IP_DROP_MEMBERSHIP , IP_MULTICAST_LOOP , IP_MULTICAST_TTL , IP_TTL ,
38+ SOCKADDR as sockaddr, SOCKADDR_STORAGE as sockaddr_storage, SOCK_DGRAM , SOCK_STREAM ,
39+ SOL_SOCKET , SO_BROADCAST , SO_RCVTIMEO , SO_SNDTIMEO ,
40+ } ;
41+
42+ #[ allow( non_camel_case_types) ]
43+ pub type socklen_t = c_int ;
44+
45+ pub const AF_INET : socklen_t = c:: AF_INET as socklen_t ;
46+ pub const AF_INET6 : socklen_t = c:: AF_INET6 as socklen_t ;
47+
48+ // The following two structs use a union in the generated bindings but
49+ // our cross-platform code expects a normal field so it's redefined here.
50+ // As a consequence, we also need to redefine other structs that use this struct.
51+ #[ repr( C ) ]
52+ #[ derive( Copy , Clone ) ]
53+ pub struct in_addr {
54+ pub s_addr : u32 ,
55+ }
56+
57+ #[ repr( C ) ]
58+ #[ derive( Copy , Clone ) ]
59+ pub struct in6_addr {
60+ pub s6_addr : [ u8 ; 16 ] ,
61+ }
62+
63+ #[ repr( C ) ]
64+ pub struct ip_mreq {
65+ pub imr_multiaddr : in_addr ,
66+ pub imr_interface : in_addr ,
67+ }
68+
69+ #[ repr( C ) ]
70+ pub struct ipv6_mreq {
71+ pub ipv6mr_multiaddr : in6_addr ,
72+ pub ipv6mr_interface : c_uint ,
73+ }
74+
75+ #[ repr( C ) ]
76+ #[ derive( Copy , Clone ) ]
77+ pub struct sockaddr_in {
78+ pub sin_family : ADDRESS_FAMILY ,
79+ pub sin_port : c_ushort ,
80+ pub sin_addr : in_addr ,
81+ pub sin_zero : [ c_char ; 8 ] ,
82+ }
83+
84+ #[ repr( C ) ]
85+ #[ derive( Copy , Clone ) ]
86+ pub struct sockaddr_in6 {
87+ pub sin6_family : ADDRESS_FAMILY ,
88+ pub sin6_port : c_ushort ,
89+ pub sin6_flowinfo : c_ulong ,
90+ pub sin6_addr : in6_addr ,
91+ pub sin6_scope_id : c_ulong ,
92+ }
93+
94+ pub unsafe fn send ( socket : SOCKET , buf : * const c_void , len : c_int , flags : c_int ) -> c_int {
95+ c:: send ( socket, buf. cast :: < u8 > ( ) , len, flags)
96+ }
97+ pub unsafe fn sendto (
98+ socket : SOCKET ,
99+ buf : * const c_void ,
100+ len : c_int ,
101+ flags : c_int ,
102+ addr : * const SOCKADDR ,
103+ addrlen : c_int ,
104+ ) -> c_int {
105+ c:: sendto ( socket, buf. cast :: < u8 > ( ) , len, flags, addr, addrlen)
106+ }
107+ pub unsafe fn getaddrinfo (
108+ node : * const c_char ,
109+ service : * const c_char ,
110+ hints : * const ADDRINFOA ,
111+ res : * mut * mut ADDRINFOA ,
112+ ) -> c_int {
113+ c:: getaddrinfo ( node. cast :: < u8 > ( ) , service. cast :: < u8 > ( ) , hints, res)
114+ }
28115}
29116
30117pub struct Socket ( OwnedSocket ) ;
@@ -102,8 +189,8 @@ where
102189impl Socket {
103190 pub fn new ( addr : & SocketAddr , ty : c_int ) -> io:: Result < Socket > {
104191 let family = match * addr {
105- SocketAddr :: V4 ( ..) => c :: AF_INET ,
106- SocketAddr :: V6 ( ..) => c :: AF_INET6 ,
192+ SocketAddr :: V4 ( ..) => netc :: AF_INET ,
193+ SocketAddr :: V6 ( ..) => netc :: AF_INET6 ,
107194 } ;
108195 let socket = unsafe {
109196 c:: WSASocketW (
@@ -157,7 +244,7 @@ impl Socket {
157244 return Err ( io:: Error :: ZERO_TIMEOUT ) ;
158245 }
159246
160- let mut timeout = c:: timeval {
247+ let mut timeout = c:: TIMEVAL {
161248 tv_sec : cmp:: min ( timeout. as_secs ( ) , c_long:: MAX as u64 ) as c_long ,
162249 tv_usec : timeout. subsec_micros ( ) as c_long ,
163250 } ;
@@ -167,7 +254,7 @@ impl Socket {
167254 }
168255
169256 let fds = {
170- let mut fds = unsafe { mem:: zeroed :: < c:: fd_set > ( ) } ;
257+ let mut fds = unsafe { mem:: zeroed :: < c:: FD_SET > ( ) } ;
171258 fds. fd_count = 1 ;
172259 fds. fd_array [ 0 ] = self . as_raw ( ) ;
173260 fds
@@ -295,8 +382,8 @@ impl Socket {
295382 buf : & mut [ u8 ] ,
296383 flags : c_int ,
297384 ) -> 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 ;
385+ let mut storage = unsafe { mem:: zeroed :: < netc :: sockaddr_storage > ( ) } ;
386+ let mut addrlen = mem:: size_of_val ( & storage) as netc :: socklen_t ;
300387 let length = cmp:: min ( buf. len ( ) , <wrlen_t >:: MAX as usize ) as wrlen_t ;
301388
302389 // On unix when a socket is shut down all further reads return 0, so we
@@ -399,7 +486,7 @@ impl Socket {
399486 }
400487
401488 pub fn set_linger ( & self , linger : Option < Duration > ) -> io:: Result < ( ) > {
402- let linger = c:: linger {
489+ let linger = c:: LINGER {
403490 l_onoff : linger. is_some ( ) as c_ushort ,
404491 l_linger : linger. unwrap_or_default ( ) . as_secs ( ) as c_ushort ,
405492 } ;
@@ -408,7 +495,7 @@ impl Socket {
408495 }
409496
410497 pub fn linger ( & self ) -> io:: Result < Option < Duration > > {
411- let val: c:: linger = net:: getsockopt ( self , c:: SOL_SOCKET , c:: SO_LINGER ) ?;
498+ let val: c:: LINGER = net:: getsockopt ( self , c:: SOL_SOCKET , c:: SO_LINGER ) ?;
412499
413500 Ok ( ( val. l_onoff != 0 ) . then ( || Duration :: from_secs ( val. l_linger as u64 ) ) )
414501 }
0 commit comments