aboutsummaryrefslogtreecommitdiff
path: root/src/net/tcp/socket.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/tcp/socket.rs')
-rw-r--r--src/net/tcp/socket.rs490
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()
- }
-}