]> git.proxmox.com Git - rustc.git/blob - src/vendor/net2/src/ext.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / vendor / net2 / src / ext.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![allow(bad_style, dead_code)]
12
13 use std::io;
14 use std::mem;
15 use std::net::{TcpStream, TcpListener, UdpSocket, Ipv4Addr, Ipv6Addr};
16 use std::net::ToSocketAddrs;
17
18 use {TcpBuilder, UdpBuilder, FromInner};
19 use sys;
20 use socket;
21
22 cfg_if! {
23 if #[cfg(any(target_os = "dragonfly",
24 target_os = "freebsd",
25 target_os = "ios",
26 target_os = "macos",
27 target_os = "netbsd",
28 target_os = "openbsd",
29 target_os = "solaris",
30 target_env = "uclibc"))] {
31 use libc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
32 use libc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP;
33 } else {
34 // ...
35 }
36 }
37
38 use std::time::Duration;
39
40 #[cfg(unix)] pub type Socket = c_int;
41 #[cfg(unix)] use std::os::unix::prelude::*;
42 #[cfg(unix)] use libc::*;
43 #[cfg(windows)] pub type Socket = SOCKET;
44 #[cfg(windows)] use std::os::windows::prelude::*;
45 #[cfg(windows)] use ws2_32::*;
46 #[cfg(windows)] use winapi::*;
47
48 #[cfg(windows)] const SIO_KEEPALIVE_VALS: DWORD = 0x98000004;
49 #[cfg(windows)]
50 #[repr(C)]
51 struct tcp_keepalive {
52 onoff: c_ulong,
53 keepalivetime: c_ulong,
54 keepaliveinterval: c_ulong,
55 }
56
57 #[cfg(windows)] fn v(opt: IPPROTO) -> c_int { opt.0 as c_int }
58 #[cfg(unix)] fn v(opt: c_int) -> c_int { opt }
59
60 pub fn set_opt<T: Copy>(sock: Socket, opt: c_int, val: c_int,
61 payload: T) -> io::Result<()> {
62 unsafe {
63 let payload = &payload as *const T as *const c_void;
64 try!(::cvt(setsockopt(sock, opt, val, payload as *const _,
65 mem::size_of::<T>() as socklen_t)));
66 Ok(())
67 }
68 }
69
70 pub fn get_opt<T: Copy>(sock: Socket, opt: c_int, val: c_int) -> io::Result<T> {
71 unsafe {
72 let mut slot: T = mem::zeroed();
73 let mut len = mem::size_of::<T>() as socklen_t;
74 try!(::cvt(getsockopt(sock, opt, val,
75 &mut slot as *mut _ as *mut _,
76 &mut len)));
77 assert_eq!(len as usize, mem::size_of::<T>());
78 Ok(slot)
79 }
80 }
81
82 /// Extension methods for the standard [`TcpStream` type][link] in `std::net`.
83 ///
84 /// [link]: https://doc.rust-lang.org/std/net/struct.TcpStream.html
85 pub trait TcpStreamExt {
86 /// Sets the value of the `TCP_NODELAY` option on this socket.
87 ///
88 /// If set, this option disables the Nagle algorithm. This means that
89 /// segments are always sent as soon as possible, even if there is only a
90 /// small amount of data. When not set, data is buffered until there is a
91 /// sufficient amount to send out, thereby avoiding the frequent sending of
92 /// small packets.
93 fn set_nodelay(&self, nodelay: bool) -> io::Result<()>;
94
95 /// Gets the value of the `TCP_NODELAY` option on this socket.
96 ///
97 /// For more information about this option, see [`set_nodelay`][link].
98 ///
99 /// [link]: #tymethod.set_nodelay
100 fn nodelay(&self) -> io::Result<bool>;
101
102 /// Sets the value of the `SO_RCVBUF` option on this socket.
103 ///
104 /// Changes the size of the operating system's receive buffer associated with the socket.
105 fn set_recv_buffer_size(&self, size: usize) -> io::Result<()>;
106
107 /// Gets the value of the `SO_RCVBUF` option on this socket.
108 ///
109 /// For more information about this option, see [`set_recv_buffer_size`][link].
110 ///
111 /// [link]: #tymethod.set_recv_buffer_size
112 fn recv_buffer_size(&self) -> io::Result<usize>;
113
114 /// Sets the value of the `SO_SNDBUF` option on this socket.
115 ///
116 /// Changes the size of the operating system's send buffer associated with the socket.
117 fn set_send_buffer_size(&self, size: usize) -> io::Result<()>;
118
119 /// Gets the value of the `SO_SNDBUF` option on this socket.
120 ///
121 /// For more information about this option, see [`set_send_buffer`][link].
122 ///
123 /// [link]: #tymethod.set_send_buffer
124 fn send_buffer_size(&self) -> io::Result<usize>;
125
126 /// Sets whether keepalive messages are enabled to be sent on this socket.
127 ///
128 /// On Unix, this option will set the `SO_KEEPALIVE` as well as the
129 /// `TCP_KEEPALIVE` or `TCP_KEEPIDLE` option (depending on your platform).
130 /// On Windows, this will set the `SIO_KEEPALIVE_VALS` option.
131 ///
132 /// If `None` is specified then keepalive messages are disabled, otherwise
133 /// the number of milliseconds specified will be the time to remain idle
134 /// before sending a TCP keepalive probe.
135 ///
136 /// Some platforms specify this value in seconds, so sub-second millisecond
137 /// specifications may be omitted.
138 fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()>;
139
140 /// Returns whether keepalive messages are enabled on this socket, and if so
141 /// the amount of milliseconds between them.
142 ///
143 /// For more information about this option, see [`set_keepalive_ms`][link].
144 ///
145 /// [link]: #tymethod.set_keepalive_ms
146 fn keepalive_ms(&self) -> io::Result<Option<u32>>;
147
148 /// Sets whether keepalive messages are enabled to be sent on this socket.
149 ///
150 /// On Unix, this option will set the `SO_KEEPALIVE` as well as the
151 /// `TCP_KEEPALIVE` or `TCP_KEEPIDLE` option (depending on your platform).
152 /// On Windows, this will set the `SIO_KEEPALIVE_VALS` option.
153 ///
154 /// If `None` is specified then keepalive messages are disabled, otherwise
155 /// the duration specified will be the time to remain idle before sending a
156 /// TCP keepalive probe.
157 ///
158 /// Some platforms specify this value in seconds, so sub-second
159 /// specifications may be omitted.
160 fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()>;
161
162 /// Returns whether keepalive messages are enabled on this socket, and if so
163 /// the duration of time between them.
164 ///
165 /// For more information about this option, see [`set_keepalive`][link].
166 ///
167 /// [link]: #tymethod.set_keepalive
168 fn keepalive(&self) -> io::Result<Option<Duration>>;
169
170 /// Sets the `SO_RCVTIMEO` option for this socket.
171 ///
172 /// This option specifies the timeout, in milliseconds, of how long calls to
173 /// this socket's `read` function will wait before returning a timeout. A
174 /// value of `None` means that no read timeout should be specified and
175 /// otherwise `Some` indicates the number of milliseconds for the timeout.
176 fn set_read_timeout_ms(&self, val: Option<u32>) -> io::Result<()>;
177
178 /// Sets the `SO_RCVTIMEO` option for this socket.
179 ///
180 /// This option specifies the timeout of how long calls to this socket's
181 /// `read` function will wait before returning a timeout. A value of `None`
182 /// means that no read timeout should be specified and otherwise `Some`
183 /// indicates the number of duration of the timeout.
184 fn set_read_timeout(&self, val: Option<Duration>) -> io::Result<()>;
185
186 /// Gets the value of the `SO_RCVTIMEO` option for this socket.
187 ///
188 /// For more information about this option, see [`set_read_timeout_ms`][link].
189 ///
190 /// [link]: #tymethod.set_read_timeout_ms
191 fn read_timeout_ms(&self) -> io::Result<Option<u32>>;
192
193 /// Gets the value of the `SO_RCVTIMEO` option for this socket.
194 ///
195 /// For more information about this option, see [`set_read_timeout`][link].
196 ///
197 /// [link]: #tymethod.set_read_timeout
198 fn read_timeout(&self) -> io::Result<Option<Duration>>;
199
200 /// Sets the `SO_SNDTIMEO` option for this socket.
201 ///
202 /// This option specifies the timeout, in milliseconds, of how long calls to
203 /// this socket's `write` function will wait before returning a timeout. A
204 /// value of `None` means that no read timeout should be specified and
205 /// otherwise `Some` indicates the number of milliseconds for the timeout.
206 fn set_write_timeout_ms(&self, val: Option<u32>) -> io::Result<()>;
207
208 /// Sets the `SO_SNDTIMEO` option for this socket.
209 ///
210 /// This option specifies the timeout of how long calls to this socket's
211 /// `write` function will wait before returning a timeout. A value of `None`
212 /// means that no read timeout should be specified and otherwise `Some`
213 /// indicates the duration of the timeout.
214 fn set_write_timeout(&self, val: Option<Duration>) -> io::Result<()>;
215
216 /// Gets the value of the `SO_SNDTIMEO` option for this socket.
217 ///
218 /// For more information about this option, see [`set_write_timeout_ms`][link].
219 ///
220 /// [link]: #tymethod.set_write_timeout_ms
221 fn write_timeout_ms(&self) -> io::Result<Option<u32>>;
222
223 /// Gets the value of the `SO_SNDTIMEO` option for this socket.
224 ///
225 /// For more information about this option, see [`set_write_timeout`][link].
226 ///
227 /// [link]: #tymethod.set_write_timeout
228 fn write_timeout(&self) -> io::Result<Option<Duration>>;
229
230 /// Sets the value for the `IP_TTL` option on this socket.
231 ///
232 /// This value sets the time-to-live field that is used in every packet sent
233 /// from this socket.
234 fn set_ttl(&self, ttl: u32) -> io::Result<()>;
235
236 /// Gets the value of the `IP_TTL` option for this socket.
237 ///
238 /// For more information about this option, see [`set_ttl`][link].
239 ///
240 /// [link]: #tymethod.set_ttl
241 fn ttl(&self) -> io::Result<u32>;
242
243 /// Sets the value for the `IPV6_V6ONLY` option on this socket.
244 ///
245 /// If this is set to `true` then the socket is restricted to sending and
246 /// receiving IPv6 packets only. In this case two IPv4 and IPv6 applications
247 /// can bind the same port at the same time.
248 ///
249 /// If this is set to `false` then the socket can be used to send and
250 /// receive packets from an IPv4-mapped IPv6 address.
251 fn set_only_v6(&self, only_v6: bool) -> io::Result<()>;
252
253 /// Gets the value of the `IPV6_V6ONLY` option for this socket.
254 ///
255 /// For more information about this option, see [`set_only_v6`][link].
256 ///
257 /// [link]: #tymethod.set_only_v6
258 fn only_v6(&self) -> io::Result<bool>;
259
260 /// Executes a `connect` operation on this socket, establishing a connection
261 /// to the host specified by `addr`.
262 ///
263 /// Note that this normally does not need to be called on a `TcpStream`,
264 /// it's typically automatically done as part of a normal
265 /// `TcpStream::connect` function call or `TcpBuilder::connect` method call.
266 ///
267 /// This should only be necessary if an unconnected socket was extracted
268 /// from a `TcpBuilder` and then needs to be connected.
269 fn connect<T: ToSocketAddrs>(&self, addr: T) -> io::Result<()>;
270
271 /// Get the value of the `SO_ERROR` option on this socket.
272 ///
273 /// This will retrieve the stored error in the underlying socket, clearing
274 /// the field in the process. This can be useful for checking errors between
275 /// calls.
276 fn take_error(&self) -> io::Result<Option<io::Error>>;
277
278 /// Moves this TCP stream into or out of nonblocking mode.
279 ///
280 /// On Unix this corresponds to calling fcntl, and on Windows this
281 /// corresponds to calling ioctlsocket.
282 fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()>;
283
284 /// Sets the linger duration of this socket by setting the SO_LINGER option
285 fn set_linger(&self, dur: Option<Duration>) -> io::Result<()>;
286
287 /// reads the linger duration for this socket by getting the SO_LINGER option
288 fn linger(&self) -> io::Result<Option<Duration>>;
289 }
290
291 /// Extension methods for the standard [`TcpListener` type][link] in `std::net`.
292 ///
293 /// [link]: https://doc.rust-lang.org/std/net/struct.TcpListener.html
294 pub trait TcpListenerExt {
295 /// Sets the value for the `IP_TTL` option on this socket.
296 ///
297 /// This is the same as [`TcpStreamExt::set_ttl`][other].
298 ///
299 /// [other]: trait.TcpStreamExt.html#tymethod.set_ttl
300 fn set_ttl(&self, ttl: u32) -> io::Result<()>;
301
302 /// Gets the value of the `IP_TTL` option for this socket.
303 ///
304 /// For more information about this option, see
305 /// [`TcpStreamExt::set_ttl`][link].
306 ///
307 /// [link]: trait.TcpStreamExt.html#tymethod.set_ttl
308 fn ttl(&self) -> io::Result<u32>;
309
310 /// Sets the value for the `IPV6_V6ONLY` option on this socket.
311 ///
312 /// For more information about this option, see
313 /// [`TcpStreamExt::set_only_v6`][link].
314 ///
315 /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
316 fn set_only_v6(&self, only_v6: bool) -> io::Result<()>;
317
318 /// Gets the value of the `IPV6_V6ONLY` option for this socket.
319 ///
320 /// For more information about this option, see
321 /// [`TcpStreamExt::set_only_v6`][link].
322 ///
323 /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
324 fn only_v6(&self) -> io::Result<bool>;
325
326 /// Get the value of the `SO_ERROR` option on this socket.
327 ///
328 /// This will retrieve the stored error in the underlying socket, clearing
329 /// the field in the process. This can be useful for checking errors between
330 /// calls.
331 fn take_error(&self) -> io::Result<Option<io::Error>>;
332
333 /// Moves this TCP listener into or out of nonblocking mode.
334 ///
335 /// For more information about this option, see
336 /// [`TcpStreamExt::set_nonblocking`][link].
337 ///
338 /// [link]: trait.TcpStreamExt.html#tymethod.set_nonblocking
339 fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()>;
340
341 /// Sets the linger duration of this socket by setting the SO_LINGER option
342 fn set_linger(&self, dur: Option<Duration>) -> io::Result<()>;
343
344 /// reads the linger duration for this socket by getting the SO_LINGER option
345 fn linger(&self) -> io::Result<Option<Duration>>;
346 }
347
348 /// Extension methods for the standard [`UdpSocket` type][link] in `std::net`.
349 ///
350 /// [link]: https://doc.rust-lang.org/std/net/struct.UdpSocket.html
351 pub trait UdpSocketExt {
352 /// Sets the value of the `SO_RCVBUF` option on this socket.
353 ///
354 /// Changes the size of the operating system's receive buffer associated with the socket.
355 fn set_recv_buffer_size(&self, size: usize) -> io::Result<()>;
356
357 /// Gets the value of the `SO_RCVBUF` option on this socket.
358 ///
359 /// For more information about this option, see [`set_recv_buffer_size`][link].
360 ///
361 /// [link]: #tymethod.set_recv_buffer_size
362 fn recv_buffer_size(&self) -> io::Result<usize>;
363
364 /// Sets the value of the `SO_SNDBUF` option on this socket.
365 ///
366 /// Changes the size of the operating system's send buffer associated with the socket.
367 fn set_send_buffer_size(&self, size: usize) -> io::Result<()>;
368
369 /// Gets the value of the `SO_SNDBUF` option on this socket.
370 ///
371 /// For more information about this option, see [`set_send_buffer`][link].
372 ///
373 /// [link]: #tymethod.set_send_buffer
374 fn send_buffer_size(&self) -> io::Result<usize>;
375
376 /// Sets the value of the `SO_BROADCAST` option for this socket.
377 ///
378 /// When enabled, this socket is allowed to send packets to a broadcast
379 /// address.
380 fn set_broadcast(&self, broadcast: bool) -> io::Result<()>;
381
382 /// Gets the value of the `SO_BROADCAST` option for this socket.
383 ///
384 /// For more information about this option, see
385 /// [`set_broadcast`][link].
386 ///
387 /// [link]: #tymethod.set_broadcast
388 fn broadcast(&self) -> io::Result<bool>;
389
390 /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
391 ///
392 /// If enabled, multicast packets will be looped back to the local socket.
393 /// Note that this may not have any affect on IPv6 sockets.
394 fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()>;
395
396 /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
397 ///
398 /// For more information about this option, see
399 /// [`set_multicast_loop_v4`][link].
400 ///
401 /// [link]: #tymethod.set_multicast_loop_v4
402 fn multicast_loop_v4(&self) -> io::Result<bool>;
403
404 /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
405 ///
406 /// Indicates the time-to-live value of outgoing multicast packets for
407 /// this socket. The default value is 1 which means that multicast packets
408 /// don't leave the local network unless explicitly requested.
409 ///
410 /// Note that this may not have any affect on IPv6 sockets.
411 fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()>;
412
413 /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
414 ///
415 /// For more information about this option, see
416 /// [`set_multicast_ttl_v4`][link].
417 ///
418 /// [link]: #tymethod.set_multicast_ttl_v4
419 fn multicast_ttl_v4(&self) -> io::Result<u32>;
420
421 /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
422 ///
423 /// Controls whether this socket sees the multicast packets it sends itself.
424 /// Note that this may not have any affect on IPv4 sockets.
425 fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()>;
426
427 /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
428 ///
429 /// For more information about this option, see
430 /// [`set_multicast_loop_v6`][link].
431 ///
432 /// [link]: #tymethod.set_multicast_loop_v6
433 fn multicast_loop_v6(&self) -> io::Result<bool>;
434
435 /// Sets the value for the `IP_TTL` option on this socket.
436 ///
437 /// This is the same as [`TcpStreamExt::set_ttl`][other].
438 ///
439 /// [other]: trait.TcpStreamExt.html#tymethod.set_ttl
440 fn set_ttl(&self, ttl: u32) -> io::Result<()>;
441
442 /// Gets the value of the `IP_TTL` option for this socket.
443 ///
444 /// For more information about this option, see
445 /// [`TcpStreamExt::set_ttl`][link].
446 ///
447 /// [link]: trait.TcpStreamExt.html#tymethod.set_ttl
448 fn ttl(&self) -> io::Result<u32>;
449
450 /// Sets the value for the `IPV6_V6ONLY` option on this socket.
451 ///
452 /// For more information about this option, see
453 /// [`TcpStreamExt::set_only_v6`][link].
454 ///
455 /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
456 fn set_only_v6(&self, only_v6: bool) -> io::Result<()>;
457
458 /// Gets the value of the `IPV6_V6ONLY` option for this socket.
459 ///
460 /// For more information about this option, see
461 /// [`TcpStreamExt::set_only_v6`][link].
462 ///
463 /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
464 fn only_v6(&self) -> io::Result<bool>;
465
466 /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
467 ///
468 /// This function specifies a new multicast group for this socket to join.
469 /// The address must be a valid multicast address, and `interface` is the
470 /// address of the local interface with which the system should join the
471 /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
472 /// interface is chosen by the system.
473 fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
474 -> io::Result<()>;
475
476 /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
477 ///
478 /// This function specifies a new multicast group for this socket to join.
479 /// The address must be a valid multicast address, and `interface` is the
480 /// index of the interface to join/leave (or 0 to indicate any interface).
481 fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
482 -> io::Result<()>;
483
484 /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
485 ///
486 /// For more information about this option, see
487 /// [`join_multicast_v4`][link].
488 ///
489 /// [link]: #tymethod.join_multicast_v4
490 fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
491 -> io::Result<()>;
492
493 /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
494 ///
495 /// For more information about this option, see
496 /// [`join_multicast_v6`][link].
497 ///
498 /// [link]: #tymethod.join_multicast_v6
499 fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
500 -> io::Result<()>;
501
502 /// Sets the `SO_RCVTIMEO` option for this socket.
503 ///
504 /// This option specifies the timeout, in milliseconds, of how long calls to
505 /// this socket's `read` function will wait before returning a timeout. A
506 /// value of `None` means that no read timeout should be specified and
507 /// otherwise `Some` indicates the number of milliseconds for the timeout.
508 fn set_read_timeout_ms(&self, val: Option<u32>) -> io::Result<()>;
509
510 /// Sets the `SO_RCVTIMEO` option for this socket.
511 ///
512 /// This option specifies the timeout of how long calls to this socket's
513 /// `read` function will wait before returning a timeout. A value of `None`
514 /// means that no read timeout should be specified and otherwise `Some`
515 /// indicates the number of duration of the timeout.
516 fn set_read_timeout(&self, val: Option<Duration>) -> io::Result<()>;
517
518 /// Gets the value of the `SO_RCVTIMEO` option for this socket.
519 ///
520 /// For more information about this option, see [`set_read_timeout_ms`][link].
521 ///
522 /// [link]: #tymethod.set_read_timeout_ms
523 fn read_timeout_ms(&self) -> io::Result<Option<u32>>;
524
525 /// Gets the value of the `SO_RCVTIMEO` option for this socket.
526 ///
527 /// For more information about this option, see [`set_read_timeout`][link].
528 ///
529 /// [link]: #tymethod.set_read_timeout
530 fn read_timeout(&self) -> io::Result<Option<Duration>>;
531
532 /// Sets the `SO_SNDTIMEO` option for this socket.
533 ///
534 /// This option specifies the timeout, in milliseconds, of how long calls to
535 /// this socket's `write` function will wait before returning a timeout. A
536 /// value of `None` means that no read timeout should be specified and
537 /// otherwise `Some` indicates the number of milliseconds for the timeout.
538 fn set_write_timeout_ms(&self, val: Option<u32>) -> io::Result<()>;
539
540 /// Sets the `SO_SNDTIMEO` option for this socket.
541 ///
542 /// This option specifies the timeout of how long calls to this socket's
543 /// `write` function will wait before returning a timeout. A value of `None`
544 /// means that no read timeout should be specified and otherwise `Some`
545 /// indicates the duration of the timeout.
546 fn set_write_timeout(&self, val: Option<Duration>) -> io::Result<()>;
547
548 /// Gets the value of the `SO_SNDTIMEO` option for this socket.
549 ///
550 /// For more information about this option, see [`set_write_timeout_ms`][link].
551 ///
552 /// [link]: #tymethod.set_write_timeout_ms
553 fn write_timeout_ms(&self) -> io::Result<Option<u32>>;
554
555 /// Gets the value of the `SO_SNDTIMEO` option for this socket.
556 ///
557 /// For more information about this option, see [`set_write_timeout`][link].
558 ///
559 /// [link]: #tymethod.set_write_timeout
560 fn write_timeout(&self) -> io::Result<Option<Duration>>;
561
562 /// Get the value of the `SO_ERROR` option on this socket.
563 ///
564 /// This will retrieve the stored error in the underlying socket, clearing
565 /// the field in the process. This can be useful for checking errors between
566 /// calls.
567 fn take_error(&self) -> io::Result<Option<io::Error>>;
568
569 /// Connects this UDP socket to a remote address, allowing the `send` and
570 /// `recv` syscalls to be used to send data and also applies filters to only
571 /// receive data from the specified address.
572 fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()>;
573
574 /// Sends data on the socket to the remote address to which it is connected.
575 ///
576 /// The `connect` method will connect this socket to a remote address. This
577 /// method will fail if the socket is not connected.
578 fn send(&self, buf: &[u8]) -> io::Result<usize>;
579
580 /// Receives data on the socket from the remote address to which it is
581 /// connected.
582 ///
583 /// The `connect` method will connect this socket to a remote address. This
584 /// method will fail if the socket is not connected.
585 fn recv(&self, buf: &mut [u8]) -> io::Result<usize>;
586
587 /// Moves this UDP socket into or out of nonblocking mode.
588 ///
589 /// For more information about this option, see
590 /// [`TcpStreamExt::set_nonblocking`][link].
591 ///
592 /// [link]: trait.TcpStreamExt.html#tymethod.set_nonblocking
593 fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()>;
594 }
595
596 #[doc(hidden)]
597 pub trait AsSock {
598 fn as_sock(&self) -> Socket;
599 }
600
601 #[cfg(unix)]
602 impl<T: AsRawFd> AsSock for T {
603 fn as_sock(&self) -> Socket { self.as_raw_fd() }
604 }
605 #[cfg(windows)]
606 impl<T: AsRawSocket> AsSock for T {
607 fn as_sock(&self) -> Socket { self.as_raw_socket() }
608 }
609
610 cfg_if! {
611 if #[cfg(any(target_os = "macos", target_os = "ios"))] {
612 use libc::TCP_KEEPALIVE as KEEPALIVE_OPTION;
613 } else if #[cfg(any(target_os = "openbsd", target_os = "netbsd"))] {
614 use libc::SO_KEEPALIVE as KEEPALIVE_OPTION;
615 } else if #[cfg(unix)] {
616 use libc::TCP_KEEPIDLE as KEEPALIVE_OPTION;
617 } else {
618 // ...
619 }
620 }
621
622 impl TcpStreamExt for TcpStream {
623
624 fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
625 // TODO: casting usize to a c_int should be a checked cast
626 set_opt(self.as_sock(), SOL_SOCKET, SO_RCVBUF, size as c_int)
627 }
628
629 fn recv_buffer_size(&self) -> io::Result<usize> {
630 get_opt(self.as_sock(), SOL_SOCKET, SO_RCVBUF).map(int2usize)
631 }
632
633 fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
634 set_opt(self.as_sock(), SOL_SOCKET, SO_SNDBUF, size as c_int)
635 }
636
637 fn send_buffer_size(&self) -> io::Result<usize> {
638 get_opt(self.as_sock(), SOL_SOCKET, SO_SNDBUF).map(int2usize)
639 }
640
641 fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
642 set_opt(self.as_sock(), v(IPPROTO_TCP), TCP_NODELAY,
643 nodelay as c_int)
644 }
645 fn nodelay(&self) -> io::Result<bool> {
646 get_opt(self.as_sock(), v(IPPROTO_TCP), TCP_NODELAY)
647 .map(int2bool)
648 }
649
650 fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
651 self.set_keepalive_ms(keepalive.map(dur2ms))
652 }
653
654 fn keepalive(&self) -> io::Result<Option<Duration>> {
655 self.keepalive_ms().map(|o| o.map(ms2dur))
656 }
657
658 #[cfg(unix)]
659 fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
660 try!(set_opt(self.as_sock(), SOL_SOCKET, SO_KEEPALIVE,
661 keepalive.is_some() as c_int));
662 if let Some(dur) = keepalive {
663 try!(set_opt(self.as_sock(), v(IPPROTO_TCP), KEEPALIVE_OPTION,
664 (dur / 1000) as c_int));
665 }
666 Ok(())
667 }
668
669 #[cfg(unix)]
670 fn keepalive_ms(&self) -> io::Result<Option<u32>> {
671 let keepalive = try!(get_opt::<c_int>(self.as_sock(), SOL_SOCKET,
672 SO_KEEPALIVE));
673 if keepalive == 0 {
674 return Ok(None)
675 }
676 let secs = try!(get_opt::<c_int>(self.as_sock(), v(IPPROTO_TCP),
677 KEEPALIVE_OPTION));
678 Ok(Some((secs as u32) * 1000))
679 }
680
681 #[cfg(windows)]
682 fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
683 let ms = keepalive.unwrap_or(INFINITE);
684 let ka = tcp_keepalive {
685 onoff: keepalive.is_some() as c_ulong,
686 keepalivetime: ms as c_ulong,
687 keepaliveinterval: ms as c_ulong,
688 };
689 unsafe {
690 ::cvt_win(WSAIoctl(self.as_sock(),
691 SIO_KEEPALIVE_VALS,
692 &ka as *const _ as *mut _,
693 mem::size_of_val(&ka) as DWORD,
694 0 as *mut _,
695 0,
696 0 as *mut _,
697 0 as *mut _,
698 None)).map(|_| ())
699 }
700 }
701
702 #[cfg(windows)]
703 fn keepalive_ms(&self) -> io::Result<Option<u32>> {
704 let mut ka = tcp_keepalive {
705 onoff: 0,
706 keepalivetime: 0,
707 keepaliveinterval: 0,
708 };
709 unsafe {
710 try!(::cvt_win(WSAIoctl(self.as_sock(),
711 SIO_KEEPALIVE_VALS,
712 0 as *mut _,
713 0,
714 &mut ka as *mut _ as *mut _,
715 mem::size_of_val(&ka) as DWORD,
716 0 as *mut _,
717 0 as *mut _,
718 None)));
719 }
720 Ok({
721 if ka.onoff == 0 {
722 None
723 } else {
724 timeout2ms(ka.keepaliveinterval as DWORD)
725 }
726 })
727 }
728
729 fn set_read_timeout_ms(&self, dur: Option<u32>) -> io::Result<()> {
730 set_opt(self.as_sock(), SOL_SOCKET, SO_RCVTIMEO,
731 ms2timeout(dur))
732 }
733
734 fn read_timeout_ms(&self) -> io::Result<Option<u32>> {
735 get_opt(self.as_sock(), SOL_SOCKET, SO_RCVTIMEO)
736 .map(timeout2ms)
737 }
738
739 fn set_write_timeout_ms(&self, dur: Option<u32>) -> io::Result<()> {
740 set_opt(self.as_sock(), SOL_SOCKET, SO_SNDTIMEO,
741 ms2timeout(dur))
742 }
743
744 fn write_timeout_ms(&self) -> io::Result<Option<u32>> {
745 get_opt(self.as_sock(), SOL_SOCKET, SO_SNDTIMEO)
746 .map(timeout2ms)
747 }
748
749 fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
750 self.set_read_timeout_ms(dur.map(dur2ms))
751 }
752
753 fn read_timeout(&self) -> io::Result<Option<Duration>> {
754 self.read_timeout_ms().map(|o| o.map(ms2dur))
755 }
756
757 fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
758 self.set_write_timeout_ms(dur.map(dur2ms))
759 }
760
761 fn write_timeout(&self) -> io::Result<Option<Duration>> {
762 self.write_timeout_ms().map(|o| o.map(ms2dur))
763 }
764
765 fn set_ttl(&self, ttl: u32) -> io::Result<()> {
766 set_opt(self.as_sock(), IPPROTO_IP, IP_TTL, ttl as c_int)
767 }
768
769 fn ttl(&self) -> io::Result<u32> {
770 get_opt::<c_int>(self.as_sock(), IPPROTO_IP, IP_TTL)
771 .map(|b| b as u32)
772 }
773
774 fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
775 set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY, only_v6 as c_int)
776 }
777
778 fn only_v6(&self) -> io::Result<bool> {
779 get_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY).map(int2bool)
780 }
781
782 fn connect<T: ToSocketAddrs>(&self, addr: T) -> io::Result<()> {
783 do_connect(self.as_sock(), addr)
784 }
785
786 fn take_error(&self) -> io::Result<Option<io::Error>> {
787 get_opt(self.as_sock(), SOL_SOCKET, SO_ERROR).map(int2err)
788 }
789
790 fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
791 set_nonblocking(self.as_sock(), nonblocking)
792 }
793
794 fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
795 set_opt(self.as_sock(), SOL_SOCKET, SO_LINGER, dur2linger(dur))
796 }
797
798 fn linger(&self) -> io::Result<Option<Duration>> {
799 get_opt(self.as_sock(), SOL_SOCKET, SO_LINGER).map(linger2dur)
800 }
801 }
802
803 #[cfg(unix)]
804 fn ms2timeout(dur: Option<u32>) -> timeval {
805 // TODO: be more rigorous
806 match dur {
807 Some(d) => timeval {
808 tv_sec: (d / 1000) as time_t,
809 tv_usec: (d % 1000) as suseconds_t,
810 },
811 None => timeval { tv_sec: 0, tv_usec: 0 },
812 }
813 }
814
815 #[cfg(unix)]
816 fn timeout2ms(dur: timeval) -> Option<u32> {
817 if dur.tv_sec == 0 && dur.tv_usec == 0 {
818 None
819 } else {
820 Some(dur.tv_sec as u32 * 1000 + dur.tv_usec as u32 / 1000)
821 }
822 }
823
824 #[cfg(windows)]
825 fn ms2timeout(dur: Option<u32>) -> DWORD {
826 dur.unwrap_or(0)
827 }
828
829 #[cfg(windows)]
830 fn timeout2ms(dur: DWORD) -> Option<u32> {
831 if dur == 0 {
832 None
833 } else {
834 Some(dur)
835 }
836 }
837
838 fn linger2dur(linger_opt: linger) -> Option<Duration> {
839 if linger_opt.l_onoff == 0 {
840 None
841 }
842 else {
843 Some(Duration::from_secs(linger_opt.l_linger as u64))
844 }
845 }
846
847 #[cfg(windows)]
848 fn dur2linger(dur: Option<Duration>) -> linger {
849 match dur {
850 Some(d) => {
851 linger {
852 l_onoff: 1,
853 l_linger: d.as_secs() as u16,
854 }
855 },
856 None => linger { l_onoff: 0, l_linger: 0 },
857 }
858 }
859
860 #[cfg(unix)]
861 fn dur2linger(dur: Option<Duration>) -> linger {
862 match dur {
863 Some(d) => {
864 linger {
865 l_onoff: 1,
866 l_linger: d.as_secs() as c_int,
867 }
868 },
869 None => linger { l_onoff: 0, l_linger: 0 },
870 }
871 }
872
873 fn ms2dur(ms: u32) -> Duration {
874 Duration::new((ms as u64) / 1000, (ms as u32) % 1000 * 1_000_000)
875 }
876
877 fn dur2ms(dur: Duration) -> u32 {
878 (dur.as_secs() as u32 * 1000) + (dur.subsec_nanos() / 1_000_000)
879 }
880
881 pub fn int2bool(n: c_int) -> bool {
882 if n == 0 {false} else {true}
883 }
884
885 pub fn int2usize(n: c_int) -> usize {
886 // TODO: casting c_int to a usize should be a checked cast
887 n as usize
888 }
889
890 pub fn int2err(n: c_int) -> Option<io::Error> {
891 if n == 0 {
892 None
893 } else {
894 Some(io::Error::from_raw_os_error(n as i32))
895 }
896 }
897
898 impl UdpSocketExt for UdpSocket {
899
900 fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
901 set_opt(self.as_sock(), SOL_SOCKET, SO_RCVBUF, size as c_int)
902 }
903
904 fn recv_buffer_size(&self) -> io::Result<usize> {
905 get_opt(self.as_sock(), SOL_SOCKET, SO_RCVBUF).map(int2usize)
906 }
907
908 fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
909 set_opt(self.as_sock(), SOL_SOCKET, SO_SNDBUF, size as c_int)
910 }
911
912 fn send_buffer_size(&self) -> io::Result<usize> {
913 get_opt(self.as_sock(), SOL_SOCKET, SO_SNDBUF).map(int2usize)
914 }
915
916 fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
917 set_opt(self.as_sock(), SOL_SOCKET, SO_BROADCAST,
918 broadcast as c_int)
919 }
920 fn broadcast(&self) -> io::Result<bool> {
921 get_opt(self.as_sock(), SOL_SOCKET, SO_BROADCAST)
922 .map(int2bool)
923 }
924 fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
925 set_opt(self.as_sock(), IPPROTO_IP, IP_MULTICAST_LOOP,
926 multicast_loop_v4 as c_int)
927 }
928 fn multicast_loop_v4(&self) -> io::Result<bool> {
929 get_opt(self.as_sock(), IPPROTO_IP, IP_MULTICAST_LOOP)
930 .map(int2bool)
931 }
932 fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
933 set_opt(self.as_sock(), IPPROTO_IP, IP_MULTICAST_TTL,
934 multicast_ttl_v4 as c_int)
935 }
936 fn multicast_ttl_v4(&self) -> io::Result<u32> {
937 get_opt::<c_int>(self.as_sock(), IPPROTO_IP, IP_MULTICAST_TTL)
938 .map(|b| b as u32)
939 }
940 fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
941 set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_MULTICAST_LOOP,
942 multicast_loop_v6 as c_int)
943 }
944 fn multicast_loop_v6(&self) -> io::Result<bool> {
945 get_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_MULTICAST_LOOP)
946 .map(int2bool)
947 }
948
949 fn set_ttl(&self, ttl: u32) -> io::Result<()> {
950 set_opt(self.as_sock(), IPPROTO_IP, IP_TTL, ttl as c_int)
951 }
952
953 fn ttl(&self) -> io::Result<u32> {
954 get_opt::<c_int>(self.as_sock(), IPPROTO_IP, IP_TTL)
955 .map(|b| b as u32)
956 }
957
958 fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
959 set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY, only_v6 as c_int)
960 }
961
962 fn only_v6(&self) -> io::Result<bool> {
963 get_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY).map(int2bool)
964 }
965
966 fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
967 -> io::Result<()> {
968 let mreq = ip_mreq {
969 imr_multiaddr: ip2in_addr(multiaddr),
970 imr_interface: ip2in_addr(interface),
971 };
972 set_opt(self.as_sock(), IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
973 }
974
975 fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
976 -> io::Result<()> {
977 let mreq = ipv6_mreq {
978 ipv6mr_multiaddr: ip2in6_addr(multiaddr),
979 ipv6mr_interface: to_ipv6mr_interface(interface),
980 };
981 set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_ADD_MEMBERSHIP,
982 mreq)
983 }
984
985 fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
986 -> io::Result<()> {
987 let mreq = ip_mreq {
988 imr_multiaddr: ip2in_addr(multiaddr),
989 imr_interface: ip2in_addr(interface),
990 };
991 set_opt(self.as_sock(), IPPROTO_IP, IP_DROP_MEMBERSHIP, mreq)
992 }
993
994 fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
995 -> io::Result<()> {
996 let mreq = ipv6_mreq {
997 ipv6mr_multiaddr: ip2in6_addr(multiaddr),
998 ipv6mr_interface: to_ipv6mr_interface(interface),
999 };
1000 set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_DROP_MEMBERSHIP,
1001 mreq)
1002 }
1003
1004 fn set_read_timeout_ms(&self, dur: Option<u32>) -> io::Result<()> {
1005 set_opt(self.as_sock(), SOL_SOCKET, SO_RCVTIMEO,
1006 ms2timeout(dur))
1007 }
1008
1009 fn read_timeout_ms(&self) -> io::Result<Option<u32>> {
1010 get_opt(self.as_sock(), SOL_SOCKET, SO_RCVTIMEO)
1011 .map(timeout2ms)
1012 }
1013
1014 fn set_write_timeout_ms(&self, dur: Option<u32>) -> io::Result<()> {
1015 set_opt(self.as_sock(), SOL_SOCKET, SO_SNDTIMEO,
1016 ms2timeout(dur))
1017 }
1018
1019 fn write_timeout_ms(&self) -> io::Result<Option<u32>> {
1020 get_opt(self.as_sock(), SOL_SOCKET, SO_SNDTIMEO)
1021 .map(timeout2ms)
1022 }
1023
1024 fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
1025 self.set_read_timeout_ms(dur.map(dur2ms))
1026 }
1027
1028 fn read_timeout(&self) -> io::Result<Option<Duration>> {
1029 self.read_timeout_ms().map(|o| o.map(ms2dur))
1030 }
1031
1032 fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
1033 self.set_write_timeout_ms(dur.map(dur2ms))
1034 }
1035
1036 fn write_timeout(&self) -> io::Result<Option<Duration>> {
1037 self.write_timeout_ms().map(|o| o.map(ms2dur))
1038 }
1039
1040 fn take_error(&self) -> io::Result<Option<io::Error>> {
1041 get_opt(self.as_sock(), SOL_SOCKET, SO_ERROR).map(int2err)
1042 }
1043
1044 fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
1045 do_connect(self.as_sock(), addr)
1046 }
1047
1048 #[cfg(unix)]
1049 fn send(&self, buf: &[u8]) -> io::Result<usize> {
1050 unsafe {
1051 ::cvt(send(self.as_sock(), buf.as_ptr() as *const _, buf.len(), 0)).map(|n| n as usize)
1052 }
1053 }
1054
1055 #[cfg(windows)]
1056 fn send(&self, buf: &[u8]) -> io::Result<usize> {
1057 let len = ::std::cmp::min(buf.len(), c_int::max_value() as usize);
1058 let buf = &buf[..len];
1059 unsafe {
1060 ::cvt(send(self.as_sock(), buf.as_ptr() as *const _, len as c_int, 0))
1061 .map(|n| n as usize)
1062 }
1063 }
1064
1065 #[cfg(unix)]
1066 fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
1067 unsafe {
1068 ::cvt(recv(self.as_sock(), buf.as_mut_ptr() as *mut _, buf.len(), 0))
1069 .map(|n| n as usize)
1070 }
1071 }
1072
1073 #[cfg(windows)]
1074 fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
1075 let len = ::std::cmp::min(buf.len(), c_int::max_value() as usize);
1076 let buf = &mut buf[..len];
1077 unsafe {
1078 ::cvt(recv(self.as_sock(), buf.as_mut_ptr() as *mut _, buf.len() as c_int, 0))
1079 .map(|n| n as usize)
1080 }
1081 }
1082
1083 fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
1084 set_nonblocking(self.as_sock(), nonblocking)
1085 }
1086 }
1087
1088 fn do_connect<A: ToSocketAddrs>(sock: Socket, addr: A) -> io::Result<()> {
1089 let err = io::Error::new(io::ErrorKind::Other,
1090 "no socket addresses resolved");
1091 let addrs = try!(addr.to_socket_addrs());
1092 let sys = sys::Socket::from_inner(sock);
1093 let sock = socket::Socket::from_inner(sys);
1094 let ret = addrs.fold(Err(err), |prev, addr| {
1095 prev.or_else(|_| sock.connect(&addr))
1096 });
1097 mem::forget(sock);
1098 return ret
1099 }
1100
1101 #[cfg(unix)]
1102 fn set_nonblocking(sock: Socket, nonblocking: bool) -> io::Result<()> {
1103 let mut nonblocking = nonblocking as c_ulong;
1104 ::cvt(unsafe {
1105 ioctl(sock, FIONBIO, &mut nonblocking)
1106 }).map(|_| ())
1107 }
1108
1109 #[cfg(windows)]
1110 fn set_nonblocking(sock: Socket, nonblocking: bool) -> io::Result<()> {
1111 let mut nonblocking = nonblocking as c_ulong;
1112 ::cvt(unsafe {
1113 ioctlsocket(sock, FIONBIO as c_int, &mut nonblocking)
1114 }).map(|_| ())
1115 }
1116
1117 #[cfg(unix)]
1118 fn ip2in_addr(ip: &Ipv4Addr) -> in_addr {
1119 let oct = ip.octets();
1120 in_addr {
1121 s_addr: ::hton(((oct[0] as u32) << 24) |
1122 ((oct[1] as u32) << 16) |
1123 ((oct[2] as u32) << 8) |
1124 ((oct[3] as u32) << 0)),
1125 }
1126 }
1127
1128 #[cfg(windows)]
1129 fn ip2in_addr(ip: &Ipv4Addr) -> in_addr {
1130 let oct = ip.octets();
1131 in_addr {
1132 S_un: ::hton(((oct[0] as u32) << 24) |
1133 ((oct[1] as u32) << 16) |
1134 ((oct[2] as u32) << 8) |
1135 ((oct[3] as u32) << 0)),
1136 }
1137 }
1138
1139 #[cfg(target_os = "android")]
1140 fn to_ipv6mr_interface(value: u32) -> c_int {
1141 value as c_int
1142 }
1143
1144 #[cfg(not(target_os = "android"))]
1145 fn to_ipv6mr_interface(value: u32) -> c_uint {
1146 value as c_uint
1147 }
1148
1149 fn ip2in6_addr(ip: &Ipv6Addr) -> in6_addr {
1150 let mut ret: in6_addr = unsafe { mem::zeroed() };
1151 let seg = ip.segments();
1152 ret.s6_addr = [
1153 (seg[0] >> 8) as u8,
1154 (seg[0] >> 0) as u8,
1155 (seg[1] >> 8) as u8,
1156 (seg[1] >> 0) as u8,
1157 (seg[2] >> 8) as u8,
1158 (seg[2] >> 0) as u8,
1159 (seg[3] >> 8) as u8,
1160 (seg[3] >> 0) as u8,
1161 (seg[4] >> 8) as u8,
1162 (seg[4] >> 0) as u8,
1163 (seg[5] >> 8) as u8,
1164 (seg[5] >> 0) as u8,
1165 (seg[6] >> 8) as u8,
1166 (seg[6] >> 0) as u8,
1167 (seg[7] >> 8) as u8,
1168 (seg[7] >> 0) as u8,
1169 ];
1170 return ret
1171 }
1172
1173 impl TcpListenerExt for TcpListener {
1174 fn set_ttl(&self, ttl: u32) -> io::Result<()> {
1175 set_opt(self.as_sock(), IPPROTO_IP, IP_TTL, ttl as c_int)
1176 }
1177
1178 fn ttl(&self) -> io::Result<u32> {
1179 get_opt::<c_int>(self.as_sock(), IPPROTO_IP, IP_TTL)
1180 .map(|b| b as u32)
1181 }
1182
1183 fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
1184 set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY, only_v6 as c_int)
1185 }
1186
1187 fn only_v6(&self) -> io::Result<bool> {
1188 get_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY).map(int2bool)
1189 }
1190
1191 fn take_error(&self) -> io::Result<Option<io::Error>> {
1192 get_opt(self.as_sock(), SOL_SOCKET, SO_ERROR).map(int2err)
1193 }
1194
1195 fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
1196 set_nonblocking(self.as_sock(), nonblocking)
1197 }
1198
1199 fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
1200 set_opt(self.as_sock(), SOL_SOCKET, SO_LINGER, dur2linger(dur))
1201 }
1202
1203 fn linger(&self) -> io::Result<Option<Duration>> {
1204 get_opt(self.as_sock(), SOL_SOCKET, SO_LINGER).map(linger2dur)
1205 }
1206 }
1207
1208 impl TcpBuilder {
1209 /// Sets the value for the `IP_TTL` option on this socket.
1210 ///
1211 /// This is the same as [`TcpStreamExt::set_ttl`][other].
1212 ///
1213 /// [other]: trait.TcpStreamExt.html#tymethod.set_ttl
1214 pub fn ttl(&self, ttl: u32) -> io::Result<&Self> {
1215 set_opt(self.as_sock(), IPPROTO_IP, IP_TTL, ttl as c_int)
1216 .map(|()| self)
1217 }
1218
1219 /// Sets the value for the `IPV6_V6ONLY` option on this socket.
1220 ///
1221 /// This is the same as [`TcpStreamExt::set_only_v6`][other].
1222 ///
1223 /// [other]: trait.TcpStreamExt.html#tymethod.set_only_v6
1224 pub fn only_v6(&self, only_v6: bool) -> io::Result<&Self> {
1225 set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY, only_v6 as c_int)
1226 .map(|()| self)
1227 }
1228
1229 /// Set value for the `SO_REUSEADDR` option on this socket.
1230 ///
1231 /// This indicates that futher calls to `bind` may allow reuse of local
1232 /// addresses. For IPv4 sockets this means that a socket may bind even when
1233 /// there's a socket already listening on this port.
1234 pub fn reuse_address(&self, reuse: bool) -> io::Result<&Self> {
1235 set_opt(self.as_sock(), SOL_SOCKET, SO_REUSEADDR,
1236 reuse as c_int).map(|()| self)
1237 }
1238
1239 /// Check the `SO_REUSEADDR` option on this socket.
1240 pub fn get_reuse_address(&self) -> io::Result<bool> {
1241 get_opt(self.as_sock(), SOL_SOCKET, SO_REUSEADDR).map(int2bool)
1242 }
1243
1244 /// Get the value of the `SO_ERROR` option on this socket.
1245 ///
1246 /// This will retrieve the stored error in the underlying socket, clearing
1247 /// the field in the process. This can be useful for checking errors between
1248 /// calls.
1249 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
1250 get_opt(self.as_sock(), SOL_SOCKET, SO_ERROR).map(int2err)
1251 }
1252
1253 /// Sets the linger option for this socket
1254 fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
1255 set_opt(self.as_sock(), SOL_SOCKET, SO_LINGER, dur2linger(dur))
1256 }
1257
1258 /// Gets the linger option for this socket
1259 fn linger(&self) -> io::Result<Option<Duration>> {
1260 get_opt(self.as_sock(), SOL_SOCKET, SO_LINGER).map(linger2dur)
1261 }
1262 }
1263
1264 impl UdpBuilder {
1265 /// Sets the value for the `IP_TTL` option on this socket.
1266 ///
1267 /// This is the same as [`TcpStreamExt::set_ttl`][other].
1268 ///
1269 /// [other]: trait.TcpStreamExt.html#tymethod.set_ttl
1270 pub fn ttl(&self, ttl: u32) -> io::Result<&Self> {
1271 set_opt(self.as_sock(), IPPROTO_IP, IP_TTL, ttl as c_int)
1272 .map(|()| self)
1273 }
1274
1275 /// Sets the value for the `IPV6_V6ONLY` option on this socket.
1276 ///
1277 /// This is the same as [`TcpStream::only_v6`][other].
1278 ///
1279 /// [other]: struct.TcpBuilder.html#method.only_v6
1280 pub fn only_v6(&self, only_v6: bool) -> io::Result<&Self> {
1281 set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY, only_v6 as c_int)
1282 .map(|()| self)
1283 }
1284
1285 /// Set value for the `SO_REUSEADDR` option on this socket.
1286 ///
1287 /// This is the same as [`TcpBuilder::reuse_address`][other].
1288 ///
1289 /// [other]: struct.TcpBuilder.html#method.reuse_address
1290 pub fn reuse_address(&self, reuse: bool) -> io::Result<&Self> {
1291 set_opt(self.as_sock(), SOL_SOCKET, SO_REUSEADDR,
1292 reuse as c_int).map(|()| self)
1293 }
1294
1295 /// Check the `SO_REUSEADDR` option on this socket.
1296 pub fn get_reuse_address(&self) -> io::Result<bool> {
1297 get_opt(self.as_sock(), SOL_SOCKET, SO_REUSEADDR).map(int2bool)
1298 }
1299
1300 /// Get the value of the `SO_ERROR` option on this socket.
1301 ///
1302 /// This will retrieve the stored error in the underlying socket, clearing
1303 /// the field in the process. This can be useful for checking errors between
1304 /// calls.
1305 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
1306 get_opt(self.as_sock(), SOL_SOCKET, SO_ERROR).map(int2err)
1307 }
1308 }