From 51d4dede151abf7c2fbfd249d32b319db71d72a7 Mon Sep 17 00:00:00 2001 From: Philipp Dresselmann Date: Fri, 13 Dec 2024 18:26:09 +0100 Subject: [PATCH 1/4] chore(doc): Add a link to the MIO utils module summary --- util/src/lib.rs | 2 +- util/src/mio/mio.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/util/src/lib.rs b/util/src/lib.rs index ca65b47..66d2387 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -22,7 +22,7 @@ pub mod io; pub mod length_prefix_encoding; /// Memory manipulation and allocation utilities. pub mod mem; -/// MIO integration utilities. +/// [MIO (Metal I/O)](https://docs.rs/crate/mio/) integration utilities. pub mod mio; /// Extended Option type functionality. pub mod option; diff --git a/util/src/mio/mio.rs b/util/src/mio/mio.rs index 1df9310..a228e80 100644 --- a/util/src/mio/mio.rs +++ b/util/src/mio/mio.rs @@ -6,7 +6,7 @@ use crate::{ result::OkExt, }; -/// Module containing I/O interest flags for Unix operations +/// Module containing I/O interest flags for Unix operations (see also: [mio::Interest]) pub mod interest { use mio::Interest; From db8796ab408ceae9aaffed303112175c28700df0 Mon Sep 17 00:00:00 2001 From: Philipp Dresselmann Date: Fri, 13 Dec 2024 21:59:54 +0100 Subject: [PATCH 2/4] chore(docs): Add an example for the uds_recv_fd module --- util/src/mio/uds_recv_fd.rs | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/util/src/mio/uds_recv_fd.rs b/util/src/mio/uds_recv_fd.rs index 834b10c..8cba2a3 100644 --- a/util/src/mio/uds_recv_fd.rs +++ b/util/src/mio/uds_recv_fd.rs @@ -12,6 +12,58 @@ use crate::fd::{claim_fd_inplace, IntoStdioErr}; /// A wrapper around a socket that combines reading from the socket with tracking /// received file descriptors. Limits the maximum number of file descriptors that /// can be received in a single read operation via the `MAX_FDS` parameter. +/// +/// # Example +/// +/// ```rust +/// use std::collections::VecDeque; +/// use std::io::Cursor; +/// use std::io::Read; +/// use std::os::fd::AsRawFd; +/// use std::os::fd::OwnedFd; +/// +/// use mio::net::UnixStream; +/// use rosenpass_util::mio::ReadWithFileDescriptors; +/// use rosenpass_util::io::TryIoResultKindHintExt; +/// +/// const MAX_REQUEST_FDS : usize = 2; // Limit to 2 descriptors per read operation +/// let mut read_fd_buffer = VecDeque::::new(); // File descriptor queue +/// +/// // In this case, the unused writable end of the connection can be ignored +/// let (io_stream, _) = UnixStream::pair().expect("failed to create socket pair"); +/// +/// // Wait until the output stream is writable... +/// +/// // Wrap the socket to start tracking received file descriptors +/// let mut fd_passing_sock = ReadWithFileDescriptors::::new( +/// &io_stream, +/// &mut read_fd_buffer, +/// ); +//// +/// // Simulated reads; the actual operations will depend on the protocol (implementation details) +/// let mut recv_buffer = Vec::::new(); +/// let bytes_read = fd_passing_sock.read(&mut recv_buffer[..]).expect("error reading from socket"); +/// assert_eq!(bytes_read, 0); +/// assert_eq!(&recv_buffer[..bytes_read], []); +/// +/// // Alternatively, it's possible to use the try_io_err_kind_hint utility provided by this crate +/// match fd_passing_sock.read(&mut recv_buffer).try_io_err_kind_hint() { +/// Err(_) => { +/// // Handle errors here ... +/// } +/// Ok(result) => { +/// // Process messages here ... +/// assert_eq!(0, result); // Nothing to read in this example +/// } +/// }; +/// +/// // The wrapped components can still be accessed +/// assert_eq!(fd_passing_sock.socket().as_raw_fd(), io_stream.as_raw_fd()); +/// let (socket, fd_queue) = fd_passing_sock.into_parts(); +/// assert_eq!(socket.as_raw_fd(), io_stream.as_raw_fd()); +/// +/// // Shutdown, cleanup, etc. goes here ... +/// ``` pub struct ReadWithFileDescriptors where Sock: FdPassingExt, From ea233bf137fd998099533fc562eaed6a5280b123 Mon Sep 17 00:00:00 2001 From: Philipp Dresselmann Date: Mon, 16 Dec 2024 22:28:21 +0100 Subject: [PATCH 3/4] chore(docs): Add an example for the UnixListenerExt trait --- util/src/mio/mio.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/util/src/mio/mio.rs b/util/src/mio/mio.rs index a228e80..d8bdc70 100644 --- a/util/src/mio/mio.rs +++ b/util/src/mio/mio.rs @@ -21,6 +21,44 @@ pub mod interest { } /// Extension trait providing additional functionality for Unix listener +/// +/// # Example +/// +/// ```rust +/// use mio::net::{UnixListener, UnixStream}; +/// use rosenpass_util::mio::{UnixListenerExt, UnixStreamExt}; +/// +/// use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; +/// use std::path::Path; +/// +/// // This would be the UDS created by an external source +/// let socket_path = "/tmp/rp_mio_uds_test_socket"; +/// if Path::new(socket_path).exists() { +/// std::fs::remove_file(socket_path).expect("Failed to remove existing socket"); +/// } +/// +/// // An extended MIO listener can then be created by claiming the existing socket +/// // Note that the original descriptor is not reused, but copied before claiming it here +/// let listener = UnixListener::bind(socket_path).unwrap(); +/// let listener_fd: RawFd = listener.as_raw_fd(); +/// let ext_listener = +/// ::claim_fd(listener_fd).expect("Failed to claim_fd for ext_listener socket"); +/// +/// // Similarly, "client" connections can be established by claiming existing sockets +/// // Note that in this case, the file descriptor will be reused (safety implications!) +/// let stream = UnixStream::connect(socket_path).unwrap(); +/// let stream_fd = stream.into_raw_fd(); +/// let ext_stream = +/// ::claim_fd_inplace(stream_fd).expect("Failed to claim_fd_inplace for ext_stream socket"); +/// +/// // Handle accepted connections... +/// ext_listener.accept().expect("Failed to accept incoming connection"); +/// +/// // Send or receive messages ... +/// +/// // Cleanup, shutdown etc. goes here ... +/// std::fs::remove_file(socket_path).unwrap(); +/// ``` pub trait UnixListenerExt: Sized { /// Creates a new Unix listener by claiming ownership of a raw file descriptor fn claim_fd(fd: RawFd) -> anyhow::Result; From a537eb3e1b7372c791b91f1083e7ba549fa4dc95 Mon Sep 17 00:00:00 2001 From: Philipp Dresselmann Date: Mon, 16 Dec 2024 22:28:07 +0100 Subject: [PATCH 4/4] chore(docs): Adjust docstrings for the mio module --- util/src/mio/mio.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/util/src/mio/mio.rs b/util/src/mio/mio.rs index d8bdc70..97c724b 100644 --- a/util/src/mio/mio.rs +++ b/util/src/mio/mio.rs @@ -20,7 +20,7 @@ pub mod interest { pub const RW: Interest = R.add(W); } -/// Extension trait providing additional functionality for Unix listener +/// Extension trait providing additional functionality for a Unix listener /// /// # Example /// @@ -61,6 +61,7 @@ pub mod interest { /// ``` pub trait UnixListenerExt: Sized { /// Creates a new Unix listener by claiming ownership of a raw file descriptor + /// (see [fd::claim_fd](crate::fd::claim_fd)) fn claim_fd(fd: RawFd) -> anyhow::Result; } @@ -74,15 +75,17 @@ impl UnixListenerExt for UnixListener { } } -/// Extension trait providing additional functionality for Unix streams +/// Extension trait providing additional functionality for a Unix stream pub trait UnixStreamExt: Sized { /// Creates a new Unix stream from an owned file descriptor fn from_fd(fd: OwnedFd) -> anyhow::Result; /// Claims ownership of a raw file descriptor and creates a new Unix stream + /// (see [fd::claim_fd](crate::fd::claim_fd)) fn claim_fd(fd: RawFd) -> anyhow::Result; /// Claims ownership of a raw file descriptor in place and creates a new Unix stream + /// (see [fd::claim_fd_inplace](crate::fd::claim_fd_inplace)) fn claim_fd_inplace(fd: RawFd) -> anyhow::Result; }