@@ -17,14 +17,100 @@ use crate::time::Duration;
17
17
18
18
use core:: ffi:: { c_int, c_long, c_ulong, c_ushort} ;
19
19
20
+ #[ allow( non_camel_case_types) ]
20
21
pub type wrlen_t = i32 ;
21
22
22
23
pub 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
+ }
28
114
}
29
115
30
116
pub struct Socket ( OwnedSocket ) ;
@@ -102,8 +188,8 @@ where
102
188
impl Socket {
103
189
pub fn new ( addr : & SocketAddr , ty : c_int ) -> io:: Result < Socket > {
104
190
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 ,
107
193
} ;
108
194
let socket = unsafe {
109
195
c:: WSASocketW (
@@ -157,7 +243,7 @@ impl Socket {
157
243
return Err ( io:: Error :: ZERO_TIMEOUT ) ;
158
244
}
159
245
160
- let mut timeout = c:: timeval {
246
+ let mut timeout = c:: TIMEVAL {
161
247
tv_sec : cmp:: min ( timeout. as_secs ( ) , c_long:: MAX as u64 ) as c_long ,
162
248
tv_usec : timeout. subsec_micros ( ) as c_long ,
163
249
} ;
@@ -167,7 +253,7 @@ impl Socket {
167
253
}
168
254
169
255
let fds = {
170
- let mut fds = unsafe { mem:: zeroed :: < c:: fd_set > ( ) } ;
256
+ let mut fds = unsafe { mem:: zeroed :: < c:: FD_SET > ( ) } ;
171
257
fds. fd_count = 1 ;
172
258
fds. fd_array [ 0 ] = self . as_raw ( ) ;
173
259
fds
@@ -295,8 +381,8 @@ impl Socket {
295
381
buf : & mut [ u8 ] ,
296
382
flags : c_int ,
297
383
) -> 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 ;
300
386
let length = cmp:: min ( buf. len ( ) , <wrlen_t >:: MAX as usize ) as wrlen_t ;
301
387
302
388
// On unix when a socket is shut down all further reads return 0, so we
@@ -399,7 +485,7 @@ impl Socket {
399
485
}
400
486
401
487
pub fn set_linger ( & self , linger : Option < Duration > ) -> io:: Result < ( ) > {
402
- let linger = c:: linger {
488
+ let linger = c:: LINGER {
403
489
l_onoff : linger. is_some ( ) as c_ushort ,
404
490
l_linger : linger. unwrap_or_default ( ) . as_secs ( ) as c_ushort ,
405
491
} ;
@@ -408,7 +494,7 @@ impl Socket {
408
494
}
409
495
410
496
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 ) ?;
412
498
413
499
Ok ( ( val. l_onoff != 0 ) . then ( || Duration :: from_secs ( val. l_linger as u64 ) ) )
414
500
}
0 commit comments