diff options
Diffstat (limited to 'src/net/tcp/socket.rs')
-rw-r--r-- | src/net/tcp/socket.rs | 490 |
1 files changed, 0 insertions, 490 deletions
diff --git a/src/net/tcp/socket.rs b/src/net/tcp/socket.rs deleted file mode 100644 index 69fbacf..0000000 --- a/src/net/tcp/socket.rs +++ /dev/null @@ -1,490 +0,0 @@ -use std::io; -use std::mem; -use std::net::SocketAddr; -#[cfg(unix)] -use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; -#[cfg(windows)] -use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket}; -use std::time::Duration; - -use crate::net::{TcpListener, TcpStream}; -use crate::sys; - -/// A non-blocking TCP socket used to configure a stream or listener. -/// -/// The `TcpSocket` type wraps the operating-system's socket handle. This type -/// is used to configure the socket before establishing a connection or start -/// listening for inbound connections. -/// -/// The socket will be closed when the value is dropped. -#[derive(Debug)] -pub struct TcpSocket { - sys: sys::tcp::TcpSocket, -} - -/// Configures a socket's TCP keepalive parameters. -#[derive(Debug, Default, Clone)] -pub struct TcpKeepalive { - pub(crate) time: Option<Duration>, - #[cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "freebsd", - target_os = "netbsd", - target_os = "windows", - ))] - pub(crate) interval: Option<Duration>, - #[cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "freebsd", - target_os = "netbsd", - ))] - pub(crate) retries: Option<u32>, -} - -impl TcpSocket { - /// Create a new IPv4 TCP socket. - /// - /// This calls `socket(2)`. - pub fn new_v4() -> io::Result<TcpSocket> { - sys::tcp::new_v4_socket().map(|sys| TcpSocket { sys }) - } - - /// Create a new IPv6 TCP socket. - /// - /// This calls `socket(2)`. - pub fn new_v6() -> io::Result<TcpSocket> { - sys::tcp::new_v6_socket().map(|sys| TcpSocket { sys }) - } - - pub(crate) fn new_for_addr(addr: SocketAddr) -> io::Result<TcpSocket> { - if addr.is_ipv4() { - TcpSocket::new_v4() - } else { - TcpSocket::new_v6() - } - } - - /// Bind `addr` to the TCP socket. - pub fn bind(&self, addr: SocketAddr) -> io::Result<()> { - sys::tcp::bind(self.sys, addr) - } - - /// Connect the socket to `addr`. - /// - /// This consumes the socket and performs the connect operation. Once the - /// connection completes, the socket is now a non-blocking `TcpStream` and - /// can be used as such. - pub fn connect(self, addr: SocketAddr) -> io::Result<TcpStream> { - let stream = sys::tcp::connect(self.sys, addr)?; - - // Don't close the socket - mem::forget(self); - Ok(TcpStream::from_std(stream)) - } - - /// Listen for inbound connections, converting the socket to a - /// `TcpListener`. - pub fn listen(self, backlog: u32) -> io::Result<TcpListener> { - let listener = sys::tcp::listen(self.sys, backlog)?; - - // Don't close the socket - mem::forget(self); - Ok(TcpListener::from_std(listener)) - } - - /// Sets the value of `SO_REUSEADDR` on this socket. - pub fn set_reuseaddr(&self, reuseaddr: bool) -> io::Result<()> { - sys::tcp::set_reuseaddr(self.sys, reuseaddr) - } - - /// Get the value of `SO_REUSEADDR` set on this socket. - pub fn get_reuseaddr(&self) -> io::Result<bool> { - sys::tcp::get_reuseaddr(self.sys) - } - - /// Sets the value of `SO_REUSEPORT` on this socket. - /// Only supported available in unix - #[cfg(all(unix, not(any(target_os = "solaris", target_os = "illumos"))))] - pub fn set_reuseport(&self, reuseport: bool) -> io::Result<()> { - sys::tcp::set_reuseport(self.sys, reuseport) - } - - /// Get the value of `SO_REUSEPORT` set on this socket. - /// Only supported available in unix - #[cfg(all(unix, not(any(target_os = "solaris", target_os = "illumos"))))] - pub fn get_reuseport(&self) -> io::Result<bool> { - sys::tcp::get_reuseport(self.sys) - } - - /// Sets the value of `SO_LINGER` on this socket. - pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> { - sys::tcp::set_linger(self.sys, dur) - } - - /// Gets the value of `SO_LINGER` on this socket - pub fn get_linger(&self) -> io::Result<Option<Duration>> { - sys::tcp::get_linger(self.sys) - } - - /// Sets the value of `SO_RCVBUF` on this socket. - pub fn set_recv_buffer_size(&self, size: u32) -> io::Result<()> { - sys::tcp::set_recv_buffer_size(self.sys, size) - } - - /// Get the value of `SO_RCVBUF` set on this socket. - /// - /// Note that if [`set_recv_buffer_size`] has been called on this socket - /// previously, the value returned by this function may not be the same as - /// the argument provided to `set_recv_buffer_size`. This is for the - /// following reasons: - /// - /// * Most operating systems have minimum and maximum allowed sizes for the - /// receive buffer, and will clamp the provided value if it is below the - /// minimum or above the maximum. The minimum and maximum buffer sizes are - /// OS-dependent. - /// * Linux will double the buffer size to account for internal bookkeeping - /// data, and returns the doubled value from `getsockopt(2)`. As per `man - /// 7 socket`: - /// > Sets or gets the maximum socket receive buffer in bytes. The - /// > kernel doubles this value (to allow space for bookkeeping - /// > overhead) when it is set using `setsockopt(2)`, and this doubled - /// > value is returned by `getsockopt(2)`. - /// - /// [`set_recv_buffer_size`]: #method.set_recv_buffer_size - pub fn get_recv_buffer_size(&self) -> io::Result<u32> { - sys::tcp::get_recv_buffer_size(self.sys) - } - - /// Sets the value of `SO_SNDBUF` on this socket. - pub fn set_send_buffer_size(&self, size: u32) -> io::Result<()> { - sys::tcp::set_send_buffer_size(self.sys, size) - } - - /// Get the value of `SO_SNDBUF` set on this socket. - /// - /// Note that if [`set_send_buffer_size`] has been called on this socket - /// previously, the value returned by this function may not be the same as - /// the argument provided to `set_send_buffer_size`. This is for the - /// following reasons: - /// - /// * Most operating systems have minimum and maximum allowed sizes for the - /// receive buffer, and will clamp the provided value if it is below the - /// minimum or above the maximum. The minimum and maximum buffer sizes are - /// OS-dependent. - /// * Linux will double the buffer size to account for internal bookkeeping - /// data, and returns the doubled value from `getsockopt(2)`. As per `man - /// 7 socket`: - /// > Sets or gets the maximum socket send buffer in bytes. The - /// > kernel doubles this value (to allow space for bookkeeping - /// > overhead) when it is set using `setsockopt(2)`, and this doubled - /// > value is returned by `getsockopt(2)`. - /// - /// [`set_send_buffer_size`]: #method.set_send_buffer_size - pub fn get_send_buffer_size(&self) -> io::Result<u32> { - sys::tcp::get_send_buffer_size(self.sys) - } - - /// Sets whether keepalive messages are enabled to be sent on this socket. - /// - /// This will set the `SO_KEEPALIVE` option on this socket. - pub fn set_keepalive(&self, keepalive: bool) -> io::Result<()> { - sys::tcp::set_keepalive(self.sys, keepalive) - } - - /// Returns whether or not TCP keepalive probes will be sent by this socket. - pub fn get_keepalive(&self) -> io::Result<bool> { - sys::tcp::get_keepalive(self.sys) - } - - /// Sets 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. - /// - /// # Notes - /// - /// * This will enable TCP 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 - #[cfg_attr(feature = "os-poll", doc = "```")] - #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")] - /// use mio::net::{TcpSocket, TcpKeepalive}; - /// use std::time::Duration; - /// - /// # fn main() -> Result<(), std::io::Error> { - /// let socket = TcpSocket::new_v6()?; - /// let keepalive = TcpKeepalive::default() - /// .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_keepalive_params(keepalive)?; - /// # Ok(()) } - /// ``` - /// - /// [`TcpKeepalive`]: ../struct.TcpKeepalive.html - /// [keepalive time]: ../struct.TcpKeepalive.html#method.with_time - pub fn set_keepalive_params(&self, keepalive: TcpKeepalive) -> io::Result<()> { - self.set_keepalive(true)?; - sys::tcp::set_keepalive_params(self.sys, keepalive) - } - - /// Returns the amount of time after which TCP keepalive probes will be sent - /// on idle connections. - /// - /// If `None`, then keepalive messages are disabled. - /// - /// This returns the value of `SO_KEEPALIVE` + `IPPROTO_TCP` on OpenBSD, - /// NetBSD, and Haiku, `TCP_KEEPALIVE` on macOS and iOS, and `TCP_KEEPIDLE` - /// on all other Unix operating systems. On Windows, it is not possible to - /// access the value of TCP keepalive parameters after they have been set. - /// - /// Some platforms specify this value in seconds, so sub-second - /// specifications may be omitted. - #[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))] - #[cfg(not(target_os = "windows"))] - pub fn get_keepalive_time(&self) -> io::Result<Option<Duration>> { - sys::tcp::get_keepalive_time(self.sys) - } - - /// Returns the time interval between TCP keepalive probes, if TCP keepalive is - /// enabled on this socket. - /// - /// If `None`, then keepalive messages are disabled. - /// - /// This returns the value of `TCP_KEEPINTVL` on supported Unix operating - /// systems. On Windows, it is not possible to access the value of TCP - /// keepalive parameters after they have been set.. - /// - /// Some platforms specify this value in seconds, so sub-second - /// specifications may be omitted. - #[cfg_attr( - docsrs, - doc(cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "freebsd", - target_os = "netbsd", - ))) - )] - #[cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "freebsd", - target_os = "netbsd", - ))] - pub fn get_keepalive_interval(&self) -> io::Result<Option<Duration>> { - sys::tcp::get_keepalive_interval(self.sys) - } - - /// Returns the maximum number of TCP keepalive probes that will be sent before - /// dropping a connection, if TCP keepalive is enabled on this socket. - /// - /// If `None`, then keepalive messages are disabled. - /// - /// This returns the value of `TCP_KEEPCNT` on Unix operating systems that - /// support this option. On Windows, it is not possible to access the value - /// of TCP keepalive parameters after they have been set. - #[cfg_attr( - docsrs, - doc(cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "freebsd", - target_os = "netbsd", - ))) - )] - #[cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "freebsd", - target_os = "netbsd", - ))] - pub fn get_keepalive_retries(&self) -> io::Result<Option<u32>> { - sys::tcp::get_keepalive_retries(self.sys) - } - - /// Returns the local address of this socket - /// - /// Will return `Err` result in windows if called before calling `bind` - pub fn get_localaddr(&self) -> io::Result<SocketAddr> { - sys::tcp::get_localaddr(self.sys) - } -} - -impl Drop for TcpSocket { - fn drop(&mut self) { - sys::tcp::close(self.sys); - } -} - -#[cfg(unix)] -impl IntoRawFd for TcpSocket { - fn into_raw_fd(self) -> RawFd { - let ret = self.sys; - // Avoid closing the socket - mem::forget(self); - ret - } -} - -#[cfg(unix)] -impl AsRawFd for TcpSocket { - fn as_raw_fd(&self) -> RawFd { - self.sys - } -} - -#[cfg(unix)] -impl FromRawFd for TcpSocket { - /// Converts a `RawFd` to a `TcpSocket`. - /// - /// # Notes - /// - /// The caller is responsible for ensuring that the socket is in - /// non-blocking mode. - unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket { - TcpSocket { sys: fd } - } -} - -#[cfg(windows)] -impl IntoRawSocket for TcpSocket { - fn into_raw_socket(self) -> RawSocket { - // The winapi crate defines `SOCKET` as `usize`. The Rust std - // conditionally defines `RawSocket` as a fixed size unsigned integer - // matching the pointer width. These end up being the same type but we - // must cast between them. - let ret = self.sys as RawSocket; - - // Avoid closing the socket - mem::forget(self); - - ret - } -} - -#[cfg(windows)] -impl AsRawSocket for TcpSocket { - fn as_raw_socket(&self) -> RawSocket { - self.sys as RawSocket - } -} - -#[cfg(windows)] -impl FromRawSocket for TcpSocket { - /// Converts a `RawSocket` to a `TcpSocket`. - /// - /// # Notes - /// - /// The caller is responsible for ensuring that the socket is in - /// non-blocking mode. - unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket { - TcpSocket { - sys: socket as sys::tcp::TcpSocket, - } - } -} - -impl TcpKeepalive { - // Sets the amount of time after which TCP keepalive probes will be sent - /// on idle connections. - /// - /// This will set the value of `SO_KEEPALIVE` + `IPPROTO_TCP` on OpenBSD, - /// NetBSD, and Haiku, `TCP_KEEPALIVE` on macOS and iOS, and `TCP_KEEPIDLE` - /// on all other Unix operating systems. On Windows, this sets the value of - /// the `tcp_keepalive` struct's `keepalivetime` field. - /// - /// Some platforms specify this value in seconds, so sub-second - /// specifications may be omitted. - pub fn with_time(self, time: Duration) -> Self { - Self { - time: Some(time), - ..self - } - } - - /// Sets the time interval between TCP keepalive probes. - /// This sets the value of `TCP_KEEPINTVL` on supported Unix operating - /// systems. On Windows, this sets the value of the `tcp_keepalive` struct's - /// `keepaliveinterval` field. - /// - /// Some platforms specify this value in seconds, so sub-second - /// specifications may be omitted. - #[cfg_attr( - docsrs, - doc(cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "freebsd", - target_os = "netbsd", - target_os = "windows" - ))) - )] - #[cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "freebsd", - target_os = "netbsd", - target_os = "windows" - ))] - pub fn with_interval(self, interval: Duration) -> Self { - Self { - interval: Some(interval), - ..self - } - } - - /// Sets the maximum number of TCP keepalive probes that will be sent before - /// dropping a connection, if TCP keepalive is enabled on this socket. - /// - /// This will set the value of `TCP_KEEPCNT` on Unix operating systems that - /// support this option. - #[cfg_attr( - docsrs, - doc(cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "freebsd", - target_os = "netbsd", - ))) - )] - #[cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "freebsd", - target_os = "netbsd", - ))] - pub fn with_retries(self, retries: u32) -> Self { - Self { - retries: Some(retries), - ..self - } - } - - /// Returns a new, empty set of TCP keepalive parameters. - pub fn new() -> Self { - Self::default() - } -} |