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