From 6e81ba0777b2ba8f4fc2193a40b9bfdbe0c4c127 Mon Sep 17 00:00:00 2001 From: beroal Date: Sat, 28 Aug 2021 17:53:36 +0300 Subject: [PATCH 1/2] ancillary data size and doc improvement --- library/std/src/os/unix/net/ancillary.rs | 61 +++++++++++++++++++++--- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs index 1f9d42812ecc7..97a9f8395718c 100644 --- a/library/std/src/os/unix/net/ancillary.rs +++ b/library/std/src/os/unix/net/ancillary.rs @@ -78,6 +78,36 @@ pub(super) fn send_vectored_with_ancillary_to( } } +/// The size in octets of a control message containing `n` `T`s. +/// +/// # Panics +/// +/// If the size is so large that it causes arithmetic overflow. +fn ancillary_size_data(n: usize) -> u32 { + let r = u32::try_from(n.checked_mul(size_of::()).unwrap()).unwrap(); + unsafe { libc::CMSG_SPACE(r) } +} + +/// The size in octets of a control message containing `n` file descriptors. +/// +/// # Panics +/// +/// If the size is so large that it causes arithmetic overflow. +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub fn ancillary_size_fds(n: usize) -> u32 { + ancillary_size_data::(n) +} + +/// The size in octets of a control message containing `n` unix credentials. +/// +/// # Panics +/// +/// If the size is so large that it causes arithmetic overflow. +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub fn ancillary_size_creds(n: usize) -> u32 { + ancillary_size_data::(n) +} + fn add_to_ancillary_data( buffer: &mut [u8], length: &mut usize, @@ -369,7 +399,19 @@ impl<'a> Iterator for Messages<'a> { } } -/// A Unix socket Ancillary data struct. +/// A struct for accessing a Unix socket ancillary data packet. +/// +/// An *ancillary data* (also known as *control data*) *packet* may be attached +/// to a usual *data segment* transferred through a Unix socket. +/// See [“2.10.11 Socket Receive Queue”](https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_10_11) +/// in POSIX for details. An ancillary data packet is a list of *ancillary data objects* +/// (also known as *control messages*). +/// Here an ancillary data packet is represented by a [`SocketAncillary`] and a control message +/// (see `struct cmsghdr` in the C API) is represented by an [`AncillaryData`]. +/// The C API for ancillary data: +/// +/// - [`sys/socket.h`](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html) +/// - [`cmsg`(3)](https://man7.org/linux/man-pages/man3/cmsg.3.html) /// /// # Example /// ```no_run @@ -407,7 +449,13 @@ pub struct SocketAncillary<'a> { } impl<'a> SocketAncillary<'a> { - /// Create an ancillary data with the given buffer. + /// Create a struct for accessing an ancillary data packet in `buffer`. + /// This ancillary data packet will be empty. + /// The result won't own the ancillary data and will read them from + /// and write them into `buffer`. Obviously, this buffer isn't extensible. + /// In order to ensure that there is enough space in `buffer` when adding control messages, + /// provide `buffer` whose size is at least the sum of the sizes of these control messages + /// (see [`ancillary_size_fds`] and [`ancillary_size_creds`]). /// /// # Example /// @@ -418,6 +466,7 @@ impl<'a> SocketAncillary<'a> { /// let mut ancillary_buffer = [0; 128]; /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); /// ``` + // FIXME: add size example #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub fn new(buffer: &'a mut [u8]) -> Self { SocketAncillary { buffer, length: 0, truncated: false } @@ -475,10 +524,10 @@ impl<'a> SocketAncillary<'a> { self.truncated } - /// Add file descriptors to the ancillary data. + /// Add one control message containing file descriptors to the ancillary data. /// /// The function returns `true` if there was enough space in the buffer. - /// If there was not enough space then no file descriptors was appended. + /// If there was not enough space then no control message was appended. /// Technically, that means this operation adds a control message with the level `SOL_SOCKET` /// and type `SCM_RIGHTS`. /// @@ -515,10 +564,10 @@ impl<'a> SocketAncillary<'a> { ) } - /// Add credentials to the ancillary data. + /// Add one control message containing credentials to the ancillary data. /// /// The function returns `true` if there was enough space in the buffer. - /// If there was not enough space then no credentials was appended. + /// If there was not enough space then no control message was appended. /// Technically, that means this operation adds a control message with the level `SOL_SOCKET` /// and type `SCM_CREDENTIALS` or `SCM_CREDS`. /// From 5dbca75f2826c729877d19355ea3576e143825bd Mon Sep 17 00:00:00 2001 From: beroal Date: Sat, 28 Aug 2021 20:09:16 +0300 Subject: [PATCH 2/2] generic ancillary data size function; delete Unix; delete obvious --- library/std/src/os/unix/net/ancillary.rs | 37 +++++++----------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs index 97a9f8395718c..39ce453f24f93 100644 --- a/library/std/src/os/unix/net/ancillary.rs +++ b/library/std/src/os/unix/net/ancillary.rs @@ -79,33 +79,18 @@ pub(super) fn send_vectored_with_ancillary_to( } /// The size in octets of a control message containing `n` `T`s. +/// `T` must be one of: /// -/// # Panics -/// -/// If the size is so large that it causes arithmetic overflow. -fn ancillary_size_data(n: usize) -> u32 { - let r = u32::try_from(n.checked_mul(size_of::()).unwrap()).unwrap(); - unsafe { libc::CMSG_SPACE(r) } -} - -/// The size in octets of a control message containing `n` file descriptors. -/// -/// # Panics -/// -/// If the size is so large that it causes arithmetic overflow. -#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] -pub fn ancillary_size_fds(n: usize) -> u32 { - ancillary_size_data::(n) -} - -/// The size in octets of a control message containing `n` unix credentials. +/// - [`RawFd`] (file descriptor) +/// - [`SocketCred`] (Unix credentials) /// /// # Panics /// /// If the size is so large that it causes arithmetic overflow. #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] -pub fn ancillary_size_creds(n: usize) -> u32 { - ancillary_size_data::(n) +pub fn ancillary_data_size(n: usize) -> usize { + let r = u32::try_from(n.checked_mul(size_of::()).unwrap()).unwrap(); + unsafe { libc::CMSG_SPACE(r) as usize } } fn add_to_ancillary_data( @@ -399,10 +384,10 @@ impl<'a> Iterator for Messages<'a> { } } -/// A struct for accessing a Unix socket ancillary data packet. +/// A struct for accessing a socket ancillary data packet. /// /// An *ancillary data* (also known as *control data*) *packet* may be attached -/// to a usual *data segment* transferred through a Unix socket. +/// to a usual *data segment* transferred through a socket. /// See [“2.10.11 Socket Receive Queue”](https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_10_11) /// in POSIX for details. An ancillary data packet is a list of *ancillary data objects* /// (also known as *control messages*). @@ -451,11 +436,11 @@ pub struct SocketAncillary<'a> { impl<'a> SocketAncillary<'a> { /// Create a struct for accessing an ancillary data packet in `buffer`. /// This ancillary data packet will be empty. - /// The result won't own the ancillary data and will read them from - /// and write them into `buffer`. Obviously, this buffer isn't extensible. + /// The result won't own the ancillary data and will read them from `buffer` + /// and write them into `buffer`. /// In order to ensure that there is enough space in `buffer` when adding control messages, /// provide `buffer` whose size is at least the sum of the sizes of these control messages - /// (see [`ancillary_size_fds`] and [`ancillary_size_creds`]). + /// (see [`ancillary_data_size`]). /// /// # Example ///