Skip to main content

std/os/net/linux_ext/
tcp.rs

1//! Linux and Android-specific tcp extensions to primitives in the [`std::net`] module.
2//!
3//! [`std::net`]: crate::net
4
5use crate::sys::AsInner;
6#[cfg(target_os = "linux")]
7use crate::time::Duration;
8use crate::{io, net};
9
10/// Os-specific extensions for [`TcpStream`]
11///
12/// [`TcpStream`]: net::TcpStream
13#[stable(feature = "tcp_quickack", since = "1.89.0")]
14pub impl(self) trait TcpStreamExt {
15    /// Enable or disable `TCP_QUICKACK`.
16    ///
17    /// This flag causes Linux to eagerly send ACKs rather than delaying them.
18    /// Linux may reset this flag after further operations on the socket.
19    ///
20    /// See [`man 7 tcp`](https://man7.org/linux/man-pages/man7/tcp.7.html) and
21    /// [TCP delayed acknowledgement](https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment)
22    /// for more information.
23    ///
24    /// # Examples
25    ///
26    #[cfg_attr(
27        any(target_os = "linux", target_os = "android", target_os = "cygwin"),
28        doc = "```no_run"
29    )]
30    #[cfg_attr(
31        not(any(target_os = "linux", target_os = "android", target_os = "cygwin")),
32        doc = "```ignore (needs linux)"
33    )]
34    /// use std::net::TcpStream;
35    /// #[cfg(target_os = "linux")]
36    /// use std::os::linux::net::TcpStreamExt;
37    /// #[cfg(target_os = "android")]
38    /// use std::os::android::net::TcpStreamExt;
39    ///
40    /// let stream = TcpStream::connect("127.0.0.1:8080")
41    ///         .expect("Couldn't connect to the server...");
42    /// stream.set_quickack(true).expect("set_quickack call failed");
43    /// ```
44    #[stable(feature = "tcp_quickack", since = "1.89.0")]
45    fn set_quickack(&self, quickack: bool) -> io::Result<()>;
46
47    /// Gets the value of the `TCP_QUICKACK` option on this socket.
48    ///
49    /// For more information about this option, see [`TcpStreamExt::set_quickack`].
50    ///
51    /// # Examples
52    ///
53    #[cfg_attr(
54        any(target_os = "linux", target_os = "android", target_os = "cygwin"),
55        doc = "```no_run"
56    )]
57    #[cfg_attr(
58        not(any(target_os = "linux", target_os = "android", target_os = "cygwin")),
59        doc = "```ignore (needs linux)"
60    )]
61    /// use std::net::TcpStream;
62    /// #[cfg(target_os = "linux")]
63    /// use std::os::linux::net::TcpStreamExt;
64    /// #[cfg(target_os = "android")]
65    /// use std::os::android::net::TcpStreamExt;
66    ///
67    /// let stream = TcpStream::connect("127.0.0.1:8080")
68    ///         .expect("Couldn't connect to the server...");
69    /// stream.set_quickack(true).expect("set_quickack call failed");
70    /// assert_eq!(stream.quickack().unwrap_or(false), true);
71    /// ```
72    #[stable(feature = "tcp_quickack", since = "1.89.0")]
73    fn quickack(&self) -> io::Result<bool>;
74
75    /// A socket listener will be awakened solely when data arrives.
76    ///
77    /// The `accept` argument set the maximum delay until the
78    /// data is available to read, reducing the number of short lived
79    /// connections without data to process.
80    /// Contrary to other platforms `SO_ACCEPTFILTER` feature equivalent, there is
81    /// no necessity to set it after the `listen` call.
82    /// Note that the delay is expressed as Duration from user's perspective
83    /// the call rounds it down to the nearest second expressible as a `c_int`.
84    ///
85    /// See [`man 7 tcp`](https://man7.org/linux/man-pages/man7/tcp.7.html)
86    ///
87    /// # Examples
88    ///
89    /// ```no run
90    /// #![feature(tcp_deferaccept)]
91    /// use std::net::TcpStream;
92    /// use std::os::linux::net::TcpStreamExt;
93    /// use std::time::Duration;
94    ///
95    /// let stream = TcpStream::connect("127.0.0.1:8080")
96    ///         .expect("Couldn't connect to the server...");
97    /// stream.set_deferaccept(Duration::from_secs(1u64)).expect("set_deferaccept call failed");
98    /// ```
99    #[unstable(feature = "tcp_deferaccept", issue = "119639")]
100    #[cfg(target_os = "linux")]
101    fn set_deferaccept(&self, accept: Duration) -> io::Result<()>;
102
103    /// Gets the accept delay value of the `TCP_DEFER_ACCEPT` option.
104    ///
105    /// For more information about this option, see [`TcpStreamExt::set_deferaccept`].
106    ///
107    /// # Examples
108    ///
109    #[cfg_attr(
110        any(target_os = "linux", target_os = "android", target_os = "cygwin"),
111        doc = "```no_run"
112    )]
113    #[cfg_attr(
114        not(any(target_os = "linux", target_os = "android", target_os = "cygwin")),
115        doc = "```ignore (needs linux)"
116    )]
117    /// #![feature(tcp_deferaccept)]
118    /// use std::net::TcpStream;
119    /// use std::os::linux::net::TcpStreamExt;
120    /// use std::time::Duration;
121    ///
122    /// let stream = TcpStream::connect("127.0.0.1:8080")
123    ///         .expect("Couldn't connect to the server...");
124    /// stream.set_deferaccept(Duration::from_secs(1u64)).expect("set_deferaccept call failed");
125    /// assert_eq!(stream.deferaccept().unwrap(), Duration::from_secs(1u64));
126    /// ```
127    #[unstable(feature = "tcp_deferaccept", issue = "119639")]
128    #[cfg(target_os = "linux")]
129    fn deferaccept(&self) -> io::Result<Duration>;
130}
131
132#[stable(feature = "tcp_quickack", since = "1.89.0")]
133impl TcpStreamExt for net::TcpStream {
134    fn set_quickack(&self, quickack: bool) -> io::Result<()> {
135        self.as_inner().as_inner().set_quickack(quickack)
136    }
137
138    fn quickack(&self) -> io::Result<bool> {
139        self.as_inner().as_inner().quickack()
140    }
141
142    #[cfg(target_os = "linux")]
143    fn set_deferaccept(&self, accept: Duration) -> io::Result<()> {
144        self.as_inner().as_inner().set_deferaccept(accept)
145    }
146
147    #[cfg(target_os = "linux")]
148    fn deferaccept(&self) -> io::Result<Duration> {
149        self.as_inner().as_inner().deferaccept()
150    }
151}