1//! Linux and Android-specific tcp extensions to primitives in the [`std::net`] module.
2//!
3//! [`std::net`]: crate::net
4
5use crate::io;
6use crate::net;
7use crate::sealed::Sealed;
8use crate::sys_common::AsInner;
9
10/// Os-specific extensions for [`TcpStream`]
11///
12/// [`TcpStream`]: net::TcpStream
13#[unstable(feature = "tcp_quickack", issue = "96256")]
14pub trait TcpStreamExt: Sealed {
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 /// ```no_run
27 /// #![feature(tcp_quickack)]
28 /// use std::net::TcpStream;
29 /// use std::os::linux::net::TcpStreamExt;
30 ///
31 /// let stream = TcpStream::connect("127.0.0.1:8080")
32 /// .expect("Couldn't connect to the server...");
33 /// stream.set_quickack(true).expect("set_quickack call failed");
34 /// ```
35 #[unstable(feature = "tcp_quickack", issue = "96256")]
36 fn set_quickack(&self, quickack: bool) -> io::Result<()>;
37
38 /// Gets the value of the `TCP_QUICKACK` option on this socket.
39 ///
40 /// For more information about this option, see [`TcpStreamExt::set_quickack`].
41 ///
42 /// # Examples
43 ///
44 /// ```no_run
45 /// #![feature(tcp_quickack)]
46 /// use std::net::TcpStream;
47 /// use std::os::linux::net::TcpStreamExt;
48 ///
49 /// let stream = TcpStream::connect("127.0.0.1:8080")
50 /// .expect("Couldn't connect to the server...");
51 /// stream.set_quickack(true).expect("set_quickack call failed");
52 /// assert_eq!(stream.quickack().unwrap_or(false), true);
53 /// ```
54 #[unstable(feature = "tcp_quickack", issue = "96256")]
55 fn quickack(&self) -> io::Result<bool>;
56
57 /// A socket listener will be awakened solely when data arrives.
58 ///
59 /// The `accept` argument set the delay in seconds until the
60 /// data is available to read, reducing the number of short lived
61 /// connections without data to process.
62 /// Contrary to other platforms `SO_ACCEPTFILTER` feature equivalent, there is
63 /// no necessity to set it after the `listen` call.
64 ///
65 /// See [`man 7 tcp`](https://man7.org/linux/man-pages/man7/tcp.7.html)
66 ///
67 /// # Examples
68 ///
69 /// ```no run
70 /// #![feature(tcp_deferaccept)]
71 /// use std::net::TcpStream;
72 /// use std::os::linux::net::TcpStreamExt;
73 ///
74 /// let stream = TcpStream::connect("127.0.0.1:8080")
75 /// .expect("Couldn't connect to the server...");
76 /// stream.set_deferaccept(1).expect("set_deferaccept call failed");
77 /// ```
78 #[unstable(feature = "tcp_deferaccept", issue = "119639")]
79 #[cfg(target_os = "linux")]
80 fn set_deferaccept(&self, accept: u32) -> io::Result<()>;
81
82 /// Gets the accept delay value (in seconds) of the `TCP_DEFER_ACCEPT` option.
83 ///
84 /// For more information about this option, see [`TcpStreamExt::set_deferaccept`].
85 ///
86 /// # Examples
87 ///
88 /// ```no_run
89 /// #![feature(tcp_deferaccept)]
90 /// use std::net::TcpStream;
91 /// use std::os::linux::net::TcpStreamExt;
92 ///
93 /// let stream = TcpStream::connect("127.0.0.1:8080")
94 /// .expect("Couldn't connect to the server...");
95 /// stream.set_deferaccept(1).expect("set_deferaccept call failed");
96 /// assert_eq!(stream.deferaccept().unwrap_or(0), 1);
97 /// ```
98 #[unstable(feature = "tcp_deferaccept", issue = "119639")]
99 #[cfg(target_os = "linux")]
100 fn deferaccept(&self) -> io::Result<u32>;
101}
102
103#[unstable(feature = "tcp_quickack", issue = "96256")]
104impl Sealed for net::TcpStream {}
105
106#[unstable(feature = "tcp_quickack", issue = "96256")]
107impl TcpStreamExt for net::TcpStream {
108 fn set_quickack(&self, quickack: bool) -> io::Result<()> {
109 self.as_inner().as_inner().set_quickack(quickack)
110 }
111
112 fn quickack(&self) -> io::Result<bool> {
113 self.as_inner().as_inner().quickack()
114 }
115
116 #[cfg(target_os = "linux")]
117 fn set_deferaccept(&self, accept: u32) -> io::Result<()> {
118 self.as_inner().as_inner().set_deferaccept(accept)
119 }
120
121 #[cfg(target_os = "linux")]
122 fn deferaccept(&self) -> io::Result<u32> {
123 self.as_inner().as_inner().deferaccept()
124 }
125}
126