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