// Copyright 2015 The Rust Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;
use std::io::{self, Read, Write};
#[cfg(not(target_os = "redox"))]
use std::io::{IoSlice, IoSliceMut};
use std::mem::MaybeUninit;
use std::net::{self, Ipv4Addr, Ipv6Addr, Shutdown};
#[cfg(unix)]
use std::os::unix::io::{FromRawFd, IntoRawFd};
#[cfg(windows)]
use std::os::windows::io::{FromRawSocket, IntoRawSocket};
use std::time::Duration;

use crate::sys::{self, c_int, getsockopt, setsockopt, Bool};
use crate::{Domain, Protocol, SockAddr, TcpKeepalive, Type};
#[cfg(not(target_os = "redox"))]
use crate::{MaybeUninitSlice, RecvFlags};

/// Owned wrapper around a system socket.
///
/// This type simply wraps an instance of a file descriptor (`c_int`) on Unix
/// and an instance of `SOCKET` on Windows. This is the main type exported by
/// this crate and is intended to mirror the raw semantics of sockets on
/// platforms as closely as possible. Almost all methods correspond to
/// precisely one libc or OS API call which is essentially just a "Rustic
/// translation" of what's below.
///
/// ## Converting to and from other types
///
/// This type can be freely converted into the network primitives provided by
/// the standard library, such as [`TcpStream`] or [`UdpSocket`], using the
/// [`From`] trait, see the example below.
///
/// [`TcpStream`]: std::net::TcpStream
/// [`UdpSocket`]: std::net::UdpSocket
///
/// # Notes
///
/// Some methods that set options on `Socket` require two system calls to set
/// there options without overwriting previously set options. We do this by
/// first getting the current settings, applying the desired changes and than
/// updating the settings. This means that the operation is **not** atomic. This
/// can lead to a data race when two threads are changing options in parallel.
///
/// # Examples
/// ```no_run
/// # fn main() -> std::io::Result<()> {
/// use std::net::{SocketAddr, TcpListener};
/// use socket2::{Socket, Domain, Type};
///
/// // create a TCP listener bound to two addresses
/// let socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
///
/// let address: SocketAddr = "[::1]:12345".parse().unwrap();
/// let address = address.into();
/// socket.bind(&address)?;
/// socket.bind(&address)?;
/// socket.listen(128)?;
///
/// let listener: TcpListener = socket.into();
/// // ...
/// # drop(listener);
/// # Ok(()) }
/// ```
pub struct Socket {
    inner: Inner,
}

/// Store a `TcpStream` internally to take advantage of its niche optimizations on Unix platforms.
pub(crate) type Inner = std::net::TcpStream;

impl Socket {
    /// # Safety
    ///
    /// The caller must ensure `raw` is a valid file descriptor/socket. NOTE:
    /// this should really be marked `unsafe`, but this being an internal
    /// function, often passed as mapping function, it's makes it very
    /// inconvenient to mark it as `unsafe`.
    pub(crate) fn from_raw(raw: sys::Socket) -> Socket {
        Socket {
            inner: unsafe {
                // SAFETY: the caller must ensure that `raw` is a valid file
                // descriptor, but when it isn't it could return I/O errors, or
                // potentially close a fd it doesn't own. All of that isn't
                // memory unsafe, so it's not desired but never memory unsafe or
                // causes UB.
                //
                // However there is one exception. We use `TcpStream` to
                // represent the `Socket` internally (see `Inner` type),
                // `TcpStream` has a layout optimisation that doesn't allow for
                // negative file descriptors (as those are always invalid).
                // Violating this assumption (fd never negative) causes UB,
                // something we don't want. So check for that we have this
                // `assert!`.
                #[cfg(unix)]
                assert!(raw >= 0, "tried to create a `Socket` with an invalid fd");
                sys::socket_from_raw(raw)
            },
        }
    }

    pub(crate) fn as_raw(&self) -> sys::Socket {
        sys::socket_as_raw(&self.inner)
    }

    pub(crate) fn into_raw(self) -> sys::Socket {
        sys::socket_into_raw(self.inner)
    }

    /// Creates a new socket and sets common flags.
    ///
    /// This function corresponds to `socket(2)` on Unix and `WSASocketW` on
    /// Windows.
    ///
    /// On Unix-like systems, the close-on-exec flag is set on the new socket.
    /// Additionally, on Apple platforms `SOCK_NOSIGPIPE` is set. On Windows,
    /// the socket is made non-inheritable.
    ///
    /// [`Socket::new_raw`] can be used if you don't want these flags to be set.
    pub fn new(domain: Domain, ty: Type, protocol: Option<Protocol>) -> io::Result<Socket> {
        let ty = set_common_type(ty);
        Socket::new_raw(domain, ty, protocol).and_then(set_common_flags)
    }

    /// Creates a new socket ready to be configured.
    ///
    /// This function corresponds to `socket(2)` on Unix and `WSASocketW` on
    /// Windows and simply creates a new socket, no other configuration is done.
    pub fn new_raw(domain: Domain, ty: Type, protocol: Option<Protocol>) -> io::Result<Socket> {
        let protocol = protocol.map(|p| p.0).unwrap_or(0);
        sys::socket(domain.0, ty.0, protocol).map(Socket::from_raw)
    }

    /// Creates a pair of sockets which are connected to each other.
    ///
    /// This function corresponds to `socketpair(2)`.
    ///
    /// This function sets the same flags as in done for [`Socket::new`],
    /// [`Socket::pair_raw`] can be used if you don't want to set those flags.
    #[cfg(any(doc, all(feature = "all", unix)))]
    #[cfg_attr(docsrs, doc(cfg(all(feature = "all", unix))))]
    pub fn pair(
        domain: Domain,
        ty: Type,
        protocol: Option<Protocol>,
    ) -> io::Result<(Socket, Socket)> {
        let ty = set_common_type(ty);
        let (a, b) = Socket::pair_raw(domain, ty, protocol)?;
        let a = set_common_flags(a)?;
        let b = set_common_flags(b)?;
        Ok((a, b))
    }

    /// Creates a pair of sockets which are connected to each other.
    ///
    /// This function corresponds to `socketpair(2)`.
    #[cfg(any(doc, all(feature = "all", unix)))]
    #[cfg_attr(docsrs, doc(cfg(all(feature = "all", unix))))]
    pub fn pair_raw(
        domain: Domain,
        ty: Type,
        protocol: Option<Protocol>,
    ) -> io::Result<(Socket, Socket)> {
        let protocol = protocol.map(|p| p.0).unwrap_or(0);
        sys::socketpair(domain.0, ty.0, protocol)
            .map(|[a, b]| (Socket::from_raw(a), Socket::from_raw(b)))
    }

    /// Binds this socket to the specified address.
    ///
    /// This function directly corresponds to the `bind(2)` function on Windows
    /// and Unix.
    pub fn bind(&self, address: &SockAddr) -> io::Result<()> {
        sys::bind(self.as_raw(), address)
    }

    /// Initiate a connection on this socket to the specified address.
    ///
    /// This function directly corresponds to the `connect(2)` function on
    /// Windows and Unix.
    ///
    /// An error will be returned if `listen` or `connect` has already been
    /// called on this builder.
    ///
    /// # Notes
    ///
    /// When using a non-blocking connect (by setting the socket into
    /// non-blocking mode before calling this function), socket option can't be
    /// set *while connecting*. This will cause errors on Windows. Socket
    /// options can be safely set before and after connecting the socket.
    pub fn connect(&self, address: &SockAddr) -> io::Result<()> {
        sys::connect(self.as_raw(), address)
    }

    /// Initiate a connection on this socket to the specified address, only
    /// only waiting for a certain period of time for the connection to be
    /// established.
    ///
    /// Unlike many other methods on `Socket`, this does *not* correspond to a
    /// single C function. It sets the socket to nonblocking mode, connects via
    /// connect(2), and then waits for the connection to complete with poll(2)
    /// on Unix and select on Windows. When the connection is complete, the
    /// socket is set back to blocking mode. On Unix, this will loop over
    /// `EINTR` errors.
    ///
    /// # Warnings
    ///
    /// The non-blocking state of the socket is overridden by this function -
    /// it will be returned in blocking mode on success, and in an indeterminate
    /// state on failure.
    ///
    /// If the connection request times out, it may still be processing in the
    /// background - a second call to `connect` or `connect_timeout` may fail.
    pub fn connect_timeout(&self, addr: &SockAddr, timeout: Duration) -> io::Result<()> {
        self.set_nonblocking(true)?;
        let res = self.connect(addr);
        self.set_nonblocking(false)?;

        match res {
            Ok(()) => return Ok(()),
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
            #[cfg(unix)]
            Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {}
            Err(e) => return Err(e),
        }

        sys::poll_connect(self, timeout)
    }

    /// Mark a socket as ready to accept incoming connection requests using
    /// [`Socket::accept()`].
    ///
    /// This function directly corresponds to the `listen(2)` function on
    /// Windows and Unix.
    ///
    /// An error will be returned if `listen` or `connect` has already been
    /// called on this builder.
    pub fn listen(&self, backlog: c_int) -> io::Result<()> {
        sys::listen(self.as_raw(), backlog)
    }

    /// Accept a new incoming connection from this listener.
    ///
    /// This function uses `accept4(2)` on platforms that support it and
    /// `accept(2)` platforms that do not.
    ///
    /// This function sets the same flags as in done for [`Socket::new`],
    /// [`Socket::accept_raw`] can be used if you don't want to set those flags.
    pub fn accept(&self) -> io::Result<(Socket, SockAddr)> {
        // Use `accept4` on platforms that support it.
        #[cfg(any(
            target_os = "android",
            target_os = "dragonfly",
            target_os = "freebsd",
            target_os = "fuchsia",
            target_os = "illumos",
            target_os = "linux",
            target_os = "netbsd",
            target_os = "openbsd",
        ))]
        return self._accept4(libc::SOCK_CLOEXEC);

        // Fall back to `accept` on platforms that do not support `accept4`.
        #[cfg(not(any(
            target_os = "android",
            target_os = "dragonfly",
            target_os = "freebsd",
            target_os = "fuchsia",
            target_os = "illumos",
            target_os = "linux",
            target_os = "netbsd",
            target_os = "openbsd",
        )))]
        {
            let (socket, addr) = self.accept_raw()?;
            let socket = set_common_flags(socket)?;
            // `set_common_flags` does not disable inheritance on Windows because `Socket::new`
            // unlike `accept` is able to create the socket with inheritance disabled.
            #[cfg(windows)]
            socket._set_no_inherit(true)?;
            Ok((socket, addr))
        }
    }

    /// Accept a new incoming connection from this listener.
    ///
    /// This function directly corresponds to the `accept(2)` function on
    /// Windows and Unix.
    pub fn accept_raw(&self) -> io::Result<(Socket, SockAddr)> {
        sys::accept(self.as_raw()).map(|(inner, addr)| (Socket::from_raw(inner), addr))
    }

    /// Returns the socket address of the local half of this socket.
    ///
    /// # Notes
    ///
    /// Depending on the OS this may return an error if the socket is not
    /// [bound].
    ///
    /// [bound]: Socket::bind
    pub fn local_addr(&self) -> io::Result<SockAddr> {
        sys::getsockname(self.as_raw())
    }

    /// Returns the socket address of the remote peer of this socket.
    ///
    /// # Notes
    ///
    /// This returns an error if the socket is not [`connect`ed].
    ///
    /// [`connect`ed]: Socket::connect
    pub fn peer_addr(&self) -> io::Result<SockAddr> {
        sys::getpeername(self.as_raw())
    }

    /// Returns the [`Type`] of this socket by checking the `SO_TYPE` option on
    /// this socket.
    pub fn r#type(&self) -> io::Result<Type> {
        unsafe { getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_TYPE).map(Type) }
    }

    /// Creates a new independently owned handle to the underlying socket.
    ///
    /// # Notes
    ///
    /// On Unix this uses `F_DUPFD_CLOEXEC` and thus sets the `FD_CLOEXEC` on
    /// the returned socket.
    ///
    /// On Windows this uses `WSA_FLAG_NO_HANDLE_INHERIT` setting inheriting to
    /// false.
    ///
    /// On Windows this can **not** be used function cannot be used on a
    /// QOS-enabled socket, see
    /// <https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaduplicatesocketw>.
    pub fn try_clone(&self) -> io::Result<Socket> {
        sys::try_clone(self.as_raw()).map(Socket::from_raw)
    }

    /// Moves this TCP stream into or out of nonblocking mode.
    ///
    /// # Notes
    ///
    /// On Unix this corresponds to calling `fcntl` (un)setting `O_NONBLOCK`.
    ///
    /// On Windows this corresponds to calling `ioctlsocket` (un)setting
    /// `FIONBIO`.
    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
        sys::set_nonblocking(self.as_raw(), nonblocking)
    }

    /// Shuts down the read, write, or both halves of this connection.
    ///
    /// This function will cause all pending and future I/O on the specified
    /// portions to return immediately with an appropriate value.
    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
        sys::shutdown(self.as_raw(), how)
    }

    /// Receives data on the socket from the remote address to which it is
    /// connected.
    ///
    /// The [`connect`] method will connect this socket to a remote address.
    /// This method might fail if the socket is not connected.
    ///
    /// [`connect`]: Socket::connect
    ///
    /// # Safety
    ///
    /// Normally casting a `&mut [u8]` to `&mut [MaybeUninit<u8>]` would be
    /// unsound, as that allows us to write uninitialised bytes to the buffer.
    /// However this implementation promises to not write uninitialised bytes to
    /// the `buf`fer and passes it directly to `recv(2)` system call. This
    /// promise ensures that this function can be called using a `buf`fer of
    /// type `&mut [u8]`.
    ///
    /// Note that the [`io::Read::read`] implementation calls this function with
    /// a `buf`fer of type `&mut [u8]`, allowing initialised buffers to be used
    /// without using `unsafe`.
    pub fn recv(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> {
        self.recv_with_flags(buf, 0)
    }

    /// Receives out-of-band (OOB) data on the socket from the remote address to
    /// which it is connected by setting the `MSG_OOB` flag for this call.
    ///
    /// For more information, see [`recv`], [`out_of_band_inline`].
    ///
    /// [`recv`]: Socket::recv
    /// [`out_of_band_inline`]: Socket::out_of_band_inline
    pub fn recv_out_of_band(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> {
        self.recv_with_flags(buf, sys::MSG_OOB)
    }

    /// Identical to [`recv`] but allows for specification of arbitrary flags to
    /// the underlying `recv` call.
    ///
    /// [`recv`]: Socket::recv
    pub fn recv_with_flags(
        &self,
        buf: &mut [MaybeUninit<u8>],
        flags: sys::c_int,
    ) -> io::Result<usize> {
        sys::recv(self.as_raw(), buf, flags)
    }

    /// Receives data on the socket from the remote address to which it is
    /// connected. Unlike [`recv`] this allows passing multiple buffers.
    ///
    /// The [`connect`] method will connect this socket to a remote address.
    /// This method might fail if the socket is not connected.
    ///
    /// In addition to the number of bytes read, this function returns the flags
    /// for the received message. See [`RecvFlags`] for more information about
    /// the returned flags.
    ///
    /// [`recv`]: Socket::recv
    /// [`connect`]: Socket::connect
    ///
    /// # Safety
    ///
    /// Normally casting a `IoSliceMut` to `MaybeUninitSlice` would be unsound,
    /// as that allows us to write uninitialised bytes to the buffer. However
    /// this implementation promises to not write uninitialised bytes to the
    /// `bufs` and passes it directly to `recvmsg(2)` system call. This promise
    /// ensures that this function can be called using `bufs` of type `&mut
    /// [IoSliceMut]`.
    ///
    /// Note that the [`io::Read::read_vectored`] implementation calls this
    /// function with `buf`s of type `&mut [IoSliceMut]`, allowing initialised
    /// buffers to be used without using `unsafe`.
    #[cfg(not(target_os = "redox"))]
    #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
    pub fn recv_vectored(
        &self,
        bufs: &mut [MaybeUninitSlice<'_>],
    ) -> io::Result<(usize, RecvFlags)> {
        self.recv_vectored_with_flags(bufs, 0)
    }

    /// Identical to [`recv_vectored`] but allows for specification of arbitrary
    /// flags to the underlying `recvmsg`/`WSARecv` call.
    ///
    /// [`recv_vectored`]: Socket::recv_vectored
    ///
    /// # Safety
    ///
    /// `recv_from_vectored` makes the same safety guarantees regarding `bufs`
    /// as [`recv_vectored`].
    ///
    /// [`recv_vectored`]: Socket::recv_vectored
    #[cfg(not(target_os = "redox"))]
    #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
    pub fn recv_vectored_with_flags(
        &self,
        bufs: &mut [MaybeUninitSlice<'_>],
        flags: c_int,
    ) -> io::Result<(usize, RecvFlags)> {
        sys::recv_vectored(self.as_raw(), bufs, flags)
    }

    /// Receives data on the socket from the remote adress to which it is
    /// connected, without removing that data from the queue. On success,
    /// returns the number of bytes peeked.
    ///
    /// Successive calls return the same data. This is accomplished by passing
    /// `MSG_PEEK` as a flag to the underlying `recv` system call.
    ///
    /// # Safety
    ///
    /// `peek` makes the same safety guarantees regarding the `buf`fer as
    /// [`recv`].
    ///
    /// [`recv`]: Socket::recv
    pub fn peek(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> {
        self.recv_with_flags(buf, sys::MSG_PEEK)
    }

    /// Receives data from the socket. On success, returns the number of bytes
    /// read and the address from whence the data came.
    ///
    /// # Safety
    ///
    /// `recv_from` makes the same safety guarantees regarding the `buf`fer as
    /// [`recv`].
    ///
    /// [`recv`]: Socket::recv
    pub fn recv_from(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<(usize, SockAddr)> {
        self.recv_from_with_flags(buf, 0)
    }

    /// Identical to [`recv_from`] but allows for specification of arbitrary
    /// flags to the underlying `recvfrom` call.
    ///
    /// [`recv_from`]: Socket::recv_from
    pub fn recv_from_with_flags(
        &self,
        buf: &mut [MaybeUninit<u8>],
        flags: c_int,
    ) -> io::Result<(usize, SockAddr)> {
        sys::recv_from(self.as_raw(), buf, flags)
    }

    /// Receives data from the socket. Returns the amount of bytes read, the
    /// [`RecvFlags`] and the remote address from the data is coming. Unlike
    /// [`recv_from`] this allows passing multiple buffers.
    ///
    /// [`recv_from`]: Socket::recv_from
    ///
    /// # Safety
    ///
    /// `recv_from_vectored` makes the same safety guarantees regarding `bufs`
    /// as [`recv_vectored`].
    ///
    /// [`recv_vectored`]: Socket::recv_vectored
    #[cfg(not(target_os = "redox"))]
    #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
    pub fn recv_from_vectored(
        &self,
        bufs: &mut [MaybeUninitSlice<'_>],
    ) -> io::Result<(usize, RecvFlags, SockAddr)> {
        self.recv_from_vectored_with_flags(bufs, 0)
    }

    /// Identical to [`recv_from_vectored`] but allows for specification of
    /// arbitrary flags to the underlying `recvmsg`/`WSARecvFrom` call.
    ///
    /// [`recv_from_vectored`]: Socket::recv_from_vectored
    ///
    /// # Safety
    ///
    /// `recv_from_vectored` makes the same safety guarantees regarding `bufs`
    /// as [`recv_vectored`].
    ///
    /// [`recv_vectored`]: Socket::recv_vectored
    #[cfg(not(target_os = "redox"))]
    #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
    pub fn recv_from_vectored_with_flags(
        &self,
        bufs: &mut [MaybeUninitSlice<'_>],
        flags: c_int,
    ) -> io::Result<(usize, RecvFlags, SockAddr)> {
        sys::recv_from_vectored(self.as_raw(), bufs, flags)
    }

    /// Receives data from the socket, without removing it from the queue.
    ///
    /// Successive calls return the same data. This is accomplished by passing
    /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
    ///
    /// On success, returns the number of bytes peeked and the address from
    /// whence the data came.
    ///
    /// # Safety
    ///
    /// `peek_from` makes the same safety guarantees regarding the `buf`fer as
    /// [`recv`].
    ///
    /// [`recv`]: Socket::recv
    pub fn peek_from(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<(usize, SockAddr)> {
        self.recv_from_with_flags(buf, sys::MSG_PEEK)
    }

    /// Sends data on the socket to a connected peer.
    ///
    /// This is typically used on TCP sockets or datagram sockets which have
    /// been connected.
    ///
    /// On success returns the number of bytes that were sent.
    pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
        self.send_with_flags(buf, 0)
    }

    /// Identical to [`send`] but allows for specification of arbitrary flags to the underlying
    /// `send` call.
    ///
    /// [`send`]: #method.send
    pub fn send_with_flags(&self, buf: &[u8], flags: c_int) -> io::Result<usize> {
        sys::send(self.as_raw(), buf, flags)
    }

    /// Send data to the connected peer. Returns the amount of bytes written.
    #[cfg(not(target_os = "redox"))]
    #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
    pub fn send_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        self.send_vectored_with_flags(bufs, 0)
    }

    /// Identical to [`send_vectored`] but allows for specification of arbitrary
    /// flags to the underlying `sendmsg`/`WSASend` call.
    ///
    /// [`send_vectored`]: Socket::send_vectored
    #[cfg(not(target_os = "redox"))]
    #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
    pub fn send_vectored_with_flags(
        &self,
        bufs: &[IoSlice<'_>],
        flags: c_int,
    ) -> io::Result<usize> {
        sys::send_vectored(self.as_raw(), bufs, flags)
    }

    /// Sends out-of-band (OOB) data on the socket to connected peer
    /// by setting the `MSG_OOB` flag for this call.
    ///
    /// For more information, see [`send`], [`out_of_band_inline`].
    ///
    /// [`send`]: #method.send
    /// [`out_of_band_inline`]: #method.out_of_band_inline
    pub fn send_out_of_band(&self, buf: &[u8]) -> io::Result<usize> {
        self.send_with_flags(buf, sys::MSG_OOB)
    }

    /// Sends data on the socket to the given address. On success, returns the
    /// number of bytes written.
    ///
    /// This is typically used on UDP or datagram-oriented sockets.
    pub fn send_to(&self, buf: &[u8], addr: &SockAddr) -> io::Result<usize> {
        self.send_to_with_flags(buf, addr, 0)
    }

    /// Identical to [`send_to`] but allows for specification of arbitrary flags
    /// to the underlying `sendto` call.
    ///
    /// [`send_to`]: Socket::send_to
    pub fn send_to_with_flags(
        &self,
        buf: &[u8],
        addr: &SockAddr,
        flags: c_int,
    ) -> io::Result<usize> {
        sys::send_to(self.as_raw(), buf, addr, flags)
    }

    /// Send data to a peer listening on `addr`. Returns the amount of bytes
    /// written.
    #[cfg(not(target_os = "redox"))]
    #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
    pub fn send_to_vectored(&self, bufs: &[IoSlice<'_>], addr: &SockAddr) -> io::Result<usize> {
        self.send_to_vectored_with_flags(bufs, addr, 0)
    }

    /// Identical to [`send_to_vectored`] but allows for specification of
    /// arbitrary flags to the underlying `sendmsg`/`WSASendTo` call.
    ///
    /// [`send_to_vectored`]: Socket::send_to_vectored
    #[cfg(not(target_os = "redox"))]
    #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
    pub fn send_to_vectored_with_flags(
        &self,
        bufs: &[IoSlice<'_>],
        addr: &SockAddr,
        flags: c_int,
    ) -> io::Result<usize> {
        sys::send_to_vectored(self.as_raw(), bufs, addr, flags)
    }
}

/// Set `SOCK_CLOEXEC` and `NO_HANDLE_INHERIT` on the `ty`pe on platforms that
/// support it.
#[inline(always)]
fn set_common_type(ty: Type) -> Type {
    // On platforms that support it set `SOCK_CLOEXEC`.
    #[cfg(any(
        target_os = "android",
        target_os = "dragonfly",
        target_os = "freebsd",
        target_os = "fuchsia",
        target_os = "illumos",
        target_os = "linux",
        target_os = "netbsd",
        target_os = "openbsd",
    ))]
    let ty = ty._cloexec();

    // On windows set `NO_HANDLE_INHERIT`.
    #[cfg(windows)]
    let ty = ty._no_inherit();

    ty
}

/// Set `FD_CLOEXEC` and `NOSIGPIPE` on the `socket` for platforms that need it.
#[inline(always)]
#[allow(clippy::unnecessary_wraps)]
fn set_common_flags(socket: Socket) -> io::Result<Socket> {
    // On platforms that don't have `SOCK_CLOEXEC` use `FD_CLOEXEC`.
    #[cfg(all(
        unix,
        not(any(
            target_os = "android",
            target_os = "dragonfly",
            target_os = "freebsd",
            target_os = "fuchsia",
            target_os = "illumos",
            target_os = "linux",
            target_os = "netbsd",
            target_os = "openbsd",
        ))
    ))]
    socket._set_cloexec(true)?;

    // On Apple platforms set `NOSIGPIPE`.
    #[cfg(target_vendor = "apple")]
    socket._set_nosigpipe(true)?;

    Ok(socket)
}

/// A local interface specified by its index or an address assigned to it.
///
/// `Index(0)` and `Address(Ipv4Addr::UNSPECIFIED)` are equivalent and indicate
/// that an appropriate interface should be selected by the system.
#[cfg(not(any(
    target_os = "haiku",
    target_os = "illumos",
    target_os = "netbsd",
    target_os = "redox",
    target_os = "solaris",
)))]
#[derive(Debug)]
pub enum InterfaceIndexOrAddress {
    /// An interface index.
    Index(u32),
    /// An address assigned to an interface.
    Address(Ipv4Addr),
}

/// Socket options get/set using `SOL_SOCKET`.
///
/// Additional documentation can be found in documentation of the OS.
/// * Linux: <https://man7.org/linux/man-pages/man7/socket.7.html>
/// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options>
impl Socket {
    /// Get the value of the `SO_BROADCAST` option for this socket.
    ///
    /// For more information about this option, see [`set_broadcast`].
    ///
    /// [`set_broadcast`]: Socket::set_broadcast
    pub fn broadcast(&self) -> io::Result<bool> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_BROADCAST)
                .map(|broadcast| broadcast != 0)
        }
    }

    /// Set the value of the `SO_BROADCAST` option for this socket.
    ///
    /// When enabled, this socket is allowed to send packets to a broadcast
    /// address.
    pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::SOL_SOCKET,
                sys::SO_BROADCAST,
                broadcast as c_int,
            )
        }
    }

    /// Get the value of the `SO_ERROR` option on this socket.
    ///
    /// This will retrieve the stored error in the underlying socket, clearing
    /// the field in the process. This can be useful for checking errors between
    /// calls.
    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match unsafe { getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_ERROR) } {
            Ok(0) => Ok(None),
            Ok(errno) => Ok(Some(io::Error::from_raw_os_error(errno))),
            Err(err) => Err(err),
        }
    }

    /// Get the value of the `SO_KEEPALIVE` option on this socket.
    ///
    /// For more information about this option, see [`set_keepalive`].
    ///
    /// [`set_keepalive`]: Socket::set_keepalive
    pub fn keepalive(&self) -> io::Result<bool> {
        unsafe {
            getsockopt::<Bool>(self.as_raw(), sys::SOL_SOCKET, sys::SO_KEEPALIVE)
                .map(|keepalive| keepalive != 0)
        }
    }

    /// Set value for the `SO_KEEPALIVE` option on this socket.
    ///
    /// Enable sending of keep-alive messages on connection-oriented sockets.
    pub fn set_keepalive(&self, keepalive: bool) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::SOL_SOCKET,
                sys::SO_KEEPALIVE,
                keepalive as c_int,
            )
        }
    }

    /// Get the value of the `SO_LINGER` option on this socket.
    ///
    /// For more information about this option, see [`set_linger`].
    ///
    /// [`set_linger`]: Socket::set_linger
    pub fn linger(&self) -> io::Result<Option<Duration>> {
        unsafe {
            getsockopt::<sys::linger>(self.as_raw(), sys::SOL_SOCKET, sys::SO_LINGER)
                .map(from_linger)
        }
    }

    /// Set value for the `SO_LINGER` option on this socket.
    ///
    /// If `linger` is not `None`, a close(2) or shutdown(2) will not return
    /// until all queued messages for the socket have been successfully sent or
    /// the linger timeout has been reached. Otherwise, the call returns
    /// immediately and the closing is done in the background. When the socket
    /// is closed as part of exit(2), it always lingers in the background.
    ///
    /// # Notes
    ///
    /// On most OSs the duration only has a precision of seconds and will be
    /// silently truncated.
    ///
    /// On Apple platforms (e.g. macOS, iOS, etc) this uses `SO_LINGER_SEC`.
    pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
        let linger = into_linger(linger);
        unsafe { setsockopt(self.as_raw(), sys::SOL_SOCKET, sys::SO_LINGER, linger) }
    }

    /// Get value for the `SO_OOBINLINE` option on this socket.
    ///
    /// For more information about this option, see [`set_out_of_band_inline`].
    ///
    /// [`set_out_of_band_inline`]: Socket::set_out_of_band_inline
    #[cfg(not(target_os = "redox"))]
    #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
    pub fn out_of_band_inline(&self) -> io::Result<bool> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_OOBINLINE)
                .map(|oob_inline| oob_inline != 0)
        }
    }

    /// Set value for the `SO_OOBINLINE` option on this socket.
    ///
    /// If this option is enabled, out-of-band data is directly placed into the
    /// receive data stream. Otherwise, out-of-band data is passed only when the
    /// `MSG_OOB` flag is set during receiving. As per RFC6093, TCP sockets
    /// using the Urgent mechanism are encouraged to set this flag.
    #[cfg(not(target_os = "redox"))]
    #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
    pub fn set_out_of_band_inline(&self, oob_inline: bool) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::SOL_SOCKET,
                sys::SO_OOBINLINE,
                oob_inline as c_int,
            )
        }
    }

    /// Get value for the `SO_RCVBUF` option on this socket.
    ///
    /// For more information about this option, see [`set_recv_buffer_size`].
    ///
    /// [`set_recv_buffer_size`]: Socket::set_recv_buffer_size
    pub fn recv_buffer_size(&self) -> io::Result<usize> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_RCVBUF)
                .map(|size| size as usize)
        }
    }

    /// Set value for the `SO_RCVBUF` option on this socket.
    ///
    /// Changes the size of the operating system's receive buffer associated
    /// with the socket.
    pub fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::SOL_SOCKET,
                sys::SO_RCVBUF,
                size as c_int,
            )
        }
    }

    /// Get value for the `SO_RCVTIMEO` option on this socket.
    ///
    /// If the returned timeout is `None`, then `read` and `recv` calls will
    /// block indefinitely.
    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        sys::timeout_opt(self.as_raw(), sys::SOL_SOCKET, sys::SO_RCVTIMEO)
    }

    /// Set value for the `SO_RCVTIMEO` option on this socket.
    ///
    /// If `timeout` is `None`, then `read` and `recv` calls will block
    /// indefinitely.
    pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
        sys::set_timeout_opt(self.as_raw(), sys::SOL_SOCKET, sys::SO_RCVTIMEO, duration)
    }

    /// Get the value of the `SO_REUSEADDR` option on this socket.
    ///
    /// For more information about this option, see [`set_reuse_address`].
    ///
    /// [`set_reuse_address`]: Socket::set_reuse_address
    pub fn reuse_address(&self) -> io::Result<bool> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_REUSEADDR)
                .map(|reuse| reuse != 0)
        }
    }

    /// Set value for the `SO_REUSEADDR` option on this socket.
    ///
    /// This indicates that futher calls to `bind` may allow reuse of local
    /// addresses. For IPv4 sockets this means that a socket may bind even when
    /// there's a socket already listening on this port.
    pub fn set_reuse_address(&self, reuse: bool) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::SOL_SOCKET,
                sys::SO_REUSEADDR,
                reuse as c_int,
            )
        }
    }

    /// Get the value of the `SO_SNDBUF` option on this socket.
    ///
    /// For more information about this option, see [`set_send_buffer_size`].
    ///
    /// [`set_send_buffer_size`]: Socket::set_send_buffer_size
    pub fn send_buffer_size(&self) -> io::Result<usize> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_SNDBUF)
                .map(|size| size as usize)
        }
    }

    /// Set value for the `SO_SNDBUF` option on this socket.
    ///
    /// Changes the size of the operating system's send buffer associated with
    /// the socket.
    pub fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::SOL_SOCKET,
                sys::SO_SNDBUF,
                size as c_int,
            )
        }
    }

    /// Get value for the `SO_SNDTIMEO` option on this socket.
    ///
    /// If the returned timeout is `None`, then `write` and `send` calls will
    /// block indefinitely.
    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        sys::timeout_opt(self.as_raw(), sys::SOL_SOCKET, sys::SO_SNDTIMEO)
    }

    /// Set value for the `SO_SNDTIMEO` option on this socket.
    ///
    /// If `timeout` is `None`, then `write` and `send` calls will block
    /// indefinitely.
    pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
        sys::set_timeout_opt(self.as_raw(), sys::SOL_SOCKET, sys::SO_SNDTIMEO, duration)
    }
}

fn from_linger(linger: sys::linger) -> Option<Duration> {
    if linger.l_onoff == 0 {
        None
    } else {
        Some(Duration::from_secs(linger.l_linger as u64))
    }
}

fn into_linger(duration: Option<Duration>) -> sys::linger {
    match duration {
        Some(duration) => sys::linger {
            l_onoff: 1,
            l_linger: duration.as_secs() as _,
        },
        None => sys::linger {
            l_onoff: 0,
            l_linger: 0,
        },
    }
}

/// Socket options for IPv4 sockets, get/set using `IPPROTO_IP`.
///
/// Additional documentation can be found in documentation of the OS.
/// * Linux: <https://man7.org/linux/man-pages/man7/ip.7.html>
/// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options>
impl Socket {
    /// Get the value of the `IP_HDRINCL` option on this socket.
    ///
    /// For more information about this option, see [`set_header_included`].
    ///
    /// [`set_header_included`]: Socket::set_header_included
    #[cfg(all(feature = "all", not(target_os = "redox")))]
    #[cfg_attr(docsrs, doc(all(feature = "all", not(target_os = "redox"))))]
    pub fn header_included(&self) -> io::Result<bool> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_HDRINCL)
                .map(|included| included != 0)
        }
    }

    /// Set the value of the `IP_HDRINCL` option on this socket.
    ///
    /// If enabled, the user supplies an IP header in front of the user data.
    /// Valid only for [`SOCK_RAW`] sockets; see [raw(7)] for more information.
    /// When this flag is enabled, the values set by `IP_OPTIONS`, [`IP_TTL`],
    /// and [`IP_TOS`] are ignored.
    ///
    /// [`SOCK_RAW`]: Type::RAW
    /// [raw(7)]: https://man7.org/linux/man-pages/man7/raw.7.html
    /// [`IP_TTL`]: Socket::set_ttl
    /// [`IP_TOS`]: Socket::set_tos
    #[cfg(all(feature = "all", not(target_os = "redox")))]
    #[cfg_attr(docsrs, doc(all(feature = "all", not(target_os = "redox"))))]
    pub fn set_header_included(&self, included: bool) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IP,
                sys::IP_HDRINCL,
                included as c_int,
            )
        }
    }

    /// Get the value of the `IP_TRANSPARENT` option on this socket.
    ///
    /// For more information about this option, see [`set_ip_transparent`].
    ///
    /// [`set_ip_transparent`]: Socket::set_ip_transparent
    #[cfg(any(doc, all(feature = "all", target_os = "linux")))]
    #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))]
    pub fn ip_transparent(&self) -> io::Result<bool> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, libc::IP_TRANSPARENT)
                .map(|transparent| transparent != 0)
        }
    }

    /// Set the value of the `IP_TRANSPARENT` option on this socket.
    ///
    /// Setting this boolean option enables transparent proxying
    /// on this socket.  This socket option allows the calling
    /// application to bind to a nonlocal IP address and operate
    /// both as a client and a server with the foreign address as
    /// the local endpoint.  NOTE: this requires that routing be
    /// set up in a way that packets going to the foreign address
    /// are routed through the TProxy box (i.e., the system
    /// hosting the application that employs the IP_TRANSPARENT
    /// socket option).  Enabling this socket option requires
    /// superuser privileges (the `CAP_NET_ADMIN` capability).
    ///
    /// TProxy redirection with the iptables TPROXY target also
    /// requires that this option be set on the redirected socket.
    #[cfg(any(doc, all(feature = "all", target_os = "linux")))]
    #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))]
    pub fn set_ip_transparent(&self, transparent: bool) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IP,
                libc::IP_TRANSPARENT,
                transparent as c_int,
            )
        }
    }

    /// Join a multicast group using `IP_ADD_MEMBERSHIP` option on this socket.
    ///
    /// This function specifies a new multicast group for this socket to join.
    /// The address must be a valid multicast address, and `interface` is the
    /// address of the local interface with which the system should join the
    /// multicast group. If it's [`Ipv4Addr::UNSPECIFIED`] (`INADDR_ANY`) then
    /// an appropriate interface is chosen by the system.
    pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
        let mreq = sys::IpMreq {
            imr_multiaddr: sys::to_in_addr(multiaddr),
            imr_interface: sys::to_in_addr(interface),
        };
        unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_ADD_MEMBERSHIP, mreq) }
    }

    /// Leave a multicast group using `IP_DROP_MEMBERSHIP` option on this socket.
    ///
    /// For more information about this option, see [`join_multicast_v4`].
    ///
    /// [`join_multicast_v4`]: Socket::join_multicast_v4
    pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
        let mreq = sys::IpMreq {
            imr_multiaddr: sys::to_in_addr(multiaddr),
            imr_interface: sys::to_in_addr(interface),
        };
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IP,
                sys::IP_DROP_MEMBERSHIP,
                mreq,
            )
        }
    }

    /// Join a multicast group using `IP_ADD_MEMBERSHIP` option on this socket.
    ///
    /// This function specifies a new multicast group for this socket to join.
    /// The address must be a valid multicast address, and `interface` specifies
    /// the local interface with which the system should join the multicast
    /// group. See [`InterfaceIndexOrAddress`].
    #[cfg(not(any(
        target_os = "haiku",
        target_os = "illumos",
        target_os = "netbsd",
        target_os = "redox",
        target_os = "solaris",
    )))]
    pub fn join_multicast_v4_n(
        &self,
        multiaddr: &Ipv4Addr,
        interface: &InterfaceIndexOrAddress,
    ) -> io::Result<()> {
        let mreqn = sys::to_mreqn(multiaddr, interface);
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IP,
                sys::IP_ADD_MEMBERSHIP,
                mreqn,
            )
        }
    }

    /// Leave a multicast group using `IP_DROP_MEMBERSHIP` option on this socket.
    ///
    /// For more information about this option, see [`join_multicast_v4_n`].
    ///
    /// [`join_multicast_v4_n`]: Socket::join_multicast_v4_n
    #[cfg(not(any(
        target_os = "haiku",
        target_os = "illumos",
        target_os = "netbsd",
        target_os = "redox",
        target_os = "solaris",
    )))]
    pub fn leave_multicast_v4_n(
        &self,
        multiaddr: &Ipv4Addr,
        interface: &InterfaceIndexOrAddress,
    ) -> io::Result<()> {
        let mreqn = sys::to_mreqn(multiaddr, interface);
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IP,
                sys::IP_DROP_MEMBERSHIP,
                mreqn,
            )
        }
    }

    /// Get the value of the `IP_MULTICAST_IF` option for this socket.
    ///
    /// For more information about this option, see [`set_multicast_if_v4`].
    ///
    /// [`set_multicast_if_v4`]: Socket::set_multicast_if_v4
    pub fn multicast_if_v4(&self) -> io::Result<Ipv4Addr> {
        unsafe {
            getsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_MULTICAST_IF).map(sys::from_in_addr)
        }
    }

    /// Set the value of the `IP_MULTICAST_IF` option for this socket.
    ///
    /// Specifies the interface to use for routing multicast packets.
    pub fn set_multicast_if_v4(&self, interface: &Ipv4Addr) -> io::Result<()> {
        let interface = sys::to_in_addr(interface);
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IP,
                sys::IP_MULTICAST_IF,
                interface,
            )
        }
    }

    /// Get the value of the `IP_MULTICAST_LOOP` option for this socket.
    ///
    /// For more information about this option, see [`set_multicast_loop_v4`].
    ///
    /// [`set_multicast_loop_v4`]: Socket::set_multicast_loop_v4
    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_MULTICAST_LOOP)
                .map(|loop_v4| loop_v4 != 0)
        }
    }

    /// Set the value of the `IP_MULTICAST_LOOP` option for this socket.
    ///
    /// If enabled, multicast packets will be looped back to the local socket.
    /// Note that this may not have any affect on IPv6 sockets.
    pub fn set_multicast_loop_v4(&self, loop_v4: bool) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IP,
                sys::IP_MULTICAST_LOOP,
                loop_v4 as c_int,
            )
        }
    }

    /// Get the value of the `IP_MULTICAST_TTL` option for this socket.
    ///
    /// For more information about this option, see [`set_multicast_ttl_v4`].
    ///
    /// [`set_multicast_ttl_v4`]: Socket::set_multicast_ttl_v4
    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_MULTICAST_TTL)
                .map(|ttl| ttl as u32)
        }
    }

    /// Set the value of the `IP_MULTICAST_TTL` option for this socket.
    ///
    /// Indicates the time-to-live value of outgoing multicast packets for
    /// this socket. The default value is 1 which means that multicast packets
    /// don't leave the local network unless explicitly requested.
    ///
    /// Note that this may not have any affect on IPv6 sockets.
    pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IP,
                sys::IP_MULTICAST_TTL,
                ttl as c_int,
            )
        }
    }

    /// Get the value of the `IP_TTL` option for this socket.
    ///
    /// For more information about this option, see [`set_ttl`].
    ///
    /// [`set_ttl`]: Socket::set_ttl
    pub fn ttl(&self) -> io::Result<u32> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_TTL).map(|ttl| ttl as u32)
        }
    }

    /// Set the value of the `IP_TTL` option for this socket.
    ///
    /// This value sets the time-to-live field that is used in every packet sent
    /// from this socket.
    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
        unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_TTL, ttl as c_int) }
    }

    /// Set the value of the `IP_TOS` option for this socket.
    ///
    /// This value sets the type-of-service field that is used in every packet
    /// sent from this socket.
    ///
    /// NOTE: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options>
    /// documents that not all versions of windows support `IP_TOS`.
    #[cfg(not(any(
        target_os = "fuschia",
        target_os = "redox",
        target_os = "solaris",
        target_os = "illumos",
    )))]
    pub fn set_tos(&self, tos: u32) -> io::Result<()> {
        unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_TOS, tos as c_int) }
    }

    /// Get the value of the `IP_TOS` option for this socket.
    ///
    /// For more information about this option, see [`set_tos`].
    ///
    /// NOTE: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options>
    /// documents that not all versions of windows support `IP_TOS`.
    ///
    /// [`set_tos`]: Socket::set_tos
    #[cfg(not(any(
        target_os = "fuschia",
        target_os = "redox",
        target_os = "solaris",
        target_os = "illumos",
    )))]
    pub fn tos(&self) -> io::Result<u32> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_TOS).map(|tos| tos as u32)
        }
    }
}

/// Socket options for IPv6 sockets, get/set using `IPPROTO_IPV6`.
///
/// Additional documentation can be found in documentation of the OS.
/// * Linux: <https://man7.org/linux/man-pages/man7/ipv6.7.html>
/// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options>
impl Socket {
    /// Join a multicast group using `IPV6_ADD_MEMBERSHIP` option on this socket.
    ///
    /// Some OSs use `IPV6_JOIN_GROUP` for this option.
    ///
    /// This function specifies a new multicast group for this socket to join.
    /// The address must be a valid multicast address, and `interface` is the
    /// index of the interface to join/leave (or 0 to indicate any interface).
    pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
        let mreq = sys::Ipv6Mreq {
            ipv6mr_multiaddr: sys::to_in6_addr(multiaddr),
            // NOTE: some OSs use `c_int`, others use `c_uint`.
            ipv6mr_interface: interface as _,
        };
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IPV6,
                sys::IPV6_ADD_MEMBERSHIP,
                mreq,
            )
        }
    }

    /// Leave a multicast group using `IPV6_DROP_MEMBERSHIP` option on this socket.
    ///
    /// Some OSs use `IPV6_LEAVE_GROUP` for this option.
    ///
    /// For more information about this option, see [`join_multicast_v6`].
    ///
    /// [`join_multicast_v6`]: Socket::join_multicast_v6
    pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
        let mreq = sys::Ipv6Mreq {
            ipv6mr_multiaddr: sys::to_in6_addr(multiaddr),
            // NOTE: some OSs use `c_int`, others use `c_uint`.
            ipv6mr_interface: interface as _,
        };
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IPV6,
                sys::IPV6_DROP_MEMBERSHIP,
                mreq,
            )
        }
    }

    /// Get the value of the `IPV6_MULTICAST_HOPS` option for this socket
    ///
    /// For more information about this option, see [`set_multicast_hops_v6`].
    ///
    /// [`set_multicast_hops_v6`]: Socket::set_multicast_hops_v6
    pub fn multicast_hops_v6(&self) -> io::Result<u32> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_MULTICAST_HOPS)
                .map(|hops| hops as u32)
        }
    }

    /// Set the value of the `IPV6_MULTICAST_HOPS` option for this socket
    ///
    /// Indicates the number of "routers" multicast packets will transit for
    /// this socket. The default value is 1 which means that multicast packets
    /// don't leave the local network unless explicitly requested.
    pub fn set_multicast_hops_v6(&self, hops: u32) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IPV6,
                sys::IPV6_MULTICAST_HOPS,
                hops as c_int,
            )
        }
    }

    /// Get the value of the `IPV6_MULTICAST_IF` option for this socket.
    ///
    /// For more information about this option, see [`set_multicast_if_v6`].
    ///
    /// [`set_multicast_if_v6`]: Socket::set_multicast_if_v6
    pub fn multicast_if_v6(&self) -> io::Result<u32> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_MULTICAST_IF)
                .map(|interface| interface as u32)
        }
    }

    /// Set the value of the `IPV6_MULTICAST_IF` option for this socket.
    ///
    /// Specifies the interface to use for routing multicast packets. Unlike
    /// ipv4, this is generally required in ipv6 contexts where network routing
    /// prefixes may overlap.
    pub fn set_multicast_if_v6(&self, interface: u32) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IPV6,
                sys::IPV6_MULTICAST_IF,
                interface as c_int,
            )
        }
    }

    /// Get the value of the `IPV6_MULTICAST_LOOP` option for this socket.
    ///
    /// For more information about this option, see [`set_multicast_loop_v6`].
    ///
    /// [`set_multicast_loop_v6`]: Socket::set_multicast_loop_v6
    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_MULTICAST_LOOP)
                .map(|loop_v6| loop_v6 != 0)
        }
    }

    /// Set the value of the `IPV6_MULTICAST_LOOP` option for this socket.
    ///
    /// Controls whether this socket sees the multicast packets it sends itself.
    /// Note that this may not have any affect on IPv4 sockets.
    pub fn set_multicast_loop_v6(&self, loop_v6: bool) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IPV6,
                sys::IPV6_MULTICAST_LOOP,
                loop_v6 as c_int,
            )
        }
    }

    /// Get the value of the `IPV6_UNICAST_HOPS` option for this socket.
    ///
    /// Specifies the hop limit for ipv6 unicast packets
    pub fn unicast_hops_v6(&self) -> io::Result<u32> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_UNICAST_HOPS)
                .map(|hops| hops as u32)
        }
    }

    /// Set the value for the `IPV6_UNICAST_HOPS` option on this socket.
    ///
    /// Specifies the hop limit for ipv6 unicast packets
    pub fn set_unicast_hops_v6(&self, hops: u32) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IPV6,
                sys::IPV6_UNICAST_HOPS,
                hops as c_int,
            )
        }
    }

    /// Get the value of the `IPV6_V6ONLY` option for this socket.
    ///
    /// For more information about this option, see [`set_only_v6`].
    ///
    /// [`set_only_v6`]: Socket::set_only_v6
    pub fn only_v6(&self) -> io::Result<bool> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_V6ONLY)
                .map(|only_v6| only_v6 != 0)
        }
    }

    /// Set the value for the `IPV6_V6ONLY` option on this socket.
    ///
    /// If this is set to `true` then the socket is restricted to sending and
    /// receiving IPv6 packets only. In this case two IPv4 and IPv6 applications
    /// can bind the same port at the same time.
    ///
    /// If this is set to `false` then the socket can be used to send and
    /// receive packets from an IPv4-mapped IPv6 address.
    pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_IPV6,
                sys::IPV6_V6ONLY,
                only_v6 as c_int,
            )
        }
    }
}

/// Socket options for TCP sockets, get/set using `IPPROTO_TCP`.
///
/// Additional documentation can be found in documentation of the OS.
/// * Linux: <https://man7.org/linux/man-pages/man7/tcp.7.html>
/// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options>
impl Socket {
    /// Get the value of the `TCP_KEEPIDLE` option on this socket.
    ///
    /// This returns the value of `TCP_KEEPALIVE` on macOS and iOS and `TCP_KEEPIDLE` on all other
    /// supported Unix operating systems.
    #[cfg(any(
        doc,
        all(
            feature = "all",
            not(any(windows, target_os = "haiku", target_os = "openbsd"))
        )
    ))]
    #[cfg_attr(
        docsrs,
        doc(cfg(all(
            feature = "all",
            not(any(windows, target_os = "haiku", target_os = "openbsd"))
        )))
    )]
    pub fn keepalive_time(&self) -> io::Result<Duration> {
        sys::keepalive_time(self.as_raw())
    }

    /// Get the value of the `TCP_KEEPINTVL` option on this socket.
    ///
    /// For more information about this option, see [`set_tcp_keepalive`].
    ///
    /// [`set_tcp_keepalive`]: Socket::set_tcp_keepalive
    #[cfg(all(
        feature = "all",
        any(
            doc,
            target_os = "android",
            target_os = "dragonfly",
            target_os = "freebsd",
            target_os = "fuchsia",
            target_os = "illumos",
            target_os = "linux",
            target_os = "netbsd",
            target_vendor = "apple",
        )
    ))]
    #[cfg_attr(
        docsrs,
        doc(cfg(all(
            feature = "all",
            any(
                target_os = "android",
                target_os = "dragonfly",
                target_os = "freebsd",
                target_os = "fuchsia",
                target_os = "illumos",
                target_os = "linux",
                target_os = "netbsd",
                target_vendor = "apple",
            )
        )))
    )]
    pub fn keepalive_interval(&self) -> io::Result<Duration> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_KEEPINTVL)
                .map(|secs| Duration::from_secs(secs as u64))
        }
    }

    /// Get the value of the `TCP_KEEPCNT` option on this socket.
    ///
    /// For more information about this option, see [`set_tcp_keepalive`].
    ///
    /// [`set_tcp_keepalive`]: Socket::set_tcp_keepalive
    #[cfg(all(
        feature = "all",
        any(
            doc,
            target_os = "android",
            target_os = "dragonfly",
            target_os = "freebsd",
            target_os = "fuchsia",
            target_os = "illumos",
            target_os = "linux",
            target_os = "netbsd",
            target_vendor = "apple",
        )
    ))]
    #[cfg_attr(
        docsrs,
        doc(cfg(all(
            feature = "all",
            any(
                target_os = "android",
                target_os = "dragonfly",
                target_os = "freebsd",
                target_os = "fuchsia",
                target_os = "illumos",
                target_os = "linux",
                target_os = "netbsd",
                target_vendor = "apple",
            )
        )))
    )]
    pub fn keepalive_retries(&self) -> io::Result<u32> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_KEEPCNT)
                .map(|retries| retries as u32)
        }
    }

    /// Set parameters configuring TCP keepalive probes for this socket.
    ///
    /// The supported parameters depend on the operating system, and are
    /// configured using the [`TcpKeepalive`] struct. At a minimum, all systems
    /// support configuring the [keepalive time]: the time after which the OS
    /// will start sending keepalive messages on an idle connection.
    ///
    /// [keepalive time]: TcpKeepalive::with_time
    ///
    /// # Notes
    ///
    /// * This will enable `SO_KEEPALIVE` on this socket, if it is not already
    ///   enabled.
    /// * On some platforms, such as Windows, any keepalive parameters *not*
    ///   configured by the `TcpKeepalive` struct passed to this function may be
    ///   overwritten with their default values. Therefore, this function should
    ///   either only be called once per socket, or the same parameters should
    ///   be passed every time it is called.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::time::Duration;
    ///
    /// use socket2::{Socket, TcpKeepalive, Domain, Type};
    ///
    /// # fn main() -> std::io::Result<()> {
    /// let socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
    /// let keepalive = TcpKeepalive::new()
    ///     .with_time(Duration::from_secs(4));
    ///     // Depending on the target operating system, we may also be able to
    ///     // configure the keepalive probe interval and/or the number of
    ///     // retries here as well.
    ///
    /// socket.set_tcp_keepalive(&keepalive)?;
    /// # Ok(()) }
    /// ```
    ///
    pub fn set_tcp_keepalive(&self, params: &TcpKeepalive) -> io::Result<()> {
        self.set_keepalive(true)?;
        sys::set_tcp_keepalive(self.as_raw(), params)
    }

    /// Get the value of the `TCP_NODELAY` option on this socket.
    ///
    /// For more information about this option, see [`set_nodelay`].
    ///
    /// [`set_nodelay`]: Socket::set_nodelay
    pub fn nodelay(&self) -> io::Result<bool> {
        unsafe {
            getsockopt::<Bool>(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_NODELAY)
                .map(|nodelay| nodelay != 0)
        }
    }

    /// Set the value of the `TCP_NODELAY` option on this socket.
    ///
    /// If set, this option disables the Nagle algorithm. This means that
    /// segments are always sent as soon as possible, even if there is only a
    /// small amount of data. When not set, data is buffered until there is a
    /// sufficient amount to send out, thereby avoiding the frequent sending of
    /// small packets.
    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
        unsafe {
            setsockopt(
                self.as_raw(),
                sys::IPPROTO_TCP,
                sys::TCP_NODELAY,
                nodelay as c_int,
            )
        }
    }
}

impl Read for Socket {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        // Safety: the `recv` implementation promises not to write uninitialised
        // bytes to the `buf`fer, so this casting is safe.
        let buf = unsafe { &mut *(buf as *mut [u8] as *mut [MaybeUninit<u8>]) };
        self.recv(buf)
    }

    #[cfg(not(target_os = "redox"))]
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        // Safety: both `IoSliceMut` and `MaybeUninitSlice` promise to have the
        // same layout, that of `iovec`/`WSABUF`. Furthermore `recv_vectored`
        // promises to not write unitialised bytes to the `bufs` and pass it
        // directly to the `recvmsg` system call, so this is safe.
        let bufs = unsafe { &mut *(bufs as *mut [IoSliceMut<'_>] as *mut [MaybeUninitSlice<'_>]) };
        self.recv_vectored(bufs).map(|(n, _)| n)
    }
}

impl<'a> Read for &'a Socket {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        // Safety: see other `Read::read` impl.
        let buf = unsafe { &mut *(buf as *mut [u8] as *mut [MaybeUninit<u8>]) };
        self.recv(buf)
    }

    #[cfg(not(target_os = "redox"))]
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        // Safety: see other `Read::read` impl.
        let bufs = unsafe { &mut *(bufs as *mut [IoSliceMut<'_>] as *mut [MaybeUninitSlice<'_>]) };
        self.recv_vectored(bufs).map(|(n, _)| n)
    }
}

impl Write for Socket {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.send(buf)
    }

    #[cfg(not(target_os = "redox"))]
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        self.send_vectored(bufs)
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl<'a> Write for &'a Socket {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.send(buf)
    }

    #[cfg(not(target_os = "redox"))]
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        self.send_vectored(bufs)
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl fmt::Debug for Socket {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Socket")
            .field("raw", &self.as_raw())
            .field("local_addr", &self.local_addr().ok())
            .field("peer_addr", &self.peer_addr().ok())
            .finish()
    }
}

from!(net::TcpStream, Socket);
from!(net::TcpListener, Socket);
from!(net::UdpSocket, Socket);
from!(Socket, net::TcpStream);
from!(Socket, net::TcpListener);
from!(Socket, net::UdpSocket);
