packet/
records.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Utilities for parsing and serializing sequential records.
6//!
7//! This module provides utilities for parsing and serializing repeated,
8//! sequential records. Examples of packet formats which include such records
9//! include IPv4, IPv6, TCP, NDP, and IGMP.
10//!
11//! The utilities in this module are very flexible and generic. The user must
12//! supply a number of details about the format in order for parsing and
13//! serializing to work.
14//!
15//! Some packet formats use a [type-length-value]-like encoding for options.
16//! Examples include IPv4, TCP, and NDP options. Special support for these
17//! formats is provided by the [`options`] submodule.
18//!
19//! [type-length-value]: https://en.wikipedia.org/wiki/Type-length-value
20
21use core::borrow::Borrow;
22use core::convert::Infallible as Never;
23use core::marker::PhantomData;
24use core::num::NonZeroUsize;
25use core::ops::Deref;
26
27use zerocopy::{ByteSlice, IntoByteSlice, SplitByteSlice};
28
29use crate::serialize::InnerPacketBuilder;
30use crate::util::{FromRaw, MaybeParsed};
31use crate::{BufferView, BufferViewMut, SplitByteSliceBufView};
32
33/// A type that encapsuates the result of a record parsing operation.
34pub type RecordParseResult<T, E> = core::result::Result<ParsedRecord<T>, E>;
35
36/// A type that encapsulates the successful result of a parsing operation.
37pub enum ParsedRecord<T> {
38    /// A record was successfully consumed and parsed.
39    Parsed(T),
40
41    /// A record was consumed but not parsed for non-fatal reasons.
42    ///
43    /// The caller should attempt to parse the next record to get a successfully
44    /// parsed record.
45    ///
46    /// An example of a record that is skippable is a record used for padding.
47    Skipped,
48
49    /// All possible records have been already been consumed; there is nothing
50    /// left to parse.
51    ///
52    /// The behavior is unspecified if callers attempt to parse another record.
53    Done,
54}
55
56impl<T> ParsedRecord<T> {
57    /// Does this result indicate that a record was consumed?
58    ///
59    /// Returns `true` for `Parsed` and `Skipped` and `false` for `Done`.
60    pub fn consumed(&self) -> bool {
61        match self {
62            ParsedRecord::Parsed(_) | ParsedRecord::Skipped => true,
63            ParsedRecord::Done => false,
64        }
65    }
66}
67
68/// A type that encapsulates the result of measuring the next record.
69pub enum MeasuredRecord {
70    /// A record was measured. This record may be skipped once it is actually parsed.
71    Measured(NonZeroUsize),
72    /// All possible records have been already been consumed; there is nothing
73    /// left to parse.
74    Done,
75}
76
77/// A parsed sequence of records.
78///
79/// `Records` represents a pre-parsed sequence of records whose structure is
80/// enforced by the impl in `R`.
81#[derive(Debug, PartialEq)]
82pub struct Records<B, R: RecordsImplLayout> {
83    bytes: B,
84    record_count: usize,
85    context: R::Context,
86}
87
88/// An unchecked sequence of records.
89///
90/// `RecordsRaw` represents a not-yet-parsed and not-yet-validated sequence of
91/// records, whose structure is enforced by the impl in `R`.
92///
93/// [`Records`] provides an implementation of [`FromRaw`] that can be used to
94/// validate a `RecordsRaw`.
95#[derive(Debug)]
96pub struct RecordsRaw<B, R: RecordsImplLayout> {
97    bytes: B,
98    context: R::Context,
99}
100
101impl<B, R> RecordsRaw<B, R>
102where
103    R: RecordsImplLayout<Context = ()>,
104{
105    /// Creates a new `RecordsRaw` with the data in `bytes`.
106    pub fn new(bytes: B) -> Self {
107        Self { bytes, context: () }
108    }
109}
110
111impl<B, R> RecordsRaw<B, R>
112where
113    R: for<'a> RecordsRawImpl<'a>,
114    B: SplitByteSlice,
115{
116    /// Raw-parses a sequence of records with a context.
117    ///
118    /// See [`RecordsRaw::parse_raw_with_mut_context`] for details on `bytes`,
119    /// `context`, and return value. `parse_raw_with_context` just calls
120    /// `parse_raw_with_mut_context` with a mutable reference to the `context`
121    /// which is passed by value to this function.
122    pub fn parse_raw_with_context<BV: BufferView<B>>(
123        bytes: &mut BV,
124        mut context: R::Context,
125    ) -> MaybeParsed<Self, (B, R::Error)> {
126        Self::parse_raw_with_mut_context(bytes, &mut context)
127    }
128
129    /// Raw-parses a sequence of records with a mutable context.
130    ///
131    /// `parse_raw_with_mut_context` shallowly parses `bytes` as a sequence of
132    /// records. `context` may be used by implementers to maintain state.
133    ///
134    /// `parse_raw_with_mut_context` performs a single pass over all of the
135    /// records to be able to find the end of the records list and update
136    /// `bytes` accordingly. Upon return with [`MaybeParsed::Complete`],
137    /// `bytes` will include only those bytes which are not part of the records
138    /// list. Upon return with [`MaybeParsed::Incomplete`], `bytes` will still
139    /// contain the bytes which could not be parsed, and all subsequent bytes.
140    pub fn parse_raw_with_mut_context<BV: BufferView<B>>(
141        bytes: &mut BV,
142        context: &mut R::Context,
143    ) -> MaybeParsed<Self, (B, R::Error)> {
144        let c = context.clone();
145        let mut b = SplitSliceBufferView::new(bytes.as_ref());
146        let r = loop {
147            match R::parse_raw_with_context(&mut b, context) {
148                Ok(true) => {} // continue consuming from data
149                Ok(false) => {
150                    break None;
151                }
152                Err(e) => {
153                    break Some(e);
154                }
155            }
156        };
157
158        // When we get here, we know that whatever is left in `b` is not needed
159        // so we only take the amount of bytes we actually need from `bytes`,
160        // leaving the rest alone for the caller to continue parsing with.
161        let bytes_len = bytes.len();
162        let b_len = b.as_ref().len();
163        let taken = bytes.take_front(bytes_len - b_len).unwrap();
164
165        match r {
166            Some(error) => MaybeParsed::Incomplete((taken, error)),
167            None => MaybeParsed::Complete(RecordsRaw { bytes: taken, context: c }),
168        }
169    }
170}
171
172impl<B, R> RecordsRaw<B, R>
173where
174    R: for<'a> RecordsRawImpl<'a> + RecordsImplLayout<Context = ()>,
175    B: SplitByteSlice,
176{
177    /// Raw-parses a sequence of records.
178    ///
179    /// Equivalent to calling [`RecordsRaw::parse_raw_with_context`] with
180    /// `context = ()`.
181    pub fn parse_raw<BV: BufferView<B>>(bytes: &mut BV) -> MaybeParsed<Self, (B, R::Error)> {
182        Self::parse_raw_with_context(bytes, ())
183    }
184}
185
186impl<B, R> Deref for RecordsRaw<B, R>
187where
188    B: SplitByteSlice,
189    R: RecordsImplLayout,
190{
191    type Target = [u8];
192
193    fn deref(&self) -> &[u8] {
194        self.bytes.deref()
195    }
196}
197
198impl<B: Deref<Target = [u8]>, R: RecordsImplLayout> RecordsRaw<B, R> {
199    /// Gets the underlying bytes.
200    ///
201    /// `bytes` returns a reference to the byte slice backing this `RecordsRaw`.
202    pub fn bytes(&self) -> &[u8] {
203        &self.bytes
204    }
205}
206
207/// An iterator over the records contained inside a [`Records`] instance.
208#[derive(Copy, Clone, Debug)]
209pub struct RecordsIter<'a, B, R: RecordsImpl> {
210    bytes: B,
211    records_left: usize,
212    context: R::Context,
213    _marker: PhantomData<&'a ()>,
214}
215
216/// An iterator over the records bytes contained inside a [`Records`] instance.
217#[derive(Copy, Clone, Debug)]
218pub struct RecordsBytesIter<'a, B, R: RecordsImpl> {
219    bytes: B,
220    context: R::Context,
221    _marker: PhantomData<&'a ()>,
222}
223
224/// The error returned when fewer records were found than expected.
225#[derive(Copy, Clone, Debug, PartialEq, Eq)]
226pub struct TooFewRecordsErr;
227
228/// A counter used to keep track of how many records are remaining to be parsed.
229///
230/// Some record sequence formats include an indication of how many records
231/// should be expected. For example, the [IGMPv3 Membership Report Message]
232/// includes a "Number of Group Records" field in its header which indicates how
233/// many Group Records are present following the header. A `RecordsCounter` is a
234/// type used by these protocols to keep track of how many records are remaining
235/// to be parsed. It is implemented for all unsigned numeric primitive types
236/// (`usize`, `u8`, `u16`, `u32`, `u64`, and `u128`). A no-op implementation
237/// which does not track the number of remaining records is provided for `()`.
238///
239/// [IGMPv3 Membership Report Message]: https://www.rfc-editor.org/rfc/rfc3376#section-4.2
240pub trait RecordsCounter: Sized {
241    /// The error returned from [`result_for_end_of_records`] when fewer records
242    /// were found than expected.
243    ///
244    /// Some formats which store the number of records out-of-band consider it
245    /// an error to provide fewer records than this out-of-band value.
246    /// `TooFewRecordsErr` is the error returned by
247    /// [`result_for_end_of_records`] when this condition is encountered. If the
248    /// number of records is not tracked (usually, when `Self = ()`) or if it is
249    /// not an error to provide fewer records than expected, it is recommended
250    /// that `TooFewRecordsErr` be set to an uninhabited type like [`Never`].
251    ///
252    /// [`result_for_end_of_records`]: RecordsCounter::result_for_end_of_records
253    type TooFewRecordsErr;
254
255    /// Gets the next lowest value unless the counter is already at 0.
256    ///
257    /// During parsing, this value will be queried prior to parsing a record. If
258    /// the counter has already reached zero (`next_lowest_value` returns
259    /// `None`), parsing will be terminated. If the counter has not yet reached
260    /// zero and a record is successfully parsed, the previous counter value
261    /// will be overwritten with the one provided by `next_lowest_value`. In
262    /// other words, the parsing logic will look something like the following
263    /// pseudocode:
264    ///
265    /// ```rust,ignore
266    /// let next = counter.next_lowest_value()?;
267    /// let record = parse()?;
268    /// *counter = next;
269    /// ```
270    ///
271    /// If `Self` is a type which does not impose a limit on the number of
272    /// records parsed (usually, `()`), `next_lowest_value` must always return
273    /// `Some`. The value contained in the `Some` is irrelevant - it will just
274    /// be written back verbatim after a record is successfully parsed.
275    fn next_lowest_value(&self) -> Option<Self>;
276
277    /// Gets a result which can be used to determine whether it is an error that
278    /// there are no more records left to parse.
279    ///
280    /// Some formats which store the number of records out-of-band consider it
281    /// an error to provide fewer records than this out-of-band value.
282    /// `result_for_end_of_records` is called when there are no more records
283    /// left to parse. If the counter is still at a non-zero value, and the
284    /// protocol considers this to be an error, `result_for_end_of_records`
285    /// should return an appropriate error. Otherwise, it should return
286    /// `Ok(())`.
287    fn result_for_end_of_records(&self) -> Result<(), Self::TooFewRecordsErr> {
288        Ok(())
289    }
290}
291
292/// The context kept while performing records parsing.
293///
294/// Types which implement `RecordsContext` can be used as the long-lived context
295/// which is kept during records parsing. This context allows parsers to keep
296/// running computations over the span of multiple records.
297pub trait RecordsContext: Sized + Clone {
298    /// A counter used to keep track of how many records are left to parse.
299    ///
300    /// See the documentation on [`RecordsCounter`] for more details.
301    type Counter: RecordsCounter;
302
303    /// Clones a context for iterator purposes.
304    ///
305    /// `clone_for_iter` is useful for cloning a context to be used by
306    /// [`RecordsIter`]. Since [`Records::parse_with_context`] will do a full
307    /// pass over all the records to check for errors, a `RecordsIter` should
308    /// never error. Therefore, instead of doing checks when iterating (if a
309    /// context was used for checks), a clone of a context can be made
310    /// specifically for iterator purposes that does not do checks (which may be
311    /// expensive).
312    ///
313    /// The default implementation of this method is equivalent to
314    /// [`Clone::clone`].
315    fn clone_for_iter(&self) -> Self {
316        self.clone()
317    }
318
319    /// Gets the counter mutably.
320    fn counter_mut(&mut self) -> &mut Self::Counter;
321}
322
323macro_rules! impl_records_counter_and_context_for_uxxx {
324    ($ty:ty) => {
325        impl RecordsCounter for $ty {
326            type TooFewRecordsErr = TooFewRecordsErr;
327
328            fn next_lowest_value(&self) -> Option<Self> {
329                self.checked_sub(1)
330            }
331
332            fn result_for_end_of_records(&self) -> Result<(), TooFewRecordsErr> {
333                if *self == 0 { Ok(()) } else { Err(TooFewRecordsErr) }
334            }
335        }
336
337        impl RecordsContext for $ty {
338            type Counter = $ty;
339
340            fn counter_mut(&mut self) -> &mut $ty {
341                self
342            }
343        }
344    };
345}
346
347impl_records_counter_and_context_for_uxxx!(usize);
348impl_records_counter_and_context_for_uxxx!(u128);
349impl_records_counter_and_context_for_uxxx!(u64);
350impl_records_counter_and_context_for_uxxx!(u32);
351impl_records_counter_and_context_for_uxxx!(u16);
352impl_records_counter_and_context_for_uxxx!(u8);
353
354impl RecordsCounter for () {
355    type TooFewRecordsErr = Never;
356
357    fn next_lowest_value(&self) -> Option<()> {
358        Some(())
359    }
360}
361
362impl RecordsContext for () {
363    type Counter = ();
364
365    fn counter_mut(&mut self) -> &mut () {
366        self
367    }
368}
369
370/// Basic associated types used by a [`RecordsImpl`].
371///
372/// This trait is kept separate from `RecordsImpl` so that the associated types
373/// do not depend on the lifetime parameter to `RecordsImpl`.
374pub trait RecordsImplLayout {
375    // TODO(https://github.com/rust-lang/rust/issues/29661): Give the `Context`
376    // type a default of `()`.
377
378    /// A context type that can be used to maintain state while parsing multiple
379    /// records.
380    type Context: RecordsContext;
381
382    /// The type of errors that may be returned by a call to
383    /// [`RecordsImpl::parse_with_context`].
384    type Error: From<
385        <<Self::Context as RecordsContext>::Counter as RecordsCounter>::TooFewRecordsErr,
386    >;
387}
388
389/// An implementation of a records parser.
390///
391/// `RecordsImpl` provides functions to parse sequential records. It is required
392///  in order to construct a [`Records`] or [`RecordsIter`].
393pub trait RecordsImpl: RecordsImplLayout {
394    /// The type of a single record; the output from the [`parse_with_context`]
395    /// function.
396    ///
397    /// For long or variable-length data, implementers are advised to make
398    /// `Record` a reference into the bytes passed to `parse_with_context`. Such
399    /// a reference will need to carry the lifetime `'a`, which is the same
400    /// lifetime that is passed to `parse_with_context`, and is also the
401    /// lifetime parameter to this trait.
402    ///
403    /// [`parse_with_context`]: RecordsImpl::parse_with_context
404    type Record<'a>;
405
406    /// Parses a record with some context.
407    ///
408    /// `parse_with_context` takes a variable-length `data` and a `context` to
409    /// maintain state.
410    ///
411    /// `data` may be empty. It is up to the implementer to handle an exhausted
412    /// `data`.
413    ///
414    /// When returning `Ok(ParsedRecord::Skipped)`, it's the implementer's
415    /// responsibility to consume the bytes of the record from `data`. If this
416    /// doesn't happen, then `parse_with_context` will be called repeatedly on
417    /// the same `data`, and the program will be stuck in an infinite loop. If
418    /// the implementation is unable to determine how many bytes to consume from
419    /// `data` in order to skip the record, `parse_with_context` must return
420    /// `Err`.
421    ///
422    /// `parse_with_context` must be deterministic, or else
423    /// [`Records::parse_with_context`] cannot guarantee that future iterations
424    /// will not produce errors (and thus panic).
425    fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
426        data: &mut BV,
427        context: &mut Self::Context,
428    ) -> RecordParseResult<Self::Record<'a>, Self::Error>;
429}
430
431/// Implemented for [`RecordsImpl`] instances that allow peeking at the length
432/// of the first record in the buffer.
433pub trait MeasureRecordsImpl: RecordsImpl {
434    /// Returns the length in bytes of the next record.
435    fn measure_next_record<'a, BV: BufferView<&'a [u8]>>(
436        data: &BV,
437        context: &mut Self::Context,
438    ) -> core::result::Result<MeasuredRecord, Self::Error>;
439}
440
441/// An implementation of a raw records parser.
442///
443/// `RecordsRawImpl` provides functions to raw-parse sequential records. It is
444/// required to construct a partially-parsed [`RecordsRaw`].
445///
446/// `RecordsRawImpl` is meant to perform little or no validation on each record
447/// it consumes. It is primarily used to be able to walk record sequences with
448/// unknown lengths.
449pub trait RecordsRawImpl<'a>: RecordsImplLayout {
450    /// Raw-parses a single record with some context.
451    ///
452    /// `parse_raw_with_context` takes a variable length `data` and a `context`
453    /// to maintain state, and returns `Ok(true)` if a record is successfully
454    /// consumed, `Ok(false)` if it is unable to parse more records, and
455    /// `Err(err)` if the `data` is malformed in any way.
456    ///
457    /// `data` may be empty. It is up to the implementer to handle an exhausted
458    /// `data`.
459    ///
460    /// It's the implementer's responsibility to consume exactly one record from
461    /// `data` when returning `Ok(_)`.
462    fn parse_raw_with_context<BV: BufferView<&'a [u8]>>(
463        data: &mut BV,
464        context: &mut Self::Context,
465    ) -> Result<bool, Self::Error>;
466}
467
468/// A builder capable of serializing a record.
469///
470/// Given `R: RecordBuilder`, an iterator of `R` can be used with a
471/// [`RecordSequenceBuilder`] to serialize a sequence of records.
472pub trait RecordBuilder {
473    /// Provides the serialized length of a record.
474    ///
475    /// Returns the total length, in bytes, of the serialized encoding of
476    /// `self`.
477    fn serialized_len(&self) -> usize;
478
479    /// Serializes `self` into a buffer.
480    ///
481    /// `data` will be exactly `self.serialized_len()` bytes long.
482    ///
483    /// # Panics
484    ///
485    /// May panic if `data` is not exactly `self.serialized_len()` bytes long.
486    fn serialize_into(&self, data: &mut [u8]);
487}
488
489/// A builder capable of serializing a record with an alignment requirement.
490///
491/// Given `R: AlignedRecordBuilder`, an iterator of `R` can be used with an
492/// [`AlignedRecordSequenceBuilder`] to serialize a sequence of aligned records.
493pub trait AlignedRecordBuilder: RecordBuilder {
494    /// Returns the alignment requirement of `self`.
495    ///
496    /// The alignment requirement is returned as `(x, y)`, which means that the
497    /// record must be aligned at  `x * n + y` bytes from the beginning of the
498    /// records sequence for some non-negative `n`.
499    ///
500    /// It is guaranteed that `x > 0` and that `x > y`.
501    fn alignment_requirement(&self) -> (usize, usize);
502
503    /// Serializes the padding between subsequent aligned records.
504    ///
505    /// Some formats require that padding bytes have particular content. This
506    /// function serializes padding bytes as required by the format.
507    fn serialize_padding(buf: &mut [u8], length: usize);
508}
509
510/// A builder capable of serializing a sequence of records.
511///
512/// A `RecordSequenceBuilder` is instantiated with an [`Iterator`] that provides
513/// [`RecordBuilder`]s to be serialized. The item produced by the iterator can
514/// be any type which implements `Borrow<R>` for `R: RecordBuilder`.
515///
516/// `RecordSequenceBuilder` implements [`InnerPacketBuilder`].
517#[derive(Debug, Clone)]
518pub struct RecordSequenceBuilder<R, I> {
519    records: I,
520    _marker: PhantomData<R>,
521}
522
523impl<R, I> RecordSequenceBuilder<R, I> {
524    /// Creates a new `RecordSequenceBuilder` with the given `records`.
525    ///
526    /// `records` must produce the same sequence of values from every iteration,
527    /// even if cloned. Serialization is typically performed with two passes on
528    /// `records`: one to calculate the total length in bytes (`serialized_len`)
529    /// and another one to serialize to a buffer (`serialize_into`). Violating
530    /// this rule may result in panics or malformed serialized record sequences.
531    pub fn new(records: I) -> Self {
532        Self { records, _marker: PhantomData }
533    }
534}
535
536impl<R, I> RecordSequenceBuilder<R, I>
537where
538    R: RecordBuilder,
539    I: Iterator + Clone,
540    I::Item: Borrow<R>,
541{
542    /// Returns the total length, in bytes, of the serialized encoding of the
543    /// records contained within `self`.
544    pub fn serialized_len(&self) -> usize {
545        self.records.clone().map(|r| r.borrow().serialized_len()).sum()
546    }
547
548    /// Serializes all the records contained within `self` into the given
549    /// buffer.
550    ///
551    /// # Panics
552    ///
553    /// `serialize_into` expects that `buffer` has enough bytes to serialize the
554    /// contained records (as obtained from `serialized_len`), otherwise it's
555    /// considered a violation of the API contract and the call may panic.
556    pub fn serialize_into(&self, buffer: &mut [u8]) {
557        let mut b = &mut &mut buffer[..];
558        for r in self.records.clone() {
559            // SECURITY: Take a zeroed buffer from b to prevent leaking
560            // information from packets previously stored in this buffer.
561            r.borrow().serialize_into(b.take_front_zero(r.borrow().serialized_len()).unwrap());
562        }
563    }
564
565    /// Returns a reference to the inner records of this builder.
566    pub fn records(&self) -> &I {
567        &self.records
568    }
569}
570
571impl<R, I> InnerPacketBuilder for RecordSequenceBuilder<R, I>
572where
573    R: RecordBuilder,
574    I: Iterator + Clone,
575    I::Item: Borrow<R>,
576{
577    fn bytes_len(&self) -> usize {
578        self.serialized_len()
579    }
580
581    fn serialize(&self, buffer: &mut [u8]) {
582        self.serialize_into(buffer)
583    }
584}
585
586/// A builder capable of serializing a sequence of aligned records.
587///
588/// An `AlignedRecordSequenceBuilder` is instantiated with an [`Iterator`] that
589/// provides [`AlignedRecordBuilder`]s to be serialized. The item produced by
590/// the iterator can be any type which implements `Borrow<R>` for `R:
591/// AlignedRecordBuilder`.
592///
593/// `AlignedRecordSequenceBuilder` implements [`InnerPacketBuilder`].
594#[derive(Debug, Clone)]
595pub struct AlignedRecordSequenceBuilder<R, I> {
596    start_pos: usize,
597    records: I,
598    _marker: PhantomData<R>,
599}
600
601impl<R, I> AlignedRecordSequenceBuilder<R, I> {
602    /// Creates a new `AlignedRecordSequenceBuilder` with given `records` and
603    /// `start_pos`.
604    ///
605    /// `records` must produce the same sequence of values from every iteration,
606    /// even if cloned. See [`RecordSequenceBuilder`] for more details.
607    ///
608    /// Alignment is calculated relative to the beginning of a virtual space of
609    /// bytes. If non-zero, `start_pos` instructs the serializer to consider the
610    /// buffer passed to [`serialize_into`] to start at the byte `start_pos`
611    /// within this virtual space, and to calculate alignment and padding
612    /// accordingly. For example, in the IPv6 Hop-by-Hop extension header, a
613    /// fixed header of two bytes precedes that extension header's options, but
614    /// alignment is calculated relative to the beginning of the extension
615    /// header, not relative to the beginning of the options. Thus, when
616    /// constructing an `AlignedRecordSequenceBuilder` to serialize those
617    /// options, `start_pos` would be 2.
618    ///
619    /// [`serialize_into`]: AlignedRecordSequenceBuilder::serialize_into
620    pub fn new(start_pos: usize, records: I) -> Self {
621        Self { start_pos, records, _marker: PhantomData }
622    }
623}
624
625impl<R, I> AlignedRecordSequenceBuilder<R, I>
626where
627    R: AlignedRecordBuilder,
628    I: Iterator + Clone,
629    I::Item: Borrow<R>,
630{
631    /// Returns the total length, in bytes, of the serialized records contained
632    /// within `self`.
633    ///
634    /// Note that this length includes all padding required to ensure that all
635    /// records satisfy their alignment requirements.
636    pub fn serialized_len(&self) -> usize {
637        let mut pos = self.start_pos;
638        self.records
639            .clone()
640            .map(|r| {
641                let (x, y) = r.borrow().alignment_requirement();
642                let new_pos = align_up_to(pos, x, y) + r.borrow().serialized_len();
643                let result = new_pos - pos;
644                pos = new_pos;
645                result
646            })
647            .sum()
648    }
649
650    /// Serializes all the records contained within `self` into the given
651    /// buffer.
652    ///
653    /// # Panics
654    ///
655    /// `serialize_into` expects that `buffer` has enough bytes to serialize the
656    /// contained records (as obtained from `serialized_len`), otherwise it's
657    /// considered a violation of the API contract and the call may panic.
658    pub fn serialize_into(&self, buffer: &mut [u8]) {
659        let mut b = &mut &mut buffer[..];
660        let mut pos = self.start_pos;
661        for r in self.records.clone() {
662            let (x, y) = r.borrow().alignment_requirement();
663            let aligned = align_up_to(pos, x, y);
664            let pad_len = aligned - pos;
665            let pad = b.take_front_zero(pad_len).unwrap();
666            R::serialize_padding(pad, pad_len);
667            pos = aligned;
668            // SECURITY: Take a zeroed buffer from b to prevent leaking
669            // information from packets previously stored in this buffer.
670            r.borrow().serialize_into(b.take_front_zero(r.borrow().serialized_len()).unwrap());
671            pos += r.borrow().serialized_len();
672        }
673        // we have to pad the containing header to 8-octet boundary.
674        let padding = b.take_rest_front_zero();
675        R::serialize_padding(padding, padding.len());
676    }
677}
678
679/// Returns the aligned offset which is at `x * n + y`.
680///
681/// # Panics
682///
683/// Panics if `x == 0` or `y >= x`.
684fn align_up_to(offset: usize, x: usize, y: usize) -> usize {
685    assert!(x != 0 && y < x);
686    // first add `x` to prevent overflow.
687    (offset + x - 1 - y) / x * x + y
688}
689
690impl<B, R> Records<B, R>
691where
692    B: SplitByteSlice,
693    R: RecordsImpl,
694{
695    /// Parses a sequence of records with a context.
696    ///
697    /// See [`parse_with_mut_context`] for details on `bytes`, `context`, and
698    /// return value. `parse_with_context` just calls `parse_with_mut_context`
699    /// with a mutable reference to the `context` which is passed by value to
700    /// this function.
701    ///
702    /// [`parse_with_mut_context`]: Records::parse_with_mut_context
703    pub fn parse_with_context(
704        bytes: B,
705        mut context: R::Context,
706    ) -> Result<Records<B, R>, R::Error> {
707        Self::parse_with_mut_context(bytes, &mut context)
708    }
709
710    /// Parses a sequence of records with a mutable context.
711    ///
712    /// `context` may be used by implementers to maintain state while parsing
713    /// multiple records.
714    ///
715    /// `parse_with_mut_context` performs a single pass over all of the records
716    /// to verify that they are well-formed. Once `parse_with_context` returns
717    /// successfully, the resulting `Records` can be used to construct
718    /// infallible iterators.
719    pub fn parse_with_mut_context(
720        bytes: B,
721        context: &mut R::Context,
722    ) -> Result<Records<B, R>, R::Error> {
723        // First, do a single pass over the bytes to detect any errors up front.
724        // Once this is done, since we have a reference to `bytes`, these bytes
725        // can't change out from under us, and so we can treat any iterator over
726        // these bytes as infallible. This makes a few assumptions, but none of
727        // them are that big of a deal. In all cases, breaking these assumptions
728        // would at worst result in a runtime panic.
729        // - B could return different bytes each time
730        // - R::parse could be non-deterministic
731        let c = context.clone();
732        let mut b = SplitSliceBufferView::new(bytes.as_ref());
733        let mut record_count = 0;
734        while next::<_, R>(&mut b, context)?.is_some() {
735            record_count += 1;
736        }
737        Ok(Records { bytes, record_count, context: c })
738    }
739}
740
741impl<B, R> Records<B, R>
742where
743    B: SplitByteSlice,
744    R: RecordsImpl<Context = ()>,
745{
746    /// Parses a sequence of records.
747    ///
748    /// Equivalent to calling [`parse_with_context`] with `context = ()`.
749    ///
750    /// [`parse_with_context`]: Records::parse_with_context
751    pub fn parse(bytes: B) -> Result<Records<B, R>, R::Error> {
752        Self::parse_with_context(bytes, ())
753    }
754}
755
756impl<B, R> FromRaw<RecordsRaw<B, R>, ()> for Records<B, R>
757where
758    R: RecordsImpl,
759    B: SplitByteSlice,
760{
761    type Error = R::Error;
762
763    fn try_from_raw_with(raw: RecordsRaw<B, R>, _args: ()) -> Result<Self, R::Error> {
764        Records::<B, R>::parse_with_context(raw.bytes, raw.context)
765    }
766}
767
768impl<B: Deref<Target = [u8]>, R> Records<B, R>
769where
770    R: RecordsImpl,
771{
772    /// Gets the underlying bytes.
773    ///
774    /// `bytes` returns a reference to the byte slice backing this `Records`.
775    pub fn bytes(&self) -> &[u8] {
776        &self.bytes
777    }
778}
779
780impl<B, R> Records<B, R>
781where
782    B: ByteSlice,
783    R: RecordsImpl,
784{
785    /// Returns the same records but coerces the backing `B` type to `&[u8]`.
786    pub fn as_ref(&self) -> Records<&[u8], R> {
787        let Self { bytes, record_count, context } = self;
788        Records { bytes: &*bytes, record_count: *record_count, context: context.clone() }
789    }
790}
791
792impl<'a, B, R> Records<B, R>
793where
794    B: 'a + SplitByteSlice,
795    R: RecordsImpl,
796{
797    /// Iterates over options.
798    ///
799    /// Since the records were validated in [`parse`], then so long as
800    /// [`R::parse_with_context`] is deterministic, the iterator is infallible.
801    ///
802    /// [`parse`]: Records::parse
803    /// [`R::parse_with_context`]: RecordsImpl::parse_with_context
804    pub fn iter(&'a self) -> RecordsIter<'a, &'a [u8], R> {
805        RecordsIter {
806            bytes: &self.bytes,
807            records_left: self.record_count,
808            context: self.context.clone_for_iter(),
809            _marker: PhantomData,
810        }
811    }
812
813    /// Iterates over byte slices corresponding to options.
814    ///
815    /// Since the records were validated in [`parse`], then so long as
816    /// [`R::parse_with_context`] is deterministic, the iterator is infallible.
817    /// Unrecognized record types will still be included as long as they don't
818    /// fail length validation, even if they would be skipped by the
819    /// [`RecordsIter`] returned by [`Records::iter`].
820    ///
821    /// [`parse`]: Records::parse
822    /// [`R::parse_with_context`]: RecordsImpl::parse_with_context
823    pub fn iter_bytes(&'a self) -> RecordsBytesIter<'a, &'a [u8], R> {
824        RecordsBytesIter {
825            bytes: &self.bytes,
826            context: self.context.clone_for_iter(),
827            _marker: PhantomData,
828        }
829    }
830}
831
832impl<'a, B, R> Records<B, R>
833where
834    B: SplitByteSlice + IntoByteSlice<'a>,
835    R: RecordsImpl,
836{
837    /// Iterates over options.
838    ///
839    /// Since the records were validated in [`parse`], then so long as
840    /// [`R::parse_with_context`] is deterministic, the iterator is infallible.
841    ///
842    /// [`parse`]: Records::parse
843    /// [`R::parse_with_context`]: RecordsImpl::parse_with_context
844    pub fn into_iter(self) -> RecordsIter<'a, B, R> {
845        RecordsIter {
846            bytes: self.bytes,
847            records_left: self.record_count,
848            context: self.context,
849            _marker: PhantomData,
850        }
851    }
852}
853
854impl<'a, B, R> RecordsIter<'a, B, R>
855where
856    R: RecordsImpl,
857{
858    /// Gets a reference to the context.
859    pub fn context(&self) -> &R::Context {
860        &self.context
861    }
862}
863
864impl<'a, B, R> Iterator for RecordsIter<'a, B, R>
865where
866    R: RecordsImpl,
867    B: SplitByteSlice + IntoByteSlice<'a>,
868{
869    type Item = R::Record<'a>;
870
871    fn next(&mut self) -> Option<R::Record<'a>> {
872        replace_with::replace_with_and(&mut self.bytes, |bytes| {
873            let mut bytes = SplitSliceBufferView::new(bytes);
874            // use match rather than expect because expect requires that Err: Debug
875            #[allow(clippy::match_wild_err_arm)]
876            let result = match next::<_, R>(&mut bytes, &mut self.context) {
877                Ok(o) => o,
878                Err(_) => panic!("already-validated options should not fail to parse"),
879            };
880            if result.is_some() {
881                self.records_left -= 1;
882            }
883            (bytes.into_inner(), result)
884        })
885    }
886
887    fn size_hint(&self) -> (usize, Option<usize>) {
888        (self.records_left, Some(self.records_left))
889    }
890}
891
892impl<'a, B, R> ExactSizeIterator for RecordsIter<'a, B, R>
893where
894    R: RecordsImpl,
895    B: SplitByteSlice + IntoByteSlice<'a>,
896{
897    fn len(&self) -> usize {
898        self.records_left
899    }
900}
901
902impl<'a, B, R> RecordsBytesIter<'a, B, R>
903where
904    R: RecordsImpl,
905{
906    /// Gets a reference to the context.
907    pub fn context(&self) -> &R::Context {
908        &self.context
909    }
910}
911
912impl<'a, B, R> Iterator for RecordsBytesIter<'a, B, R>
913where
914    R: MeasureRecordsImpl,
915    B: SplitByteSlice + IntoByteSlice<'a>,
916{
917    type Item = &'a [u8];
918
919    fn next(&mut self) -> Option<&'a [u8]> {
920        replace_with::replace_with_and(&mut self.bytes, |bytes| {
921            let mut bytes = SplitSliceBufferView::new(bytes);
922            // use match rather than expect because expect requires that Err: Debug
923            #[allow(clippy::match_wild_err_arm)]
924            let result = match next_bytes::<_, R>(&mut bytes, &mut self.context) {
925                Ok(o) => o,
926                Err(_) => panic!("already-validated options should not fail to parse"),
927            };
928            (bytes.into_inner(), result)
929        })
930    }
931}
932
933fn next_bytes<'a, BV, R>(
934    bytes: &mut BV,
935    context: &mut R::Context,
936) -> Result<Option<&'a [u8]>, R::Error>
937where
938    R: MeasureRecordsImpl,
939    BV: BufferView<&'a [u8]>,
940{
941    match R::measure_next_record(bytes, context)? {
942        MeasuredRecord::Measured(len) => {
943            let buf = bytes.take_front(len.get()).expect("should have already measured");
944            Ok(Some(buf))
945        }
946        MeasuredRecord::Done => Ok(None),
947    }
948}
949
950/// Gets the next entry for a set of sequential records in `bytes`.
951///
952/// On return, `bytes` will be pointing to the start of where a next record
953/// would be.
954fn next<'a, BV, R>(
955    bytes: &mut BV,
956    context: &mut R::Context,
957) -> Result<Option<R::Record<'a>>, R::Error>
958where
959    R: RecordsImpl,
960    BV: BufferView<&'a [u8]>,
961{
962    loop {
963        // If we're already at 0, don't attempt to parse any more records.
964        let next_lowest_counter_val = match context.counter_mut().next_lowest_value() {
965            Some(val) => val,
966            None => return Ok(None),
967        };
968        match R::parse_with_context(bytes, context)? {
969            ParsedRecord::Done => {
970                return context
971                    .counter_mut()
972                    .result_for_end_of_records()
973                    .map_err(Into::into)
974                    .map(|()| None);
975            }
976            ParsedRecord::Skipped => {}
977            ParsedRecord::Parsed(o) => {
978                *context.counter_mut() = next_lowest_counter_val;
979                return Ok(Some(o));
980            }
981        }
982    }
983}
984
985/// Like `SplitByteSliceBufferView`, but with a specialized
986/// `BufferView<&'a [u8]>` implementation.
987struct SplitSliceBufferView<B>(SplitByteSliceBufView<B>);
988
989impl<B> SplitSliceBufferView<B> {
990    fn new(buf: B) -> Self {
991        Self(SplitByteSliceBufView::new(buf))
992    }
993
994    fn into_inner(self) -> B {
995        let Self(buf) = self;
996        buf.into_inner()
997    }
998}
999
1000impl<B: SplitByteSlice> AsRef<[u8]> for SplitSliceBufferView<B> {
1001    fn as_ref(&self) -> &[u8] {
1002        self.0.as_ref()
1003    }
1004}
1005
1006impl<'a, B: SplitByteSlice + IntoByteSlice<'a>> BufferView<&'a [u8]> for SplitSliceBufferView<B> {
1007    fn take_front(&mut self, n: usize) -> Option<&'a [u8]> {
1008        self.0.take_front(n).map(IntoByteSlice::into_byte_slice)
1009    }
1010
1011    fn take_back(&mut self, n: usize) -> Option<&'a [u8]> {
1012        self.0.take_back(n).map(IntoByteSlice::into_byte_slice)
1013    }
1014
1015    fn into_rest(self) -> &'a [u8] {
1016        self.0.into_rest().into_byte_slice()
1017    }
1018}
1019
1020#[cfg(test)]
1021mod tests {
1022    use test_case::test_case;
1023    use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Ref, Unaligned};
1024
1025    use super::*;
1026
1027    const DUMMY_BYTES: [u8; 16] = [
1028        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03,
1029        0x04,
1030    ];
1031
1032    fn get_empty_tuple_mut_ref<'a>() -> &'a mut () {
1033        // This is a hack since `&mut ()` is invalid.
1034        let bytes: &mut [u8] = &mut [];
1035        zerocopy::Ref::into_mut(zerocopy::Ref::<_, ()>::from_bytes(bytes).unwrap())
1036    }
1037
1038    #[derive(Debug, IntoBytes, KnownLayout, FromBytes, Immutable, Unaligned)]
1039    #[repr(C)]
1040    struct DummyRecord {
1041        a: [u8; 2],
1042        b: u8,
1043        c: u8,
1044    }
1045
1046    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1047    enum DummyRecordErr {
1048        Parse,
1049        TooFewRecords,
1050    }
1051
1052    impl From<Never> for DummyRecordErr {
1053        fn from(err: Never) -> DummyRecordErr {
1054            match err {}
1055        }
1056    }
1057
1058    impl From<TooFewRecordsErr> for DummyRecordErr {
1059        fn from(_: TooFewRecordsErr) -> DummyRecordErr {
1060            DummyRecordErr::TooFewRecords
1061        }
1062    }
1063
1064    fn parse_dummy_rec<'a, BV>(
1065        data: &mut BV,
1066    ) -> RecordParseResult<Ref<&'a [u8], DummyRecord>, DummyRecordErr>
1067    where
1068        BV: BufferView<&'a [u8]>,
1069    {
1070        if data.is_empty() {
1071            return Ok(ParsedRecord::Done);
1072        }
1073
1074        match data.take_obj_front::<DummyRecord>() {
1075            Some(res) => Ok(ParsedRecord::Parsed(res)),
1076            None => Err(DummyRecordErr::Parse),
1077        }
1078    }
1079
1080    //
1081    // Context-less records
1082    //
1083
1084    #[derive(Debug)]
1085    struct ContextlessRecordImpl;
1086
1087    impl RecordsImplLayout for ContextlessRecordImpl {
1088        type Context = ();
1089        type Error = DummyRecordErr;
1090    }
1091
1092    impl RecordsImpl for ContextlessRecordImpl {
1093        type Record<'a> = Ref<&'a [u8], DummyRecord>;
1094
1095        fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1096            data: &mut BV,
1097            _context: &mut Self::Context,
1098        ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1099            parse_dummy_rec(data)
1100        }
1101    }
1102
1103    //
1104    // Limit context records
1105    //
1106
1107    #[derive(Debug)]
1108    struct LimitContextRecordImpl;
1109
1110    impl RecordsImplLayout for LimitContextRecordImpl {
1111        type Context = usize;
1112        type Error = DummyRecordErr;
1113    }
1114
1115    impl RecordsImpl for LimitContextRecordImpl {
1116        type Record<'a> = Ref<&'a [u8], DummyRecord>;
1117
1118        fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1119            data: &mut BV,
1120            _context: &mut usize,
1121        ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1122            parse_dummy_rec(data)
1123        }
1124    }
1125
1126    //
1127    // Filter context records
1128    //
1129
1130    #[derive(Debug)]
1131    struct FilterContextRecordImpl;
1132
1133    #[derive(Clone)]
1134    struct FilterContext {
1135        pub disallowed: [bool; 256],
1136    }
1137
1138    impl RecordsContext for FilterContext {
1139        type Counter = ();
1140        fn counter_mut(&mut self) -> &mut () {
1141            get_empty_tuple_mut_ref()
1142        }
1143    }
1144
1145    impl RecordsImplLayout for FilterContextRecordImpl {
1146        type Context = FilterContext;
1147        type Error = DummyRecordErr;
1148    }
1149
1150    impl core::fmt::Debug for FilterContext {
1151        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1152            write!(f, "FilterContext{{disallowed:{:?}}}", &self.disallowed[..])
1153        }
1154    }
1155
1156    impl RecordsImpl for FilterContextRecordImpl {
1157        type Record<'a> = Ref<&'a [u8], DummyRecord>;
1158
1159        fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1160            bytes: &mut BV,
1161            context: &mut Self::Context,
1162        ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1163            if bytes.len() < core::mem::size_of::<DummyRecord>() {
1164                Ok(ParsedRecord::Done)
1165            } else if bytes.as_ref()[0..core::mem::size_of::<DummyRecord>()]
1166                .iter()
1167                .any(|x| context.disallowed[*x as usize])
1168            {
1169                Err(DummyRecordErr::Parse)
1170            } else {
1171                parse_dummy_rec(bytes)
1172            }
1173        }
1174    }
1175
1176    //
1177    // Stateful context records
1178    //
1179
1180    #[derive(Debug)]
1181    struct StatefulContextRecordImpl;
1182
1183    #[derive(Clone, Debug)]
1184    struct StatefulContext {
1185        pub pre_parse_counter: usize,
1186        pub parse_counter: usize,
1187        pub post_parse_counter: usize,
1188        pub iter: bool,
1189    }
1190
1191    impl RecordsImplLayout for StatefulContextRecordImpl {
1192        type Context = StatefulContext;
1193        type Error = DummyRecordErr;
1194    }
1195
1196    impl StatefulContext {
1197        pub fn new() -> StatefulContext {
1198            StatefulContext {
1199                pre_parse_counter: 0,
1200                parse_counter: 0,
1201                post_parse_counter: 0,
1202                iter: false,
1203            }
1204        }
1205    }
1206
1207    impl RecordsContext for StatefulContext {
1208        type Counter = ();
1209
1210        fn clone_for_iter(&self) -> Self {
1211            let mut x = self.clone();
1212            x.iter = true;
1213            x
1214        }
1215
1216        fn counter_mut(&mut self) -> &mut () {
1217            get_empty_tuple_mut_ref()
1218        }
1219    }
1220
1221    impl RecordsImpl for StatefulContextRecordImpl {
1222        type Record<'a> = Ref<&'a [u8], DummyRecord>;
1223
1224        fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1225            data: &mut BV,
1226            context: &mut Self::Context,
1227        ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1228            if !context.iter {
1229                context.pre_parse_counter += 1;
1230            }
1231
1232            let ret = parse_dummy_rec_with_context(data, context);
1233
1234            if let Ok(ParsedRecord::Parsed(_)) = ret {
1235                if !context.iter {
1236                    context.post_parse_counter += 1;
1237                }
1238            }
1239
1240            ret
1241        }
1242    }
1243
1244    impl<'a> RecordsRawImpl<'a> for StatefulContextRecordImpl {
1245        fn parse_raw_with_context<BV: BufferView<&'a [u8]>>(
1246            data: &mut BV,
1247            context: &mut Self::Context,
1248        ) -> Result<bool, Self::Error> {
1249            Self::parse_with_context(data, context).map(|r| r.consumed())
1250        }
1251    }
1252
1253    fn parse_dummy_rec_with_context<'a, BV>(
1254        data: &mut BV,
1255        context: &mut StatefulContext,
1256    ) -> RecordParseResult<Ref<&'a [u8], DummyRecord>, DummyRecordErr>
1257    where
1258        BV: BufferView<&'a [u8]>,
1259    {
1260        if data.is_empty() {
1261            return Ok(ParsedRecord::Done);
1262        }
1263
1264        if !context.iter {
1265            context.parse_counter += 1;
1266        }
1267
1268        match data.take_obj_front::<DummyRecord>() {
1269            Some(res) => Ok(ParsedRecord::Parsed(res)),
1270            None => Err(DummyRecordErr::Parse),
1271        }
1272    }
1273
1274    fn check_parsed_record(rec: &DummyRecord) {
1275        assert_eq!(rec.a[0], 0x01);
1276        assert_eq!(rec.a[1], 0x02);
1277        assert_eq!(rec.b, 0x03);
1278    }
1279
1280    fn validate_parsed_stateful_context_records<B: SplitByteSlice>(
1281        records: Records<B, StatefulContextRecordImpl>,
1282        context: StatefulContext,
1283    ) {
1284        // Should be 5 because on the last iteration, we should realize that we
1285        // have no more bytes left and end before parsing (also explaining why
1286        // `parse_counter` should only be 4.
1287        assert_eq!(context.pre_parse_counter, 5);
1288        assert_eq!(context.parse_counter, 4);
1289        assert_eq!(context.post_parse_counter, 4);
1290
1291        let mut iter = records.iter();
1292        let context = &iter.context;
1293        assert_eq!(context.pre_parse_counter, 0);
1294        assert_eq!(context.parse_counter, 0);
1295        assert_eq!(context.post_parse_counter, 0);
1296        assert_eq!(context.iter, true);
1297
1298        // Manually iterate over `iter` so as to not move it.
1299        let mut count = 0;
1300        while let Some(_) = iter.next() {
1301            count += 1;
1302        }
1303        assert_eq!(count, 4);
1304
1305        // Check to see that when iterating, the context doesn't update counters
1306        // as that is how we implemented our StatefulContextRecordImpl..
1307        let context = &iter.context;
1308        assert_eq!(context.pre_parse_counter, 0);
1309        assert_eq!(context.parse_counter, 0);
1310        assert_eq!(context.post_parse_counter, 0);
1311        assert_eq!(context.iter, true);
1312    }
1313
1314    #[test]
1315    fn all_records_parsing() {
1316        let parsed = Records::<_, ContextlessRecordImpl>::parse(&DUMMY_BYTES[..]).unwrap();
1317        let mut iter = parsed.iter();
1318        // Test ExactSizeIterator implementation.
1319        assert_eq!(iter.len(), 4);
1320        let mut cnt = 4;
1321        while let Some(_) = iter.next() {
1322            cnt -= 1;
1323            assert_eq!(iter.len(), cnt);
1324        }
1325        assert_eq!(iter.len(), 0);
1326        for rec in parsed.iter() {
1327            check_parsed_record(rec.deref());
1328        }
1329    }
1330
1331    // `expect` is either the number of records that should have been parsed or
1332    // the error returned from the `Records` constructor.
1333    //
1334    // If there are more records than the limit, then we just truncate (not
1335    // parsing all of them) and don't return an error.
1336    #[test_case(0, Ok(0))]
1337    #[test_case(1, Ok(1))]
1338    #[test_case(2, Ok(2))]
1339    #[test_case(3, Ok(3))]
1340    // If there are the same number of records as the limit, then we
1341    // succeed.
1342    #[test_case(4, Ok(4))]
1343    // If there are fewer records than the limit, then we fail.
1344    #[test_case(5, Err(DummyRecordErr::TooFewRecords))]
1345    fn limit_records_parsing(limit: usize, expect: Result<usize, DummyRecordErr>) {
1346        // Test without mutable limit/context
1347        let check_result =
1348            |result: Result<Records<_, LimitContextRecordImpl>, _>| match (expect, result) {
1349                (Ok(expect_parsed), Ok(records)) => {
1350                    assert_eq!(records.iter().count(), expect_parsed);
1351                    for rec in records.iter() {
1352                        check_parsed_record(rec.deref());
1353                    }
1354                }
1355                (Err(expect), Err(got)) => assert_eq!(expect, got),
1356                (Ok(expect_parsed), Err(err)) => {
1357                    panic!("wanted {expect_parsed} successfully-parsed records; got error {err:?}")
1358                }
1359                (Err(expect), Ok(records)) => panic!(
1360                    "wanted error {expect:?}, got {} successfully-parsed records",
1361                    records.iter().count()
1362                ),
1363            };
1364
1365        check_result(Records::<_, LimitContextRecordImpl>::parse_with_context(
1366            &DUMMY_BYTES[..],
1367            limit,
1368        ));
1369        let mut mut_limit = limit;
1370        check_result(Records::<_, LimitContextRecordImpl>::parse_with_mut_context(
1371            &DUMMY_BYTES[..],
1372            &mut mut_limit,
1373        ));
1374        if let Ok(expect_parsed) = expect {
1375            assert_eq!(limit - mut_limit, expect_parsed);
1376        }
1377    }
1378
1379    #[test]
1380    fn context_filtering_some_byte_records_parsing() {
1381        // Do not disallow any bytes
1382        let context = FilterContext { disallowed: [false; 256] };
1383        let parsed =
1384            Records::<_, FilterContextRecordImpl>::parse_with_context(&DUMMY_BYTES[..], context)
1385                .unwrap();
1386        assert_eq!(parsed.iter().count(), 4);
1387        for rec in parsed.iter() {
1388            check_parsed_record(rec.deref());
1389        }
1390
1391        // Do not allow byte value 0x01
1392        let mut context = FilterContext { disallowed: [false; 256] };
1393        context.disallowed[1] = true;
1394        assert_eq!(
1395            Records::<_, FilterContextRecordImpl>::parse_with_context(&DUMMY_BYTES[..], context)
1396                .expect_err("fails if the buffer has an element with value 0x01"),
1397            DummyRecordErr::Parse
1398        );
1399    }
1400
1401    #[test]
1402    fn stateful_context_records_parsing() {
1403        let mut context = StatefulContext::new();
1404        let parsed = Records::<_, StatefulContextRecordImpl>::parse_with_mut_context(
1405            &DUMMY_BYTES[..],
1406            &mut context,
1407        )
1408        .unwrap();
1409        validate_parsed_stateful_context_records(parsed, context);
1410    }
1411
1412    #[test]
1413    fn raw_parse_success() {
1414        let mut context = StatefulContext::new();
1415        let mut bv = &mut &DUMMY_BYTES[..];
1416        let result = RecordsRaw::<_, StatefulContextRecordImpl>::parse_raw_with_mut_context(
1417            &mut bv,
1418            &mut context,
1419        )
1420        .complete()
1421        .unwrap();
1422        let RecordsRaw { bytes, context: _ } = &result;
1423        assert_eq!(*bytes, &DUMMY_BYTES[..]);
1424        let parsed = Records::try_from_raw(result).unwrap();
1425        validate_parsed_stateful_context_records(parsed, context);
1426    }
1427
1428    #[test]
1429    fn raw_parse_failure() {
1430        let mut context = StatefulContext::new();
1431        let mut bv = &mut &DUMMY_BYTES[0..15];
1432        let result = RecordsRaw::<_, StatefulContextRecordImpl>::parse_raw_with_mut_context(
1433            &mut bv,
1434            &mut context,
1435        )
1436        .incomplete()
1437        .unwrap();
1438        assert_eq!(result, (&DUMMY_BYTES[0..12], DummyRecordErr::Parse));
1439    }
1440}
1441
1442/// Utilities for parsing the options formats in protocols like IPv4, TCP, and
1443/// NDP.
1444///
1445/// This module provides parsing utilities for [type-length-value]-like records
1446/// encodings like those used by the options in an IPv4 or TCP header or an NDP
1447/// packet. These formats are not identical, but share enough in common that the
1448/// utilities provided here only need a small amount of customization by the
1449/// user to be fully functional.
1450///
1451/// [type-length-value]: https://en.wikipedia.org/wiki/Type-length-value
1452pub mod options {
1453    use core::mem;
1454    use core::num::{NonZeroUsize, TryFromIntError};
1455
1456    use zerocopy::byteorder::ByteOrder;
1457    use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
1458
1459    use super::*;
1460
1461    /// A parsed sequence of options.
1462    ///
1463    /// `Options` represents a parsed sequence of options, for example from an
1464    /// IPv4 or TCP header or an NDP packet. `Options` uses [`Records`] under
1465    /// the hood.
1466    ///
1467    /// [`Records`]: crate::records::Records
1468    pub type Options<B, O> = Records<B, O>;
1469
1470    /// A not-yet-parsed sequence of options.
1471    ///
1472    /// `OptionsRaw` represents a not-yet-parsed and not-yet-validated sequence
1473    /// of options, for example from an IPv4 or TCP header or an NDP packet.
1474    /// `OptionsRaw` uses [`RecordsRaw`] under the hood.
1475    ///
1476    /// [`RecordsRaw`]: crate::records::RecordsRaw
1477    pub type OptionsRaw<B, O> = RecordsRaw<B, O>;
1478
1479    /// A builder capable of serializing a sequence of options.
1480    ///
1481    /// An `OptionSequenceBuilder` is instantiated with an [`Iterator`] that
1482    /// provides [`OptionBuilder`]s to be serialized. The item produced by the
1483    /// iterator can be any type which implements `Borrow<O>` for `O:
1484    /// OptionBuilder`.
1485    ///
1486    /// `OptionSequenceBuilder` implements [`InnerPacketBuilder`].
1487    pub type OptionSequenceBuilder<R, I> = RecordSequenceBuilder<R, I>;
1488
1489    /// A builder capable of serializing a sequence of aligned options.
1490    ///
1491    /// An `AlignedOptionSequenceBuilder` is instantiated with an [`Iterator`]
1492    /// that provides [`AlignedOptionBuilder`]s to be serialized. The item
1493    /// produced by the iterator can be any type which implements `Borrow<O>`
1494    /// for `O: AlignedOptionBuilder`.
1495    ///
1496    /// `AlignedOptionSequenceBuilder` implements [`InnerPacketBuilder`].
1497    pub type AlignedOptionSequenceBuilder<R, I> = AlignedRecordSequenceBuilder<R, I>;
1498
1499    impl<O: OptionsImpl> RecordsImplLayout for O {
1500        type Context = ();
1501        type Error = O::Error;
1502    }
1503
1504    impl<O: OptionsImpl> RecordsImpl for O {
1505        type Record<'a> = O::Option<'a>;
1506
1507        fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1508            data: &mut BV,
1509            _context: &mut Self::Context,
1510        ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1511            next::<_, O>(data)
1512        }
1513    }
1514
1515    impl<O: OptionsImpl> MeasureRecordsImpl for O {
1516        fn measure_next_record<'a, BV: BufferView<&'a [u8]>>(
1517            data: &BV,
1518            _context: &mut Self::Context,
1519        ) -> core::result::Result<MeasuredRecord, Self::Error> {
1520            if data.len() == 0 {
1521                return Ok(MeasuredRecord::Done);
1522            }
1523
1524            // First peek at the kind field.
1525            match data.peek_obj_front::<O::KindLenField>() {
1526                // Thanks to the preceding `if`, we know at this point that
1527                // `data.len() > 0`. If `peek_obj_front` returns `None`, that
1528                // means that `data.len()` is shorter than `O::KindLenField`.
1529                None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1530                Some(k) => {
1531                    // Can't do pattern matching with associated constants, so
1532                    // do it the good-ol' way:
1533                    if Some(*k) == O::NOP {
1534                        // The next record is a NOP record which is always just
1535                        // the kind field itself.
1536                        return Ok(MeasuredRecord::Measured(
1537                            NonZeroUsize::new(size_of::<O::KindLenField>())
1538                                .expect("KindLenField must not be 0-sized"),
1539                        ));
1540                    } else if Some(*k) == O::END_OF_OPTIONS {
1541                        return Ok(MeasuredRecord::Done);
1542                    }
1543                }
1544            };
1545
1546            // Then, since we only _peeked_ before, we have to peek again to get
1547            // both the kind field (again) and the length field.
1548            let body_len = match data.peek_obj_front::<[O::KindLenField; 2]>() {
1549                None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1550                Some([_kind, len]) => O::LENGTH_ENCODING
1551                    .decode_length::<O::KindLenField>(*len)
1552                    .ok_or(O::Error::SEQUENCE_FORMAT_ERROR)?,
1553            };
1554            Ok(MeasuredRecord::Measured(
1555                NonZeroUsize::new(
1556                    O::LENGTH_ENCODING
1557                        .record_length::<O::KindLenField>(body_len)
1558                        .expect("record_length(decode_length(..)) should succeed"),
1559                )
1560                .expect("should never get 0-length record"),
1561            ))
1562        }
1563    }
1564
1565    impl<O: OptionBuilder> RecordBuilder for O {
1566        fn serialized_len(&self) -> usize {
1567            // TODO(https://fxbug.dev/42158056): Remove this `.expect`
1568            <O::Layout as OptionLayout>::LENGTH_ENCODING
1569                .record_length::<<O::Layout as OptionLayout>::KindLenField>(
1570                    OptionBuilder::serialized_len(self),
1571                )
1572                .expect("integer overflow while computing record length")
1573        }
1574
1575        fn serialize_into(&self, mut data: &mut [u8]) {
1576            // NOTE(brunodalbo) we don't currently support serializing the two
1577            //  single-byte options used in TCP and IP: NOP and END_OF_OPTIONS.
1578            //  If it is necessary to support those as part of TLV options
1579            //  serialization, some changes will be required here.
1580
1581            // So that `data` implements `BufferViewMut`.
1582            let mut data = &mut data;
1583
1584            // Data not having enough space is a contract violation, so we panic
1585            // in that case.
1586            *BufferView::<&mut [u8]>::take_obj_front::<<O::Layout as OptionLayout>::KindLenField>(&mut data)
1587                .expect("buffer too short") = self.option_kind();
1588            let body_len = OptionBuilder::serialized_len(self);
1589            // TODO(https://fxbug.dev/42158056): Remove this `.expect`
1590            let length = <O::Layout as OptionLayout>::LENGTH_ENCODING
1591                .encode_length::<<O::Layout as OptionLayout>::KindLenField>(body_len)
1592                .expect("integer overflow while encoding length");
1593            // Length overflowing `O::Layout::KindLenField` is a contract
1594            // violation, so we panic in that case.
1595            *BufferView::<&mut [u8]>::take_obj_front::<<O::Layout as OptionLayout>::KindLenField>(&mut data)
1596                .expect("buffer too short") = length;
1597            // SECURITY: Because padding may have occurred, we zero-fill data
1598            // before passing it along in order to prevent leaking information
1599            // from packets previously stored in the buffer.
1600            let data = data.into_rest_zero();
1601            // Pass exactly `body_len` bytes even if there is padding.
1602            OptionBuilder::serialize_into(self, &mut data[..body_len]);
1603        }
1604    }
1605
1606    impl<O: AlignedOptionBuilder> AlignedRecordBuilder for O {
1607        fn alignment_requirement(&self) -> (usize, usize) {
1608            // Use the underlying option's alignment requirement as the
1609            // alignment requirement for the record.
1610            AlignedOptionBuilder::alignment_requirement(self)
1611        }
1612
1613        fn serialize_padding(buf: &mut [u8], length: usize) {
1614            <O as AlignedOptionBuilder>::serialize_padding(buf, length);
1615        }
1616    }
1617
1618    /// Whether the length field of an option encodes the length of the entire
1619    /// option (including kind and length fields) or only of the value field.
1620    ///
1621    /// For the `TypeLengthValue` variant, an `option_len_multiplier` may also
1622    /// be specified. Some formats (such as NDP) do not directly encode the
1623    /// length in bytes of each option, but instead encode a number which must
1624    /// be multiplied by `option_len_multiplier` in order to get the length in
1625    /// bytes.
1626    #[derive(Copy, Clone, Eq, PartialEq)]
1627    pub enum LengthEncoding {
1628        TypeLengthValue { option_len_multiplier: NonZeroUsize },
1629        ValueOnly,
1630    }
1631
1632    impl LengthEncoding {
1633        /// Computes the length of an entire option record - including kind and
1634        /// length fields - from the length of an option body.
1635        ///
1636        /// `record_length` takes into account the length of the kind and length
1637        /// fields and also adds any padding required to reach a multiple of
1638        /// `option_len_multiplier`, returning `None` if the value cannot be
1639        /// stored in a `usize`.
1640        fn record_length<F: KindLenField>(self, option_body_len: usize) -> Option<usize> {
1641            let unpadded_len = option_body_len.checked_add(2 * mem::size_of::<F>())?;
1642            match self {
1643                LengthEncoding::TypeLengthValue { option_len_multiplier } => {
1644                    round_up(unpadded_len, option_len_multiplier)
1645                }
1646                LengthEncoding::ValueOnly => Some(unpadded_len),
1647            }
1648        }
1649
1650        /// Encodes the length of an option's body.
1651        ///
1652        /// `option_body_len` is the length in bytes of the body option as
1653        /// returned from [`OptionsSerializerImpl::option_length`]. This value
1654        /// does not include the kind, length, or padding bytes.
1655        ///
1656        /// `encode_length` computes the value which should be stored in the
1657        /// length field, returning `None` if the value cannot be stored in an
1658        /// `F`.
1659        pub fn encode_length<F: KindLenField>(self, option_body_len: usize) -> Option<F> {
1660            let len = match self {
1661                LengthEncoding::TypeLengthValue { option_len_multiplier } => {
1662                    let unpadded_len = (2 * mem::size_of::<F>()).checked_add(option_body_len)?;
1663                    let padded_len = round_up(unpadded_len, option_len_multiplier)?;
1664                    padded_len / option_len_multiplier.get()
1665                }
1666                LengthEncoding::ValueOnly => option_body_len,
1667            };
1668            match F::try_from(len) {
1669                Ok(len) => Some(len),
1670                Err(TryFromIntError { .. }) => None,
1671            }
1672        }
1673
1674        /// Decodes the length of an option's body.
1675        ///
1676        /// `length_field` is the value of the length field. `decode_length`
1677        /// computes the length of the option's body which this value encodes,
1678        /// returning an error if `length_field` is invalid or if integer
1679        /// overflow occurs. `length_field` is invalid if it encodes a total
1680        /// length smaller than the header (specifically, if `self` is
1681        /// LengthEncoding::TypeLengthValue { option_len_multiplier }` and
1682        /// `length_field * option_len_multiplier < 2 * size_of::<F>()`).
1683        fn decode_length<F: KindLenField>(self, length_field: F) -> Option<usize> {
1684            let length_field = length_field.into();
1685            match self {
1686                LengthEncoding::TypeLengthValue { option_len_multiplier } => length_field
1687                    .checked_mul(option_len_multiplier.get())
1688                    .and_then(|product| product.checked_sub(2 * mem::size_of::<F>())),
1689                LengthEncoding::ValueOnly => Some(length_field),
1690            }
1691        }
1692    }
1693
1694    /// Rounds up `x` to the next multiple of `mul` unless `x` is already a
1695    /// multiple of `mul`.
1696    fn round_up(x: usize, mul: NonZeroUsize) -> Option<usize> {
1697        let mul = mul.get();
1698        // - Subtracting 1 can't underflow because we just added `mul`, which is
1699        //   at least 1, and the addition didn't overflow
1700        // - Dividing by `mul` can't overflow (and can't divide by 0 because
1701        //   `mul` is nonzero)
1702        // - Multiplying by `mul` can't overflow because division rounds down,
1703        //   so the result of the multiplication can't be any larger than the
1704        //   numerator in `(x_times_mul - 1) / mul`, which we already know
1705        //   didn't overflow
1706        x.checked_add(mul).map(|x_times_mul| ((x_times_mul - 1) / mul) * mul)
1707    }
1708
1709    /// The type of the "kind" and "length" fields in an option.
1710    ///
1711    /// See the docs for [`OptionLayout::KindLenField`] for more information.
1712    pub trait KindLenField:
1713        FromBytes
1714        + IntoBytes
1715        + KnownLayout
1716        + Immutable
1717        + Unaligned
1718        + Into<usize>
1719        + TryFrom<usize, Error = TryFromIntError>
1720        + Eq
1721        + Copy
1722        + crate::sealed::Sealed
1723    {
1724    }
1725
1726    impl crate::sealed::Sealed for u8 {}
1727    impl KindLenField for u8 {}
1728    impl<O: ByteOrder> crate::sealed::Sealed for zerocopy::U16<O> {}
1729    impl<O: ByteOrder> KindLenField for zerocopy::U16<O> {}
1730
1731    /// Information about an option's layout.
1732    ///
1733    /// It is recommended that this trait be implemented for an uninhabited type
1734    /// since it never needs to be instantiated:
1735    ///
1736    /// ```rust
1737    /// # use packet::records::options::{OptionLayout, LengthEncoding};
1738    /// /// A carrier for information about the layout of the IPv4 option
1739    /// /// format.
1740    /// ///
1741    /// /// This type exists only at the type level, and does not need to be
1742    /// /// constructed.
1743    /// pub enum Ipv4OptionLayout {}
1744    ///
1745    /// impl OptionLayout for Ipv4OptionLayout {
1746    ///     type KindLenField = u8;
1747    /// }
1748    /// ```
1749    pub trait OptionLayout {
1750        /// The type of the "kind" and "length" fields in an option.
1751        ///
1752        /// For most protocols, this is simply `u8`, as the "kind" and "length"
1753        /// fields are each a single byte. For protocols which use two bytes for
1754        /// these fields, this is [`zerocopy::U16`].
1755        // TODO(https://github.com/rust-lang/rust/issues/29661): Have
1756        // `KindLenField` default to `u8`.
1757        type KindLenField: KindLenField;
1758
1759        /// The encoding of the length byte.
1760        ///
1761        /// Some formats (such as IPv4) use the length field to encode the
1762        /// length of the entire option, including the kind and length bytes.
1763        /// Other formats (such as IPv6) use the length field to encode the
1764        /// length of only the value. This constant specifies which encoding is
1765        /// used.
1766        ///
1767        /// Additionally, some formats (such as NDP) do not directly encode the
1768        /// length in bytes of each option, but instead encode a number which
1769        /// must be multiplied by a constant in order to get the length in
1770        /// bytes. This is set using the [`TypeLengthValue`] variant's
1771        /// `option_len_multiplier` field, and it defaults to 1.
1772        ///
1773        /// [`TypeLengthValue`]: LengthEncoding::TypeLengthValue
1774        const LENGTH_ENCODING: LengthEncoding = LengthEncoding::TypeLengthValue {
1775            option_len_multiplier: NonZeroUsize::new(1).unwrap(),
1776        };
1777    }
1778
1779    /// An error encountered while parsing an option or sequence of options.
1780    pub trait OptionParseError: From<Never> {
1781        /// An error encountered while parsing a sequence of options.
1782        ///
1783        /// If an error is encountered while parsing a sequence of [`Options`],
1784        /// this is the error that will be emitted. This is the only type of
1785        /// error that can be generated by the [`Options`] parser itself. All
1786        /// other errors come from the user-provided [`OptionsImpl::parse`],
1787        /// which parses the data of a single option.
1788        const SEQUENCE_FORMAT_ERROR: Self;
1789    }
1790
1791    /// An error encountered while parsing an option or sequence of options.
1792    ///
1793    /// `OptionParseErr` is a simple implementation of [`OptionParseError`] that
1794    /// doesn't carry information other than the fact that an error was
1795    /// encountered.
1796    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1797    pub struct OptionParseErr;
1798
1799    impl From<Never> for OptionParseErr {
1800        fn from(err: Never) -> OptionParseErr {
1801            match err {}
1802        }
1803    }
1804
1805    impl OptionParseError for OptionParseErr {
1806        const SEQUENCE_FORMAT_ERROR: OptionParseErr = OptionParseErr;
1807    }
1808
1809    /// Information about an option's layout required in order to parse it.
1810    pub trait OptionParseLayout: OptionLayout {
1811        /// The type of errors that may be returned by a call to
1812        /// [`OptionsImpl::parse`].
1813        type Error: OptionParseError;
1814
1815        /// The End of options kind (if one exists).
1816        const END_OF_OPTIONS: Option<Self::KindLenField>;
1817
1818        /// The No-op kind (if one exists).
1819        const NOP: Option<Self::KindLenField>;
1820    }
1821
1822    /// An implementation of an options parser.
1823    ///
1824    /// `OptionsImpl` provides functions to parse fixed- and variable-length
1825    /// options. It is required in order to construct an [`Options`].
1826    pub trait OptionsImpl: OptionParseLayout {
1827        /// The type of an option; the output from the [`parse`] function.
1828        ///
1829        /// For long or variable-length data, implementers are advised to make
1830        /// `Option` a reference into the bytes passed to `parse`. Such a
1831        /// reference will need to carry the lifetime `'a`, which is the same
1832        /// lifetime that is passed to `parse`, and is also the lifetime
1833        /// parameter to this trait.
1834        ///
1835        /// [`parse`]: crate::records::options::OptionsImpl::parse
1836        type Option<'a>;
1837
1838        /// Parses an option.
1839        ///
1840        /// `parse` takes a kind byte and variable-length data and returns
1841        /// `Ok(Some(o))` if the option successfully parsed as `o`, `Ok(None)`
1842        /// if the kind byte was unrecognized, and `Err(err)` if the kind byte
1843        /// was recognized but `data` was malformed for that option kind.
1844        ///
1845        /// `parse` is allowed to not recognize certain option kinds, as the
1846        /// length field can still be used to safely skip over them, but it must
1847        /// recognize all single-byte options (if it didn't, a single-byte
1848        /// option would be spuriously interpreted as a multi-byte option, and
1849        /// the first byte of the next option byte would be spuriously
1850        /// interpreted as the option's length byte).
1851        ///
1852        /// `parse` must be deterministic, or else [`Options::parse`] cannot
1853        /// guarantee that future iterations will not produce errors (and thus
1854        /// panic).
1855        ///
1856        /// [`Options::parse`]: crate::records::Records::parse
1857        fn parse<'a>(
1858            kind: Self::KindLenField,
1859            data: &'a [u8],
1860        ) -> Result<Option<Self::Option<'a>>, Self::Error>;
1861    }
1862
1863    /// A builder capable of serializing an option.
1864    ///
1865    /// Given `O: OptionBuilder`, an iterator of `O` can be used with a
1866    /// [`OptionSequenceBuilder`] to serialize a sequence of options.
1867    pub trait OptionBuilder {
1868        /// Information about the option's layout.
1869        type Layout: OptionLayout;
1870
1871        /// Returns the serialized length, in bytes, of `self`.
1872        ///
1873        /// Implementers must return the length, in bytes, of the **data***
1874        /// portion of the option field (not counting the kind and length
1875        /// bytes). The internal machinery of options serialization takes care
1876        /// of aligning options to their [`option_len_multiplier`] boundaries,
1877        /// adding padding bytes if necessary.
1878        ///
1879        /// [`option_len_multiplier`]: LengthEncoding::TypeLengthValue::option_len_multiplier
1880        fn serialized_len(&self) -> usize;
1881
1882        /// Returns the wire value for this option kind.
1883        fn option_kind(&self) -> <Self::Layout as OptionLayout>::KindLenField;
1884
1885        /// Serializes `self` into `data`.
1886        ///
1887        /// `data` will be exactly `self.serialized_len()` bytes long.
1888        /// Implementers must write the **data** portion of `self` into `data`
1889        /// (not the kind or length fields).
1890        ///
1891        /// # Panics
1892        ///
1893        /// May panic if `data` is not exactly `self.serialized_len()` bytes
1894        /// long.
1895        fn serialize_into(&self, data: &mut [u8]);
1896    }
1897
1898    /// A builder capable of serializing an option with an alignment
1899    /// requirement.
1900    ///
1901    /// Given `O: AlignedOptionBuilder`, an iterator of `O` can be used with an
1902    /// [`AlignedOptionSequenceBuilder`] to serialize a sequence of aligned
1903    /// options.
1904    pub trait AlignedOptionBuilder: OptionBuilder {
1905        /// Returns the alignment requirement of `self`.
1906        ///
1907        /// `option.alignment_requirement()` returns `(x, y)`, which means that
1908        /// the serialized encoding of `option` must be aligned at `x * n + y`
1909        /// bytes from the beginning of the options sequence for some
1910        /// non-negative `n`. For example, the IPv6 Router Alert Hop-by-Hop
1911        /// option has alignment (2, 0), while the Jumbo Payload option has
1912        /// alignment (4, 2). (1, 0) means there is no alignment requirement.
1913        ///
1914        /// `x` must be non-zero and `y` must be smaller than `x`.
1915        fn alignment_requirement(&self) -> (usize, usize);
1916
1917        /// Serializes the padding between subsequent aligned options.
1918        ///
1919        /// Some formats require that padding bytes have particular content.
1920        /// This function serializes padding bytes as required by the format.
1921        fn serialize_padding(buf: &mut [u8], length: usize);
1922    }
1923
1924    fn next<'a, BV, O>(bytes: &mut BV) -> RecordParseResult<O::Option<'a>, O::Error>
1925    where
1926        BV: BufferView<&'a [u8]>,
1927        O: OptionsImpl,
1928    {
1929        // For an explanation of this format, see the "Options" section of
1930        // https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure
1931        loop {
1932            if bytes.len() == 0 {
1933                return Ok(ParsedRecord::Done);
1934            }
1935            let kind = match bytes.take_obj_front::<O::KindLenField>() {
1936                // Thanks to the preceding `if`, we know at this point that
1937                // `bytes.len() > 0`. If `take_obj_front` returns `None`, that
1938                // means that `bytes.len()` is shorter than `O::KindLenField`.
1939                None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1940                Some(k) => {
1941                    // Can't do pattern matching with associated constants, so
1942                    // do it the good-ol' way:
1943                    if Some(*k) == O::NOP {
1944                        continue;
1945                    } else if Some(*k) == O::END_OF_OPTIONS {
1946                        return Ok(ParsedRecord::Done);
1947                    }
1948                    k
1949                }
1950            };
1951            let body_len = match bytes.take_obj_front::<O::KindLenField>() {
1952                None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1953                Some(len) => O::LENGTH_ENCODING
1954                    .decode_length::<O::KindLenField>(*len)
1955                    .ok_or(O::Error::SEQUENCE_FORMAT_ERROR)?,
1956            };
1957
1958            let option_data = bytes.take_front(body_len).ok_or(O::Error::SEQUENCE_FORMAT_ERROR)?;
1959            match O::parse(*kind, option_data) {
1960                Ok(Some(o)) => return Ok(ParsedRecord::Parsed(o)),
1961                Ok(None) => {}
1962                Err(err) => return Err(err),
1963            }
1964        }
1965    }
1966
1967    #[cfg(test)]
1968    mod tests {
1969        use core::convert::TryInto as _;
1970        use core::fmt::Debug;
1971
1972        use zerocopy::byteorder::network_endian::U16;
1973
1974        use super::*;
1975        use crate::Serializer;
1976
1977        #[derive(Debug)]
1978        struct DummyOptionsImpl;
1979
1980        #[derive(Debug)]
1981        struct DummyOption {
1982            kind: u8,
1983            data: Vec<u8>,
1984        }
1985
1986        impl OptionLayout for DummyOptionsImpl {
1987            type KindLenField = u8;
1988        }
1989
1990        impl OptionParseLayout for DummyOptionsImpl {
1991            type Error = OptionParseErr;
1992            const END_OF_OPTIONS: Option<u8> = Some(0);
1993            const NOP: Option<u8> = Some(1);
1994        }
1995
1996        impl OptionsImpl for DummyOptionsImpl {
1997            type Option<'a> = DummyOption;
1998
1999            fn parse<'a>(
2000                kind: u8,
2001                data: &'a [u8],
2002            ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
2003                let mut v = Vec::new();
2004                v.extend_from_slice(data);
2005                Ok(Some(DummyOption { kind, data: v }))
2006            }
2007        }
2008
2009        impl OptionBuilder for DummyOption {
2010            type Layout = DummyOptionsImpl;
2011
2012            fn serialized_len(&self) -> usize {
2013                self.data.len()
2014            }
2015
2016            fn option_kind(&self) -> u8 {
2017                self.kind
2018            }
2019
2020            fn serialize_into(&self, data: &mut [u8]) {
2021                assert_eq!(data.len(), OptionBuilder::serialized_len(self));
2022                data.copy_from_slice(&self.data);
2023            }
2024        }
2025
2026        impl AlignedOptionBuilder for DummyOption {
2027            // For our `DummyOption`, we simply regard (length, kind) as their
2028            // alignment requirement.
2029            fn alignment_requirement(&self) -> (usize, usize) {
2030                (self.data.len(), self.kind as usize)
2031            }
2032
2033            fn serialize_padding(buf: &mut [u8], length: usize) {
2034                assert!(length <= buf.len());
2035                assert!(length <= (std::u8::MAX as usize) + 2);
2036
2037                if length == 1 {
2038                    // Use Pad1
2039                    buf[0] = 0
2040                } else if length > 1 {
2041                    // Use PadN
2042                    buf[0] = 1;
2043                    buf[1] = (length - 2) as u8;
2044                    for i in 2..length {
2045                        buf[i] = 0
2046                    }
2047                }
2048            }
2049        }
2050
2051        #[derive(Debug, Eq, PartialEq)]
2052        enum AlwaysErrorErr {
2053            Sequence,
2054            Option,
2055        }
2056
2057        impl From<Never> for AlwaysErrorErr {
2058            fn from(err: Never) -> AlwaysErrorErr {
2059                match err {}
2060            }
2061        }
2062
2063        impl OptionParseError for AlwaysErrorErr {
2064            const SEQUENCE_FORMAT_ERROR: AlwaysErrorErr = AlwaysErrorErr::Sequence;
2065        }
2066
2067        #[derive(Debug)]
2068        struct AlwaysErrOptionsImpl;
2069
2070        impl OptionLayout for AlwaysErrOptionsImpl {
2071            type KindLenField = u8;
2072        }
2073
2074        impl OptionParseLayout for AlwaysErrOptionsImpl {
2075            type Error = AlwaysErrorErr;
2076            const END_OF_OPTIONS: Option<u8> = Some(0);
2077            const NOP: Option<u8> = Some(1);
2078        }
2079
2080        impl OptionsImpl for AlwaysErrOptionsImpl {
2081            type Option<'a> = ();
2082
2083            fn parse<'a>(_kind: u8, _data: &'a [u8]) -> Result<Option<()>, AlwaysErrorErr> {
2084                Err(AlwaysErrorErr::Option)
2085            }
2086        }
2087
2088        #[derive(Debug)]
2089        struct DummyNdpOptionsImpl;
2090
2091        #[derive(Debug, PartialEq, Eq)]
2092        struct NdpOption {
2093            kind: u8,
2094            data: Vec<u8>,
2095        }
2096
2097        impl OptionLayout for NdpOption {
2098            type KindLenField = u8;
2099
2100            const LENGTH_ENCODING: LengthEncoding = LengthEncoding::TypeLengthValue {
2101                option_len_multiplier: NonZeroUsize::new(8).unwrap(),
2102            };
2103        }
2104
2105        impl OptionLayout for DummyNdpOptionsImpl {
2106            type KindLenField = u8;
2107
2108            const LENGTH_ENCODING: LengthEncoding = LengthEncoding::TypeLengthValue {
2109                option_len_multiplier: NonZeroUsize::new(8).unwrap(),
2110            };
2111        }
2112
2113        impl OptionParseLayout for DummyNdpOptionsImpl {
2114            type Error = OptionParseErr;
2115
2116            const END_OF_OPTIONS: Option<u8> = None;
2117
2118            const NOP: Option<u8> = None;
2119        }
2120
2121        impl OptionsImpl for DummyNdpOptionsImpl {
2122            type Option<'a> = NdpOption;
2123
2124            fn parse<'a>(
2125                kind: u8,
2126                data: &'a [u8],
2127            ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
2128                let mut v = Vec::with_capacity(data.len());
2129                v.extend_from_slice(data);
2130                Ok(Some(NdpOption { kind, data: v }))
2131            }
2132        }
2133
2134        impl OptionBuilder for NdpOption {
2135            type Layout = DummyNdpOptionsImpl;
2136
2137            fn serialized_len(&self) -> usize {
2138                self.data.len()
2139            }
2140
2141            fn option_kind(&self) -> u8 {
2142                self.kind
2143            }
2144
2145            fn serialize_into(&self, data: &mut [u8]) {
2146                assert_eq!(data.len(), OptionBuilder::serialized_len(self));
2147                data.copy_from_slice(&self.data)
2148            }
2149        }
2150
2151        #[derive(Debug)]
2152        struct DummyMultiByteKindOptionsImpl;
2153
2154        #[derive(Debug)]
2155        struct MultiByteOption {
2156            kind: U16,
2157            data: Vec<u8>,
2158        }
2159
2160        impl OptionLayout for MultiByteOption {
2161            type KindLenField = U16;
2162        }
2163
2164        impl OptionLayout for DummyMultiByteKindOptionsImpl {
2165            type KindLenField = U16;
2166        }
2167
2168        impl OptionParseLayout for DummyMultiByteKindOptionsImpl {
2169            type Error = OptionParseErr;
2170
2171            const END_OF_OPTIONS: Option<U16> = None;
2172
2173            const NOP: Option<U16> = None;
2174        }
2175
2176        impl OptionsImpl for DummyMultiByteKindOptionsImpl {
2177            type Option<'a> = MultiByteOption;
2178
2179            fn parse<'a>(
2180                kind: U16,
2181                data: &'a [u8],
2182            ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
2183                let mut v = Vec::with_capacity(data.len());
2184                v.extend_from_slice(data);
2185                Ok(Some(MultiByteOption { kind, data: v }))
2186            }
2187        }
2188
2189        impl OptionBuilder for MultiByteOption {
2190            type Layout = DummyMultiByteKindOptionsImpl;
2191
2192            fn serialized_len(&self) -> usize {
2193                self.data.len()
2194            }
2195
2196            fn option_kind(&self) -> U16 {
2197                self.kind
2198            }
2199
2200            fn serialize_into(&self, data: &mut [u8]) {
2201                data.copy_from_slice(&self.data)
2202            }
2203        }
2204
2205        #[test]
2206        fn test_length_encoding() {
2207            const TLV_1: LengthEncoding = LengthEncoding::TypeLengthValue {
2208                option_len_multiplier: NonZeroUsize::new(1).unwrap(),
2209            };
2210            const TLV_2: LengthEncoding = LengthEncoding::TypeLengthValue {
2211                option_len_multiplier: NonZeroUsize::new(2).unwrap(),
2212            };
2213
2214            // Test LengthEncoding::record_length
2215
2216            // For `ValueOnly`, `record_length` should always add 2 or 4 for the kind
2217            // and length bytes, but never add padding.
2218            assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(0), Some(2));
2219            assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(1), Some(3));
2220            assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(2), Some(4));
2221            assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(3), Some(5));
2222
2223            assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(0), Some(4));
2224            assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(1), Some(5));
2225            assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(2), Some(6));
2226            assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(3), Some(7));
2227
2228            // For `TypeLengthValue` with `option_len_multiplier = 1`,
2229            // `record_length` should always add 2 or 4 for the kind and length
2230            // bytes, but never add padding.
2231            assert_eq!(TLV_1.record_length::<u8>(0), Some(2));
2232            assert_eq!(TLV_1.record_length::<u8>(1), Some(3));
2233            assert_eq!(TLV_1.record_length::<u8>(2), Some(4));
2234            assert_eq!(TLV_1.record_length::<u8>(3), Some(5));
2235
2236            assert_eq!(TLV_1.record_length::<U16>(0), Some(4));
2237            assert_eq!(TLV_1.record_length::<U16>(1), Some(5));
2238            assert_eq!(TLV_1.record_length::<U16>(2), Some(6));
2239            assert_eq!(TLV_1.record_length::<U16>(3), Some(7));
2240
2241            // For `TypeLengthValue` with `option_len_multiplier = 2`,
2242            // `record_length` should always add 2 or 4 for the kind and length
2243            // bytes, and add padding if necessary to reach a multiple of 2.
2244            assert_eq!(TLV_2.record_length::<u8>(0), Some(2)); // (0 + 2)
2245            assert_eq!(TLV_2.record_length::<u8>(1), Some(4)); // (1 + 2 + 1)
2246            assert_eq!(TLV_2.record_length::<u8>(2), Some(4)); // (2 + 2)
2247            assert_eq!(TLV_2.record_length::<u8>(3), Some(6)); // (3 + 2 + 1)
2248
2249            assert_eq!(TLV_2.record_length::<U16>(0), Some(4)); // (0 + 4)
2250            assert_eq!(TLV_2.record_length::<U16>(1), Some(6)); // (1 + 4 + 1)
2251            assert_eq!(TLV_2.record_length::<U16>(2), Some(6)); // (2 + 4)
2252            assert_eq!(TLV_2.record_length::<U16>(3), Some(8)); // (3 + 4 + 1)
2253
2254            // Test LengthEncoding::encode_length
2255
2256            fn encode_length<K: KindLenField>(
2257                length_encoding: LengthEncoding,
2258                option_body_len: usize,
2259            ) -> Option<usize> {
2260                length_encoding.encode_length::<K>(option_body_len).map(Into::into)
2261            }
2262
2263            // For `ValueOnly`, `encode_length` should always return the
2264            // argument unmodified.
2265            assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 0), Some(0));
2266            assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 1), Some(1));
2267            assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 2), Some(2));
2268            assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 3), Some(3));
2269
2270            assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 0), Some(0));
2271            assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 1), Some(1));
2272            assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 2), Some(2));
2273            assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 3), Some(3));
2274
2275            // For `TypeLengthValue` with `option_len_multiplier = 1`,
2276            // `encode_length` should always add 2 or 4 for the kind and length
2277            // bytes.
2278            assert_eq!(encode_length::<u8>(TLV_1, 0), Some(2));
2279            assert_eq!(encode_length::<u8>(TLV_1, 1), Some(3));
2280            assert_eq!(encode_length::<u8>(TLV_1, 2), Some(4));
2281            assert_eq!(encode_length::<u8>(TLV_1, 3), Some(5));
2282
2283            assert_eq!(encode_length::<U16>(TLV_1, 0), Some(4));
2284            assert_eq!(encode_length::<U16>(TLV_1, 1), Some(5));
2285            assert_eq!(encode_length::<U16>(TLV_1, 2), Some(6));
2286            assert_eq!(encode_length::<U16>(TLV_1, 3), Some(7));
2287
2288            // For `TypeLengthValue` with `option_len_multiplier = 2`,
2289            // `encode_length` should always add 2 or 4 for the kind and length
2290            // bytes, add padding if necessary to reach a multiple of 2, and
2291            // then divide by 2.
2292            assert_eq!(encode_length::<u8>(TLV_2, 0), Some(1)); // (0 + 2)     / 2
2293            assert_eq!(encode_length::<u8>(TLV_2, 1), Some(2)); // (1 + 2 + 1) / 2
2294            assert_eq!(encode_length::<u8>(TLV_2, 2), Some(2)); // (2 + 2)     / 2
2295            assert_eq!(encode_length::<u8>(TLV_2, 3), Some(3)); // (3 + 2 + 1) / 2
2296
2297            assert_eq!(encode_length::<U16>(TLV_2, 0), Some(2)); // (0 + 4)     / 2
2298            assert_eq!(encode_length::<U16>(TLV_2, 1), Some(3)); // (1 + 4 + 1) / 2
2299            assert_eq!(encode_length::<U16>(TLV_2, 2), Some(3)); // (2 + 4)     / 2
2300            assert_eq!(encode_length::<U16>(TLV_2, 3), Some(4)); // (3 + 4 + 1) / 2
2301
2302            // Test LengthEncoding::decode_length
2303
2304            fn decode_length<K: KindLenField>(
2305                length_encoding: LengthEncoding,
2306                length_field: usize,
2307            ) -> Option<usize> {
2308                length_encoding.decode_length::<K>(length_field.try_into().unwrap())
2309            }
2310
2311            // For `ValueOnly`, `decode_length` should always return the
2312            // argument unmodified.
2313            assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 0), Some(0));
2314            assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 1), Some(1));
2315            assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 2), Some(2));
2316            assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 3), Some(3));
2317
2318            assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 0), Some(0));
2319            assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 1), Some(1));
2320            assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 2), Some(2));
2321            assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 3), Some(3));
2322
2323            // For `TypeLengthValue` with `option_len_multiplier = 1`,
2324            // `decode_length` should always subtract 2 or 4 for the kind and
2325            // length bytes.
2326            assert_eq!(decode_length::<u8>(TLV_1, 0), None);
2327            assert_eq!(decode_length::<u8>(TLV_1, 1), None);
2328            assert_eq!(decode_length::<u8>(TLV_1, 2), Some(0));
2329            assert_eq!(decode_length::<u8>(TLV_1, 3), Some(1));
2330
2331            assert_eq!(decode_length::<U16>(TLV_1, 0), None);
2332            assert_eq!(decode_length::<U16>(TLV_1, 1), None);
2333            assert_eq!(decode_length::<U16>(TLV_1, 2), None);
2334            assert_eq!(decode_length::<U16>(TLV_1, 3), None);
2335            assert_eq!(decode_length::<U16>(TLV_1, 4), Some(0));
2336            assert_eq!(decode_length::<U16>(TLV_1, 5), Some(1));
2337
2338            // For `TypeLengthValue` with `option_len_multiplier = 2`,
2339            // `decode_length` should always multiply by 2 or 4 and then
2340            // subtract 2 for the kind and length bytes.
2341            assert_eq!(decode_length::<u8>(TLV_2, 0), None);
2342            assert_eq!(decode_length::<u8>(TLV_2, 1), Some(0));
2343            assert_eq!(decode_length::<u8>(TLV_2, 2), Some(2));
2344            assert_eq!(decode_length::<u8>(TLV_2, 3), Some(4));
2345
2346            assert_eq!(decode_length::<U16>(TLV_2, 0), None);
2347            assert_eq!(decode_length::<U16>(TLV_2, 1), None);
2348            assert_eq!(decode_length::<U16>(TLV_2, 2), Some(0));
2349            assert_eq!(decode_length::<U16>(TLV_2, 3), Some(2));
2350
2351            // Test end-to-end by creating options implementation with different
2352            // length encodings.
2353
2354            /// Declare a new options impl type with a custom `LENGTH_ENCODING`.
2355            macro_rules! declare_options_impl {
2356                ($opt:ident, $impl:ident, $encoding:expr) => {
2357                    #[derive(Debug)]
2358                    enum $impl {}
2359
2360                    #[derive(Debug, PartialEq)]
2361                    struct $opt {
2362                        kind: u8,
2363                        data: Vec<u8>,
2364                    }
2365
2366                    impl<'a> From<&'a (u8, Vec<u8>)> for $opt {
2367                        fn from((kind, data): &'a (u8, Vec<u8>)) -> $opt {
2368                            $opt { kind: *kind, data: data.clone() }
2369                        }
2370                    }
2371
2372                    impl OptionLayout for $opt {
2373                        const LENGTH_ENCODING: LengthEncoding = $encoding;
2374                        type KindLenField = u8;
2375                    }
2376
2377                    impl OptionLayout for $impl {
2378                        const LENGTH_ENCODING: LengthEncoding = $encoding;
2379                        type KindLenField = u8;
2380                    }
2381
2382                    impl OptionParseLayout for $impl {
2383                        type Error = OptionParseErr;
2384                        const END_OF_OPTIONS: Option<u8> = Some(0);
2385                        const NOP: Option<u8> = Some(1);
2386                    }
2387
2388                    impl OptionsImpl for $impl {
2389                        type Option<'a> = $opt;
2390
2391                        fn parse<'a>(
2392                            kind: u8,
2393                            data: &'a [u8],
2394                        ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
2395                            let mut v = Vec::new();
2396                            v.extend_from_slice(data);
2397                            Ok(Some($opt { kind, data: v }))
2398                        }
2399                    }
2400
2401                    impl OptionBuilder for $opt {
2402                        type Layout = $impl;
2403
2404                        fn serialized_len(&self) -> usize {
2405                            self.data.len()
2406                        }
2407
2408                        fn option_kind(&self) -> u8 {
2409                            self.kind
2410                        }
2411
2412                        fn serialize_into(&self, data: &mut [u8]) {
2413                            assert_eq!(data.len(), OptionBuilder::serialized_len(self));
2414                            data.copy_from_slice(&self.data);
2415                        }
2416                    }
2417                };
2418            }
2419
2420            declare_options_impl!(
2421                DummyImplValueOnly,
2422                DummyImplValueOnlyImpl,
2423                LengthEncoding::ValueOnly
2424            );
2425            declare_options_impl!(DummyImplTlv1, DummyImplTlv1Impl, TLV_1);
2426            declare_options_impl!(DummyImplTlv2, DummyImplTlv2Impl, TLV_2);
2427
2428            /// Tests that a given option is parsed from different byte
2429            /// sequences for different options layouts.
2430            ///
2431            /// Since some options cannot be parsed from any byte sequence using
2432            /// the `DummyImplTlv2` layout (namely, those whose lengths are not
2433            /// a multiple of 2), `tlv_2` may be `None`.
2434            fn test_parse(
2435                (expect_kind, expect_data): (u8, Vec<u8>),
2436                value_only: &[u8],
2437                tlv_1: &[u8],
2438                tlv_2: Option<&[u8]>,
2439            ) {
2440                let options = Options::<_, DummyImplValueOnlyImpl>::parse(value_only)
2441                    .unwrap()
2442                    .iter()
2443                    .collect::<Vec<_>>();
2444                let data = expect_data.clone();
2445                assert_eq!(options, [DummyImplValueOnly { kind: expect_kind, data }]);
2446
2447                let options = Options::<_, DummyImplTlv1Impl>::parse(tlv_1)
2448                    .unwrap()
2449                    .iter()
2450                    .collect::<Vec<_>>();
2451                let data = expect_data.clone();
2452                assert_eq!(options, [DummyImplTlv1 { kind: expect_kind, data }]);
2453
2454                if let Some(tlv_2) = tlv_2 {
2455                    let options = Options::<_, DummyImplTlv2Impl>::parse(tlv_2)
2456                        .unwrap()
2457                        .iter()
2458                        .collect::<Vec<_>>();
2459                    assert_eq!(options, [DummyImplTlv2 { kind: expect_kind, data: expect_data }]);
2460                }
2461            }
2462
2463            // 0-byte body
2464            test_parse((0xFF, vec![]), &[0xFF, 0], &[0xFF, 2], Some(&[0xFF, 1]));
2465            // 1-byte body
2466            test_parse((0xFF, vec![0]), &[0xFF, 1, 0], &[0xFF, 3, 0], None);
2467            // 2-byte body
2468            test_parse(
2469                (0xFF, vec![0, 1]),
2470                &[0xFF, 2, 0, 1],
2471                &[0xFF, 4, 0, 1],
2472                Some(&[0xFF, 2, 0, 1]),
2473            );
2474            // 3-byte body
2475            test_parse((0xFF, vec![0, 1, 2]), &[0xFF, 3, 0, 1, 2], &[0xFF, 5, 0, 1, 2], None);
2476            // 4-byte body
2477            test_parse(
2478                (0xFF, vec![0, 1, 2, 3]),
2479                &[0xFF, 4, 0, 1, 2, 3],
2480                &[0xFF, 6, 0, 1, 2, 3],
2481                Some(&[0xFF, 3, 0, 1, 2, 3]),
2482            );
2483
2484            /// Tests that an option can be serialized and then parsed in each
2485            /// option layout.
2486            ///
2487            /// In some cases (when the body length is not a multiple of 2), the
2488            /// `DummyImplTlv2` layout will parse a different option than was
2489            /// originally serialized. In this case, `expect_tlv_2` can be used
2490            /// to provide a different value to expect as the result of parsing.
2491            fn test_serialize_parse(opt: (u8, Vec<u8>), expect_tlv_2: Option<(u8, Vec<u8>)>) {
2492                let opts = [opt.clone()];
2493
2494                fn test_serialize_parse_inner<
2495                    O: OptionBuilder + Debug + PartialEq + for<'a> From<&'a (u8, Vec<u8>)>,
2496                    I: for<'a> OptionsImpl<Error = OptionParseErr, Option<'a> = O> + std::fmt::Debug,
2497                >(
2498                    opts: &[(u8, Vec<u8>)],
2499                    expect: &[(u8, Vec<u8>)],
2500                ) {
2501                    let opts = opts.iter().map(Into::into).collect::<Vec<_>>();
2502                    let expect = expect.iter().map(Into::into).collect::<Vec<_>>();
2503
2504                    let ser = OptionSequenceBuilder::<O, _>::new(opts.iter());
2505                    let serialized =
2506                        ser.into_serializer().serialize_vec_outer().unwrap().as_ref().to_vec();
2507                    let options = Options::<_, I>::parse(serialized.as_slice())
2508                        .unwrap()
2509                        .iter()
2510                        .collect::<Vec<_>>();
2511                    assert_eq!(options, expect);
2512                }
2513
2514                test_serialize_parse_inner::<DummyImplValueOnly, DummyImplValueOnlyImpl>(
2515                    &opts, &opts,
2516                );
2517                test_serialize_parse_inner::<DummyImplTlv1, DummyImplTlv1Impl>(&opts, &opts);
2518                let expect = if let Some(expect) = expect_tlv_2 { expect } else { opt };
2519                test_serialize_parse_inner::<DummyImplTlv2, DummyImplTlv2Impl>(&opts, &[expect]);
2520            }
2521
2522            // 0-byte body
2523            test_serialize_parse((0xFF, vec![]), None);
2524            // 1-byte body
2525            test_serialize_parse((0xFF, vec![0]), Some((0xFF, vec![0, 0])));
2526            // 2-byte body
2527            test_serialize_parse((0xFF, vec![0, 1]), None);
2528            // 3-byte body
2529            test_serialize_parse((0xFF, vec![0, 1, 2]), Some((0xFF, vec![0, 1, 2, 0])));
2530            // 4-byte body
2531            test_serialize_parse((0xFF, vec![0, 1, 2, 3]), None);
2532        }
2533
2534        #[test]
2535        fn test_empty_options() {
2536            // all END_OF_OPTIONS
2537            let bytes = [0; 64];
2538            let options = Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap();
2539            assert_eq!(options.iter().count(), 0);
2540
2541            // all NOP
2542            let bytes = [1; 64];
2543            let options = Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap();
2544            assert_eq!(options.iter().count(), 0);
2545        }
2546
2547        #[test]
2548        fn test_parse() {
2549            // Construct byte sequences in the pattern [3, 2], [4, 3, 2], [5, 4,
2550            // 3, 2], etc. The second byte is the length byte, so these are all
2551            // valid options (with data [], [2], [3, 2], etc).
2552            let mut bytes = Vec::new();
2553            for i in 4..16 {
2554                // from the user's perspective, these NOPs should be transparent
2555                bytes.push(1);
2556                for j in (2..i).rev() {
2557                    bytes.push(j);
2558                }
2559                // from the user's perspective, these NOPs should be transparent
2560                bytes.push(1);
2561            }
2562
2563            let options = Options::<_, DummyOptionsImpl>::parse(bytes.as_slice()).unwrap();
2564            for (idx, DummyOption { kind, data }) in options.iter().enumerate() {
2565                assert_eq!(kind as usize, idx + 3);
2566                assert_eq!(data.len(), idx);
2567                let mut bytes = Vec::new();
2568                for i in (2..(idx + 2)).rev() {
2569                    bytes.push(i as u8);
2570                }
2571                assert_eq!(data, bytes);
2572            }
2573
2574            // Test that we get no parse errors so long as
2575            // AlwaysErrOptionsImpl::parse is never called.
2576            //
2577            // `bytes` is a sequence of NOPs.
2578            let bytes = [1; 64];
2579            let options = Options::<_, AlwaysErrOptionsImpl>::parse(&bytes[..]).unwrap();
2580            assert_eq!(options.iter().count(), 0);
2581        }
2582
2583        #[test]
2584        fn test_parse_ndp_options() {
2585            let mut bytes = Vec::new();
2586            for i in 0..16 {
2587                bytes.push(i);
2588                // NDP uses len*8 for the actual length.
2589                bytes.push(i + 1);
2590                // Write remaining 6 bytes.
2591                for j in 2..((i + 1) * 8) {
2592                    bytes.push(j)
2593                }
2594            }
2595
2596            let options = Options::<_, DummyNdpOptionsImpl>::parse(bytes.as_slice()).unwrap();
2597            for (idx, NdpOption { kind, data }) in options.iter().enumerate() {
2598                assert_eq!(kind as usize, idx);
2599                assert_eq!(data.len(), ((idx + 1) * 8) - 2);
2600                let mut bytes = Vec::new();
2601                for i in 2..((idx + 1) * 8) {
2602                    bytes.push(i as u8);
2603                }
2604                assert_eq!(data, bytes);
2605            }
2606        }
2607
2608        #[test]
2609        fn test_parse_err() {
2610            // the length byte is too short
2611            let bytes = [2, 1];
2612            assert_eq!(
2613                Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2614                OptionParseErr
2615            );
2616
2617            // the length byte is 0 (similar check to above, but worth
2618            // explicitly testing since this was a bug in the Linux kernel:
2619            // https://bugzilla.redhat.com/show_bug.cgi?id=1622404)
2620            let bytes = [2, 0];
2621            assert_eq!(
2622                Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2623                OptionParseErr
2624            );
2625
2626            // the length byte is too long
2627            let bytes = [2, 3];
2628            assert_eq!(
2629                Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2630                OptionParseErr
2631            );
2632
2633            // the buffer is fine, but the implementation returns a parse error
2634            let bytes = [2, 2];
2635            assert_eq!(
2636                Options::<_, AlwaysErrOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2637                AlwaysErrorErr::Option,
2638            );
2639        }
2640
2641        #[test]
2642        fn test_missing_length_bytes() {
2643            // Construct a sequence with a valid record followed by an
2644            // incomplete one, where `kind` is specified but `len` is missing.
2645            // So we can assert that we'll fail cleanly in that case.
2646            //
2647            // Added as part of Change-Id
2648            // Ibd46ac7384c7c5e0d74cb344b48c88876c351b1a.
2649            //
2650            // Before the small refactor in the Change-Id above, there was a
2651            // check during parsing that guaranteed that the length of the
2652            // remaining buffer was >= 1, but it should've been a check for
2653            // >= 2, and the case below would have caused it to panic while
2654            // trying to access the length byte, which was a DoS vulnerability.
2655            assert_matches::assert_matches!(
2656                Options::<_, DummyOptionsImpl>::parse(&[0x03, 0x03, 0x01, 0x03][..]),
2657                Err(OptionParseErr)
2658            );
2659        }
2660
2661        #[test]
2662        fn test_partial_kind_field() {
2663            // Construct a sequence with only one byte where a two-byte kind
2664            // field is expected.
2665            //
2666            // Added as part of Change-Id
2667            // I468121f5712b73c4e704460f580f166c876ee7d6.
2668            //
2669            // Before the small refactor in the Change-Id above, we treated any
2670            // failure to consume the kind field from the byte slice as
2671            // indicating that there were no bytes left, and we would stop
2672            // parsing successfully. This logic was correct when we only
2673            // supported 1-byte kind fields, but it became incorrect once we
2674            // introduced multi-byte kind fields.
2675            assert_matches::assert_matches!(
2676                Options::<_, DummyMultiByteKindOptionsImpl>::parse(&[0x00][..]),
2677                Err(OptionParseErr)
2678            );
2679        }
2680
2681        #[test]
2682        fn test_parse_and_serialize() {
2683            // Construct byte sequences in the pattern [3, 2], [4, 3, 2], [5, 4,
2684            // 3, 2], etc. The second byte is the length byte, so these are all
2685            // valid options (with data [], [2], [3, 2], etc).
2686            let mut bytes = Vec::new();
2687            for i in 4..16 {
2688                // from the user's perspective, these NOPs should be transparent
2689                for j in (2..i).rev() {
2690                    bytes.push(j);
2691                }
2692            }
2693
2694            let options = Options::<_, DummyOptionsImpl>::parse(bytes.as_slice()).unwrap();
2695
2696            let collected = options.iter().collect::<Vec<_>>();
2697            // Pass `collected.iter()` instead of `options.iter()` since we need
2698            // an iterator over references, and `options.iter()` produces an
2699            // iterator over values.
2700            let ser = OptionSequenceBuilder::<DummyOption, _>::new(collected.iter());
2701
2702            let serialized = ser.into_serializer().serialize_vec_outer().unwrap().as_ref().to_vec();
2703
2704            assert_eq!(serialized, bytes);
2705        }
2706
2707        fn test_ndp_bytes() -> Vec<u8> {
2708            let mut bytes = Vec::new();
2709            for i in 0..16 {
2710                bytes.push(i);
2711                // NDP uses len*8 for the actual length.
2712                bytes.push(i + 1);
2713                // Write remaining 6 bytes.
2714                for j in 2..((i + 1) * 8) {
2715                    bytes.push(j)
2716                }
2717            }
2718            bytes
2719        }
2720
2721        #[test]
2722        fn test_parse_and_serialize_ndp() {
2723            let bytes = test_ndp_bytes();
2724            let options = Options::<_, DummyNdpOptionsImpl>::parse(bytes.as_slice()).unwrap();
2725            let collected = options.iter().collect::<Vec<_>>();
2726            // Pass `collected.iter()` instead of `options.iter()` since we need
2727            // an iterator over references, and `options.iter()` produces an
2728            // iterator over values.
2729            let ser = OptionSequenceBuilder::<NdpOption, _>::new(collected.iter());
2730
2731            let serialized = ser.into_serializer().serialize_vec_outer().unwrap().as_ref().to_vec();
2732
2733            assert_eq!(serialized, bytes);
2734        }
2735
2736        #[test]
2737        fn measure_ndp_records() {
2738            let bytes = test_ndp_bytes();
2739            let options = Options::<_, DummyNdpOptionsImpl>::parse(bytes.as_slice()).unwrap();
2740            let collected = options.iter().collect::<Vec<_>>();
2741
2742            for (i, mut bytes) in options.iter_bytes().enumerate() {
2743                // Each byte slice we iterate over should parse as the equivalent NDP option.
2744                let parsed = <DummyNdpOptionsImpl as RecordsImpl>::parse_with_context(
2745                    &mut &mut bytes,
2746                    &mut (),
2747                )
2748                .expect("should parse successfully");
2749                let option = match parsed {
2750                    ParsedRecord::Parsed(option) => option,
2751                    ParsedRecord::Skipped => panic!("no options should be skipped"),
2752                    ParsedRecord::Done => panic!("should not be done"),
2753                };
2754                assert_eq!(option, collected[i]);
2755
2756                // The byte slice should be exhausted after re-parsing the record.
2757                assert_eq!(bytes, &[]);
2758            }
2759        }
2760
2761        #[test]
2762        fn test_parse_and_serialize_multi_byte_fields() {
2763            let mut bytes = Vec::new();
2764            for i in 4..16 {
2765                // Push kind U16<NetworkEndian>.
2766                bytes.push(0);
2767                bytes.push(i);
2768                // Push length U16<NetworkEndian>.
2769                bytes.push(0);
2770                bytes.push(i);
2771                // Write `i` - 4 bytes.
2772                for j in 4..i {
2773                    bytes.push(j);
2774                }
2775            }
2776
2777            let options =
2778                Options::<_, DummyMultiByteKindOptionsImpl>::parse(bytes.as_slice()).unwrap();
2779            for (idx, MultiByteOption { kind, data }) in options.iter().enumerate() {
2780                assert_eq!(usize::from(kind), idx + 4);
2781                let idx: u8 = idx.try_into().unwrap();
2782                let bytes: Vec<_> = (4..(idx + 4)).collect();
2783                assert_eq!(data, bytes);
2784            }
2785
2786            let collected = options.iter().collect::<Vec<_>>();
2787            // Pass `collected.iter()` instead of `options.iter()` since we need
2788            // an iterator over references, and `options.iter()` produces an
2789            // iterator over values.
2790            let ser = OptionSequenceBuilder::<MultiByteOption, _>::new(collected.iter());
2791            let mut output = vec![0u8; ser.serialized_len()];
2792            ser.serialize_into(output.as_mut_slice());
2793            assert_eq!(output, bytes);
2794        }
2795
2796        #[test]
2797        fn test_align_up_to() {
2798            // We are doing some sort of property testing here:
2799            // We generate a random alignment requirement (x, y) and a random offset `pos`.
2800            // The resulting `new_pos` must:
2801            //   - 1. be at least as large as the original `pos`.
2802            //   - 2. be in form of x * n + y for some integer n.
2803            //   - 3. for any number in between, they shouldn't be in form of x * n + y.
2804            use rand::Rng;
2805            let mut rng = rand::rng();
2806            for _ in 0..100_000 {
2807                let x = rng.random_range(1usize..256);
2808                let y = rng.random_range(0..x);
2809                let pos = rng.random_range(0usize..65536);
2810                let new_pos = align_up_to(pos, x, y);
2811                // 1)
2812                assert!(new_pos >= pos);
2813                // 2)
2814                assert_eq!((new_pos - y) % x, 0);
2815                // 3) Note: `p` is not guaranteed to be bigger than `y`, plus `x` to avoid overflow.
2816                assert!((pos..new_pos).all(|p| (p + x - y) % x != 0))
2817            }
2818        }
2819
2820        #[test]
2821        #[rustfmt::skip]
2822        fn test_aligned_dummy_options_serializer() {
2823            // testing for cases: 2n+{0,1}, 3n+{1,2}, 1n+0, 4n+2
2824            let dummy_options = [
2825                // alignment requirement: 2 * n + 1,
2826                //
2827                DummyOption { kind: 1, data: vec![42, 42] },
2828                DummyOption { kind: 0, data: vec![42, 42] },
2829                DummyOption { kind: 1, data: vec![1, 2, 3] },
2830                DummyOption { kind: 2, data: vec![3, 2, 1] },
2831                DummyOption { kind: 0, data: vec![42] },
2832                DummyOption { kind: 2, data: vec![9, 9, 9, 9] },
2833            ];
2834            let ser = AlignedRecordSequenceBuilder::<DummyOption, _>::new(
2835                0,
2836                dummy_options.iter(),
2837            );
2838            assert_eq!(ser.serialized_len(), 32);
2839            let mut buf = [0u8; 32];
2840            ser.serialize_into(&mut buf[..]);
2841            assert_eq!(
2842                &buf[..],
2843                &[
2844                    0, // Pad1 padding
2845                    1, 4, 42, 42, // (1, [42, 42]) starting at 2 * 0 + 1 = 3
2846                    0,  // Pad1 padding
2847                    0, 4, 42, 42, // (0, [42, 42]) starting at 2 * 3 + 0 = 6
2848                    1, 5, 1, 2, 3, // (1, [1, 2, 3]) starting at 3 * 2 + 1 = 7
2849                    1, 0, // PadN padding
2850                    2, 5, 3, 2, 1, // (2, [3, 2, 1]) starting at 3 * 4 + 2 = 14
2851                    0, 3, 42, // (0, [42]) starting at 1 * 19 + 0 = 19
2852                    0,  // PAD1 padding
2853                    2, 6, 9, 9, 9, 9 // (2, [9, 9, 9, 9]) starting at 4 * 6 + 2 = 26
2854                    // total length: 32
2855                ]
2856            );
2857        }
2858    }
2859}