1 // Copyright 2015 The Rust Project Developers.
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8 
9 use std::fmt;
10 use std::io::{self, Read, Write};
11 #[cfg(not(target_os = "redox"))]
12 use std::io::{IoSlice, IoSliceMut};
13 use std::mem::MaybeUninit;
14 use std::net::{self, Ipv4Addr, Ipv6Addr, Shutdown};
15 #[cfg(unix)]
16 use std::os::unix::io::{FromRawFd, IntoRawFd};
17 #[cfg(windows)]
18 use std::os::windows::io::{FromRawSocket, IntoRawSocket};
19 use std::time::Duration;
20 
21 use crate::sys::{self, c_int, getsockopt, setsockopt, Bool};
22 use crate::{Domain, Protocol, SockAddr, TcpKeepalive, Type};
23 #[cfg(not(target_os = "redox"))]
24 use crate::{MaybeUninitSlice, RecvFlags};
25 
26 /// Owned wrapper around a system socket.
27 ///
28 /// This type simply wraps an instance of a file descriptor (`c_int`) on Unix
29 /// and an instance of `SOCKET` on Windows. This is the main type exported by
30 /// this crate and is intended to mirror the raw semantics of sockets on
31 /// platforms as closely as possible. Almost all methods correspond to
32 /// precisely one libc or OS API call which is essentially just a "Rustic
33 /// translation" of what's below.
34 ///
35 /// This type can be freely converted into the network primitives provided by
36 /// the standard library, such as [`TcpStream`] or [`UdpSocket`], using the
37 /// [`Into`] trait, see the example below.
38 ///
39 /// [`TcpStream`]: std::net::TcpStream
40 /// [`UdpSocket`]: std::net::UdpSocket
41 ///
42 /// # Notes
43 ///
44 /// Some methods that set options on `Socket` require two system calls to set
45 /// there options without overwriting previously set options. We do this by
46 /// first getting the current settings, applying the desired changes and than
47 /// updating the settings. This means that the operation is **not** atomic. This
48 /// can lead to a data race when two threads are changing options in parallel.
49 ///
50 /// # Examples
51 /// ```no_run
52 /// # fn main() -> std::io::Result<()> {
53 /// use std::net::{SocketAddr, TcpListener};
54 /// use socket2::{Socket, Domain, Type};
55 ///
56 /// // create a TCP listener bound to two addresses
57 /// let socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
58 ///
59 /// let address: SocketAddr = "[::1]:12345".parse().unwrap();
60 /// let address = address.into();
61 /// socket.bind(&address)?;
62 /// socket.bind(&address)?;
63 /// socket.listen(128)?;
64 ///
65 /// let listener: TcpListener = socket.into();
66 /// // ...
67 /// # drop(listener);
68 /// # Ok(()) }
69 /// ```
70 pub struct Socket {
71     inner: Inner,
72 }
73 
74 /// Store a `TcpStream` internally to take advantage of its niche optimizations on Unix platforms.
75 pub(crate) type Inner = std::net::TcpStream;
76 
77 impl Socket {
78     /// # Safety
79     ///
80     /// The caller must ensure `raw` is a valid file descriptor/socket. NOTE:
81     /// this should really be marked `unsafe`, but this being an internal
82     /// function, often passed as mapping function, it's makes it very
83     /// inconvenient to mark it as `unsafe`.
from_raw(raw: sys::Socket) -> Socket84     pub(crate) fn from_raw(raw: sys::Socket) -> Socket {
85         Socket {
86             inner: unsafe {
87                 // SAFETY: the caller must ensure that `raw` is a valid file
88                 // descriptor, but when it isn't it could return I/O errors, or
89                 // potentially close a fd it doesn't own. All of that isn't
90                 // memory unsafe, so it's not desired but never memory unsafe or
91                 // causes UB.
92                 //
93                 // However there is one exception. We use `TcpStream` to
94                 // represent the `Socket` internally (see `Inner` type),
95                 // `TcpStream` has a layout optimisation that doesn't allow for
96                 // negative file descriptors (as those are always invalid).
97                 // Violating this assumption (fd never negative) causes UB,
98                 // something we don't want. So check for that we have this
99                 // `assert!`.
100                 #[cfg(unix)]
101                 assert!(raw >= 0, "tried to create a `Socket` with an invalid fd");
102                 sys::socket_from_raw(raw)
103             },
104         }
105     }
106 
as_raw(&self) -> sys::Socket107     pub(crate) fn as_raw(&self) -> sys::Socket {
108         sys::socket_as_raw(&self.inner)
109     }
110 
into_raw(self) -> sys::Socket111     pub(crate) fn into_raw(self) -> sys::Socket {
112         sys::socket_into_raw(self.inner)
113     }
114 
115     /// Creates a new socket and sets common flags.
116     ///
117     /// This function corresponds to `socket(2)` on Unix and `WSASocketW` on
118     /// Windows.
119     ///
120     /// On Unix-like systems, the close-on-exec flag is set on the new socket.
121     /// Additionally, on Apple platforms `SOCK_NOSIGPIPE` is set. On Windows,
122     /// the socket is made non-inheritable.
123     ///
124     /// [`Socket::new_raw`] can be used if you don't want these flags to be set.
new(domain: Domain, ty: Type, protocol: Option<Protocol>) -> io::Result<Socket>125     pub fn new(domain: Domain, ty: Type, protocol: Option<Protocol>) -> io::Result<Socket> {
126         let ty = set_common_type(ty);
127         Socket::new_raw(domain, ty, protocol).and_then(set_common_flags)
128     }
129 
130     /// Creates a new socket ready to be configured.
131     ///
132     /// This function corresponds to `socket(2)` on Unix and `WSASocketW` on
133     /// Windows and simply creates a new socket, no other configuration is done.
new_raw(domain: Domain, ty: Type, protocol: Option<Protocol>) -> io::Result<Socket>134     pub fn new_raw(domain: Domain, ty: Type, protocol: Option<Protocol>) -> io::Result<Socket> {
135         let protocol = protocol.map(|p| p.0).unwrap_or(0);
136         sys::socket(domain.0, ty.0, protocol).map(Socket::from_raw)
137     }
138 
139     /// Creates a pair of sockets which are connected to each other.
140     ///
141     /// This function corresponds to `socketpair(2)`.
142     ///
143     /// This function sets the same flags as in done for [`Socket::new`],
144     /// [`Socket::pair_raw`] can be used if you don't want to set those flags.
145     #[cfg(any(doc, all(feature = "all", unix)))]
146     #[cfg_attr(docsrs, doc(cfg(all(feature = "all", unix))))]
pair( domain: Domain, ty: Type, protocol: Option<Protocol>, ) -> io::Result<(Socket, Socket)>147     pub fn pair(
148         domain: Domain,
149         ty: Type,
150         protocol: Option<Protocol>,
151     ) -> io::Result<(Socket, Socket)> {
152         let ty = set_common_type(ty);
153         let (a, b) = Socket::pair_raw(domain, ty, protocol)?;
154         let a = set_common_flags(a)?;
155         let b = set_common_flags(b)?;
156         Ok((a, b))
157     }
158 
159     /// Creates a pair of sockets which are connected to each other.
160     ///
161     /// This function corresponds to `socketpair(2)`.
162     #[cfg(any(doc, all(feature = "all", unix)))]
163     #[cfg_attr(docsrs, doc(cfg(all(feature = "all", unix))))]
pair_raw( domain: Domain, ty: Type, protocol: Option<Protocol>, ) -> io::Result<(Socket, Socket)>164     pub fn pair_raw(
165         domain: Domain,
166         ty: Type,
167         protocol: Option<Protocol>,
168     ) -> io::Result<(Socket, Socket)> {
169         let protocol = protocol.map(|p| p.0).unwrap_or(0);
170         sys::socketpair(domain.0, ty.0, protocol)
171             .map(|[a, b]| (Socket::from_raw(a), Socket::from_raw(b)))
172     }
173 
174     /// Binds this socket to the specified address.
175     ///
176     /// This function directly corresponds to the `bind(2)` function on Windows
177     /// and Unix.
bind(&self, address: &SockAddr) -> io::Result<()>178     pub fn bind(&self, address: &SockAddr) -> io::Result<()> {
179         sys::bind(self.as_raw(), address)
180     }
181 
182     /// Initiate a connection on this socket to the specified address.
183     ///
184     /// This function directly corresponds to the `connect(2)` function on
185     /// Windows and Unix.
186     ///
187     /// An error will be returned if `listen` or `connect` has already been
188     /// called on this builder.
189     ///
190     /// # Notes
191     ///
192     /// When using a non-blocking connect (by setting the socket into
193     /// non-blocking mode before calling this function), socket option can't be
194     /// set *while connecting*. This will cause errors on Windows. Socket
195     /// options can be safely set before and after connecting the socket.
connect(&self, address: &SockAddr) -> io::Result<()>196     pub fn connect(&self, address: &SockAddr) -> io::Result<()> {
197         sys::connect(self.as_raw(), address)
198     }
199 
200     /// Initiate a connection on this socket to the specified address, only
201     /// only waiting for a certain period of time for the connection to be
202     /// established.
203     ///
204     /// Unlike many other methods on `Socket`, this does *not* correspond to a
205     /// single C function. It sets the socket to nonblocking mode, connects via
206     /// connect(2), and then waits for the connection to complete with poll(2)
207     /// on Unix and select on Windows. When the connection is complete, the
208     /// socket is set back to blocking mode. On Unix, this will loop over
209     /// `EINTR` errors.
210     ///
211     /// # Warnings
212     ///
213     /// The non-blocking state of the socket is overridden by this function -
214     /// it will be returned in blocking mode on success, and in an indeterminate
215     /// state on failure.
216     ///
217     /// If the connection request times out, it may still be processing in the
218     /// background - a second call to `connect` or `connect_timeout` may fail.
connect_timeout(&self, addr: &SockAddr, timeout: Duration) -> io::Result<()>219     pub fn connect_timeout(&self, addr: &SockAddr, timeout: Duration) -> io::Result<()> {
220         self.set_nonblocking(true)?;
221         let res = self.connect(addr);
222         self.set_nonblocking(false)?;
223 
224         match res {
225             Ok(()) => return Ok(()),
226             Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
227             #[cfg(unix)]
228             Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {}
229             Err(e) => return Err(e),
230         }
231 
232         sys::poll_connect(self, timeout)
233     }
234 
235     /// Mark a socket as ready to accept incoming connection requests using
236     /// [`Socket::accept()`].
237     ///
238     /// This function directly corresponds to the `listen(2)` function on
239     /// Windows and Unix.
240     ///
241     /// An error will be returned if `listen` or `connect` has already been
242     /// called on this builder.
listen(&self, backlog: c_int) -> io::Result<()>243     pub fn listen(&self, backlog: c_int) -> io::Result<()> {
244         sys::listen(self.as_raw(), backlog)
245     }
246 
247     /// Accept a new incoming connection from this listener.
248     ///
249     /// This function uses `accept4(2)` on platforms that support it and
250     /// `accept(2)` platforms that do not.
251     ///
252     /// This function sets the same flags as in done for [`Socket::new`],
253     /// [`Socket::accept_raw`] can be used if you don't want to set those flags.
accept(&self) -> io::Result<(Socket, SockAddr)>254     pub fn accept(&self) -> io::Result<(Socket, SockAddr)> {
255         // Use `accept4` on platforms that support it.
256         #[cfg(any(
257             target_os = "android",
258             target_os = "dragonfly",
259             target_os = "freebsd",
260             target_os = "fuchsia",
261             target_os = "illumos",
262             target_os = "linux",
263             target_os = "netbsd",
264             target_os = "openbsd",
265         ))]
266         return self._accept4(libc::SOCK_CLOEXEC);
267 
268         // Fall back to `accept` on platforms that do not support `accept4`.
269         #[cfg(not(any(
270             target_os = "android",
271             target_os = "dragonfly",
272             target_os = "freebsd",
273             target_os = "fuchsia",
274             target_os = "illumos",
275             target_os = "linux",
276             target_os = "netbsd",
277             target_os = "openbsd",
278         )))]
279         {
280             let (socket, addr) = self.accept_raw()?;
281             let socket = set_common_flags(socket)?;
282             // `set_common_flags` does not disable inheritance on Windows because `Socket::new`
283             // unlike `accept` is able to create the socket with inheritance disabled.
284             #[cfg(windows)]
285             socket._set_no_inherit(true)?;
286             Ok((socket, addr))
287         }
288     }
289 
290     /// Accept a new incoming connection from this listener.
291     ///
292     /// This function directly corresponds to the `accept(2)` function on
293     /// Windows and Unix.
accept_raw(&self) -> io::Result<(Socket, SockAddr)>294     pub fn accept_raw(&self) -> io::Result<(Socket, SockAddr)> {
295         sys::accept(self.as_raw()).map(|(inner, addr)| (Socket::from_raw(inner), addr))
296     }
297 
298     /// Returns the socket address of the local half of this socket.
299     ///
300     /// # Notes
301     ///
302     /// Depending on the OS this may return an error if the socket is not
303     /// [bound].
304     ///
305     /// [bound]: Socket::bind
local_addr(&self) -> io::Result<SockAddr>306     pub fn local_addr(&self) -> io::Result<SockAddr> {
307         sys::getsockname(self.as_raw())
308     }
309 
310     /// Returns the socket address of the remote peer of this socket.
311     ///
312     /// # Notes
313     ///
314     /// This returns an error if the socket is not [`connect`ed].
315     ///
316     /// [`connect`ed]: Socket::connect
peer_addr(&self) -> io::Result<SockAddr>317     pub fn peer_addr(&self) -> io::Result<SockAddr> {
318         sys::getpeername(self.as_raw())
319     }
320 
321     /// Returns the [`Type`] of this socket by checking the `SO_TYPE` option on
322     /// this socket.
323     pub fn r#type(&self) -> io::Result<Type> {
324         unsafe { getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_TYPE).map(Type) }
325     }
326 
327     /// Creates a new independently owned handle to the underlying socket.
328     ///
329     /// # Notes
330     ///
331     /// On Unix this uses `F_DUPFD_CLOEXEC` and thus sets the `FD_CLOEXEC` on
332     /// the returned socket.
333     ///
334     /// On Windows this uses `WSA_FLAG_NO_HANDLE_INHERIT` setting inheriting to
335     /// false.
336     ///
337     /// On Windows this can **not** be used function cannot be used on a
338     /// QOS-enabled socket, see
339     /// <https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaduplicatesocketw>.
try_clone(&self) -> io::Result<Socket>340     pub fn try_clone(&self) -> io::Result<Socket> {
341         sys::try_clone(self.as_raw()).map(Socket::from_raw)
342     }
343 
344     /// Moves this TCP stream into or out of nonblocking mode.
345     ///
346     /// # Notes
347     ///
348     /// On Unix this corresponds to calling `fcntl` (un)setting `O_NONBLOCK`.
349     ///
350     /// On Windows this corresponds to calling `ioctlsocket` (un)setting
351     /// `FIONBIO`.
set_nonblocking(&self, nonblocking: bool) -> io::Result<()>352     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
353         sys::set_nonblocking(self.as_raw(), nonblocking)
354     }
355 
356     /// Shuts down the read, write, or both halves of this connection.
357     ///
358     /// This function will cause all pending and future I/O on the specified
359     /// portions to return immediately with an appropriate value.
shutdown(&self, how: Shutdown) -> io::Result<()>360     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
361         sys::shutdown(self.as_raw(), how)
362     }
363 
364     /// Receives data on the socket from the remote address to which it is
365     /// connected.
366     ///
367     /// The [`connect`] method will connect this socket to a remote address.
368     /// This method might fail if the socket is not connected.
369     ///
370     /// [`connect`]: Socket::connect
371     ///
372     /// # Safety
373     ///
374     /// Normally casting a `&mut [u8]` to `&mut [MaybeUninit<u8>]` would be
375     /// unsound, as that allows us to write uninitialised bytes to the buffer.
376     /// However this implementation promises to not write uninitialised bytes to
377     /// the `buf`fer and passes it directly to `recv(2)` system call. This
378     /// promise ensures that this function can be called using a `buf`fer of
379     /// type `&mut [u8]`.
380     ///
381     /// Note that the [`io::Read::read`] implementation calls this function with
382     /// a `buf`fer of type `&mut [u8]`, allowing initialised buffers to be used
383     /// without using `unsafe`.
recv(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize>384     pub fn recv(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> {
385         self.recv_with_flags(buf, 0)
386     }
387 
388     /// Receives out-of-band (OOB) data on the socket from the remote address to
389     /// which it is connected by setting the `MSG_OOB` flag for this call.
390     ///
391     /// For more information, see [`recv`], [`out_of_band_inline`].
392     ///
393     /// [`recv`]: Socket::recv
394     /// [`out_of_band_inline`]: Socket::out_of_band_inline
recv_out_of_band(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize>395     pub fn recv_out_of_band(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> {
396         self.recv_with_flags(buf, sys::MSG_OOB)
397     }
398 
399     /// Identical to [`recv`] but allows for specification of arbitrary flags to
400     /// the underlying `recv` call.
401     ///
402     /// [`recv`]: Socket::recv
recv_with_flags( &self, buf: &mut [MaybeUninit<u8>], flags: sys::c_int, ) -> io::Result<usize>403     pub fn recv_with_flags(
404         &self,
405         buf: &mut [MaybeUninit<u8>],
406         flags: sys::c_int,
407     ) -> io::Result<usize> {
408         sys::recv(self.as_raw(), buf, flags)
409     }
410 
411     /// Receives data on the socket from the remote address to which it is
412     /// connected. Unlike [`recv`] this allows passing multiple buffers.
413     ///
414     /// The [`connect`] method will connect this socket to a remote address.
415     /// This method might fail if the socket is not connected.
416     ///
417     /// In addition to the number of bytes read, this function returns the flags
418     /// for the received message. See [`RecvFlags`] for more information about
419     /// the returned flags.
420     ///
421     /// [`recv`]: Socket::recv
422     /// [`connect`]: Socket::connect
423     ///
424     /// # Safety
425     ///
426     /// Normally casting a `IoSliceMut` to `MaybeUninitSlice` would be unsound,
427     /// as that allows us to write uninitialised bytes to the buffer. However
428     /// this implementation promises to not write uninitialised bytes to the
429     /// `bufs` and passes it directly to `recvmsg(2)` system call. This promise
430     /// ensures that this function can be called using `bufs` of type `&mut
431     /// [IoSliceMut]`.
432     ///
433     /// Note that the [`io::Read::read_vectored`] implementation calls this
434     /// function with `buf`s of type `&mut [IoSliceMut]`, allowing initialised
435     /// buffers to be used without using `unsafe`.
436     #[cfg(not(target_os = "redox"))]
437     #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
recv_vectored( &self, bufs: &mut [MaybeUninitSlice<'_>], ) -> io::Result<(usize, RecvFlags)>438     pub fn recv_vectored(
439         &self,
440         bufs: &mut [MaybeUninitSlice<'_>],
441     ) -> io::Result<(usize, RecvFlags)> {
442         self.recv_vectored_with_flags(bufs, 0)
443     }
444 
445     /// Identical to [`recv_vectored`] but allows for specification of arbitrary
446     /// flags to the underlying `recvmsg`/`WSARecv` call.
447     ///
448     /// [`recv_vectored`]: Socket::recv_vectored
449     ///
450     /// # Safety
451     ///
452     /// `recv_from_vectored` makes the same safety guarantees regarding `bufs`
453     /// as [`recv_vectored`].
454     ///
455     /// [`recv_vectored`]: Socket::recv_vectored
456     #[cfg(not(target_os = "redox"))]
457     #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
recv_vectored_with_flags( &self, bufs: &mut [MaybeUninitSlice<'_>], flags: c_int, ) -> io::Result<(usize, RecvFlags)>458     pub fn recv_vectored_with_flags(
459         &self,
460         bufs: &mut [MaybeUninitSlice<'_>],
461         flags: c_int,
462     ) -> io::Result<(usize, RecvFlags)> {
463         sys::recv_vectored(self.as_raw(), bufs, flags)
464     }
465 
466     /// Receives data on the socket from the remote adress to which it is
467     /// connected, without removing that data from the queue. On success,
468     /// returns the number of bytes peeked.
469     ///
470     /// Successive calls return the same data. This is accomplished by passing
471     /// `MSG_PEEK` as a flag to the underlying `recv` system call.
472     ///
473     /// # Safety
474     ///
475     /// `peek` makes the same safety guarantees regarding the `buf`fer as
476     /// [`recv`].
477     ///
478     /// [`recv`]: Socket::recv
peek(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize>479     pub fn peek(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> {
480         self.recv_with_flags(buf, sys::MSG_PEEK)
481     }
482 
483     /// Receives data from the socket. On success, returns the number of bytes
484     /// read and the address from whence the data came.
485     ///
486     /// # Safety
487     ///
488     /// `recv_from` makes the same safety guarantees regarding the `buf`fer as
489     /// [`recv`].
490     ///
491     /// [`recv`]: Socket::recv
recv_from(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<(usize, SockAddr)>492     pub fn recv_from(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<(usize, SockAddr)> {
493         self.recv_from_with_flags(buf, 0)
494     }
495 
496     /// Identical to [`recv_from`] but allows for specification of arbitrary
497     /// flags to the underlying `recvfrom` call.
498     ///
499     /// [`recv_from`]: Socket::recv_from
recv_from_with_flags( &self, buf: &mut [MaybeUninit<u8>], flags: c_int, ) -> io::Result<(usize, SockAddr)>500     pub fn recv_from_with_flags(
501         &self,
502         buf: &mut [MaybeUninit<u8>],
503         flags: c_int,
504     ) -> io::Result<(usize, SockAddr)> {
505         sys::recv_from(self.as_raw(), buf, flags)
506     }
507 
508     /// Receives data from the socket. Returns the amount of bytes read, the
509     /// [`RecvFlags`] and the remote address from the data is coming. Unlike
510     /// [`recv_from`] this allows passing multiple buffers.
511     ///
512     /// [`recv_from`]: Socket::recv_from
513     ///
514     /// # Safety
515     ///
516     /// `recv_from_vectored` makes the same safety guarantees regarding `bufs`
517     /// as [`recv_vectored`].
518     ///
519     /// [`recv_vectored`]: Socket::recv_vectored
520     #[cfg(not(target_os = "redox"))]
521     #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
recv_from_vectored( &self, bufs: &mut [MaybeUninitSlice<'_>], ) -> io::Result<(usize, RecvFlags, SockAddr)>522     pub fn recv_from_vectored(
523         &self,
524         bufs: &mut [MaybeUninitSlice<'_>],
525     ) -> io::Result<(usize, RecvFlags, SockAddr)> {
526         self.recv_from_vectored_with_flags(bufs, 0)
527     }
528 
529     /// Identical to [`recv_from_vectored`] but allows for specification of
530     /// arbitrary flags to the underlying `recvmsg`/`WSARecvFrom` call.
531     ///
532     /// [`recv_from_vectored`]: Socket::recv_from_vectored
533     ///
534     /// # Safety
535     ///
536     /// `recv_from_vectored` makes the same safety guarantees regarding `bufs`
537     /// as [`recv_vectored`].
538     ///
539     /// [`recv_vectored`]: Socket::recv_vectored
540     #[cfg(not(target_os = "redox"))]
541     #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
recv_from_vectored_with_flags( &self, bufs: &mut [MaybeUninitSlice<'_>], flags: c_int, ) -> io::Result<(usize, RecvFlags, SockAddr)>542     pub fn recv_from_vectored_with_flags(
543         &self,
544         bufs: &mut [MaybeUninitSlice<'_>],
545         flags: c_int,
546     ) -> io::Result<(usize, RecvFlags, SockAddr)> {
547         sys::recv_from_vectored(self.as_raw(), bufs, flags)
548     }
549 
550     /// Receives data from the socket, without removing it from the queue.
551     ///
552     /// Successive calls return the same data. This is accomplished by passing
553     /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
554     ///
555     /// On success, returns the number of bytes peeked and the address from
556     /// whence the data came.
557     ///
558     /// # Safety
559     ///
560     /// `peek_from` makes the same safety guarantees regarding the `buf`fer as
561     /// [`recv`].
562     ///
563     /// [`recv`]: Socket::recv
peek_from(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<(usize, SockAddr)>564     pub fn peek_from(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<(usize, SockAddr)> {
565         self.recv_from_with_flags(buf, sys::MSG_PEEK)
566     }
567 
568     /// Sends data on the socket to a connected peer.
569     ///
570     /// This is typically used on TCP sockets or datagram sockets which have
571     /// been connected.
572     ///
573     /// On success returns the number of bytes that were sent.
send(&self, buf: &[u8]) -> io::Result<usize>574     pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
575         self.send_with_flags(buf, 0)
576     }
577 
578     /// Identical to [`send`] but allows for specification of arbitrary flags to the underlying
579     /// `send` call.
580     ///
581     /// [`send`]: #method.send
send_with_flags(&self, buf: &[u8], flags: c_int) -> io::Result<usize>582     pub fn send_with_flags(&self, buf: &[u8], flags: c_int) -> io::Result<usize> {
583         sys::send(self.as_raw(), buf, flags)
584     }
585 
586     /// Send data to the connected peer. Returns the amount of bytes written.
587     #[cfg(not(target_os = "redox"))]
588     #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
send_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize>589     pub fn send_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
590         self.send_vectored_with_flags(bufs, 0)
591     }
592 
593     /// Identical to [`send_vectored`] but allows for specification of arbitrary
594     /// flags to the underlying `sendmsg`/`WSASend` call.
595     ///
596     /// [`send_vectored`]: Socket::send_vectored
597     #[cfg(not(target_os = "redox"))]
598     #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
send_vectored_with_flags( &self, bufs: &[IoSlice<'_>], flags: c_int, ) -> io::Result<usize>599     pub fn send_vectored_with_flags(
600         &self,
601         bufs: &[IoSlice<'_>],
602         flags: c_int,
603     ) -> io::Result<usize> {
604         sys::send_vectored(self.as_raw(), bufs, flags)
605     }
606 
607     /// Sends out-of-band (OOB) data on the socket to connected peer
608     /// by setting the `MSG_OOB` flag for this call.
609     ///
610     /// For more information, see [`send`], [`out_of_band_inline`].
611     ///
612     /// [`send`]: #method.send
613     /// [`out_of_band_inline`]: #method.out_of_band_inline
send_out_of_band(&self, buf: &[u8]) -> io::Result<usize>614     pub fn send_out_of_band(&self, buf: &[u8]) -> io::Result<usize> {
615         self.send_with_flags(buf, sys::MSG_OOB)
616     }
617 
618     /// Sends data on the socket to the given address. On success, returns the
619     /// number of bytes written.
620     ///
621     /// This is typically used on UDP or datagram-oriented sockets.
send_to(&self, buf: &[u8], addr: &SockAddr) -> io::Result<usize>622     pub fn send_to(&self, buf: &[u8], addr: &SockAddr) -> io::Result<usize> {
623         self.send_to_with_flags(buf, addr, 0)
624     }
625 
626     /// Identical to [`send_to`] but allows for specification of arbitrary flags
627     /// to the underlying `sendto` call.
628     ///
629     /// [`send_to`]: Socket::send_to
send_to_with_flags( &self, buf: &[u8], addr: &SockAddr, flags: c_int, ) -> io::Result<usize>630     pub fn send_to_with_flags(
631         &self,
632         buf: &[u8],
633         addr: &SockAddr,
634         flags: c_int,
635     ) -> io::Result<usize> {
636         sys::send_to(self.as_raw(), buf, addr, flags)
637     }
638 
639     /// Send data to a peer listening on `addr`. Returns the amount of bytes
640     /// written.
641     #[cfg(not(target_os = "redox"))]
642     #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
send_to_vectored(&self, bufs: &[IoSlice<'_>], addr: &SockAddr) -> io::Result<usize>643     pub fn send_to_vectored(&self, bufs: &[IoSlice<'_>], addr: &SockAddr) -> io::Result<usize> {
644         self.send_to_vectored_with_flags(bufs, addr, 0)
645     }
646 
647     /// Identical to [`send_to_vectored`] but allows for specification of
648     /// arbitrary flags to the underlying `sendmsg`/`WSASendTo` call.
649     ///
650     /// [`send_to_vectored`]: Socket::send_to_vectored
651     #[cfg(not(target_os = "redox"))]
652     #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
send_to_vectored_with_flags( &self, bufs: &[IoSlice<'_>], addr: &SockAddr, flags: c_int, ) -> io::Result<usize>653     pub fn send_to_vectored_with_flags(
654         &self,
655         bufs: &[IoSlice<'_>],
656         addr: &SockAddr,
657         flags: c_int,
658     ) -> io::Result<usize> {
659         sys::send_to_vectored(self.as_raw(), bufs, addr, flags)
660     }
661 }
662 
663 /// Set `SOCK_CLOEXEC` and `NO_HANDLE_INHERIT` on the `ty`pe on platforms that
664 /// support it.
665 #[inline(always)]
set_common_type(ty: Type) -> Type666 fn set_common_type(ty: Type) -> Type {
667     // On platforms that support it set `SOCK_CLOEXEC`.
668     #[cfg(any(
669         target_os = "android",
670         target_os = "dragonfly",
671         target_os = "freebsd",
672         target_os = "fuchsia",
673         target_os = "illumos",
674         target_os = "linux",
675         target_os = "netbsd",
676         target_os = "openbsd",
677     ))]
678     let ty = ty._cloexec();
679 
680     // On windows set `NO_HANDLE_INHERIT`.
681     #[cfg(windows)]
682     let ty = ty._no_inherit();
683 
684     ty
685 }
686 
687 /// Set `FD_CLOEXEC` and `NOSIGPIPE` on the `socket` for platforms that need it.
688 #[inline(always)]
689 #[allow(clippy::unnecessary_wraps)]
set_common_flags(socket: Socket) -> io::Result<Socket>690 fn set_common_flags(socket: Socket) -> io::Result<Socket> {
691     // On platforms that don't have `SOCK_CLOEXEC` use `FD_CLOEXEC`.
692     #[cfg(all(
693         unix,
694         not(any(
695             target_os = "android",
696             target_os = "dragonfly",
697             target_os = "freebsd",
698             target_os = "fuchsia",
699             target_os = "illumos",
700             target_os = "linux",
701             target_os = "netbsd",
702             target_os = "openbsd",
703         ))
704     ))]
705     socket._set_cloexec(true)?;
706 
707     // On Apple platforms set `NOSIGPIPE`.
708     #[cfg(target_vendor = "apple")]
709     socket._set_nosigpipe(true)?;
710 
711     Ok(socket)
712 }
713 
714 /// Socket options get/set using `SOL_SOCKET`.
715 ///
716 /// Additional documentation can be found in documentation of the OS.
717 /// * Linux: <https://man7.org/linux/man-pages/man7/socket.7.html>
718 /// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options>
719 impl Socket {
720     /// Get the value of the `SO_BROADCAST` option for this socket.
721     ///
722     /// For more information about this option, see [`set_broadcast`].
723     ///
724     /// [`set_broadcast`]: Socket::set_broadcast
broadcast(&self) -> io::Result<bool>725     pub fn broadcast(&self) -> io::Result<bool> {
726         unsafe {
727             getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_BROADCAST)
728                 .map(|broadcast| broadcast != 0)
729         }
730     }
731 
732     /// Set the value of the `SO_BROADCAST` option for this socket.
733     ///
734     /// When enabled, this socket is allowed to send packets to a broadcast
735     /// address.
set_broadcast(&self, broadcast: bool) -> io::Result<()>736     pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
737         unsafe {
738             setsockopt(
739                 self.as_raw(),
740                 sys::SOL_SOCKET,
741                 sys::SO_BROADCAST,
742                 broadcast as c_int,
743             )
744         }
745     }
746 
747     /// Get the value of the `SO_ERROR` option on this socket.
748     ///
749     /// This will retrieve the stored error in the underlying socket, clearing
750     /// the field in the process. This can be useful for checking errors between
751     /// calls.
take_error(&self) -> io::Result<Option<io::Error>>752     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
753         match unsafe { getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_ERROR) } {
754             Ok(0) => Ok(None),
755             Ok(errno) => Ok(Some(io::Error::from_raw_os_error(errno))),
756             Err(err) => Err(err),
757         }
758     }
759 
760     /// Get the value of the `SO_KEEPALIVE` option on this socket.
761     ///
762     /// For more information about this option, see [`set_keepalive`].
763     ///
764     /// [`set_keepalive`]: Socket::set_keepalive
keepalive(&self) -> io::Result<bool>765     pub fn keepalive(&self) -> io::Result<bool> {
766         unsafe {
767             getsockopt::<Bool>(self.as_raw(), sys::SOL_SOCKET, sys::SO_KEEPALIVE)
768                 .map(|keepalive| keepalive != 0)
769         }
770     }
771 
772     /// Set value for the `SO_KEEPALIVE` option on this socket.
773     ///
774     /// Enable sending of keep-alive messages on connection-oriented sockets.
set_keepalive(&self, keepalive: bool) -> io::Result<()>775     pub fn set_keepalive(&self, keepalive: bool) -> io::Result<()> {
776         unsafe {
777             setsockopt(
778                 self.as_raw(),
779                 sys::SOL_SOCKET,
780                 sys::SO_KEEPALIVE,
781                 keepalive as c_int,
782             )
783         }
784     }
785 
786     /// Get the value of the `SO_LINGER` option on this socket.
787     ///
788     /// For more information about this option, see [`set_linger`].
789     ///
790     /// [`set_linger`]: Socket::set_linger
linger(&self) -> io::Result<Option<Duration>>791     pub fn linger(&self) -> io::Result<Option<Duration>> {
792         unsafe {
793             getsockopt::<sys::linger>(self.as_raw(), sys::SOL_SOCKET, sys::SO_LINGER)
794                 .map(from_linger)
795         }
796     }
797 
798     /// Set value for the `SO_LINGER` option on this socket.
799     ///
800     /// If `linger` is not `None`, a close(2) or shutdown(2) will not return
801     /// until all queued messages for the socket have been successfully sent or
802     /// the linger timeout has been reached. Otherwise, the call returns
803     /// immediately and the closing is done in the background. When the socket
804     /// is closed as part of exit(2), it always lingers in the background.
805     ///
806     /// # Notes
807     ///
808     /// On most OSs the duration only has a precision of seconds and will be
809     /// silently truncated.
810     ///
811     /// On Apple platforms (e.g. macOS, iOS, etc) this uses `SO_LINGER_SEC`.
set_linger(&self, linger: Option<Duration>) -> io::Result<()>812     pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
813         let linger = into_linger(linger);
814         unsafe { setsockopt(self.as_raw(), sys::SOL_SOCKET, sys::SO_LINGER, linger) }
815     }
816 
817     /// Get value for the `SO_OOBINLINE` option on this socket.
818     ///
819     /// For more information about this option, see [`set_out_of_band_inline`].
820     ///
821     /// [`set_out_of_band_inline`]: Socket::set_out_of_band_inline
822     #[cfg(not(target_os = "redox"))]
823     #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
out_of_band_inline(&self) -> io::Result<bool>824     pub fn out_of_band_inline(&self) -> io::Result<bool> {
825         unsafe {
826             getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_OOBINLINE)
827                 .map(|oob_inline| oob_inline != 0)
828         }
829     }
830 
831     /// Set value for the `SO_OOBINLINE` option on this socket.
832     ///
833     /// If this option is enabled, out-of-band data is directly placed into the
834     /// receive data stream. Otherwise, out-of-band data is passed only when the
835     /// `MSG_OOB` flag is set during receiving. As per RFC6093, TCP sockets
836     /// using the Urgent mechanism are encouraged to set this flag.
837     #[cfg(not(target_os = "redox"))]
838     #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
set_out_of_band_inline(&self, oob_inline: bool) -> io::Result<()>839     pub fn set_out_of_band_inline(&self, oob_inline: bool) -> io::Result<()> {
840         unsafe {
841             setsockopt(
842                 self.as_raw(),
843                 sys::SOL_SOCKET,
844                 sys::SO_OOBINLINE,
845                 oob_inline as c_int,
846             )
847         }
848     }
849 
850     /// Get value for the `SO_RCVBUF` option on this socket.
851     ///
852     /// For more information about this option, see [`set_recv_buffer_size`].
853     ///
854     /// [`set_recv_buffer_size`]: Socket::set_recv_buffer_size
recv_buffer_size(&self) -> io::Result<usize>855     pub fn recv_buffer_size(&self) -> io::Result<usize> {
856         unsafe {
857             getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_RCVBUF)
858                 .map(|size| size as usize)
859         }
860     }
861 
862     /// Set value for the `SO_RCVBUF` option on this socket.
863     ///
864     /// Changes the size of the operating system's receive buffer associated
865     /// with the socket.
set_recv_buffer_size(&self, size: usize) -> io::Result<()>866     pub fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
867         unsafe {
868             setsockopt(
869                 self.as_raw(),
870                 sys::SOL_SOCKET,
871                 sys::SO_RCVBUF,
872                 size as c_int,
873             )
874         }
875     }
876 
877     /// Get value for the `SO_RCVTIMEO` option on this socket.
878     ///
879     /// If the returned timeout is `None`, then `read` and `recv` calls will
880     /// block indefinitely.
read_timeout(&self) -> io::Result<Option<Duration>>881     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
882         sys::timeout_opt(self.as_raw(), sys::SOL_SOCKET, sys::SO_RCVTIMEO)
883     }
884 
885     /// Set value for the `SO_RCVTIMEO` option on this socket.
886     ///
887     /// If `timeout` is `None`, then `read` and `recv` calls will block
888     /// indefinitely.
set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()>889     pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
890         sys::set_timeout_opt(self.as_raw(), sys::SOL_SOCKET, sys::SO_RCVTIMEO, duration)
891     }
892 
893     /// Get the value of the `SO_REUSEADDR` option on this socket.
894     ///
895     /// For more information about this option, see [`set_reuse_address`].
896     ///
897     /// [`set_reuse_address`]: Socket::set_reuse_address
reuse_address(&self) -> io::Result<bool>898     pub fn reuse_address(&self) -> io::Result<bool> {
899         unsafe {
900             getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_REUSEADDR)
901                 .map(|reuse| reuse != 0)
902         }
903     }
904 
905     /// Set value for the `SO_REUSEADDR` option on this socket.
906     ///
907     /// This indicates that futher calls to `bind` may allow reuse of local
908     /// addresses. For IPv4 sockets this means that a socket may bind even when
909     /// there's a socket already listening on this port.
set_reuse_address(&self, reuse: bool) -> io::Result<()>910     pub fn set_reuse_address(&self, reuse: bool) -> io::Result<()> {
911         unsafe {
912             setsockopt(
913                 self.as_raw(),
914                 sys::SOL_SOCKET,
915                 sys::SO_REUSEADDR,
916                 reuse as c_int,
917             )
918         }
919     }
920 
921     /// Get the value of the `SO_SNDBUF` option on this socket.
922     ///
923     /// For more information about this option, see [`set_send_buffer_size`].
924     ///
925     /// [`set_send_buffer_size`]: Socket::set_send_buffer_size
send_buffer_size(&self) -> io::Result<usize>926     pub fn send_buffer_size(&self) -> io::Result<usize> {
927         unsafe {
928             getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_SNDBUF)
929                 .map(|size| size as usize)
930         }
931     }
932 
933     /// Set value for the `SO_SNDBUF` option on this socket.
934     ///
935     /// Changes the size of the operating system's send buffer associated with
936     /// the socket.
set_send_buffer_size(&self, size: usize) -> io::Result<()>937     pub fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
938         unsafe {
939             setsockopt(
940                 self.as_raw(),
941                 sys::SOL_SOCKET,
942                 sys::SO_SNDBUF,
943                 size as c_int,
944             )
945         }
946     }
947 
948     /// Get value for the `SO_SNDTIMEO` option on this socket.
949     ///
950     /// If the returned timeout is `None`, then `write` and `send` calls will
951     /// block indefinitely.
write_timeout(&self) -> io::Result<Option<Duration>>952     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
953         sys::timeout_opt(self.as_raw(), sys::SOL_SOCKET, sys::SO_SNDTIMEO)
954     }
955 
956     /// Set value for the `SO_SNDTIMEO` option on this socket.
957     ///
958     /// If `timeout` is `None`, then `write` and `send` calls will block
959     /// indefinitely.
set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()>960     pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
961         sys::set_timeout_opt(self.as_raw(), sys::SOL_SOCKET, sys::SO_SNDTIMEO, duration)
962     }
963 }
964 
from_linger(linger: sys::linger) -> Option<Duration>965 fn from_linger(linger: sys::linger) -> Option<Duration> {
966     if linger.l_onoff == 0 {
967         None
968     } else {
969         Some(Duration::from_secs(linger.l_linger as u64))
970     }
971 }
972 
into_linger(duration: Option<Duration>) -> sys::linger973 fn into_linger(duration: Option<Duration>) -> sys::linger {
974     match duration {
975         Some(duration) => sys::linger {
976             l_onoff: 1,
977             l_linger: duration.as_secs() as _,
978         },
979         None => sys::linger {
980             l_onoff: 0,
981             l_linger: 0,
982         },
983     }
984 }
985 
986 /// Socket options for IPv4 sockets, get/set using `IPPROTO_IP`.
987 ///
988 /// Additional documentation can be found in documentation of the OS.
989 /// * Linux: <https://man7.org/linux/man-pages/man7/ip.7.html>
990 /// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options>
991 impl Socket {
992     /// Get the value of the `IP_TRANSPARENT` option on this socket.
993     ///
994     /// For more information about this option, see [`set_ip_transparent`].
995     ///
996     /// [`set_ip_transparent`]: Socket::set_ip_transparent
997     #[cfg(any(doc, all(feature = "all", target_os = "linux")))]
998     #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))]
ip_transparent(&self) -> io::Result<bool>999     pub fn ip_transparent(&self) -> io::Result<bool> {
1000         unsafe {
1001             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, libc::IP_TRANSPARENT)
1002                 .map(|transparent| transparent != 0)
1003         }
1004     }
1005 
1006     /// Set the value of the `IP_TRANSPARENT` option on this socket.
1007     ///
1008     /// Setting this boolean option enables transparent proxying
1009     /// on this socket.  This socket option allows the calling
1010     /// application to bind to a nonlocal IP address and operate
1011     /// both as a client and a server with the foreign address as
1012     /// the local endpoint.  NOTE: this requires that routing be
1013     /// set up in a way that packets going to the foreign address
1014     /// are routed through the TProxy box (i.e., the system
1015     /// hosting the application that employs the IP_TRANSPARENT
1016     /// socket option).  Enabling this socket option requires
1017     /// superuser privileges (the CAP_NET_ADMIN capability).
1018     ///
1019     /// TProxy redirection with the iptables TPROXY target also
1020     /// requires that this option be set on the redirected socket.
1021     #[cfg(any(doc, all(feature = "all", target_os = "linux")))]
1022     #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))]
set_ip_transparent(&self, transparent: bool) -> io::Result<()>1023     pub fn set_ip_transparent(&self, transparent: bool) -> io::Result<()> {
1024         unsafe {
1025             setsockopt(
1026                 self.as_raw(),
1027                 sys::IPPROTO_IP,
1028                 libc::IP_TRANSPARENT,
1029                 transparent as c_int,
1030             )
1031         }
1032     }
1033 
1034     /// Join a multicast group using `IP_ADD_MEMBERSHIP` option on this socket.
1035     ///
1036     /// This function specifies a new multicast group for this socket to join.
1037     /// The address must be a valid multicast address, and `interface` is the
1038     /// address of the local interface with which the system should join the
1039     /// multicast group. If it's [`Ipv4Addr::UNSPECIFIED`] (`INADDR_ANY`) then
1040     /// an appropriate interface is chosen by the system.
join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>1041     pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
1042         let mreq = sys::IpMreq {
1043             imr_multiaddr: sys::to_in_addr(multiaddr),
1044             imr_interface: sys::to_in_addr(interface),
1045         };
1046         unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_ADD_MEMBERSHIP, mreq) }
1047     }
1048 
1049     /// Leave a multicast group using `IP_DROP_MEMBERSHIP` option on this socket.
1050     ///
1051     /// For more information about this option, see [`join_multicast_v4`].
1052     ///
1053     /// [`join_multicast_v4`]: Socket::join_multicast_v4
leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>1054     pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
1055         let mreq = sys::IpMreq {
1056             imr_multiaddr: sys::to_in_addr(multiaddr),
1057             imr_interface: sys::to_in_addr(interface),
1058         };
1059         unsafe {
1060             setsockopt(
1061                 self.as_raw(),
1062                 sys::IPPROTO_IP,
1063                 sys::IP_DROP_MEMBERSHIP,
1064                 mreq,
1065             )
1066         }
1067     }
1068 
1069     /// Get the value of the `IP_MULTICAST_IF` option for this socket.
1070     ///
1071     /// For more information about this option, see [`set_multicast_if_v4`].
1072     ///
1073     /// [`set_multicast_if_v4`]: Socket::set_multicast_if_v4
multicast_if_v4(&self) -> io::Result<Ipv4Addr>1074     pub fn multicast_if_v4(&self) -> io::Result<Ipv4Addr> {
1075         unsafe {
1076             getsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_MULTICAST_IF).map(sys::from_in_addr)
1077         }
1078     }
1079 
1080     /// Set the value of the `IP_MULTICAST_IF` option for this socket.
1081     ///
1082     /// Specifies the interface to use for routing multicast packets.
set_multicast_if_v4(&self, interface: &Ipv4Addr) -> io::Result<()>1083     pub fn set_multicast_if_v4(&self, interface: &Ipv4Addr) -> io::Result<()> {
1084         let interface = sys::to_in_addr(interface);
1085         unsafe {
1086             setsockopt(
1087                 self.as_raw(),
1088                 sys::IPPROTO_IP,
1089                 sys::IP_MULTICAST_IF,
1090                 interface,
1091             )
1092         }
1093     }
1094 
1095     /// Get the value of the `IP_MULTICAST_LOOP` option for this socket.
1096     ///
1097     /// For more information about this option, see [`set_multicast_loop_v4`].
1098     ///
1099     /// [`set_multicast_loop_v4`]: Socket::set_multicast_loop_v4
multicast_loop_v4(&self) -> io::Result<bool>1100     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
1101         unsafe {
1102             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_MULTICAST_LOOP)
1103                 .map(|loop_v4| loop_v4 != 0)
1104         }
1105     }
1106 
1107     /// Set the value of the `IP_MULTICAST_LOOP` option for this socket.
1108     ///
1109     /// If enabled, multicast packets will be looped back to the local socket.
1110     /// Note that this may not have any affect on IPv6 sockets.
set_multicast_loop_v4(&self, loop_v4: bool) -> io::Result<()>1111     pub fn set_multicast_loop_v4(&self, loop_v4: bool) -> io::Result<()> {
1112         unsafe {
1113             setsockopt(
1114                 self.as_raw(),
1115                 sys::IPPROTO_IP,
1116                 sys::IP_MULTICAST_LOOP,
1117                 loop_v4 as c_int,
1118             )
1119         }
1120     }
1121 
1122     /// Get the value of the `IP_MULTICAST_TTL` option for this socket.
1123     ///
1124     /// For more information about this option, see [`set_multicast_ttl_v4`].
1125     ///
1126     /// [`set_multicast_ttl_v4`]: Socket::set_multicast_ttl_v4
multicast_ttl_v4(&self) -> io::Result<u32>1127     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
1128         unsafe {
1129             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_MULTICAST_TTL)
1130                 .map(|ttl| ttl as u32)
1131         }
1132     }
1133 
1134     /// Set the value of the `IP_MULTICAST_TTL` option for this socket.
1135     ///
1136     /// Indicates the time-to-live value of outgoing multicast packets for
1137     /// this socket. The default value is 1 which means that multicast packets
1138     /// don't leave the local network unless explicitly requested.
1139     ///
1140     /// Note that this may not have any affect on IPv6 sockets.
set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()>1141     pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
1142         unsafe {
1143             setsockopt(
1144                 self.as_raw(),
1145                 sys::IPPROTO_IP,
1146                 sys::IP_MULTICAST_TTL,
1147                 ttl as c_int,
1148             )
1149         }
1150     }
1151 
1152     /// Get the value of the `IP_TTL` option for this socket.
1153     ///
1154     /// For more information about this option, see [`set_ttl`].
1155     ///
1156     /// [`set_ttl`]: Socket::set_ttl
ttl(&self) -> io::Result<u32>1157     pub fn ttl(&self) -> io::Result<u32> {
1158         unsafe {
1159             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_TTL).map(|ttl| ttl as u32)
1160         }
1161     }
1162 
1163     /// Set the value of the `IP_TTL` option for this socket.
1164     ///
1165     /// This value sets the time-to-live field that is used in every packet sent
1166     /// from this socket.
set_ttl(&self, ttl: u32) -> io::Result<()>1167     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
1168         unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_TTL, ttl as c_int) }
1169     }
1170 
1171     /// Set the value of the `IP_TOS` option for this socket.
1172     ///
1173     /// This value sets the type-of-service field that is used in every packet
1174     /// sent from this socket.
1175     ///
1176     /// NOTE: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options>
1177     /// documents that not all versions of windows support `IP_TOS`.
1178     #[cfg(not(any(
1179         target_os = "fuschia",
1180         target_os = "redox",
1181         target_os = "solaris",
1182         target_os = "illumos",
1183     )))]
set_tos(&self, tos: u32) -> io::Result<()>1184     pub fn set_tos(&self, tos: u32) -> io::Result<()> {
1185         unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_TOS, tos as c_int) }
1186     }
1187 
1188     /// Get the value of the `IP_TOS` option for this socket.
1189     ///
1190     /// For more information about this option, see [`set_tos`].
1191     ///
1192     /// NOTE: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options>
1193     /// documents that not all versions of windows support `IP_TOS`.
1194     /// [`set_tos`]: Socket::set_tos
1195     #[cfg(not(any(
1196         target_os = "fuschia",
1197         target_os = "redox",
1198         target_os = "solaris",
1199         target_os = "illumos",
1200     )))]
tos(&self) -> io::Result<u32>1201     pub fn tos(&self) -> io::Result<u32> {
1202         unsafe {
1203             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_TOS).map(|tos| tos as u32)
1204         }
1205     }
1206 }
1207 
1208 /// Socket options for IPv6 sockets, get/set using `IPPROTO_IPV6`.
1209 ///
1210 /// Additional documentation can be found in documentation of the OS.
1211 /// * Linux: <https://man7.org/linux/man-pages/man7/ipv6.7.html>
1212 /// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options>
1213 impl Socket {
1214     /// Join a multicast group using `IPV6_ADD_MEMBERSHIP` option on this socket.
1215     ///
1216     /// Some OSs use `IPV6_JOIN_GROUP` for this option.
1217     ///
1218     /// This function specifies a new multicast group for this socket to join.
1219     /// The address must be a valid multicast address, and `interface` is the
1220     /// index of the interface to join/leave (or 0 to indicate any interface).
join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>1221     pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
1222         let mreq = sys::Ipv6Mreq {
1223             ipv6mr_multiaddr: sys::to_in6_addr(multiaddr),
1224             // NOTE: some OSs use `c_int`, others use `c_uint`.
1225             ipv6mr_interface: interface as _,
1226         };
1227         unsafe {
1228             setsockopt(
1229                 self.as_raw(),
1230                 sys::IPPROTO_IPV6,
1231                 sys::IPV6_ADD_MEMBERSHIP,
1232                 mreq,
1233             )
1234         }
1235     }
1236 
1237     /// Leave a multicast group using `IPV6_DROP_MEMBERSHIP` option on this socket.
1238     ///
1239     /// Some OSs use `IPV6_LEAVE_GROUP` for this option.
1240     ///
1241     /// For more information about this option, see [`join_multicast_v6`].
1242     ///
1243     /// [`join_multicast_v6`]: Socket::join_multicast_v6
leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>1244     pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
1245         let mreq = sys::Ipv6Mreq {
1246             ipv6mr_multiaddr: sys::to_in6_addr(multiaddr),
1247             // NOTE: some OSs use `c_int`, others use `c_uint`.
1248             ipv6mr_interface: interface as _,
1249         };
1250         unsafe {
1251             setsockopt(
1252                 self.as_raw(),
1253                 sys::IPPROTO_IPV6,
1254                 sys::IPV6_DROP_MEMBERSHIP,
1255                 mreq,
1256             )
1257         }
1258     }
1259 
1260     /// Get the value of the `IPV6_MULTICAST_HOPS` option for this socket
1261     ///
1262     /// For more information about this option, see [`set_multicast_hops_v6`].
1263     ///
1264     /// [`set_multicast_hops_v6`]: Socket::set_multicast_hops_v6
multicast_hops_v6(&self) -> io::Result<u32>1265     pub fn multicast_hops_v6(&self) -> io::Result<u32> {
1266         unsafe {
1267             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_MULTICAST_HOPS)
1268                 .map(|hops| hops as u32)
1269         }
1270     }
1271 
1272     /// Set the value of the `IPV6_MULTICAST_HOPS` option for this socket
1273     ///
1274     /// Indicates the number of "routers" multicast packets will transit for
1275     /// this socket. The default value is 1 which means that multicast packets
1276     /// don't leave the local network unless explicitly requested.
set_multicast_hops_v6(&self, hops: u32) -> io::Result<()>1277     pub fn set_multicast_hops_v6(&self, hops: u32) -> io::Result<()> {
1278         unsafe {
1279             setsockopt(
1280                 self.as_raw(),
1281                 sys::IPPROTO_IPV6,
1282                 sys::IPV6_MULTICAST_HOPS,
1283                 hops as c_int,
1284             )
1285         }
1286     }
1287 
1288     /// Get the value of the `IPV6_MULTICAST_IF` option for this socket.
1289     ///
1290     /// For more information about this option, see [`set_multicast_if_v6`].
1291     ///
1292     /// [`set_multicast_if_v6`]: Socket::set_multicast_if_v6
multicast_if_v6(&self) -> io::Result<u32>1293     pub fn multicast_if_v6(&self) -> io::Result<u32> {
1294         unsafe {
1295             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_MULTICAST_IF)
1296                 .map(|interface| interface as u32)
1297         }
1298     }
1299 
1300     /// Set the value of the `IPV6_MULTICAST_IF` option for this socket.
1301     ///
1302     /// Specifies the interface to use for routing multicast packets. Unlike
1303     /// ipv4, this is generally required in ipv6 contexts where network routing
1304     /// prefixes may overlap.
set_multicast_if_v6(&self, interface: u32) -> io::Result<()>1305     pub fn set_multicast_if_v6(&self, interface: u32) -> io::Result<()> {
1306         unsafe {
1307             setsockopt(
1308                 self.as_raw(),
1309                 sys::IPPROTO_IPV6,
1310                 sys::IPV6_MULTICAST_IF,
1311                 interface as c_int,
1312             )
1313         }
1314     }
1315 
1316     /// Get the value of the `IPV6_MULTICAST_LOOP` option for this socket.
1317     ///
1318     /// For more information about this option, see [`set_multicast_loop_v6`].
1319     ///
1320     /// [`set_multicast_loop_v6`]: Socket::set_multicast_loop_v6
multicast_loop_v6(&self) -> io::Result<bool>1321     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
1322         unsafe {
1323             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_MULTICAST_LOOP)
1324                 .map(|loop_v6| loop_v6 != 0)
1325         }
1326     }
1327 
1328     /// Set the value of the `IPV6_MULTICAST_LOOP` option for this socket.
1329     ///
1330     /// Controls whether this socket sees the multicast packets it sends itself.
1331     /// Note that this may not have any affect on IPv4 sockets.
set_multicast_loop_v6(&self, loop_v6: bool) -> io::Result<()>1332     pub fn set_multicast_loop_v6(&self, loop_v6: bool) -> io::Result<()> {
1333         unsafe {
1334             setsockopt(
1335                 self.as_raw(),
1336                 sys::IPPROTO_IPV6,
1337                 sys::IPV6_MULTICAST_LOOP,
1338                 loop_v6 as c_int,
1339             )
1340         }
1341     }
1342 
1343     /// Get the value of the `IPV6_UNICAST_HOPS` option for this socket.
1344     ///
1345     /// Specifies the hop limit for ipv6 unicast packets
unicast_hops_v6(&self) -> io::Result<u32>1346     pub fn unicast_hops_v6(&self) -> io::Result<u32> {
1347         unsafe {
1348             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_UNICAST_HOPS)
1349                 .map(|hops| hops as u32)
1350         }
1351     }
1352 
1353     /// Set the value for the `IPV6_UNICAST_HOPS` option on this socket.
1354     ///
1355     /// Specifies the hop limit for ipv6 unicast packets
set_unicast_hops_v6(&self, hops: u32) -> io::Result<()>1356     pub fn set_unicast_hops_v6(&self, hops: u32) -> io::Result<()> {
1357         unsafe {
1358             setsockopt(
1359                 self.as_raw(),
1360                 sys::IPPROTO_IPV6,
1361                 sys::IPV6_UNICAST_HOPS,
1362                 hops as c_int,
1363             )
1364         }
1365     }
1366 
1367     /// Get the value of the `IPV6_V6ONLY` option for this socket.
1368     ///
1369     /// For more information about this option, see [`set_only_v6`].
1370     ///
1371     /// [`set_only_v6`]: Socket::set_only_v6
only_v6(&self) -> io::Result<bool>1372     pub fn only_v6(&self) -> io::Result<bool> {
1373         unsafe {
1374             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_V6ONLY)
1375                 .map(|only_v6| only_v6 != 0)
1376         }
1377     }
1378 
1379     /// Set the value for the `IPV6_V6ONLY` option on this socket.
1380     ///
1381     /// If this is set to `true` then the socket is restricted to sending and
1382     /// receiving IPv6 packets only. In this case two IPv4 and IPv6 applications
1383     /// can bind the same port at the same time.
1384     ///
1385     /// If this is set to `false` then the socket can be used to send and
1386     /// receive packets from an IPv4-mapped IPv6 address.
set_only_v6(&self, only_v6: bool) -> io::Result<()>1387     pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
1388         unsafe {
1389             setsockopt(
1390                 self.as_raw(),
1391                 sys::IPPROTO_IPV6,
1392                 sys::IPV6_V6ONLY,
1393                 only_v6 as c_int,
1394             )
1395         }
1396     }
1397 }
1398 
1399 /// Socket options for TCP sockets, get/set using `IPPROTO_TCP`.
1400 ///
1401 /// Additional documentation can be found in documentation of the OS.
1402 /// * Linux: <https://man7.org/linux/man-pages/man7/tcp.7.html>
1403 /// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options>
1404 impl Socket {
1405     /// Get the value of the `TCP_KEEPIDLE` option on this socket.
1406     ///
1407     /// This returns the value of `SO_KEEPALIVE` on OpenBSD and Haiku,
1408     /// `TCP_KEEPALIVE` on macOS and iOS, and `TCP_KEEPIDLE` on all other Unix
1409     /// operating systems.
1410     #[cfg(any(doc, all(feature = "all", not(windows))))]
1411     #[cfg_attr(docsrs, doc(cfg(all(feature = "all", not(windows)))))]
keepalive_time(&self) -> io::Result<Duration>1412     pub fn keepalive_time(&self) -> io::Result<Duration> {
1413         sys::keepalive_time(self.as_raw())
1414     }
1415 
1416     /// Get the value of the `TCP_KEEPINTVL` option on this socket.
1417     ///
1418     /// For more information about this option, see [`set_tcp_keepalive`].
1419     ///
1420     /// [`set_tcp_keepalive`]: Socket::set_tcp_keepalive
1421     #[cfg(all(
1422         feature = "all",
1423         any(
1424             doc,
1425             target_os = "android",
1426             target_os = "dragonfly",
1427             target_os = "freebsd",
1428             target_os = "fuchsia",
1429             target_os = "illumos",
1430             target_os = "linux",
1431             target_os = "netbsd",
1432             target_vendor = "apple",
1433         )
1434     ))]
1435     #[cfg_attr(
1436         docsrs,
1437         doc(cfg(all(
1438             feature = "all",
1439             any(
1440                 target_os = "android",
1441                 target_os = "dragonfly",
1442                 target_os = "freebsd",
1443                 target_os = "fuchsia",
1444                 target_os = "illumos",
1445                 target_os = "linux",
1446                 target_os = "netbsd",
1447                 target_vendor = "apple",
1448             )
1449         )))
1450     )]
keepalive_interval(&self) -> io::Result<Duration>1451     pub fn keepalive_interval(&self) -> io::Result<Duration> {
1452         unsafe {
1453             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_KEEPINTVL)
1454                 .map(|secs| Duration::from_secs(secs as u64))
1455         }
1456     }
1457 
1458     /// Get the value of the `TCP_KEEPCNT` option on this socket.
1459     ///
1460     /// For more information about this option, see [`set_tcp_keepalive`].
1461     ///
1462     /// [`set_tcp_keepalive`]: Socket::set_tcp_keepalive
1463     #[cfg(all(
1464         feature = "all",
1465         any(
1466             doc,
1467             target_os = "android",
1468             target_os = "dragonfly",
1469             target_os = "freebsd",
1470             target_os = "fuchsia",
1471             target_os = "illumos",
1472             target_os = "linux",
1473             target_os = "netbsd",
1474             target_vendor = "apple",
1475         )
1476     ))]
1477     #[cfg_attr(
1478         docsrs,
1479         doc(cfg(all(
1480             feature = "all",
1481             any(
1482                 target_os = "android",
1483                 target_os = "dragonfly",
1484                 target_os = "freebsd",
1485                 target_os = "fuchsia",
1486                 target_os = "illumos",
1487                 target_os = "linux",
1488                 target_os = "netbsd",
1489                 target_vendor = "apple",
1490             )
1491         )))
1492     )]
keepalive_retries(&self) -> io::Result<u32>1493     pub fn keepalive_retries(&self) -> io::Result<u32> {
1494         unsafe {
1495             getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_KEEPCNT)
1496                 .map(|retries| retries as u32)
1497         }
1498     }
1499 
1500     /// Set parameters configuring TCP keepalive probes for this socket.
1501     ///
1502     /// The supported parameters depend on the operating system, and are
1503     /// configured using the [`TcpKeepalive`] struct. At a minimum, all systems
1504     /// support configuring the [keepalive time]: the time after which the OS
1505     /// will start sending keepalive messages on an idle connection.
1506     ///
1507     /// [keepalive time]: TcpKeepalive::with_time
1508     ///
1509     /// # Notes
1510     ///
1511     /// * This will enable `SO_KEEPALIVE` on this socket, if it is not already
1512     ///   enabled.
1513     /// * On some platforms, such as Windows, any keepalive parameters *not*
1514     ///   configured by the `TcpKeepalive` struct passed to this function may be
1515     ///   overwritten with their default values. Therefore, this function should
1516     ///   either only be called once per socket, or the same parameters should
1517     ///   be passed every time it is called.
1518     ///
1519     /// # Examples
1520     ///
1521     /// ```
1522     /// use std::time::Duration;
1523     ///
1524     /// use socket2::{Socket, TcpKeepalive, Domain, Type};
1525     ///
1526     /// # fn main() -> std::io::Result<()> {
1527     /// let socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
1528     /// let keepalive = TcpKeepalive::new()
1529     ///     .with_time(Duration::from_secs(4));
1530     ///     // Depending on the target operating system, we may also be able to
1531     ///     // configure the keepalive probe interval and/or the number of
1532     ///     // retries here as well.
1533     ///
1534     /// socket.set_tcp_keepalive(&keepalive)?;
1535     /// # Ok(()) }
1536     /// ```
1537     ///
set_tcp_keepalive(&self, params: &TcpKeepalive) -> io::Result<()>1538     pub fn set_tcp_keepalive(&self, params: &TcpKeepalive) -> io::Result<()> {
1539         self.set_keepalive(true)?;
1540         sys::set_tcp_keepalive(self.as_raw(), params)
1541     }
1542 
1543     /// Get the value of the `TCP_NODELAY` option on this socket.
1544     ///
1545     /// For more information about this option, see [`set_nodelay`].
1546     ///
1547     /// [`set_nodelay`]: Socket::set_nodelay
nodelay(&self) -> io::Result<bool>1548     pub fn nodelay(&self) -> io::Result<bool> {
1549         unsafe {
1550             getsockopt::<Bool>(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_NODELAY)
1551                 .map(|nodelay| nodelay != 0)
1552         }
1553     }
1554 
1555     /// Set the value of the `TCP_NODELAY` option on this socket.
1556     ///
1557     /// If set, this option disables the Nagle algorithm. This means that
1558     /// segments are always sent as soon as possible, even if there is only a
1559     /// small amount of data. When not set, data is buffered until there is a
1560     /// sufficient amount to send out, thereby avoiding the frequent sending of
1561     /// small packets.
set_nodelay(&self, nodelay: bool) -> io::Result<()>1562     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
1563         unsafe {
1564             setsockopt(
1565                 self.as_raw(),
1566                 sys::IPPROTO_TCP,
1567                 sys::TCP_NODELAY,
1568                 nodelay as c_int,
1569             )
1570         }
1571     }
1572 }
1573 
1574 impl Read for Socket {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>1575     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1576         // Safety: the `recv` implementation promises not to write uninitialised
1577         // bytes to the `buf`fer, so this casting is safe.
1578         let buf = unsafe { &mut *(buf as *mut [u8] as *mut [MaybeUninit<u8>]) };
1579         self.recv(buf)
1580     }
1581 
1582     #[cfg(not(target_os = "redox"))]
read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>1583     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
1584         // Safety: both `IoSliceMut` and `MaybeUninitSlice` promise to have the
1585         // same layout, that of `iovec`/`WSABUF`. Furthermore `recv_vectored`
1586         // promises to not write unitialised bytes to the `bufs` and pass it
1587         // directly to the `recvmsg` system call, so this is safe.
1588         let bufs = unsafe { &mut *(bufs as *mut [IoSliceMut<'_>] as *mut [MaybeUninitSlice<'_>]) };
1589         self.recv_vectored(bufs).map(|(n, _)| n)
1590     }
1591 }
1592 
1593 impl<'a> Read for &'a Socket {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>1594     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1595         // Safety: see other `Read::read` impl.
1596         let buf = unsafe { &mut *(buf as *mut [u8] as *mut [MaybeUninit<u8>]) };
1597         self.recv(buf)
1598     }
1599 
1600     #[cfg(not(target_os = "redox"))]
read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>1601     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
1602         // Safety: see other `Read::read` impl.
1603         let bufs = unsafe { &mut *(bufs as *mut [IoSliceMut<'_>] as *mut [MaybeUninitSlice<'_>]) };
1604         self.recv_vectored(bufs).map(|(n, _)| n)
1605     }
1606 }
1607 
1608 impl Write for Socket {
write(&mut self, buf: &[u8]) -> io::Result<usize>1609     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1610         self.send(buf)
1611     }
1612 
1613     #[cfg(not(target_os = "redox"))]
write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>1614     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
1615         self.send_vectored(bufs)
1616     }
1617 
flush(&mut self) -> io::Result<()>1618     fn flush(&mut self) -> io::Result<()> {
1619         Ok(())
1620     }
1621 }
1622 
1623 impl<'a> Write for &'a Socket {
write(&mut self, buf: &[u8]) -> io::Result<usize>1624     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1625         self.send(buf)
1626     }
1627 
1628     #[cfg(not(target_os = "redox"))]
write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>1629     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
1630         self.send_vectored(bufs)
1631     }
1632 
flush(&mut self) -> io::Result<()>1633     fn flush(&mut self) -> io::Result<()> {
1634         Ok(())
1635     }
1636 }
1637 
1638 impl fmt::Debug for Socket {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1639     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1640         f.debug_struct("Socket")
1641             .field("raw", &self.as_raw())
1642             .field("local_addr", &self.local_addr().ok())
1643             .field("peer_addr", &self.peer_addr().ok())
1644             .finish()
1645     }
1646 }
1647 
1648 from!(net::TcpStream, Socket);
1649 from!(net::TcpListener, Socket);
1650 from!(net::UdpSocket, Socket);
1651 from!(Socket, net::TcpStream);
1652 from!(Socket, net::TcpListener);
1653 from!(Socket, net::UdpSocket);
1654