From 1e3e03a47b73966c68a4585b5ecbc7f4efb66b34 Mon Sep 17 00:00:00 2001 From: Evan Brass Date: Tue, 8 Jul 2025 15:14:38 -0700 Subject: [PATCH 1/2] Add a borrowing cmsg api This is mainly to support implementing custom control messages. --- src/sys/socket/mod.rs | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 30c4e0a082..bb60316a17 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -725,19 +725,43 @@ impl Iterator for CmsgIterator<'_> { type Item = ControlMessageOwned; fn next(&mut self) -> Option { - match self.cmsghdr { + match self.next_raw() { None => None, // No more messages - Some(hdr) => { + Some((hdr, _)) => { // Get the data. // Safe if cmsghdr points to valid data returned by recvmsg(2) - let cm = unsafe { Some(ControlMessageOwned::decode_from(hdr))}; + unsafe { Some(ControlMessageOwned::decode_from(hdr))} + } + } + } +} + +impl CmsgIterator<'_> { + pub fn next_raw(&mut self) -> Option<(&cmsghdr, &[u8])> { + match self.cmsghdr { + None => None, // No more messages + Some(header) => { + // Get the data. + let p = unsafe { CMSG_DATA(header) }; + + // Determine the length of the control message data + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + let len = header as *const _ as usize + header.cmsg_len as usize + - p as usize; + + // Read the value as a slice (This slice is the same one that ControlMessageOwned::Unknown copies) + let value = unsafe { core::slice::from_raw_parts(p, len) }; + // Advance the internal pointer. Safe if mhdr and cmsghdr point // to valid data returned by recvmsg(2) self.cmsghdr = unsafe { - let p = CMSG_NXTHDR(self.mhdr as *const _, hdr as *const _); + let p = CMSG_NXTHDR(self.mhdr as *const _, header as *const _); p.as_ref() }; - cm + + // Return the header and data + Some((header, value)) } } } From 10c04451984d6e6f934d19bda10e30ddbd454d00 Mon Sep 17 00:00:00 2001 From: Evan Brass Date: Wed, 9 Jul 2025 12:14:22 -0700 Subject: [PATCH 2/2] use map --- src/sys/socket/mod.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index bb60316a17..4af588d770 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -725,14 +725,8 @@ impl Iterator for CmsgIterator<'_> { type Item = ControlMessageOwned; fn next(&mut self) -> Option { - match self.next_raw() { - None => None, // No more messages - Some((hdr, _)) => { - // Get the data. - // Safe if cmsghdr points to valid data returned by recvmsg(2) - unsafe { Some(ControlMessageOwned::decode_from(hdr))} - } - } + // Safe if cmsghdr points to valid data returned by recvmsg(2) + self.next_raw().map(|(hdr, _)| unsafe { ControlMessageOwned::decode_from(hdr) }) } }