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