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}