Auto merge of #96324 - berendjan:set_tcp_quickack, r=dtolnay
Add setter and getter for TCP_QUICKACK on TcpStream for Linux Reference issue #96256 Setting TCP_QUICKACK on TcpStream for Linux
This commit is contained in:
commit
ee285eab69
@ -41,7 +41,7 @@ mod ip;
|
||||
mod parser;
|
||||
mod tcp;
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
pub(crate) mod test;
|
||||
mod udp;
|
||||
|
||||
/// Possible values which can be passed to the [`TcpStream::shutdown`] method.
|
||||
|
@ -3,4 +3,5 @@
|
||||
#![stable(feature = "raw_ext", since = "1.1.0")]
|
||||
|
||||
pub mod fs;
|
||||
pub mod net;
|
||||
pub mod raw;
|
||||
|
4
library/std/src/os/android/net.rs
Normal file
4
library/std/src/os/android/net.rs
Normal file
@ -0,0 +1,4 @@
|
||||
//! Linux and Android-specific definitions for socket options.
|
||||
|
||||
#![unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
pub use crate::os::net::tcp::TcpStreamExt;
|
@ -4,5 +4,6 @@
|
||||
#![doc(cfg(target_os = "linux"))]
|
||||
|
||||
pub mod fs;
|
||||
pub mod net;
|
||||
pub mod process;
|
||||
pub mod raw;
|
||||
|
4
library/std/src/os/linux/net.rs
Normal file
4
library/std/src/os/linux/net.rs
Normal file
@ -0,0 +1,4 @@
|
||||
//! Linux and Android-specific definitions for socket options.
|
||||
|
||||
#![unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
pub use crate::os::net::tcp::TcpStreamExt;
|
@ -148,3 +148,6 @@ pub mod vxworks;
|
||||
|
||||
#[cfg(any(unix, target_os = "wasi", doc))]
|
||||
mod fd;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", doc))]
|
||||
mod net;
|
||||
|
7
library/std/src/os/net/mod.rs
Normal file
7
library/std/src/os/net/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
//! Linux and Android-specific definitions for socket options.
|
||||
|
||||
#![unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
#![doc(cfg(any(target_os = "linux", target_os = "android",)))]
|
||||
pub mod tcp;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
70
library/std/src/os/net/tcp.rs
Normal file
70
library/std/src/os/net/tcp.rs
Normal file
@ -0,0 +1,70 @@
|
||||
//! Linux and Android-specific tcp extensions to primitives in the [`std::net`] module.
|
||||
//!
|
||||
//! [`std::net`]: crate::net
|
||||
|
||||
use crate::io;
|
||||
use crate::net;
|
||||
use crate::sealed::Sealed;
|
||||
use crate::sys_common::AsInner;
|
||||
|
||||
/// Os-specific extensions for [`TcpStream`]
|
||||
///
|
||||
/// [`TcpStream`]: net::TcpStream
|
||||
#[unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
pub trait TcpStreamExt: Sealed {
|
||||
/// Enable or disable `TCP_QUICKACK`.
|
||||
///
|
||||
/// This flag causes Linux to eagerly send ACKs rather than delaying them.
|
||||
/// Linux may reset this flag after further operations on the socket.
|
||||
///
|
||||
/// See [`man 7 tcp`](https://man7.org/linux/man-pages/man7/tcp.7.html) and
|
||||
/// [TCP delayed acknowledgement](https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment)
|
||||
/// for more information.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(tcp_quickack)]
|
||||
/// use std::net::TcpStream;
|
||||
/// use std::os::linux::net::TcpStreamExt;
|
||||
///
|
||||
/// let stream = TcpStream::connect("127.0.0.1:8080")
|
||||
/// .expect("Couldn't connect to the server...");
|
||||
/// stream.set_quickack(true).expect("set_quickack call failed");
|
||||
/// ```
|
||||
#[unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
fn set_quickack(&self, quickack: bool) -> io::Result<()>;
|
||||
|
||||
/// Gets the value of the `TCP_QUICKACK` option on this socket.
|
||||
///
|
||||
/// For more information about this option, see [`TcpStreamExt::set_quickack`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(tcp_quickack)]
|
||||
/// use std::net::TcpStream;
|
||||
/// use std::os::linux::net::TcpStreamExt;
|
||||
///
|
||||
/// let stream = TcpStream::connect("127.0.0.1:8080")
|
||||
/// .expect("Couldn't connect to the server...");
|
||||
/// stream.set_quickack(true).expect("set_quickack call failed");
|
||||
/// assert_eq!(stream.quickack().unwrap_or(false), true);
|
||||
/// ```
|
||||
#[unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
fn quickack(&self) -> io::Result<bool>;
|
||||
}
|
||||
|
||||
#[unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
impl Sealed for net::TcpStream {}
|
||||
|
||||
#[unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
impl TcpStreamExt for net::TcpStream {
|
||||
fn set_quickack(&self, quickack: bool) -> io::Result<()> {
|
||||
self.as_inner().as_inner().set_quickack(quickack)
|
||||
}
|
||||
|
||||
fn quickack(&self) -> io::Result<bool> {
|
||||
self.as_inner().as_inner().quickack()
|
||||
}
|
||||
}
|
29
library/std/src/os/net/tests.rs
Normal file
29
library/std/src/os/net/tests.rs
Normal file
@ -0,0 +1,29 @@
|
||||
#[cfg(any(target_os = "android", target_os = "linux",))]
|
||||
#[test]
|
||||
fn quickack() {
|
||||
use crate::{
|
||||
net::{test::next_test_ip4, TcpListener, TcpStream},
|
||||
os::net::tcp::TcpStreamExt,
|
||||
};
|
||||
|
||||
macro_rules! t {
|
||||
($e:expr) => {
|
||||
match $e {
|
||||
Ok(t) => t,
|
||||
Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let addr = next_test_ip4();
|
||||
let _listener = t!(TcpListener::bind(&addr));
|
||||
|
||||
let stream = t!(TcpStream::connect(&("localhost", addr.port())));
|
||||
|
||||
t!(stream.set_quickack(false));
|
||||
assert_eq!(false, t!(stream.quickack()));
|
||||
t!(stream.set_quickack(true));
|
||||
assert_eq!(true, t!(stream.quickack()));
|
||||
t!(stream.set_quickack(false));
|
||||
assert_eq!(false, t!(stream.quickack()));
|
||||
}
|
@ -392,6 +392,17 @@ impl Socket {
|
||||
Ok(raw != 0)
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux",))]
|
||||
pub fn set_quickack(&self, quickack: bool) -> io::Result<()> {
|
||||
setsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK, quickack as c_int)
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux",))]
|
||||
pub fn quickack(&self) -> io::Result<bool> {
|
||||
let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK)?;
|
||||
Ok(raw != 0)
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux",))]
|
||||
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
|
||||
setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int)
|
||||
|
@ -10,7 +10,7 @@ use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
|
||||
use crate::ptr;
|
||||
use crate::sys::net::netc as c;
|
||||
use crate::sys::net::{cvt, cvt_gai, cvt_r, init, wrlen_t, Socket};
|
||||
use crate::sys_common::{FromInner, IntoInner};
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::time::Duration;
|
||||
|
||||
use libc::{c_int, c_void};
|
||||
@ -345,6 +345,12 @@ impl TcpStream {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<Socket> for TcpStream {
|
||||
fn as_inner(&self) -> &Socket {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<Socket> for TcpStream {
|
||||
fn from_inner(socket: Socket) -> TcpStream {
|
||||
TcpStream { inner: socket }
|
||||
|
Loading…
x
Reference in New Issue
Block a user