From 4547b622d8d29df964fa2914213088b148c498fc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:32 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- library/std/src/os/net/linux_ext/addr.rs | 64 ++++++++++++++++++++++++++++ library/std/src/os/net/linux_ext/mod.rs | 12 ++++++ library/std/src/os/net/linux_ext/tcp.rs | 70 +++++++++++++++++++++++++++++++ library/std/src/os/net/linux_ext/tests.rs | 28 +++++++++++++ 4 files changed, 174 insertions(+) create mode 100644 library/std/src/os/net/linux_ext/addr.rs create mode 100644 library/std/src/os/net/linux_ext/mod.rs create mode 100644 library/std/src/os/net/linux_ext/tcp.rs create mode 100644 library/std/src/os/net/linux_ext/tests.rs (limited to 'library/std/src/os/net/linux_ext') diff --git a/library/std/src/os/net/linux_ext/addr.rs b/library/std/src/os/net/linux_ext/addr.rs new file mode 100644 index 000000000..df3fc8e6a --- /dev/null +++ b/library/std/src/os/net/linux_ext/addr.rs @@ -0,0 +1,64 @@ +//! Linux and Android-specific extensions to socket addresses. + +use crate::os::unix::net::SocketAddr; +use crate::sealed::Sealed; + +/// Platform-specific extensions to [`SocketAddr`]. +#[unstable(feature = "unix_socket_abstract", issue = "85410")] +pub trait SocketAddrExt: Sealed { + /// Creates a Unix socket address in the abstract namespace. + /// + /// The abstract namespace is a Linux-specific extension that allows Unix + /// sockets to be bound without creating an entry in the filesystem. + /// Abstract sockets are unaffected by filesystem layout or permissions, + /// and no cleanup is necessary when the socket is closed. + /// + /// An abstract socket address name may contain any bytes, including zero. + /// + /// # Errors + /// + /// Returns an error if the name is longer than `SUN_LEN - 1`. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(unix_socket_abstract)] + /// use std::os::unix::net::{UnixListener, SocketAddr}; + /// use std::os::linux::net::SocketAddrExt; + /// + /// fn main() -> std::io::Result<()> { + /// let addr = SocketAddr::from_abstract_name(b"hidden")?; + /// let listener = match UnixListener::bind_addr(&addr) { + /// Ok(sock) => sock, + /// Err(err) => { + /// println!("Couldn't bind: {err:?}"); + /// return Err(err); + /// } + /// }; + /// Ok(()) + /// } + /// ``` + fn from_abstract_name(name: &N) -> crate::io::Result + where + N: AsRef<[u8]>; + + /// Returns the contents of this address if it is in the abstract namespace. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(unix_socket_abstract)] + /// use std::os::unix::net::{UnixListener, SocketAddr}; + /// use std::os::linux::net::SocketAddrExt; + /// + /// fn main() -> std::io::Result<()> { + /// let name = b"hidden"; + /// let name_addr = SocketAddr::from_abstract_name(name)?; + /// let socket = UnixListener::bind_addr(&name_addr)?; + /// let local_addr = socket.local_addr().expect("Couldn't get local address"); + /// assert_eq!(local_addr.as_abstract_name(), Some(&name[..])); + /// Ok(()) + /// } + /// ``` + fn as_abstract_name(&self) -> Option<&[u8]>; +} diff --git a/library/std/src/os/net/linux_ext/mod.rs b/library/std/src/os/net/linux_ext/mod.rs new file mode 100644 index 000000000..318ebacfd --- /dev/null +++ b/library/std/src/os/net/linux_ext/mod.rs @@ -0,0 +1,12 @@ +//! Linux and Android-specific networking functionality. + +#![doc(cfg(any(target_os = "linux", target_os = "android")))] + +#[unstable(feature = "unix_socket_abstract", issue = "85410")] +pub(crate) mod addr; + +#[unstable(feature = "tcp_quickack", issue = "96256")] +pub(crate) mod tcp; + +#[cfg(test)] +mod tests; diff --git a/library/std/src/os/net/linux_ext/tcp.rs b/library/std/src/os/net/linux_ext/tcp.rs new file mode 100644 index 000000000..5e9ee65a4 --- /dev/null +++ b/library/std/src/os/net/linux_ext/tcp.rs @@ -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; +} + +#[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 { + self.as_inner().as_inner().quickack() + } +} diff --git a/library/std/src/os/net/linux_ext/tests.rs b/library/std/src/os/net/linux_ext/tests.rs new file mode 100644 index 000000000..2db4deed0 --- /dev/null +++ b/library/std/src/os/net/linux_ext/tests.rs @@ -0,0 +1,28 @@ +#[test] +fn quickack() { + use crate::{ + net::{test::next_test_ip4, TcpListener, TcpStream}, + os::net::linux_ext::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())); +} -- cgit v1.2.3