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.
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.
11 #![allow(bad_style, dead_code)]
15 use std
::net
::{TcpStream, TcpListener, UdpSocket, Ipv4Addr, Ipv6Addr}
;
16 use std
::net
::ToSocketAddrs
;
18 use {TcpBuilder, UdpBuilder, FromInner}
;
23 if #[cfg(any(target_os = "dragonfly",
24 target_os
= "freebsd",
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
;
38 use std
::time
::Duration
;
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::*;
48 #[cfg(windows)] const SIO_KEEPALIVE_VALS: DWORD = 0x98000004;
51 struct tcp_keepalive
{
53 keepalivetime
: c_ulong
,
54 keepaliveinterval
: c_ulong
,
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 }
60 pub fn set_opt
<T
: Copy
>(sock
: Socket
, opt
: c_int
, val
: c_int
,
61 payload
: T
) -> io
::Result
<()> {
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
)));
70 pub fn get_opt
<T
: Copy
>(sock
: Socket
, opt
: c_int
, val
: c_int
) -> io
::Result
<T
> {
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 _
,
77 assert_eq
!(len
as usize, mem
::size_of
::<T
>());
82 /// Extension methods for the standard [`TcpStream` type][link] in `std::net`.
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.
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
93 fn set_nodelay(&self, nodelay
: bool
) -> io
::Result
<()>;
95 /// Gets the value of the `TCP_NODELAY` option on this socket.
97 /// For more information about this option, see [`set_nodelay`][link].
99 /// [link]: #tymethod.set_nodelay
100 fn nodelay(&self) -> io
::Result
<bool
>;
102 /// Sets the value of the `SO_RCVBUF` option on this socket.
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
<()>;
107 /// Gets the value of the `SO_RCVBUF` option on this socket.
109 /// For more information about this option, see [`set_recv_buffer_size`][link].
111 /// [link]: #tymethod.set_recv_buffer_size
112 fn recv_buffer_size(&self) -> io
::Result
<usize>;
114 /// Sets the value of the `SO_SNDBUF` option on this socket.
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
<()>;
119 /// Gets the value of the `SO_SNDBUF` option on this socket.
121 /// For more information about this option, see [`set_send_buffer`][link].
123 /// [link]: #tymethod.set_send_buffer
124 fn send_buffer_size(&self) -> io
::Result
<usize>;
126 /// Sets whether keepalive messages are enabled to be sent on this socket.
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.
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.
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
<()>;
140 /// Returns whether keepalive messages are enabled on this socket, and if so
141 /// the amount of milliseconds between them.
143 /// For more information about this option, see [`set_keepalive_ms`][link].
145 /// [link]: #tymethod.set_keepalive_ms
146 fn keepalive_ms(&self) -> io
::Result
<Option
<u32>>;
148 /// Sets whether keepalive messages are enabled to be sent on this socket.
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.
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.
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
<()>;
162 /// Returns whether keepalive messages are enabled on this socket, and if so
163 /// the duration of time between them.
165 /// For more information about this option, see [`set_keepalive`][link].
167 /// [link]: #tymethod.set_keepalive
168 fn keepalive(&self) -> io
::Result
<Option
<Duration
>>;
170 /// Sets the `SO_RCVTIMEO` option for this socket.
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
<()>;
178 /// Sets the `SO_RCVTIMEO` option for this socket.
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
<()>;
186 /// Gets the value of the `SO_RCVTIMEO` option for this socket.
188 /// For more information about this option, see [`set_read_timeout_ms`][link].
190 /// [link]: #tymethod.set_read_timeout_ms
191 fn read_timeout_ms(&self) -> io
::Result
<Option
<u32>>;
193 /// Gets the value of the `SO_RCVTIMEO` option for this socket.
195 /// For more information about this option, see [`set_read_timeout`][link].
197 /// [link]: #tymethod.set_read_timeout
198 fn read_timeout(&self) -> io
::Result
<Option
<Duration
>>;
200 /// Sets the `SO_SNDTIMEO` option for this socket.
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
<()>;
208 /// Sets the `SO_SNDTIMEO` option for this socket.
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
<()>;
216 /// Gets the value of the `SO_SNDTIMEO` option for this socket.
218 /// For more information about this option, see [`set_write_timeout_ms`][link].
220 /// [link]: #tymethod.set_write_timeout_ms
221 fn write_timeout_ms(&self) -> io
::Result
<Option
<u32>>;
223 /// Gets the value of the `SO_SNDTIMEO` option for this socket.
225 /// For more information about this option, see [`set_write_timeout`][link].
227 /// [link]: #tymethod.set_write_timeout
228 fn write_timeout(&self) -> io
::Result
<Option
<Duration
>>;
230 /// Sets the value for the `IP_TTL` option on this socket.
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
<()>;
236 /// Gets the value of the `IP_TTL` option for this socket.
238 /// For more information about this option, see [`set_ttl`][link].
240 /// [link]: #tymethod.set_ttl
241 fn ttl(&self) -> io
::Result
<u32>;
243 /// Sets the value for the `IPV6_V6ONLY` option on this socket.
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.
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
<()>;
253 /// Gets the value of the `IPV6_V6ONLY` option for this socket.
255 /// For more information about this option, see [`set_only_v6`][link].
257 /// [link]: #tymethod.set_only_v6
258 fn only_v6(&self) -> io
::Result
<bool
>;
260 /// Executes a `connect` operation on this socket, establishing a connection
261 /// to the host specified by `addr`.
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.
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
<()>;
271 /// Get the value of the `SO_ERROR` option on this socket.
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
276 fn take_error(&self) -> io
::Result
<Option
<io
::Error
>>;
278 /// Moves this TCP stream into or out of nonblocking mode.
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
<()>;
284 /// Sets the linger duration of this socket by setting the SO_LINGER option
285 fn set_linger(&self, dur
: Option
<Duration
>) -> io
::Result
<()>;
287 /// reads the linger duration for this socket by getting the SO_LINGER option
288 fn linger(&self) -> io
::Result
<Option
<Duration
>>;
291 /// Extension methods for the standard [`TcpListener` type][link] in `std::net`.
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.
297 /// This is the same as [`TcpStreamExt::set_ttl`][other].
299 /// [other]: trait.TcpStreamExt.html#tymethod.set_ttl
300 fn set_ttl(&self, ttl
: u32) -> io
::Result
<()>;
302 /// Gets the value of the `IP_TTL` option for this socket.
304 /// For more information about this option, see
305 /// [`TcpStreamExt::set_ttl`][link].
307 /// [link]: trait.TcpStreamExt.html#tymethod.set_ttl
308 fn ttl(&self) -> io
::Result
<u32>;
310 /// Sets the value for the `IPV6_V6ONLY` option on this socket.
312 /// For more information about this option, see
313 /// [`TcpStreamExt::set_only_v6`][link].
315 /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
316 fn set_only_v6(&self, only_v6
: bool
) -> io
::Result
<()>;
318 /// Gets the value of the `IPV6_V6ONLY` option for this socket.
320 /// For more information about this option, see
321 /// [`TcpStreamExt::set_only_v6`][link].
323 /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
324 fn only_v6(&self) -> io
::Result
<bool
>;
326 /// Get the value of the `SO_ERROR` option on this socket.
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
331 fn take_error(&self) -> io
::Result
<Option
<io
::Error
>>;
333 /// Moves this TCP listener into or out of nonblocking mode.
335 /// For more information about this option, see
336 /// [`TcpStreamExt::set_nonblocking`][link].
338 /// [link]: trait.TcpStreamExt.html#tymethod.set_nonblocking
339 fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()>;
341 /// Sets the linger duration of this socket by setting the SO_LINGER option
342 fn set_linger(&self, dur
: Option
<Duration
>) -> io
::Result
<()>;
344 /// reads the linger duration for this socket by getting the SO_LINGER option
345 fn linger(&self) -> io
::Result
<Option
<Duration
>>;
348 /// Extension methods for the standard [`UdpSocket` type][link] in `std::net`.
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.
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
<()>;
357 /// Gets the value of the `SO_RCVBUF` option on this socket.
359 /// For more information about this option, see [`set_recv_buffer_size`][link].
361 /// [link]: #tymethod.set_recv_buffer_size
362 fn recv_buffer_size(&self) -> io
::Result
<usize>;
364 /// Sets the value of the `SO_SNDBUF` option on this socket.
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
<()>;
369 /// Gets the value of the `SO_SNDBUF` option on this socket.
371 /// For more information about this option, see [`set_send_buffer`][link].
373 /// [link]: #tymethod.set_send_buffer
374 fn send_buffer_size(&self) -> io
::Result
<usize>;
376 /// Sets the value of the `SO_BROADCAST` option for this socket.
378 /// When enabled, this socket is allowed to send packets to a broadcast
380 fn set_broadcast(&self, broadcast
: bool
) -> io
::Result
<()>;
382 /// Gets the value of the `SO_BROADCAST` option for this socket.
384 /// For more information about this option, see
385 /// [`set_broadcast`][link].
387 /// [link]: #tymethod.set_broadcast
388 fn broadcast(&self) -> io
::Result
<bool
>;
390 /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
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
<()>;
396 /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
398 /// For more information about this option, see
399 /// [`set_multicast_loop_v4`][link].
401 /// [link]: #tymethod.set_multicast_loop_v4
402 fn multicast_loop_v4(&self) -> io
::Result
<bool
>;
404 /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
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.
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
<()>;
413 /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
415 /// For more information about this option, see
416 /// [`set_multicast_ttl_v4`][link].
418 /// [link]: #tymethod.set_multicast_ttl_v4
419 fn multicast_ttl_v4(&self) -> io
::Result
<u32>;
421 /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
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
<()>;
427 /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
429 /// For more information about this option, see
430 /// [`set_multicast_loop_v6`][link].
432 /// [link]: #tymethod.set_multicast_loop_v6
433 fn multicast_loop_v6(&self) -> io
::Result
<bool
>;
435 /// Sets the value for the `IP_TTL` option on this socket.
437 /// This is the same as [`TcpStreamExt::set_ttl`][other].
439 /// [other]: trait.TcpStreamExt.html#tymethod.set_ttl
440 fn set_ttl(&self, ttl
: u32) -> io
::Result
<()>;
442 /// Gets the value of the `IP_TTL` option for this socket.
444 /// For more information about this option, see
445 /// [`TcpStreamExt::set_ttl`][link].
447 /// [link]: trait.TcpStreamExt.html#tymethod.set_ttl
448 fn ttl(&self) -> io
::Result
<u32>;
450 /// Sets the value for the `IPV6_V6ONLY` option on this socket.
452 /// For more information about this option, see
453 /// [`TcpStreamExt::set_only_v6`][link].
455 /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
456 fn set_only_v6(&self, only_v6
: bool
) -> io
::Result
<()>;
458 /// Gets the value of the `IPV6_V6ONLY` option for this socket.
460 /// For more information about this option, see
461 /// [`TcpStreamExt::set_only_v6`][link].
463 /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
464 fn only_v6(&self) -> io
::Result
<bool
>;
466 /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
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
)
476 /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
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)
484 /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
486 /// For more information about this option, see
487 /// [`join_multicast_v4`][link].
489 /// [link]: #tymethod.join_multicast_v4
490 fn leave_multicast_v4(&self, multiaddr
: &Ipv4Addr
, interface
: &Ipv4Addr
)
493 /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
495 /// For more information about this option, see
496 /// [`join_multicast_v6`][link].
498 /// [link]: #tymethod.join_multicast_v6
499 fn leave_multicast_v6(&self, multiaddr
: &Ipv6Addr
, interface
: u32)
502 /// Sets the `SO_RCVTIMEO` option for this socket.
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
<()>;
510 /// Sets the `SO_RCVTIMEO` option for this socket.
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
<()>;
518 /// Gets the value of the `SO_RCVTIMEO` option for this socket.
520 /// For more information about this option, see [`set_read_timeout_ms`][link].
522 /// [link]: #tymethod.set_read_timeout_ms
523 fn read_timeout_ms(&self) -> io
::Result
<Option
<u32>>;
525 /// Gets the value of the `SO_RCVTIMEO` option for this socket.
527 /// For more information about this option, see [`set_read_timeout`][link].
529 /// [link]: #tymethod.set_read_timeout
530 fn read_timeout(&self) -> io
::Result
<Option
<Duration
>>;
532 /// Sets the `SO_SNDTIMEO` option for this socket.
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
<()>;
540 /// Sets the `SO_SNDTIMEO` option for this socket.
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
<()>;
548 /// Gets the value of the `SO_SNDTIMEO` option for this socket.
550 /// For more information about this option, see [`set_write_timeout_ms`][link].
552 /// [link]: #tymethod.set_write_timeout_ms
553 fn write_timeout_ms(&self) -> io
::Result
<Option
<u32>>;
555 /// Gets the value of the `SO_SNDTIMEO` option for this socket.
557 /// For more information about this option, see [`set_write_timeout`][link].
559 /// [link]: #tymethod.set_write_timeout
560 fn write_timeout(&self) -> io
::Result
<Option
<Duration
>>;
562 /// Get the value of the `SO_ERROR` option on this socket.
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
567 fn take_error(&self) -> io
::Result
<Option
<io
::Error
>>;
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
<()>;
574 /// Sends data on the socket to the remote address to which it is connected.
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>;
580 /// Receives data on the socket from the remote address to which it is
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>;
587 /// Moves this UDP socket into or out of nonblocking mode.
589 /// For more information about this option, see
590 /// [`TcpStreamExt::set_nonblocking`][link].
592 /// [link]: trait.TcpStreamExt.html#tymethod.set_nonblocking
593 fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()>;
598 fn as_sock(&self) -> Socket
;
602 impl<T
: AsRawFd
> AsSock
for T
{
603 fn as_sock(&self) -> Socket { self.as_raw_fd() }
606 impl<T
: AsRawSocket
> AsSock
for T
{
607 fn as_sock(&self) -> Socket { self.as_raw_socket() }
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
;
622 impl TcpStreamExt
for TcpStream
{
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
)
629 fn recv_buffer_size(&self) -> io
::Result
<usize> {
630 get_opt(self.as_sock(), SOL_SOCKET
, SO_RCVBUF
).map(int2usize
)
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
)
637 fn send_buffer_size(&self) -> io
::Result
<usize> {
638 get_opt(self.as_sock(), SOL_SOCKET
, SO_SNDBUF
).map(int2usize
)
641 fn set_nodelay(&self, nodelay
: bool
) -> io
::Result
<()> {
642 set_opt(self.as_sock(), v(IPPROTO_TCP
), TCP_NODELAY
,
645 fn nodelay(&self) -> io
::Result
<bool
> {
646 get_opt(self.as_sock(), v(IPPROTO_TCP
), TCP_NODELAY
)
650 fn set_keepalive(&self, keepalive
: Option
<Duration
>) -> io
::Result
<()> {
651 self.set_keepalive_ms(keepalive
.map(dur2ms
))
654 fn keepalive(&self) -> io
::Result
<Option
<Duration
>> {
655 self.keepalive_ms().map(|o
| o
.map(ms2dur
))
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
));
670 fn keepalive_ms(&self) -> io
::Result
<Option
<u32>> {
671 let keepalive
= try
!(get_opt
::<c_int
>(self.as_sock(), SOL_SOCKET
,
676 let secs
= try
!(get_opt
::<c_int
>(self.as_sock(), v(IPPROTO_TCP
),
678 Ok(Some((secs
as u32) * 1000))
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
,
690 ::cvt_win(WSAIoctl(self.as_sock(),
692 &ka
as *const _
as *mut _
,
693 mem
::size_of_val(&ka
) as DWORD
,
703 fn keepalive_ms(&self) -> io
::Result
<Option
<u32>> {
704 let mut ka
= tcp_keepalive
{
707 keepaliveinterval
: 0,
710 try
!(::cvt_win(WSAIoctl(self.as_sock(),
714 &mut ka
as *mut _
as *mut _
,
715 mem
::size_of_val(&ka
) as DWORD
,
724 timeout2ms(ka
.keepaliveinterval
as DWORD
)
729 fn set_read_timeout_ms(&self, dur
: Option
<u32>) -> io
::Result
<()> {
730 set_opt(self.as_sock(), SOL_SOCKET
, SO_RCVTIMEO
,
734 fn read_timeout_ms(&self) -> io
::Result
<Option
<u32>> {
735 get_opt(self.as_sock(), SOL_SOCKET
, SO_RCVTIMEO
)
739 fn set_write_timeout_ms(&self, dur
: Option
<u32>) -> io
::Result
<()> {
740 set_opt(self.as_sock(), SOL_SOCKET
, SO_SNDTIMEO
,
744 fn write_timeout_ms(&self) -> io
::Result
<Option
<u32>> {
745 get_opt(self.as_sock(), SOL_SOCKET
, SO_SNDTIMEO
)
749 fn set_read_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
750 self.set_read_timeout_ms(dur
.map(dur2ms
))
753 fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
754 self.read_timeout_ms().map(|o
| o
.map(ms2dur
))
757 fn set_write_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
758 self.set_write_timeout_ms(dur
.map(dur2ms
))
761 fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
762 self.write_timeout_ms().map(|o
| o
.map(ms2dur
))
765 fn set_ttl(&self, ttl
: u32) -> io
::Result
<()> {
766 set_opt(self.as_sock(), IPPROTO_IP
, IP_TTL
, ttl
as c_int
)
769 fn ttl(&self) -> io
::Result
<u32> {
770 get_opt
::<c_int
>(self.as_sock(), IPPROTO_IP
, IP_TTL
)
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
)
778 fn only_v6(&self) -> io
::Result
<bool
> {
779 get_opt(self.as_sock(), v(IPPROTO_IPV6
), IPV6_V6ONLY
).map(int2bool
)
782 fn connect
<T
: ToSocketAddrs
>(&self, addr
: T
) -> io
::Result
<()> {
783 do_connect(self.as_sock(), addr
)
786 fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
787 get_opt(self.as_sock(), SOL_SOCKET
, SO_ERROR
).map(int2err
)
790 fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
791 set_nonblocking(self.as_sock(), nonblocking
)
794 fn set_linger(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
795 set_opt(self.as_sock(), SOL_SOCKET
, SO_LINGER
, dur2linger(dur
))
798 fn linger(&self) -> io
::Result
<Option
<Duration
>> {
799 get_opt(self.as_sock(), SOL_SOCKET
, SO_LINGER
).map(linger2dur
)
804 fn ms2timeout(dur
: Option
<u32>) -> timeval
{
805 // TODO: be more rigorous
808 tv_sec
: (d
/ 1000) as time_t
,
809 tv_usec
: (d
% 1000) as suseconds_t
,
811 None
=> timeval { tv_sec: 0, tv_usec: 0 }
,
816 fn timeout2ms(dur
: timeval
) -> Option
<u32> {
817 if dur
.tv_sec
== 0 && dur
.tv_usec
== 0 {
820 Some(dur
.tv_sec
as u32 * 1000 + dur
.tv_usec
as u32 / 1000)
825 fn ms2timeout(dur
: Option
<u32>) -> DWORD
{
830 fn timeout2ms(dur
: DWORD
) -> Option
<u32> {
838 fn linger2dur(linger_opt
: linger
) -> Option
<Duration
> {
839 if linger_opt
.l_onoff
== 0 {
843 Some(Duration
::from_secs(linger_opt
.l_linger
as u64))
848 fn dur2linger(dur
: Option
<Duration
>) -> linger
{
853 l_linger
: d
.as_secs() as u16,
856 None
=> linger { l_onoff: 0, l_linger: 0 }
,
861 fn dur2linger(dur
: Option
<Duration
>) -> linger
{
866 l_linger
: d
.as_secs() as c_int
,
869 None
=> linger { l_onoff: 0, l_linger: 0 }
,
873 fn ms2dur(ms
: u32) -> Duration
{
874 Duration
::new((ms
as u64) / 1000, (ms
as u32) % 1000 * 1_000_000)
877 fn dur2ms(dur
: Duration
) -> u32 {
878 (dur
.as_secs() as u32 * 1000) + (dur
.subsec_nanos() / 1_000_000)
881 pub fn int2bool(n
: c_int
) -> bool
{
882 if n
== 0 {false}
else {true}
885 pub fn int2usize(n
: c_int
) -> usize {
886 // TODO: casting c_int to a usize should be a checked cast
890 pub fn int2err(n
: c_int
) -> Option
<io
::Error
> {
894 Some(io
::Error
::from_raw_os_error(n
as i32))
898 impl UdpSocketExt
for UdpSocket
{
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
)
904 fn recv_buffer_size(&self) -> io
::Result
<usize> {
905 get_opt(self.as_sock(), SOL_SOCKET
, SO_RCVBUF
).map(int2usize
)
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
)
912 fn send_buffer_size(&self) -> io
::Result
<usize> {
913 get_opt(self.as_sock(), SOL_SOCKET
, SO_SNDBUF
).map(int2usize
)
916 fn set_broadcast(&self, broadcast
: bool
) -> io
::Result
<()> {
917 set_opt(self.as_sock(), SOL_SOCKET
, SO_BROADCAST
,
920 fn broadcast(&self) -> io
::Result
<bool
> {
921 get_opt(self.as_sock(), SOL_SOCKET
, SO_BROADCAST
)
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
)
928 fn multicast_loop_v4(&self) -> io
::Result
<bool
> {
929 get_opt(self.as_sock(), IPPROTO_IP
, IP_MULTICAST_LOOP
)
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
)
936 fn multicast_ttl_v4(&self) -> io
::Result
<u32> {
937 get_opt
::<c_int
>(self.as_sock(), IPPROTO_IP
, IP_MULTICAST_TTL
)
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
)
944 fn multicast_loop_v6(&self) -> io
::Result
<bool
> {
945 get_opt(self.as_sock(), v(IPPROTO_IPV6
), IPV6_MULTICAST_LOOP
)
949 fn set_ttl(&self, ttl
: u32) -> io
::Result
<()> {
950 set_opt(self.as_sock(), IPPROTO_IP
, IP_TTL
, ttl
as c_int
)
953 fn ttl(&self) -> io
::Result
<u32> {
954 get_opt
::<c_int
>(self.as_sock(), IPPROTO_IP
, IP_TTL
)
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
)
962 fn only_v6(&self) -> io
::Result
<bool
> {
963 get_opt(self.as_sock(), v(IPPROTO_IPV6
), IPV6_V6ONLY
).map(int2bool
)
966 fn join_multicast_v4(&self, multiaddr
: &Ipv4Addr
, interface
: &Ipv4Addr
)
969 imr_multiaddr
: ip2in_addr(multiaddr
),
970 imr_interface
: ip2in_addr(interface
),
972 set_opt(self.as_sock(), IPPROTO_IP
, IP_ADD_MEMBERSHIP
, mreq
)
975 fn join_multicast_v6(&self, multiaddr
: &Ipv6Addr
, interface
: u32)
977 let mreq
= ipv6_mreq
{
978 ipv6mr_multiaddr
: ip2in6_addr(multiaddr
),
979 ipv6mr_interface
: to_ipv6mr_interface(interface
),
981 set_opt(self.as_sock(), v(IPPROTO_IPV6
), IPV6_ADD_MEMBERSHIP
,
985 fn leave_multicast_v4(&self, multiaddr
: &Ipv4Addr
, interface
: &Ipv4Addr
)
988 imr_multiaddr
: ip2in_addr(multiaddr
),
989 imr_interface
: ip2in_addr(interface
),
991 set_opt(self.as_sock(), IPPROTO_IP
, IP_DROP_MEMBERSHIP
, mreq
)
994 fn leave_multicast_v6(&self, multiaddr
: &Ipv6Addr
, interface
: u32)
996 let mreq
= ipv6_mreq
{
997 ipv6mr_multiaddr
: ip2in6_addr(multiaddr
),
998 ipv6mr_interface
: to_ipv6mr_interface(interface
),
1000 set_opt(self.as_sock(), v(IPPROTO_IPV6
), IPV6_DROP_MEMBERSHIP
,
1004 fn set_read_timeout_ms(&self, dur
: Option
<u32>) -> io
::Result
<()> {
1005 set_opt(self.as_sock(), SOL_SOCKET
, SO_RCVTIMEO
,
1009 fn read_timeout_ms(&self) -> io
::Result
<Option
<u32>> {
1010 get_opt(self.as_sock(), SOL_SOCKET
, SO_RCVTIMEO
)
1014 fn set_write_timeout_ms(&self, dur
: Option
<u32>) -> io
::Result
<()> {
1015 set_opt(self.as_sock(), SOL_SOCKET
, SO_SNDTIMEO
,
1019 fn write_timeout_ms(&self) -> io
::Result
<Option
<u32>> {
1020 get_opt(self.as_sock(), SOL_SOCKET
, SO_SNDTIMEO
)
1024 fn set_read_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
1025 self.set_read_timeout_ms(dur
.map(dur2ms
))
1028 fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
1029 self.read_timeout_ms().map(|o
| o
.map(ms2dur
))
1032 fn set_write_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
1033 self.set_write_timeout_ms(dur
.map(dur2ms
))
1036 fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
1037 self.write_timeout_ms().map(|o
| o
.map(ms2dur
))
1040 fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
1041 get_opt(self.as_sock(), SOL_SOCKET
, SO_ERROR
).map(int2err
)
1044 fn connect
<A
: ToSocketAddrs
>(&self, addr
: A
) -> io
::Result
<()> {
1045 do_connect(self.as_sock(), addr
)
1049 fn send(&self, buf
: &[u8]) -> io
::Result
<usize> {
1051 ::cvt(send(self.as_sock(), buf
.as_ptr() as *const _
, buf
.len(), 0)).map(|n
| n
as usize)
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
];
1060 ::cvt(send(self.as_sock(), buf
.as_ptr() as *const _
, len
as c_int
, 0))
1061 .map(|n
| n
as usize)
1066 fn recv(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
1068 ::cvt(recv(self.as_sock(), buf
.as_mut_ptr() as *mut _
, buf
.len(), 0))
1069 .map(|n
| n
as usize)
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
];
1078 ::cvt(recv(self.as_sock(), buf
.as_mut_ptr() as *mut _
, buf
.len() as c_int
, 0))
1079 .map(|n
| n
as usize)
1083 fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
1084 set_nonblocking(self.as_sock(), nonblocking
)
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
))
1102 fn set_nonblocking(sock
: Socket
, nonblocking
: bool
) -> io
::Result
<()> {
1103 let mut nonblocking
= nonblocking
as c_ulong
;
1105 ioctl(sock
, FIONBIO
, &mut nonblocking
)
1110 fn set_nonblocking(sock
: Socket
, nonblocking
: bool
) -> io
::Result
<()> {
1111 let mut nonblocking
= nonblocking
as c_ulong
;
1113 ioctlsocket(sock
, FIONBIO
as c_int
, &mut nonblocking
)
1118 fn ip2in_addr(ip
: &Ipv4Addr
) -> in_addr
{
1119 let oct
= ip
.octets();
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)),
1129 fn ip2in_addr(ip
: &Ipv4Addr
) -> in_addr
{
1130 let oct
= ip
.octets();
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)),
1139 #[cfg(target_os = "android")]
1140 fn to_ipv6mr_interface(value
: u32) -> c_int
{
1144 #[cfg(not(target_os = "android"))]
1145 fn to_ipv6mr_interface(value
: u32) -> c_uint
{
1149 fn ip2in6_addr(ip
: &Ipv6Addr
) -> in6_addr
{
1150 let mut ret
: in6_addr
= unsafe { mem::zeroed() }
;
1151 let seg
= ip
.segments();
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,
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
)
1178 fn ttl(&self) -> io
::Result
<u32> {
1179 get_opt
::<c_int
>(self.as_sock(), IPPROTO_IP
, IP_TTL
)
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
)
1187 fn only_v6(&self) -> io
::Result
<bool
> {
1188 get_opt(self.as_sock(), v(IPPROTO_IPV6
), IPV6_V6ONLY
).map(int2bool
)
1191 fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
1192 get_opt(self.as_sock(), SOL_SOCKET
, SO_ERROR
).map(int2err
)
1195 fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
1196 set_nonblocking(self.as_sock(), nonblocking
)
1199 fn set_linger(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
1200 set_opt(self.as_sock(), SOL_SOCKET
, SO_LINGER
, dur2linger(dur
))
1203 fn linger(&self) -> io
::Result
<Option
<Duration
>> {
1204 get_opt(self.as_sock(), SOL_SOCKET
, SO_LINGER
).map(linger2dur
)
1209 /// Sets the value for the `IP_TTL` option on this socket.
1211 /// This is the same as [`TcpStreamExt::set_ttl`][other].
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
)
1219 /// Sets the value for the `IPV6_V6ONLY` option on this socket.
1221 /// This is the same as [`TcpStreamExt::set_only_v6`][other].
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
)
1229 /// Set value for the `SO_REUSEADDR` option on this socket.
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)
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
)
1244 /// Get the value of the `SO_ERROR` option on this socket.
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
1249 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
1250 get_opt(self.as_sock(), SOL_SOCKET
, SO_ERROR
).map(int2err
)
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
))
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
)
1265 /// Sets the value for the `IP_TTL` option on this socket.
1267 /// This is the same as [`TcpStreamExt::set_ttl`][other].
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
)
1275 /// Sets the value for the `IPV6_V6ONLY` option on this socket.
1277 /// This is the same as [`TcpStream::only_v6`][other].
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
)
1285 /// Set value for the `SO_REUSEADDR` option on this socket.
1287 /// This is the same as [`TcpBuilder::reuse_address`][other].
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)
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
)
1300 /// Get the value of the `SO_ERROR` option on this socket.
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
1305 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
1306 get_opt(self.as_sock(), SOL_SOCKET
, SO_ERROR
).map(int2err
)