Skip to content

Commit bbe8464

Browse files
authored
Support processing ancillary outside rustix infrastructure (#1008)
Signed-off-by: Alex Saveau <[email protected]>
1 parent 436daee commit bbe8464

File tree

1 file changed

+37
-32
lines changed

1 file changed

+37
-32
lines changed

src/net/send_recv/msg.rs

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,7 @@ impl<'buf> RecvAncillaryBuffer<'buf> {
440440
pub fn drain(&mut self) -> AncillaryDrain<'_> {
441441
AncillaryDrain {
442442
messages: messages::Messages::new(&mut self.buffer[self.read..][..self.length]),
443-
read: &mut self.read,
444-
length: &mut self.length,
443+
read_and_length: Some((&mut self.read, &mut self.length)),
445444
}
446445
}
447446
}
@@ -474,25 +473,40 @@ pub struct AncillaryDrain<'buf> {
474473
messages: messages::Messages<'buf>,
475474

476475
/// Increment the number of messages we've read.
477-
read: &'buf mut usize,
478-
479476
/// Decrement the total length.
480-
length: &'buf mut usize,
477+
read_and_length: Option<(&'buf mut usize, &'buf mut usize)>,
481478
}
482479

483480
impl<'buf> AncillaryDrain<'buf> {
484-
/// A closure that converts a message into a [`RecvAncillaryMessage`].
485-
fn cvt_msg(
486-
read: &mut usize,
487-
length: &mut usize,
481+
/// Create an iterator for control messages that were received without [`RecvAncillaryBuffer`].
482+
///
483+
/// # Safety
484+
///
485+
/// The buffer must contain valid message data (or be empty).
486+
pub unsafe fn parse(buffer: &'buf mut [u8]) -> Self {
487+
Self {
488+
messages: messages::Messages::new(buffer),
489+
read_and_length: None,
490+
}
491+
}
492+
493+
fn advance(
494+
read_and_length: &mut Option<(&'buf mut usize, &'buf mut usize)>,
488495
msg: &c::cmsghdr,
489496
) -> Option<RecvAncillaryMessage<'buf>> {
490-
unsafe {
491-
// Advance the `read` pointer.
497+
// Advance the `read` pointer.
498+
if let Some((read, length)) = read_and_length {
492499
let msg_len = msg.cmsg_len as usize;
493-
*read += msg_len;
494-
*length -= msg_len;
500+
**read += msg_len;
501+
**length -= msg_len;
502+
}
503+
504+
Self::cvt_msg(msg)
505+
}
495506

507+
/// A closure that converts a message into a [`RecvAncillaryMessage`].
508+
fn cvt_msg(msg: &c::cmsghdr) -> Option<RecvAncillaryMessage<'buf>> {
509+
unsafe {
496510
// Get a pointer to the payload.
497511
let payload = c::CMSG_DATA(msg);
498512
let payload_len = msg.cmsg_len as usize - c::CMSG_LEN(0) as usize;
@@ -528,55 +542,46 @@ impl<'buf> Iterator for AncillaryDrain<'buf> {
528542
type Item = RecvAncillaryMessage<'buf>;
529543

530544
fn next(&mut self) -> Option<Self::Item> {
531-
let read = &mut self.read;
532-
let length = &mut self.length;
533-
self.messages.find_map(|ev| Self::cvt_msg(read, length, ev))
545+
self.messages
546+
.find_map(|ev| Self::advance(&mut self.read_and_length, ev))
534547
}
535548

536549
fn size_hint(&self) -> (usize, Option<usize>) {
537550
let (_, max) = self.messages.size_hint();
538551
(0, max)
539552
}
540553

541-
fn fold<B, F>(self, init: B, f: F) -> B
554+
fn fold<B, F>(mut self, init: B, f: F) -> B
542555
where
543556
Self: Sized,
544557
F: FnMut(B, Self::Item) -> B,
545558
{
546-
let read = self.read;
547-
let length = self.length;
548559
self.messages
549-
.filter_map(|ev| Self::cvt_msg(read, length, ev))
560+
.filter_map(|ev| Self::advance(&mut self.read_and_length, ev))
550561
.fold(init, f)
551562
}
552563

553-
fn count(self) -> usize {
554-
let read = self.read;
555-
let length = self.length;
564+
fn count(mut self) -> usize {
556565
self.messages
557-
.filter_map(|ev| Self::cvt_msg(read, length, ev))
566+
.filter_map(|ev| Self::advance(&mut self.read_and_length, ev))
558567
.count()
559568
}
560569

561-
fn last(self) -> Option<Self::Item>
570+
fn last(mut self) -> Option<Self::Item>
562571
where
563572
Self: Sized,
564573
{
565-
let read = self.read;
566-
let length = self.length;
567574
self.messages
568-
.filter_map(|ev| Self::cvt_msg(read, length, ev))
575+
.filter_map(|ev| Self::advance(&mut self.read_and_length, ev))
569576
.last()
570577
}
571578

572-
fn collect<B: FromIterator<Self::Item>>(self) -> B
579+
fn collect<B: FromIterator<Self::Item>>(mut self) -> B
573580
where
574581
Self: Sized,
575582
{
576-
let read = self.read;
577-
let length = self.length;
578583
self.messages
579-
.filter_map(|ev| Self::cvt_msg(read, length, ev))
584+
.filter_map(|ev| Self::advance(&mut self.read_and_length, ev))
580585
.collect()
581586
}
582587
}

0 commit comments

Comments
 (0)