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