1 //! Extensions and types for the standard networking primitives.
2 //!
3 //! This module contains a number of extension traits for the types in
4 //! `std::net` for Windows-specific functionality.
5 
6 use std::cmp;
7 use std::io;
8 use std::mem;
9 use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
10 use std::net::{SocketAddr, TcpListener, TcpStream, UdpSocket};
11 use std::os::windows::prelude::*;
12 use std::sync::atomic::{AtomicUsize, Ordering};
13 
14 use winapi::ctypes::*;
15 use winapi::shared::guiddef::*;
16 use winapi::shared::in6addr::{in6_addr_u, IN6_ADDR};
17 use winapi::shared::inaddr::{in_addr_S_un, IN_ADDR};
18 use winapi::shared::minwindef::*;
19 use winapi::shared::minwindef::{FALSE, TRUE};
20 use winapi::shared::ntdef::*;
21 use winapi::shared::ws2def::SOL_SOCKET;
22 use winapi::shared::ws2def::*;
23 use winapi::shared::ws2ipdef::*;
24 use winapi::um::minwinbase::*;
25 use winapi::um::winsock2::*;
26 
27 /// A type to represent a buffer in which a socket address will be stored.
28 ///
29 /// This type is used with the `recv_from_overlapped` function on the
30 /// `UdpSocketExt` trait to provide space for the overlapped I/O operation to
31 /// fill in the address upon completion.
32 #[derive(Clone, Copy)]
33 pub struct SocketAddrBuf {
34     buf: SOCKADDR_STORAGE,
35     len: c_int,
36 }
37 
38 /// A type to represent a buffer in which an accepted socket's address will be
39 /// stored.
40 ///
41 /// This type is used with the `accept_overlapped` method on the
42 /// `TcpListenerExt` trait to provide space for the overlapped I/O operation to
43 /// fill in the socket addresses upon completion.
44 #[repr(C)]
45 pub struct AcceptAddrsBuf {
46     // For AcceptEx we've got the restriction that the addresses passed in that
47     // buffer need to be at least 16 bytes more than the maximum address length
48     // for the protocol in question, so add some extra here and there
49     local: SOCKADDR_STORAGE,
50     _pad1: [u8; 16],
51     remote: SOCKADDR_STORAGE,
52     _pad2: [u8; 16],
53 }
54 
55 /// The parsed return value of `AcceptAddrsBuf`.
56 pub struct AcceptAddrs<'a> {
57     local: LPSOCKADDR,
58     local_len: c_int,
59     remote: LPSOCKADDR,
60     remote_len: c_int,
61     _data: &'a AcceptAddrsBuf,
62 }
63 
64 struct WsaExtension {
65     guid: GUID,
66     val: AtomicUsize,
67 }
68 
69 /// Additional methods for the `TcpStream` type in the standard library.
70 pub trait TcpStreamExt {
71     /// Execute an overlapped read I/O operation on this TCP stream.
72     ///
73     /// This function will issue an overlapped I/O read (via `WSARecv`) on this
74     /// socket. The provided buffer will be filled in when the operation
75     /// completes and the given `OVERLAPPED` instance is used to track the
76     /// overlapped operation.
77     ///
78     /// If the operation succeeds, `Ok(Some(n))` is returned indicating how
79     /// many bytes were read. If the operation returns an error indicating that
80     /// the I/O is currently pending, `Ok(None)` is returned. Otherwise, the
81     /// error associated with the operation is returned and no overlapped
82     /// operation is enqueued.
83     ///
84     /// The number of bytes read will be returned as part of the completion
85     /// notification when the I/O finishes.
86     ///
87     /// # Unsafety
88     ///
89     /// This function is unsafe because the kernel requires that the `buf` and
90     /// `overlapped` pointers are valid until the end of the I/O operation. The
91     /// kernel also requires that `overlapped` is unique for this I/O operation
92     /// and is not in use for any other I/O.
93     ///
94     /// To safely use this function callers must ensure that these two input
95     /// pointers are valid until the I/O operation is completed, typically via
96     /// completion ports and waiting to receive the completion notification on
97     /// the port.
read_overlapped( &self, buf: &mut [u8], overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>98     unsafe fn read_overlapped(
99         &self,
100         buf: &mut [u8],
101         overlapped: *mut OVERLAPPED,
102     ) -> io::Result<Option<usize>>;
103 
104     /// Execute an overlapped write I/O operation on this TCP stream.
105     ///
106     /// This function will issue an overlapped I/O write (via `WSASend`) on this
107     /// socket. The provided buffer will be written when the operation completes
108     /// and the given `OVERLAPPED` instance is used to track the overlapped
109     /// operation.
110     ///
111     /// If the operation succeeds, `Ok(Some(n))` is returned where `n` is the
112     /// number of bytes that were written. If the operation returns an error
113     /// indicating that the I/O is currently pending, `Ok(None)` is returned.
114     /// Otherwise, the error associated with the operation is returned and no
115     /// overlapped operation is enqueued.
116     ///
117     /// The number of bytes written will be returned as part of the completion
118     /// notification when the I/O finishes.
119     ///
120     /// # Unsafety
121     ///
122     /// This function is unsafe because the kernel requires that the `buf` and
123     /// `overlapped` pointers are valid until the end of the I/O operation. The
124     /// kernel also requires that `overlapped` is unique for this I/O operation
125     /// and is not in use for any other I/O.
126     ///
127     /// To safely use this function callers must ensure that these two input
128     /// pointers are valid until the I/O operation is completed, typically via
129     /// completion ports and waiting to receive the completion notification on
130     /// the port.
write_overlapped( &self, buf: &[u8], overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>131     unsafe fn write_overlapped(
132         &self,
133         buf: &[u8],
134         overlapped: *mut OVERLAPPED,
135     ) -> io::Result<Option<usize>>;
136 
137     /// Attempt to consume the internal socket in this builder by executing an
138     /// overlapped connect operation.
139     ///
140     /// This function will issue a connect operation to the address specified on
141     /// the underlying socket, flagging it as an overlapped operation which will
142     /// complete asynchronously. If successful this function will return the
143     /// corresponding TCP stream.
144     ///
145     /// The `buf` argument provided is an initial buffer of data that should be
146     /// sent after the connection is initiated. It's acceptable to
147     /// pass an empty slice here.
148     ///
149     /// This function will also return whether the connect immediately
150     /// succeeded or not. If `None` is returned then the I/O operation is still
151     /// pending and will complete at a later date, and if `Some(bytes)` is
152     /// returned then that many bytes were transferred.
153     ///
154     /// Note that to succeed this requires that the underlying socket has
155     /// previously been bound via a call to `bind` to a local address.
156     ///
157     /// # Unsafety
158     ///
159     /// This function is unsafe because the kernel requires that the
160     /// `overlapped` and `buf` pointers to be  valid until the end of the I/O
161     /// operation. The kernel also requires that `overlapped` is unique for
162     /// this I/O operation and is not in use for any other I/O.
163     ///
164     /// To safely use this function callers must ensure that this pointer is
165     /// valid until the I/O operation is completed, typically via completion
166     /// ports and waiting to receive the completion notification on the port.
connect_overlapped( &self, addr: &SocketAddr, buf: &[u8], overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>167     unsafe fn connect_overlapped(
168         &self,
169         addr: &SocketAddr,
170         buf: &[u8],
171         overlapped: *mut OVERLAPPED,
172     ) -> io::Result<Option<usize>>;
173 
174     /// Once a `connect_overlapped` has finished, this function needs to be
175     /// called to finish the connect operation.
176     ///
177     /// Currently this just calls `setsockopt` with `SO_UPDATE_CONNECT_CONTEXT`
178     /// to ensure that further functions like `getpeername` and `getsockname`
179     /// work correctly.
connect_complete(&self) -> io::Result<()>180     fn connect_complete(&self) -> io::Result<()>;
181 
182     /// Calls the `GetOverlappedResult` function to get the result of an
183     /// overlapped operation for this handle.
184     ///
185     /// This function takes the `OVERLAPPED` argument which must have been used
186     /// to initiate an overlapped I/O operation, and returns either the
187     /// successful number of bytes transferred during the operation or an error
188     /// if one occurred, along with the results of the `lpFlags` parameter of
189     /// the relevant operation, if applicable.
190     ///
191     /// # Unsafety
192     ///
193     /// This function is unsafe as `overlapped` must have previously been used
194     /// to execute an operation for this handle, and it must also be a valid
195     /// pointer to an `OVERLAPPED` instance.
196     ///
197     /// # Panics
198     ///
199     /// This function will panic
result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)>200     unsafe fn result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)>;
201 }
202 
203 /// Additional methods for the `UdpSocket` type in the standard library.
204 pub trait UdpSocketExt {
205     /// Execute an overlapped receive I/O operation on this UDP socket.
206     ///
207     /// This function will issue an overlapped I/O read (via `WSARecvFrom`) on
208     /// this socket. The provided buffer will be filled in when the operation
209     /// completes, the source from where the data came from will be written to
210     /// `addr`, and the given `OVERLAPPED` instance is used to track the
211     /// overlapped operation.
212     ///
213     /// If the operation succeeds, `Ok(Some(n))` is returned where `n` is the
214     /// number of bytes that were read. If the operation returns an error
215     /// indicating that the I/O is currently pending, `Ok(None)` is returned.
216     /// Otherwise, the error associated with the operation is returned and no
217     /// overlapped operation is enqueued.
218     ///
219     /// The number of bytes read will be returned as part of the completion
220     /// notification when the I/O finishes.
221     ///
222     /// # Unsafety
223     ///
224     /// This function is unsafe because the kernel requires that the `buf`,
225     /// `addr`, and `overlapped` pointers are valid until the end of the I/O
226     /// operation. The kernel also requires that `overlapped` is unique for this
227     /// I/O operation and is not in use for any other I/O.
228     ///
229     /// To safely use this function callers must ensure that these two input
230     /// pointers are valid until the I/O operation is completed, typically via
231     /// completion ports and waiting to receive the completion notification on
232     /// the port.
recv_from_overlapped( &self, buf: &mut [u8], addr: *mut SocketAddrBuf, overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>233     unsafe fn recv_from_overlapped(
234         &self,
235         buf: &mut [u8],
236         addr: *mut SocketAddrBuf,
237         overlapped: *mut OVERLAPPED,
238     ) -> io::Result<Option<usize>>;
239 
240     /// Execute an overlapped receive I/O operation on this UDP socket.
241     ///
242     /// This function will issue an overlapped I/O read (via `WSARecv`) on
243     /// this socket. The provided buffer will be filled in when the operation
244     /// completes, the source from where the data came from will be written to
245     /// `addr`, and the given `OVERLAPPED` instance is used to track the
246     /// overlapped operation.
247     ///
248     /// If the operation succeeds, `Ok(Some(n))` is returned where `n` is the
249     /// number of bytes that were read. If the operation returns an error
250     /// indicating that the I/O is currently pending, `Ok(None)` is returned.
251     /// Otherwise, the error associated with the operation is returned and no
252     /// overlapped operation is enqueued.
253     ///
254     /// The number of bytes read will be returned as part of the completion
255     /// notification when the I/O finishes.
256     ///
257     /// # Unsafety
258     ///
259     /// This function is unsafe because the kernel requires that the `buf`,
260     /// and `overlapped` pointers are valid until the end of the I/O
261     /// operation. The kernel also requires that `overlapped` is unique for this
262     /// I/O operation and is not in use for any other I/O.
263     ///
264     /// To safely use this function callers must ensure that these two input
265     /// pointers are valid until the I/O operation is completed, typically via
266     /// completion ports and waiting to receive the completion notification on
267     /// the port.
recv_overlapped( &self, buf: &mut [u8], overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>268     unsafe fn recv_overlapped(
269         &self,
270         buf: &mut [u8],
271         overlapped: *mut OVERLAPPED,
272     ) -> io::Result<Option<usize>>;
273 
274     /// Execute an overlapped send I/O operation on this UDP socket.
275     ///
276     /// This function will issue an overlapped I/O write (via `WSASendTo`) on
277     /// this socket to the address specified by `addr`. The provided buffer will
278     /// be written when the operation completes and the given `OVERLAPPED`
279     /// instance is used to track the overlapped operation.
280     ///
281     /// If the operation succeeds, `Ok(Some(n0)` is returned where `n` byte
282     /// were written. If the operation returns an error indicating that the I/O
283     /// is currently pending, `Ok(None)` is returned. Otherwise, the error
284     /// associated with the operation is returned and no overlapped operation
285     /// is enqueued.
286     ///
287     /// The number of bytes written will be returned as part of the completion
288     /// notification when the I/O finishes.
289     ///
290     /// # Unsafety
291     ///
292     /// This function is unsafe because the kernel requires that the `buf` and
293     /// `overlapped` pointers are valid until the end of the I/O operation. The
294     /// kernel also requires that `overlapped` is unique for this I/O operation
295     /// and is not in use for any other I/O.
296     ///
297     /// To safely use this function callers must ensure that these two input
298     /// pointers are valid until the I/O operation is completed, typically via
299     /// completion ports and waiting to receive the completion notification on
300     /// the port.
send_to_overlapped( &self, buf: &[u8], addr: &SocketAddr, overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>301     unsafe fn send_to_overlapped(
302         &self,
303         buf: &[u8],
304         addr: &SocketAddr,
305         overlapped: *mut OVERLAPPED,
306     ) -> io::Result<Option<usize>>;
307 
308     /// Execute an overlapped send I/O operation on this UDP socket.
309     ///
310     /// This function will issue an overlapped I/O write (via `WSASend`) on
311     /// this socket to the address it was previously connected to. The provided
312     /// buffer will be written when the operation completes and the given `OVERLAPPED`
313     /// instance is used to track the overlapped operation.
314     ///
315     /// If the operation succeeds, `Ok(Some(n0)` is returned where `n` byte
316     /// were written. If the operation returns an error indicating that the I/O
317     /// is currently pending, `Ok(None)` is returned. Otherwise, the error
318     /// associated with the operation is returned and no overlapped operation
319     /// is enqueued.
320     ///
321     /// The number of bytes written will be returned as part of the completion
322     /// notification when the I/O finishes.
323     ///
324     /// # Unsafety
325     ///
326     /// This function is unsafe because the kernel requires that the `buf` and
327     /// `overlapped` pointers are valid until the end of the I/O operation. The
328     /// kernel also requires that `overlapped` is unique for this I/O operation
329     /// and is not in use for any other I/O.
330     ///
331     /// To safely use this function callers must ensure that these two input
332     /// pointers are valid until the I/O operation is completed, typically via
333     /// completion ports and waiting to receive the completion notification on
334     /// the port.
send_overlapped( &self, buf: &[u8], overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>335     unsafe fn send_overlapped(
336         &self,
337         buf: &[u8],
338         overlapped: *mut OVERLAPPED,
339     ) -> io::Result<Option<usize>>;
340 
341     /// Calls the `GetOverlappedResult` function to get the result of an
342     /// overlapped operation for this handle.
343     ///
344     /// This function takes the `OVERLAPPED` argument which must have been used
345     /// to initiate an overlapped I/O operation, and returns either the
346     /// successful number of bytes transferred during the operation or an error
347     /// if one occurred, along with the results of the `lpFlags` parameter of
348     /// the relevant operation, if applicable.
349     ///
350     /// # Unsafety
351     ///
352     /// This function is unsafe as `overlapped` must have previously been used
353     /// to execute an operation for this handle, and it must also be a valid
354     /// pointer to an `OVERLAPPED` instance.
355     ///
356     /// # Panics
357     ///
358     /// This function will panic
result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)>359     unsafe fn result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)>;
360 }
361 
362 /// Additional methods for the `TcpListener` type in the standard library.
363 pub trait TcpListenerExt {
364     /// Perform an accept operation on this listener, accepting a connection in
365     /// an overlapped fashion.
366     ///
367     /// This function will issue an I/O request to accept an incoming connection
368     /// with the specified overlapped instance. The `socket` provided must be a
369     /// configured but not bound or connected socket, and if successful this
370     /// will consume the internal socket of the builder to return a TCP stream.
371     ///
372     /// The `addrs` buffer provided will be filled in with the local and remote
373     /// addresses of the connection upon completion.
374     ///
375     /// If the accept succeeds immediately, `Ok(true)` is returned. If
376     /// the connect indicates that the I/O is currently pending, `Ok(false)` is
377     /// returned. Otherwise, the error associated with the operation is
378     /// returned and no overlapped operation is enqueued.
379     ///
380     /// # Unsafety
381     ///
382     /// This function is unsafe because the kernel requires that the
383     /// `addrs` and `overlapped` pointers are valid until the end of the I/O
384     /// operation. The kernel also requires that `overlapped` is unique for this
385     /// I/O operation and is not in use for any other I/O.
386     ///
387     /// To safely use this function callers must ensure that the pointers are
388     /// valid until the I/O operation is completed, typically via completion
389     /// ports and waiting to receive the completion notification on the port.
accept_overlapped( &self, socket: &TcpStream, addrs: &mut AcceptAddrsBuf, overlapped: *mut OVERLAPPED, ) -> io::Result<bool>390     unsafe fn accept_overlapped(
391         &self,
392         socket: &TcpStream,
393         addrs: &mut AcceptAddrsBuf,
394         overlapped: *mut OVERLAPPED,
395     ) -> io::Result<bool>;
396 
397     /// Once an `accept_overlapped` has finished, this function needs to be
398     /// called to finish the accept operation.
399     ///
400     /// Currently this just calls `setsockopt` with `SO_UPDATE_ACCEPT_CONTEXT`
401     /// to ensure that further functions like `getpeername` and `getsockname`
402     /// work correctly.
accept_complete(&self, socket: &TcpStream) -> io::Result<()>403     fn accept_complete(&self, socket: &TcpStream) -> io::Result<()>;
404 
405     /// Calls the `GetOverlappedResult` function to get the result of an
406     /// overlapped operation for this handle.
407     ///
408     /// This function takes the `OVERLAPPED` argument which must have been used
409     /// to initiate an overlapped I/O operation, and returns either the
410     /// successful number of bytes transferred during the operation or an error
411     /// if one occurred, along with the results of the `lpFlags` parameter of
412     /// the relevant operation, if applicable.
413     ///
414     /// # Unsafety
415     ///
416     /// This function is unsafe as `overlapped` must have previously been used
417     /// to execute an operation for this handle, and it must also be a valid
418     /// pointer to an `OVERLAPPED` instance.
419     ///
420     /// # Panics
421     ///
422     /// This function will panic
result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)>423     unsafe fn result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)>;
424 }
425 
426 #[doc(hidden)]
427 trait NetInt {
from_be(i: Self) -> Self428     fn from_be(i: Self) -> Self;
to_be(&self) -> Self429     fn to_be(&self) -> Self;
430 }
431 macro_rules! doit {
432     ($($t:ident)*) => ($(impl NetInt for $t {
433         fn from_be(i: Self) -> Self { <$t>::from_be(i) }
434         fn to_be(&self) -> Self { <$t>::to_be(*self) }
435     })*)
436 }
437 doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
438 
439 // fn hton<I: NetInt>(i: I) -> I { i.to_be() }
ntoh<I: NetInt>(i: I) -> I440 fn ntoh<I: NetInt>(i: I) -> I {
441     I::from_be(i)
442 }
443 
last_err() -> io::Result<Option<usize>>444 fn last_err() -> io::Result<Option<usize>> {
445     let err = unsafe { WSAGetLastError() };
446     if err == WSA_IO_PENDING as i32 {
447         Ok(None)
448     } else {
449         Err(io::Error::from_raw_os_error(err))
450     }
451 }
452 
cvt(i: c_int, size: DWORD) -> io::Result<Option<usize>>453 fn cvt(i: c_int, size: DWORD) -> io::Result<Option<usize>> {
454     if i == SOCKET_ERROR {
455         last_err()
456     } else {
457         Ok(Some(size as usize))
458     }
459 }
460 
461 /// A type with the same memory layout as `SOCKADDR`. Used in converting Rust level
462 /// SocketAddr* types into their system representation. The benefit of this specific
463 /// type over using `SOCKADDR_STORAGE` is that this type is exactly as large as it
464 /// needs to be and not a lot larger. And it can be initialized cleaner from Rust.
465 #[repr(C)]
466 pub(crate) union SocketAddrCRepr {
467     v4: SOCKADDR_IN,
468     v6: SOCKADDR_IN6_LH,
469 }
470 
471 impl SocketAddrCRepr {
as_ptr(&self) -> *const SOCKADDR472     pub(crate) fn as_ptr(&self) -> *const SOCKADDR {
473         self as *const _ as *const SOCKADDR
474     }
475 }
476 
socket_addr_to_ptrs(addr: &SocketAddr) -> (SocketAddrCRepr, c_int)477 fn socket_addr_to_ptrs(addr: &SocketAddr) -> (SocketAddrCRepr, c_int) {
478     match *addr {
479         SocketAddr::V4(ref a) => {
480             let sin_addr = unsafe {
481                 let mut s_un = mem::zeroed::<in_addr_S_un>();
482                 *s_un.S_addr_mut() = u32::from_ne_bytes(a.ip().octets());
483                 IN_ADDR { S_un: s_un }
484             };
485 
486             let sockaddr_in = SOCKADDR_IN {
487                 sin_family: AF_INET as ADDRESS_FAMILY,
488                 sin_port: a.port().to_be(),
489                 sin_addr,
490                 sin_zero: [0; 8],
491             };
492 
493             let sockaddr = SocketAddrCRepr { v4: sockaddr_in };
494             (sockaddr, mem::size_of::<SOCKADDR_IN>() as c_int)
495         }
496         SocketAddr::V6(ref a) => {
497             let sin6_addr = unsafe {
498                 let mut u = mem::zeroed::<in6_addr_u>();
499                 *u.Byte_mut() = a.ip().octets();
500                 IN6_ADDR { u }
501             };
502             let u = unsafe {
503                 let mut u = mem::zeroed::<SOCKADDR_IN6_LH_u>();
504                 *u.sin6_scope_id_mut() = a.scope_id();
505                 u
506             };
507 
508             let sockaddr_in6 = SOCKADDR_IN6_LH {
509                 sin6_family: AF_INET6 as ADDRESS_FAMILY,
510                 sin6_port: a.port().to_be(),
511                 sin6_addr,
512                 sin6_flowinfo: a.flowinfo(),
513                 u,
514             };
515 
516             let sockaddr = SocketAddrCRepr { v6: sockaddr_in6 };
517             (sockaddr, mem::size_of::<SOCKADDR_IN6_LH>() as c_int)
518         }
519     }
520 }
521 
ptrs_to_socket_addr(ptr: *const SOCKADDR, len: c_int) -> Option<SocketAddr>522 unsafe fn ptrs_to_socket_addr(ptr: *const SOCKADDR, len: c_int) -> Option<SocketAddr> {
523     if (len as usize) < mem::size_of::<c_int>() {
524         return None;
525     }
526     match (*ptr).sa_family as i32 {
527         AF_INET if len as usize >= mem::size_of::<SOCKADDR_IN>() => {
528             let b = &*(ptr as *const SOCKADDR_IN);
529             let ip = ntoh(*b.sin_addr.S_un.S_addr());
530             let ip = Ipv4Addr::new(
531                 (ip >> 24) as u8,
532                 (ip >> 16) as u8,
533                 (ip >> 8) as u8,
534                 (ip >> 0) as u8,
535             );
536             Some(SocketAddr::V4(SocketAddrV4::new(ip, ntoh(b.sin_port))))
537         }
538         AF_INET6 if len as usize >= mem::size_of::<SOCKADDR_IN6_LH>() => {
539             let b = &*(ptr as *const SOCKADDR_IN6_LH);
540             let arr = b.sin6_addr.u.Byte();
541             let ip = Ipv6Addr::new(
542                 ((arr[0] as u16) << 8) | (arr[1] as u16),
543                 ((arr[2] as u16) << 8) | (arr[3] as u16),
544                 ((arr[4] as u16) << 8) | (arr[5] as u16),
545                 ((arr[6] as u16) << 8) | (arr[7] as u16),
546                 ((arr[8] as u16) << 8) | (arr[9] as u16),
547                 ((arr[10] as u16) << 8) | (arr[11] as u16),
548                 ((arr[12] as u16) << 8) | (arr[13] as u16),
549                 ((arr[14] as u16) << 8) | (arr[15] as u16),
550             );
551             let addr = SocketAddrV6::new(
552                 ip,
553                 ntoh(b.sin6_port),
554                 ntoh(b.sin6_flowinfo),
555                 ntoh(*b.u.sin6_scope_id()),
556             );
557             Some(SocketAddr::V6(addr))
558         }
559         _ => None,
560     }
561 }
562 
slice2buf(slice: &[u8]) -> WSABUF563 unsafe fn slice2buf(slice: &[u8]) -> WSABUF {
564     WSABUF {
565         len: cmp::min(slice.len(), <u_long>::max_value() as usize) as u_long,
566         buf: slice.as_ptr() as *mut _,
567     }
568 }
569 
result(socket: SOCKET, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)>570 unsafe fn result(socket: SOCKET, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)> {
571     let mut transferred = 0;
572     let mut flags = 0;
573     let r = WSAGetOverlappedResult(socket, overlapped, &mut transferred, FALSE, &mut flags);
574     if r == 0 {
575         Err(io::Error::last_os_error())
576     } else {
577         Ok((transferred as usize, flags))
578     }
579 }
580 
581 impl TcpStreamExt for TcpStream {
read_overlapped( &self, buf: &mut [u8], overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>582     unsafe fn read_overlapped(
583         &self,
584         buf: &mut [u8],
585         overlapped: *mut OVERLAPPED,
586     ) -> io::Result<Option<usize>> {
587         let mut buf = slice2buf(buf);
588         let mut flags = 0;
589         let mut bytes_read: DWORD = 0;
590         let r = WSARecv(
591             self.as_raw_socket() as SOCKET,
592             &mut buf,
593             1,
594             &mut bytes_read,
595             &mut flags,
596             overlapped,
597             None,
598         );
599         cvt(r, bytes_read)
600     }
601 
write_overlapped( &self, buf: &[u8], overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>602     unsafe fn write_overlapped(
603         &self,
604         buf: &[u8],
605         overlapped: *mut OVERLAPPED,
606     ) -> io::Result<Option<usize>> {
607         let mut buf = slice2buf(buf);
608         let mut bytes_written = 0;
609 
610         // Note here that we capture the number of bytes written. The
611         // documentation on MSDN, however, states:
612         //
613         // > Use NULL for this parameter if the lpOverlapped parameter is not
614         // > NULL to avoid potentially erroneous results. This parameter can be
615         // > NULL only if the lpOverlapped parameter is not NULL.
616         //
617         // If we're not passing a null overlapped pointer here, then why are we
618         // then capturing the number of bytes! Well so it turns out that this is
619         // clearly faster to learn the bytes here rather than later calling
620         // `WSAGetOverlappedResult`, and in practice almost all implementations
621         // use this anyway [1].
622         //
623         // As a result we use this to and report back the result.
624         //
625         // [1]: https://github.com/carllerche/mio/pull/520#issuecomment-273983823
626         let r = WSASend(
627             self.as_raw_socket() as SOCKET,
628             &mut buf,
629             1,
630             &mut bytes_written,
631             0,
632             overlapped,
633             None,
634         );
635         cvt(r, bytes_written)
636     }
637 
connect_overlapped( &self, addr: &SocketAddr, buf: &[u8], overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>638     unsafe fn connect_overlapped(
639         &self,
640         addr: &SocketAddr,
641         buf: &[u8],
642         overlapped: *mut OVERLAPPED,
643     ) -> io::Result<Option<usize>> {
644         connect_overlapped(self.as_raw_socket() as SOCKET, addr, buf, overlapped)
645     }
646 
connect_complete(&self) -> io::Result<()>647     fn connect_complete(&self) -> io::Result<()> {
648         const SO_UPDATE_CONNECT_CONTEXT: c_int = 0x7010;
649         let result = unsafe {
650             setsockopt(
651                 self.as_raw_socket() as SOCKET,
652                 SOL_SOCKET,
653                 SO_UPDATE_CONNECT_CONTEXT,
654                 0 as *const _,
655                 0,
656             )
657         };
658         if result == 0 {
659             Ok(())
660         } else {
661             Err(io::Error::last_os_error())
662         }
663     }
664 
result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)>665     unsafe fn result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)> {
666         result(self.as_raw_socket() as SOCKET, overlapped)
667     }
668 }
669 
connect_overlapped( socket: SOCKET, addr: &SocketAddr, buf: &[u8], overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>670 unsafe fn connect_overlapped(
671     socket: SOCKET,
672     addr: &SocketAddr,
673     buf: &[u8],
674     overlapped: *mut OVERLAPPED,
675 ) -> io::Result<Option<usize>> {
676     static CONNECTEX: WsaExtension = WsaExtension {
677         guid: GUID {
678             Data1: 0x25a207b9,
679             Data2: 0xddf3,
680             Data3: 0x4660,
681             Data4: [0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e],
682         },
683         val: AtomicUsize::new(0),
684     };
685     type ConnectEx = unsafe extern "system" fn(
686         SOCKET,
687         *const SOCKADDR,
688         c_int,
689         PVOID,
690         DWORD,
691         LPDWORD,
692         LPOVERLAPPED,
693     ) -> BOOL;
694 
695     let ptr = CONNECTEX.get(socket)?;
696     assert!(ptr != 0);
697     let connect_ex = mem::transmute::<_, ConnectEx>(ptr);
698 
699     let (addr_buf, addr_len) = socket_addr_to_ptrs(addr);
700     let mut bytes_sent: DWORD = 0;
701     let r = connect_ex(
702         socket,
703         addr_buf.as_ptr(),
704         addr_len,
705         buf.as_ptr() as *mut _,
706         buf.len() as u32,
707         &mut bytes_sent,
708         overlapped,
709     );
710     if r == TRUE {
711         Ok(Some(bytes_sent as usize))
712     } else {
713         last_err()
714     }
715 }
716 
717 impl UdpSocketExt for UdpSocket {
recv_from_overlapped( &self, buf: &mut [u8], addr: *mut SocketAddrBuf, overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>718     unsafe fn recv_from_overlapped(
719         &self,
720         buf: &mut [u8],
721         addr: *mut SocketAddrBuf,
722         overlapped: *mut OVERLAPPED,
723     ) -> io::Result<Option<usize>> {
724         let mut buf = slice2buf(buf);
725         let mut flags = 0;
726         let mut received_bytes: DWORD = 0;
727         let r = WSARecvFrom(
728             self.as_raw_socket() as SOCKET,
729             &mut buf,
730             1,
731             &mut received_bytes,
732             &mut flags,
733             &mut (*addr).buf as *mut _ as *mut _,
734             &mut (*addr).len,
735             overlapped,
736             None,
737         );
738         cvt(r, received_bytes)
739     }
740 
recv_overlapped( &self, buf: &mut [u8], overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>741     unsafe fn recv_overlapped(
742         &self,
743         buf: &mut [u8],
744         overlapped: *mut OVERLAPPED,
745     ) -> io::Result<Option<usize>> {
746         let mut buf = slice2buf(buf);
747         let mut flags = 0;
748         let mut received_bytes: DWORD = 0;
749         let r = WSARecv(
750             self.as_raw_socket() as SOCKET,
751             &mut buf,
752             1,
753             &mut received_bytes,
754             &mut flags,
755             overlapped,
756             None,
757         );
758         cvt(r, received_bytes)
759     }
760 
send_to_overlapped( &self, buf: &[u8], addr: &SocketAddr, overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>761     unsafe fn send_to_overlapped(
762         &self,
763         buf: &[u8],
764         addr: &SocketAddr,
765         overlapped: *mut OVERLAPPED,
766     ) -> io::Result<Option<usize>> {
767         let (addr_buf, addr_len) = socket_addr_to_ptrs(addr);
768         let mut buf = slice2buf(buf);
769         let mut sent_bytes = 0;
770         let r = WSASendTo(
771             self.as_raw_socket() as SOCKET,
772             &mut buf,
773             1,
774             &mut sent_bytes,
775             0,
776             addr_buf.as_ptr() as *const _,
777             addr_len,
778             overlapped,
779             None,
780         );
781         cvt(r, sent_bytes)
782     }
783 
send_overlapped( &self, buf: &[u8], overlapped: *mut OVERLAPPED, ) -> io::Result<Option<usize>>784     unsafe fn send_overlapped(
785         &self,
786         buf: &[u8],
787         overlapped: *mut OVERLAPPED,
788     ) -> io::Result<Option<usize>> {
789         let mut buf = slice2buf(buf);
790         let mut sent_bytes = 0;
791         let r = WSASend(
792             self.as_raw_socket() as SOCKET,
793             &mut buf,
794             1,
795             &mut sent_bytes,
796             0,
797             overlapped,
798             None,
799         );
800         cvt(r, sent_bytes)
801     }
802 
result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)>803     unsafe fn result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)> {
804         result(self.as_raw_socket() as SOCKET, overlapped)
805     }
806 }
807 
808 impl TcpListenerExt for TcpListener {
accept_overlapped( &self, socket: &TcpStream, addrs: &mut AcceptAddrsBuf, overlapped: *mut OVERLAPPED, ) -> io::Result<bool>809     unsafe fn accept_overlapped(
810         &self,
811         socket: &TcpStream,
812         addrs: &mut AcceptAddrsBuf,
813         overlapped: *mut OVERLAPPED,
814     ) -> io::Result<bool> {
815         static ACCEPTEX: WsaExtension = WsaExtension {
816             guid: GUID {
817                 Data1: 0xb5367df1,
818                 Data2: 0xcbac,
819                 Data3: 0x11cf,
820                 Data4: [0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92],
821             },
822             val: AtomicUsize::new(0),
823         };
824         type AcceptEx = unsafe extern "system" fn(
825             SOCKET,
826             SOCKET,
827             PVOID,
828             DWORD,
829             DWORD,
830             DWORD,
831             LPDWORD,
832             LPOVERLAPPED,
833         ) -> BOOL;
834 
835         let ptr = ACCEPTEX.get(self.as_raw_socket() as SOCKET)?;
836         assert!(ptr != 0);
837         let accept_ex = mem::transmute::<_, AcceptEx>(ptr);
838 
839         let mut bytes = 0;
840         let (a, b, c, d) = (*addrs).args();
841         let r = accept_ex(
842             self.as_raw_socket() as SOCKET,
843             socket.as_raw_socket() as SOCKET,
844             a,
845             b,
846             c,
847             d,
848             &mut bytes,
849             overlapped,
850         );
851         let succeeded = if r == TRUE {
852             true
853         } else {
854             last_err()?;
855             false
856         };
857         Ok(succeeded)
858     }
859 
accept_complete(&self, socket: &TcpStream) -> io::Result<()>860     fn accept_complete(&self, socket: &TcpStream) -> io::Result<()> {
861         const SO_UPDATE_ACCEPT_CONTEXT: c_int = 0x700B;
862         let me = self.as_raw_socket();
863         let result = unsafe {
864             setsockopt(
865                 socket.as_raw_socket() as SOCKET,
866                 SOL_SOCKET,
867                 SO_UPDATE_ACCEPT_CONTEXT,
868                 &me as *const _ as *const _,
869                 mem::size_of_val(&me) as c_int,
870             )
871         };
872         if result == 0 {
873             Ok(())
874         } else {
875             Err(io::Error::last_os_error())
876         }
877     }
878 
result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)>879     unsafe fn result(&self, overlapped: *mut OVERLAPPED) -> io::Result<(usize, u32)> {
880         result(self.as_raw_socket() as SOCKET, overlapped)
881     }
882 }
883 
884 impl SocketAddrBuf {
885     /// Creates a new blank socket address buffer.
886     ///
887     /// This should be used before a call to `recv_from_overlapped` overlapped
888     /// to create an instance to pass down.
new() -> SocketAddrBuf889     pub fn new() -> SocketAddrBuf {
890         SocketAddrBuf {
891             buf: unsafe { mem::zeroed() },
892             len: mem::size_of::<SOCKADDR_STORAGE>() as c_int,
893         }
894     }
895 
896     /// Parses this buffer to return a standard socket address.
897     ///
898     /// This function should be called after the buffer has been filled in with
899     /// a call to `recv_from_overlapped` being completed. It will interpret the
900     /// address filled in and return the standard socket address type.
901     ///
902     /// If an error is encountered then `None` is returned.
to_socket_addr(&self) -> Option<SocketAddr>903     pub fn to_socket_addr(&self) -> Option<SocketAddr> {
904         unsafe { ptrs_to_socket_addr(&self.buf as *const _ as *const _, self.len) }
905     }
906 }
907 
908 static GETACCEPTEXSOCKADDRS: WsaExtension = WsaExtension {
909     guid: GUID {
910         Data1: 0xb5367df2,
911         Data2: 0xcbac,
912         Data3: 0x11cf,
913         Data4: [0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92],
914     },
915     val: AtomicUsize::new(0),
916 };
917 type GetAcceptExSockaddrs = unsafe extern "system" fn(
918     PVOID,
919     DWORD,
920     DWORD,
921     DWORD,
922     *mut LPSOCKADDR,
923     LPINT,
924     *mut LPSOCKADDR,
925     LPINT,
926 );
927 
928 impl AcceptAddrsBuf {
929     /// Creates a new blank buffer ready to be passed to a call to
930     /// `accept_overlapped`.
new() -> AcceptAddrsBuf931     pub fn new() -> AcceptAddrsBuf {
932         unsafe { mem::zeroed() }
933     }
934 
935     /// Parses the data contained in this address buffer, returning the parsed
936     /// result if successful.
937     ///
938     /// This function can be called after a call to `accept_overlapped` has
939     /// succeeded to parse out the data that was written in.
parse(&self, socket: &TcpListener) -> io::Result<AcceptAddrs>940     pub fn parse(&self, socket: &TcpListener) -> io::Result<AcceptAddrs> {
941         let mut ret = AcceptAddrs {
942             local: 0 as *mut _,
943             local_len: 0,
944             remote: 0 as *mut _,
945             remote_len: 0,
946             _data: self,
947         };
948         let ptr = GETACCEPTEXSOCKADDRS.get(socket.as_raw_socket() as SOCKET)?;
949         assert!(ptr != 0);
950         unsafe {
951             let get_sockaddrs = mem::transmute::<_, GetAcceptExSockaddrs>(ptr);
952             let (a, b, c, d) = self.args();
953             get_sockaddrs(
954                 a,
955                 b,
956                 c,
957                 d,
958                 &mut ret.local,
959                 &mut ret.local_len,
960                 &mut ret.remote,
961                 &mut ret.remote_len,
962             );
963             Ok(ret)
964         }
965     }
966 
args(&self) -> (PVOID, DWORD, DWORD, DWORD)967     fn args(&self) -> (PVOID, DWORD, DWORD, DWORD) {
968         let remote_offset = unsafe { &(*(0 as *const AcceptAddrsBuf)).remote as *const _ as usize };
969         (
970             self as *const _ as *mut _,
971             0,
972             remote_offset as DWORD,
973             (mem::size_of_val(self) - remote_offset) as DWORD,
974         )
975     }
976 }
977 
978 impl<'a> AcceptAddrs<'a> {
979     /// Returns the local socket address contained in this buffer.
local(&self) -> Option<SocketAddr>980     pub fn local(&self) -> Option<SocketAddr> {
981         unsafe { ptrs_to_socket_addr(self.local, self.local_len) }
982     }
983 
984     /// Returns the remote socket address contained in this buffer.
remote(&self) -> Option<SocketAddr>985     pub fn remote(&self) -> Option<SocketAddr> {
986         unsafe { ptrs_to_socket_addr(self.remote, self.remote_len) }
987     }
988 }
989 
990 impl WsaExtension {
get(&self, socket: SOCKET) -> io::Result<usize>991     fn get(&self, socket: SOCKET) -> io::Result<usize> {
992         let prev = self.val.load(Ordering::SeqCst);
993         if prev != 0 && !cfg!(debug_assertions) {
994             return Ok(prev);
995         }
996         let mut ret = 0 as usize;
997         let mut bytes = 0;
998         let r = unsafe {
999             WSAIoctl(
1000                 socket,
1001                 SIO_GET_EXTENSION_FUNCTION_POINTER,
1002                 &self.guid as *const _ as *mut _,
1003                 mem::size_of_val(&self.guid) as DWORD,
1004                 &mut ret as *mut _ as *mut _,
1005                 mem::size_of_val(&ret) as DWORD,
1006                 &mut bytes,
1007                 0 as *mut _,
1008                 None,
1009             )
1010         };
1011         cvt(r, 0).map(|_| {
1012             debug_assert_eq!(bytes as usize, mem::size_of_val(&ret));
1013             debug_assert!(prev == 0 || prev == ret);
1014             self.val.store(ret, Ordering::SeqCst);
1015             ret
1016         })
1017     }
1018 }
1019 
1020 #[cfg(test)]
1021 mod tests {
1022     use std::io::prelude::*;
1023     use std::net::{
1024         IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV6, TcpListener, TcpStream, UdpSocket,
1025     };
1026     use std::slice;
1027     use std::thread;
1028 
1029     use socket2::{Domain, Socket, Type};
1030 
1031     use crate::iocp::CompletionPort;
1032     use crate::net::{AcceptAddrsBuf, TcpListenerExt};
1033     use crate::net::{SocketAddrBuf, TcpStreamExt, UdpSocketExt};
1034     use crate::Overlapped;
1035 
each_ip(f: &mut dyn FnMut(SocketAddr))1036     fn each_ip(f: &mut dyn FnMut(SocketAddr)) {
1037         f(t!("127.0.0.1:0".parse()));
1038         f(t!("[::1]:0".parse()));
1039     }
1040 
1041     #[test]
tcp_read()1042     fn tcp_read() {
1043         each_ip(&mut |addr| {
1044             let l = t!(TcpListener::bind(addr));
1045             let addr = t!(l.local_addr());
1046             let t = thread::spawn(move || {
1047                 let mut a = t!(l.accept()).0;
1048                 t!(a.write_all(&[1, 2, 3]));
1049             });
1050 
1051             let cp = t!(CompletionPort::new(1));
1052             let s = t!(TcpStream::connect(addr));
1053             t!(cp.add_socket(1, &s));
1054 
1055             let mut b = [0; 10];
1056             let a = Overlapped::zero();
1057             unsafe {
1058                 t!(s.read_overlapped(&mut b, a.raw()));
1059             }
1060             let status = t!(cp.get(None));
1061             assert_eq!(status.bytes_transferred(), 3);
1062             assert_eq!(status.token(), 1);
1063             assert_eq!(status.overlapped(), a.raw());
1064             assert_eq!(&b[0..3], &[1, 2, 3]);
1065 
1066             t!(t.join());
1067         })
1068     }
1069 
1070     #[test]
tcp_write()1071     fn tcp_write() {
1072         each_ip(&mut |addr| {
1073             let l = t!(TcpListener::bind(addr));
1074             let addr = t!(l.local_addr());
1075             let t = thread::spawn(move || {
1076                 let mut a = t!(l.accept()).0;
1077                 let mut b = [0; 10];
1078                 let n = t!(a.read(&mut b));
1079                 assert_eq!(n, 3);
1080                 assert_eq!(&b[0..3], &[1, 2, 3]);
1081             });
1082 
1083             let cp = t!(CompletionPort::new(1));
1084             let s = t!(TcpStream::connect(addr));
1085             t!(cp.add_socket(1, &s));
1086 
1087             let b = [1, 2, 3];
1088             let a = Overlapped::zero();
1089             unsafe {
1090                 t!(s.write_overlapped(&b, a.raw()));
1091             }
1092             let status = t!(cp.get(None));
1093             assert_eq!(status.bytes_transferred(), 3);
1094             assert_eq!(status.token(), 1);
1095             assert_eq!(status.overlapped(), a.raw());
1096 
1097             t!(t.join());
1098         })
1099     }
1100 
1101     #[test]
tcp_connect()1102     fn tcp_connect() {
1103         each_ip(&mut |addr_template| {
1104             let l = t!(TcpListener::bind(addr_template));
1105             let addr = t!(l.local_addr());
1106             let t = thread::spawn(move || {
1107                 t!(l.accept());
1108             });
1109 
1110             let cp = t!(CompletionPort::new(1));
1111             let domain = Domain::for_address(addr);
1112             let socket = t!(Socket::new(domain, Type::STREAM, None));
1113             t!(socket.bind(&addr_template.into()));
1114             let socket = TcpStream::from(socket);
1115             t!(cp.add_socket(1, &socket));
1116 
1117             let a = Overlapped::zero();
1118             unsafe {
1119                 t!(socket.connect_overlapped(&addr, &[], a.raw()));
1120             }
1121             let status = t!(cp.get(None));
1122             assert_eq!(status.bytes_transferred(), 0);
1123             assert_eq!(status.token(), 1);
1124             assert_eq!(status.overlapped(), a.raw());
1125             t!(socket.connect_complete());
1126 
1127             t!(t.join());
1128         })
1129     }
1130 
1131     #[test]
udp_recv_from()1132     fn udp_recv_from() {
1133         each_ip(&mut |addr| {
1134             let a = t!(UdpSocket::bind(addr));
1135             let b = t!(UdpSocket::bind(addr));
1136             let a_addr = t!(a.local_addr());
1137             let b_addr = t!(b.local_addr());
1138             let t = thread::spawn(move || {
1139                 t!(a.send_to(&[1, 2, 3], b_addr));
1140             });
1141 
1142             let cp = t!(CompletionPort::new(1));
1143             t!(cp.add_socket(1, &b));
1144 
1145             let mut buf = [0; 10];
1146             let a = Overlapped::zero();
1147             let mut addr = SocketAddrBuf::new();
1148             unsafe {
1149                 t!(b.recv_from_overlapped(&mut buf, &mut addr, a.raw()));
1150             }
1151             let status = t!(cp.get(None));
1152             assert_eq!(status.bytes_transferred(), 3);
1153             assert_eq!(status.token(), 1);
1154             assert_eq!(status.overlapped(), a.raw());
1155             assert_eq!(&buf[..3], &[1, 2, 3]);
1156             assert_eq!(addr.to_socket_addr(), Some(a_addr));
1157 
1158             t!(t.join());
1159         })
1160     }
1161 
1162     #[test]
udp_recv()1163     fn udp_recv() {
1164         each_ip(&mut |addr| {
1165             let a = t!(UdpSocket::bind(addr));
1166             let b = t!(UdpSocket::bind(addr));
1167             let a_addr = t!(a.local_addr());
1168             let b_addr = t!(b.local_addr());
1169             assert!(b.connect(a_addr).is_ok());
1170             assert!(a.connect(b_addr).is_ok());
1171             let t = thread::spawn(move || {
1172                 t!(a.send_to(&[1, 2, 3], b_addr));
1173             });
1174 
1175             let cp = t!(CompletionPort::new(1));
1176             t!(cp.add_socket(1, &b));
1177 
1178             let mut buf = [0; 10];
1179             let a = Overlapped::zero();
1180             unsafe {
1181                 t!(b.recv_overlapped(&mut buf, a.raw()));
1182             }
1183             let status = t!(cp.get(None));
1184             assert_eq!(status.bytes_transferred(), 3);
1185             assert_eq!(status.token(), 1);
1186             assert_eq!(status.overlapped(), a.raw());
1187             assert_eq!(&buf[..3], &[1, 2, 3]);
1188 
1189             t!(t.join());
1190         })
1191     }
1192 
1193     #[test]
udp_send_to()1194     fn udp_send_to() {
1195         each_ip(&mut |addr| {
1196             let a = t!(UdpSocket::bind(addr));
1197             let b = t!(UdpSocket::bind(addr));
1198             let a_addr = t!(a.local_addr());
1199             let b_addr = t!(b.local_addr());
1200             let t = thread::spawn(move || {
1201                 let mut b = [0; 100];
1202                 let (n, addr) = t!(a.recv_from(&mut b));
1203                 assert_eq!(n, 3);
1204                 assert_eq!(addr, b_addr);
1205                 assert_eq!(&b[..3], &[1, 2, 3]);
1206             });
1207 
1208             let cp = t!(CompletionPort::new(1));
1209             t!(cp.add_socket(1, &b));
1210 
1211             let a = Overlapped::zero();
1212             unsafe {
1213                 t!(b.send_to_overlapped(&[1, 2, 3], &a_addr, a.raw()));
1214             }
1215             let status = t!(cp.get(None));
1216             assert_eq!(status.bytes_transferred(), 3);
1217             assert_eq!(status.token(), 1);
1218             assert_eq!(status.overlapped(), a.raw());
1219 
1220             t!(t.join());
1221         })
1222     }
1223 
1224     #[test]
udp_send()1225     fn udp_send() {
1226         each_ip(&mut |addr| {
1227             let a = t!(UdpSocket::bind(addr));
1228             let b = t!(UdpSocket::bind(addr));
1229             let a_addr = t!(a.local_addr());
1230             let b_addr = t!(b.local_addr());
1231             assert!(b.connect(a_addr).is_ok());
1232             assert!(a.connect(b_addr).is_ok());
1233             let t = thread::spawn(move || {
1234                 let mut b = [0; 100];
1235                 let (n, addr) = t!(a.recv_from(&mut b));
1236                 assert_eq!(n, 3);
1237                 assert_eq!(addr, b_addr);
1238                 assert_eq!(&b[..3], &[1, 2, 3]);
1239             });
1240 
1241             let cp = t!(CompletionPort::new(1));
1242             t!(cp.add_socket(1, &b));
1243 
1244             let a = Overlapped::zero();
1245             unsafe {
1246                 t!(b.send_overlapped(&[1, 2, 3], a.raw()));
1247             }
1248             let status = t!(cp.get(None));
1249             assert_eq!(status.bytes_transferred(), 3);
1250             assert_eq!(status.token(), 1);
1251             assert_eq!(status.overlapped(), a.raw());
1252 
1253             t!(t.join());
1254         })
1255     }
1256 
1257     #[test]
tcp_accept()1258     fn tcp_accept() {
1259         each_ip(&mut |addr_template| {
1260             let l = t!(TcpListener::bind(addr_template));
1261             let addr = t!(l.local_addr());
1262             let t = thread::spawn(move || {
1263                 let socket = t!(TcpStream::connect(addr));
1264                 (socket.local_addr().unwrap(), socket.peer_addr().unwrap())
1265             });
1266 
1267             let cp = t!(CompletionPort::new(1));
1268             let domain = Domain::for_address(addr);
1269             let socket = TcpStream::from(t!(Socket::new(domain, Type::STREAM, None)));
1270             t!(cp.add_socket(1, &l));
1271 
1272             let a = Overlapped::zero();
1273             let mut addrs = AcceptAddrsBuf::new();
1274             unsafe {
1275                 t!(l.accept_overlapped(&socket, &mut addrs, a.raw()));
1276             }
1277             let status = t!(cp.get(None));
1278             assert_eq!(status.bytes_transferred(), 0);
1279             assert_eq!(status.token(), 1);
1280             assert_eq!(status.overlapped(), a.raw());
1281             t!(l.accept_complete(&socket));
1282 
1283             let (remote, local) = t!(t.join());
1284             let addrs = addrs.parse(&l).unwrap();
1285             assert_eq!(addrs.local(), Some(local));
1286             assert_eq!(addrs.remote(), Some(remote));
1287         })
1288     }
1289 
1290     #[test]
sockaddr_convert_4()1291     fn sockaddr_convert_4() {
1292         let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(3, 4, 5, 6)), 0xabcd);
1293         let (raw_addr, addr_len) = super::socket_addr_to_ptrs(&addr);
1294         assert_eq!(addr_len, 16);
1295         let addr_bytes =
1296             unsafe { slice::from_raw_parts(raw_addr.as_ptr() as *const u8, addr_len as usize) };
1297         assert_eq!(
1298             addr_bytes,
1299             &[2, 0, 0xab, 0xcd, 3, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0]
1300         );
1301     }
1302 
1303     #[test]
sockaddr_convert_v6()1304     fn sockaddr_convert_v6() {
1305         let port = 0xabcd;
1306         let flowinfo = 0x12345678;
1307         let scope_id = 0x87654321;
1308         let addr = SocketAddr::V6(SocketAddrV6::new(
1309             Ipv6Addr::new(
1310                 0x0102, 0x0304, 0x0506, 0x0708, 0x090a, 0x0b0c, 0x0d0e, 0x0f10,
1311             ),
1312             port,
1313             flowinfo,
1314             scope_id,
1315         ));
1316         let (raw_addr, addr_len) = super::socket_addr_to_ptrs(&addr);
1317         assert_eq!(addr_len, 28);
1318         let addr_bytes =
1319             unsafe { slice::from_raw_parts(raw_addr.as_ptr() as *const u8, addr_len as usize) };
1320         assert_eq!(
1321             addr_bytes,
1322             &[
1323                 23, 0, // AF_INET6
1324                 0xab, 0xcd, // Port
1325                 0x78, 0x56, 0x34, 0x12, // flowinfo
1326                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
1327                 0x0f, 0x10, // IP
1328                 0x21, 0x43, 0x65, 0x87, // scope_id
1329             ]
1330         );
1331     }
1332 }
1333