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