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