netstack3_base/tcp/
segment.rs

1// Copyright 2024 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//! The definition of a TCP segment.
6
7use crate::alloc::borrow::ToOwned;
8use core::borrow::Borrow;
9use core::convert::TryFrom as _;
10use core::fmt::Debug;
11use core::mem::MaybeUninit;
12use core::num::TryFromIntError;
13use core::ops::Range;
14
15use arrayvec::ArrayVec;
16use log::info;
17use net_types::ip::IpAddress;
18use packet::InnerSerializer;
19use packet::records::options::OptionSequenceBuilder;
20use packet_formats::tcp::options::{TcpOption, TcpSackBlock};
21use packet_formats::tcp::{TcpSegment, TcpSegmentBuilder, TcpSegmentBuilderWithOptions};
22use thiserror::Error;
23
24use super::base::{Control, Mss};
25use super::seqnum::{SeqNum, UnscaledWindowSize, WindowScale, WindowSize};
26use super::timestamp::{Timestamp, TimestampOption};
27
28/// A TCP segment.
29#[derive(Debug, PartialEq, Eq, Clone)]
30pub struct Segment<P> {
31    /// The non-payload information of the segment.
32    header: SegmentHeader,
33    /// The data carried by the segment.
34    ///
35    /// It is guaranteed that data.len() plus the length of the control flag
36    /// (SYN or FIN) is <= MAX_PAYLOAD_AND_CONTROL_LEN
37    data: P,
38}
39
40/// All non-data portions of a TCP segment.
41#[derive(Debug, PartialEq, Eq, Clone)]
42pub struct SegmentHeader {
43    /// The sequence number of the segment.
44    pub seq: SeqNum,
45    /// The acknowledge number of the segment. [`None`] if not present.
46    pub ack: Option<SeqNum>,
47    /// The advertised window size.
48    pub wnd: UnscaledWindowSize,
49    /// The control flag of the segment.
50    pub control: Option<Control>,
51    /// Indicates whether the PSH bit is set.
52    pub push: bool,
53    /// Options carried by this segment.
54    pub options: Options,
55}
56
57/// Contains all supported TCP options.
58#[derive(Debug, PartialEq, Eq, Clone)]
59pub enum Options {
60    /// Options present in a handshake segment.
61    Handshake(HandshakeOptions),
62    /// Options present in a data/ack segment.
63    Segment(SegmentOptions),
64    /// Options present in a reset segment.
65    Reset(ResetOptions),
66}
67
68impl Options {
69    /// Creates a new [`Options`] with default values based on the control flag.
70    fn new(control: Option<&Control>) -> Self {
71        match control {
72            None | Some(Control::FIN) => Options::Segment(Default::default()),
73            Some(Control::SYN) => Options::Handshake(Default::default()),
74            Some(Control::RST) => Options::Reset(Default::default()),
75        }
76    }
77}
78
79impl From<HandshakeOptions> for Options {
80    fn from(value: HandshakeOptions) -> Self {
81        Self::Handshake(value)
82    }
83}
84
85impl From<SegmentOptions> for Options {
86    fn from(value: SegmentOptions) -> Self {
87        Self::Segment(value)
88    }
89}
90
91impl From<ResetOptions> for Options {
92    fn from(value: ResetOptions) -> Self {
93        Self::Reset(value)
94    }
95}
96
97impl Options {
98    /// Returns an iterator over the contained options.
99    pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Clone + Debug {
100        OptionsIter { inner: self, next: 0 }
101    }
102
103    fn as_handshake(&self) -> Option<&HandshakeOptions> {
104        match self {
105            Self::Handshake(h) => Some(h),
106            Self::Segment(_) | Self::Reset(_) => None,
107        }
108    }
109
110    fn as_handshake_mut(&mut self) -> Option<&mut HandshakeOptions> {
111        match self {
112            Self::Handshake(h) => Some(h),
113            Self::Segment(_) | Self::Reset(_) => None,
114        }
115    }
116
117    fn as_segment(&self) -> Option<&SegmentOptions> {
118        match self {
119            Self::Handshake(_) | Self::Reset(_) => None,
120            Self::Segment(s) => Some(s),
121        }
122    }
123
124    fn as_segment_mut(&mut self) -> Option<&mut SegmentOptions> {
125        match self {
126            Self::Handshake(_) | Self::Reset(_) => None,
127            Self::Segment(s) => Some(s),
128        }
129    }
130
131    /// Creates a new [`Options`] from an iterator of TcpOption.
132    pub fn from_iter<'a>(
133        control: Option<&Control>,
134        iter: impl IntoIterator<Item = TcpOption<'a>>,
135    ) -> Self {
136        let mut options = Options::new(control);
137        for option in iter {
138            match option {
139                TcpOption::Mss(mss) => {
140                    if let Some(h) = options.as_handshake_mut() {
141                        // If the provided MSS options is too small, clamp it to
142                        // the minimum value. This is in line with the behavior
143                        // of other platforms (e.g. FreeBSD & Linux). See
144                        // https://fxbug.dev/439892604#comment1.
145                        h.mss = Some(Mss::new(mss).unwrap_or(Mss::MIN));
146                    }
147                }
148                TcpOption::WindowScale(ws) => {
149                    if let Some(h) = options.as_handshake_mut() {
150                        // Per RFC 7323 Section 2.3:
151                        //   If a Window Scale option is received with a shift.cnt
152                        //   value larger than 14, the TCP SHOULD log the error but
153                        //   MUST use 14 instead of the specified value.
154                        if ws > WindowScale::MAX.get() {
155                            info!(
156                                "received an out-of-range window scale: {}, want < {}",
157                                ws,
158                                WindowScale::MAX.get()
159                            );
160                        }
161                        h.window_scale = Some(WindowScale::new(ws).unwrap_or(WindowScale::MAX));
162                    }
163                }
164                TcpOption::SackPermitted => {
165                    if let Some(h) = options.as_handshake_mut() {
166                        h.sack_permitted = true;
167                    }
168                }
169                TcpOption::Sack(sack) => {
170                    if let Some(seg) = options.as_segment_mut() {
171                        seg.sack_blocks = SackBlocks::from_option(sack);
172                    }
173                }
174                TcpOption::Timestamp { ts_val, ts_echo_reply } => {
175                    let timestamp = TimestampOption {
176                        ts_val: Timestamp::new(ts_val),
177                        ts_echo_reply: Timestamp::new(ts_echo_reply),
178                    };
179                    // NB: The timestamp option applies to all segment types.
180                    match options {
181                        Options::Handshake(ref mut h) => h.timestamp = Some(timestamp),
182                        Options::Segment(ref mut s) => s.timestamp = Some(timestamp),
183                        Options::Reset(ref mut r) => r.timestamp = Some(timestamp),
184                    }
185                }
186            }
187        }
188        options
189    }
190
191    /// Creates a new [`Options`] from an iterator of TcpOption.
192    pub fn try_from_iter<'a, A: IpAddress>(
193        builder: &TcpSegmentBuilder<A>,
194        iter: impl IntoIterator<Item = TcpOption<'a>>,
195    ) -> Result<Self, MalformedFlags> {
196        let control =
197            Flags { syn: builder.syn_set(), fin: builder.fin_set(), rst: builder.rst_set() }
198                .control()?;
199        Ok(Options::from_iter(control.as_ref(), iter))
200    }
201
202    /// Reads the window scale if this is an [`Options::Handshake`].
203    pub fn window_scale(&self) -> Option<WindowScale> {
204        self.as_handshake().and_then(|h| h.window_scale)
205    }
206
207    /// Reads the mss option if this is an [`Options::Handshake`].
208    pub fn mss(&self) -> Option<Mss> {
209        self.as_handshake().and_then(|h| h.mss)
210    }
211
212    /// Returns true IFF this is an [`Options::Handshake`] and its
213    /// [`HandShakeOptions::sack_permitted`] is set.
214    pub fn sack_permitted(&self) -> bool {
215        self.as_handshake().is_some_and(|o| o.sack_permitted)
216    }
217
218    /// Returns the segment's selective ack blocks.
219    ///
220    /// Returns a reference to empty blocks if this is not [`Options::Segment`].
221    pub fn sack_blocks(&self) -> &SackBlocks {
222        const EMPTY_REF: &'static SackBlocks = &SackBlocks::EMPTY;
223        self.as_segment().map(|s| &s.sack_blocks).unwrap_or(EMPTY_REF)
224    }
225
226    /// Returns the segment's TCP timestamp option, if there is one.
227    pub fn timestamp(&self) -> &Option<TimestampOption> {
228        match self {
229            Options::Handshake(h) => &h.timestamp,
230            Options::Segment(s) => &s.timestamp,
231            Options::Reset(r) => &r.timestamp,
232        }
233    }
234}
235
236/// Hand roll an [`Iterator`] implementation for TCP options.
237///
238/// This is primarily a performance optimization, because we found iterator
239/// combinators come with some overhead (primarily `chain()`).
240#[derive(Clone, Debug)]
241struct OptionsIter<'a> {
242    inner: &'a Options,
243    next: u8,
244}
245
246impl<'a> Iterator for OptionsIter<'a> {
247    type Item = TcpOption<'a>;
248
249    fn next(&mut self) -> Option<Self::Item> {
250        let Self { inner, next } = self;
251        match inner {
252            Options::Handshake(h) => h.next_option(next),
253            Options::Segment(s) => s.next_option(next),
254            Options::Reset(r) => r.next_option(next),
255        }
256    }
257}
258
259/// Segment options available on handshake segments.
260#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
261pub struct HandshakeOptions {
262    /// The MSS option.
263    pub mss: Option<Mss>,
264
265    /// The WS option.
266    pub window_scale: Option<WindowScale>,
267
268    /// The SACK permitted option.
269    pub sack_permitted: bool,
270
271    /// The timestamp option.
272    pub timestamp: Option<TimestampOption>,
273}
274
275impl HandshakeOptions {
276    // [`OptionsIter`] support.
277    fn next_option(&self, next: &mut u8) -> Option<TcpOption<'_>> {
278        let Self { mss, window_scale, sack_permitted, timestamp } = self;
279        // Find the next available option to produce for the iterator.
280        loop {
281            match core::mem::replace(next, next.wrapping_add(1)) {
282                0 => {
283                    if let Some(mss) = mss {
284                        return Some(TcpOption::Mss(mss.get()));
285                    }
286                }
287                1 => {
288                    if let Some(ws) = window_scale {
289                        return Some(TcpOption::WindowScale(ws.get()));
290                    }
291                }
292                2 => {
293                    if *sack_permitted {
294                        return Some(TcpOption::SackPermitted);
295                    }
296                }
297                3 => {
298                    if let Some(ts) = timestamp {
299                        return Some((*ts).into());
300                    }
301                }
302                4 => return None, // End of iterator
303                5.. => panic!("iterator already ended"),
304            }
305        }
306    }
307}
308
309/// Segment options available on data segments.
310#[derive(Debug, Default, PartialEq, Eq, Clone)]
311pub struct SegmentOptions {
312    /// The SACK option.
313    pub sack_blocks: SackBlocks,
314
315    /// The timestamp option.
316    pub timestamp: Option<TimestampOption>,
317}
318
319impl SegmentOptions {
320    /// Returns an iterator over the contained options.
321    pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Clone {
322        SegmentOptionsIter { inner: &self, next: 0 }
323    }
324
325    // [`OptionsIter`] support.
326    fn next_option(&self, next: &mut u8) -> Option<TcpOption<'_>> {
327        let Self { timestamp, sack_blocks } = self;
328        // Find the next available option to produce for the iterator.
329        loop {
330            match core::mem::replace(next, next.wrapping_add(1)) {
331                0 => {
332                    if let Some(ts) = timestamp {
333                        return Some((*ts).into());
334                    }
335                }
336                1 => {
337                    if let Some(sb) = sack_blocks.as_option() {
338                        return Some(sb);
339                    }
340                }
341                2 => return None, // End of iterator
342                3.. => panic!("iterator already ended"),
343            }
344        }
345    }
346
347    /// Returns true if there are no options present.
348    pub fn is_empty(&self) -> bool {
349        let Self { sack_blocks, timestamp } = self;
350        sack_blocks.is_empty() && timestamp.is_none()
351    }
352}
353
354/// Hand roll an [`Iterator`] implementation for TCP segment options.
355///
356/// This is primarily a performance optimization, because we found iterator
357/// combinators come with some overhead (primarily `chain()`).
358#[derive(Clone)]
359struct SegmentOptionsIter<'a> {
360    inner: &'a SegmentOptions,
361    next: u8,
362}
363
364impl<'a> Iterator for SegmentOptionsIter<'a> {
365    type Item = TcpOption<'a>;
366
367    fn next(&mut self) -> Option<Self::Item> {
368        let Self { inner, next } = self;
369        inner.next_option(next)
370    }
371}
372
373/// Segment options available on reset segments.
374#[derive(Debug, Default, PartialEq, Eq, Clone)]
375pub struct ResetOptions {
376    /// The timestamp option.
377    pub timestamp: Option<TimestampOption>,
378}
379
380impl ResetOptions {
381    // [`OptionsIter`] support.
382    fn next_option(&self, next: &mut u8) -> Option<TcpOption<'_>> {
383        let ResetOptions { timestamp } = self;
384        // Find the next available option to produce for the iterator.
385        loop {
386            match core::mem::replace(next, next.wrapping_add(1)) {
387                0 => {
388                    if let Some(ts) = timestamp {
389                        return Some((*ts).into());
390                    }
391                }
392                1 => return None, // End of iterator
393                2.. => panic!("iterator already ended"),
394            }
395        }
396    }
397}
398
399const MAX_SACK_BLOCKS: usize = 4;
400/// Blocks of selective ACKs.
401#[derive(Debug, Default, PartialEq, Eq, Clone)]
402pub struct SackBlocks(ArrayVec<TcpSackBlock, MAX_SACK_BLOCKS>);
403
404impl SackBlocks {
405    /// A constant empty instance of SACK blocks.
406    pub const EMPTY: Self = SackBlocks(ArrayVec::new_const());
407
408    /// The maximum number of selective ack blocks that can be in a TCP segment.
409    ///
410    /// See [RFC 2018 section 3].
411    ///
412    /// [RFC 2018 section 3] https://www.rfc-editor.org/rfc/rfc2018#section-3
413    pub const MAX_BLOCKS: usize = MAX_SACK_BLOCKS;
414
415    /// The maximum number of selective ack blocks that can be in a TCP segment
416    /// that includes the timestamp option.
417    ///
418    /// See [RFC 2018 section 3].
419    ///
420    /// [RFC 2018 section 3] https://www.rfc-editor.org/rfc/rfc2018#section-3
421    pub const MAX_BLOCKS_WITH_TIMESTAMP: usize = 3;
422
423    /// Returns the contained selective ACKs as a TCP option.
424    ///
425    /// Returns `None` if this [`SackBlocks`] is empty.
426    pub fn as_option(&self) -> Option<TcpOption<'_>> {
427        let Self(inner) = self;
428        if inner.is_empty() {
429            return None;
430        }
431
432        Some(TcpOption::Sack(inner.as_slice()))
433    }
434
435    /// Returns an iterator over the *valid* [`SackBlock`]s contained in this
436    /// option.
437    pub fn iter_skip_invalid(&self) -> impl Iterator<Item = SackBlock> + '_ {
438        self.try_iter().filter_map(|r| match r {
439            Ok(s) => Some(s),
440            Err(InvalidSackBlockError(_, _)) => None,
441        })
442    }
443
444    /// Returns an iterator yielding the results of converting the blocks in
445    /// this option to valid [`SackBlock`]s.
446    pub fn try_iter(&self) -> impl Iterator<Item = Result<SackBlock, InvalidSackBlockError>> + '_ {
447        let Self(inner) = self;
448        inner.iter().map(|block| SackBlock::try_from(*block))
449    }
450
451    /// Creates a new [`SackBlocks`] option from a slice of blocks seen in a TCP
452    /// segment.
453    ///
454    /// Ignores any blocks past [`SackBlocks::MAX_BLOCKS`].
455    pub fn from_option(blocks: &[TcpSackBlock]) -> Self {
456        Self(blocks.iter().take(Self::MAX_BLOCKS).copied().collect())
457    }
458
459    /// Returns `true` if there are no blocks present.
460    pub fn is_empty(&self) -> bool {
461        let Self(inner) = self;
462        inner.is_empty()
463    }
464
465    /// Drops all blocks.
466    pub fn clear(&mut self) {
467        let Self(inner) = self;
468        inner.clear()
469    }
470}
471
472/// Creates a new [`SackBlocks`] option from an iterator of [`SackBlock`].
473///
474/// Ignores any blocks past [`SackBlocks::MAX_BLOCKS`].
475impl FromIterator<SackBlock> for SackBlocks {
476    fn from_iter<T: IntoIterator<Item = SackBlock>>(iter: T) -> Self {
477        Self(iter.into_iter().take(Self::MAX_BLOCKS).map(|b| b.into()).collect())
478    }
479}
480
481mod sack_block {
482    use super::*;
483
484    /// A selective ACK block.
485    ///
486    /// Contains the left and right markers for a received data segment. It is a
487    /// witness for a valid non empty open range of `SeqNum`.
488    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
489    pub struct SackBlock {
490        // NB: We don't use core::ops::Range here because it doesn't implement Copy.
491        left: SeqNum,
492        right: SeqNum,
493    }
494
495    impl SackBlock {
496        /// Attempts to create a new [`SackBlock`] with the range `[left, right)`.
497        ///
498        /// Returns an error if `right` is at or before `left`.
499        pub fn try_new(left: SeqNum, right: SeqNum) -> Result<Self, InvalidSackBlockError> {
500            if right.after(left) {
501                Ok(Self { left, right })
502            } else {
503                Err(InvalidSackBlockError(left, right))
504            }
505        }
506
507        /// Creates a new [`SackBlock`] without checking that `right` is
508        /// strictly after `left`.
509        ///
510        /// # Safety
511        ///
512        /// Caller must guarantee that `right.after(left)`.
513        pub unsafe fn new_unchecked(left: SeqNum, right: SeqNum) -> Self {
514            Self { left, right }
515        }
516
517        /// Consumes this [`SackBlock`] returning a [`Range`] representation.
518        pub fn into_range(self) -> Range<SeqNum> {
519            let Self { left, right } = self;
520            Range { start: left, end: right }
521        }
522
523        /// Consumes this [`SackBlock`] returning a [`Range`] representation
524        /// unwrapping the [`SeqNum`] representation into `u32`.
525        pub fn into_range_u32(self) -> Range<u32> {
526            let Self { left, right } = self;
527            Range { start: left.into(), end: right.into() }
528        }
529
530        /// Returns the left (inclusive) edge of the block.
531        pub fn left(&self) -> SeqNum {
532            self.left
533        }
534
535        /// Returns the right (exclusive) edge of the block.
536        pub fn right(&self) -> SeqNum {
537            self.right
538        }
539
540        /// Returns a tuple of the left (inclusive) and right (exclusive) edges
541        /// of the block.
542        pub fn into_parts(self) -> (SeqNum, SeqNum) {
543            let Self { left, right } = self;
544            (left, right)
545        }
546    }
547
548    /// Error returned when attempting to create a [`SackBlock`] with an invalid
549    /// range (i.e. right edge <= left edge).
550    #[derive(Debug, Eq, PartialEq, Clone, Copy)]
551    pub struct InvalidSackBlockError(pub SeqNum, pub SeqNum);
552
553    impl From<SackBlock> for TcpSackBlock {
554        fn from(value: SackBlock) -> Self {
555            let SackBlock { left, right } = value;
556            TcpSackBlock::new(left.into(), right.into())
557        }
558    }
559
560    impl TryFrom<TcpSackBlock> for SackBlock {
561        type Error = InvalidSackBlockError;
562
563        fn try_from(value: TcpSackBlock) -> Result<Self, Self::Error> {
564            Self::try_new(value.left_edge().into(), value.right_edge().into())
565        }
566    }
567
568    impl From<SackBlock> for Range<SeqNum> {
569        fn from(value: SackBlock) -> Self {
570            value.into_range()
571        }
572    }
573
574    impl TryFrom<Range<SeqNum>> for SackBlock {
575        type Error = InvalidSackBlockError;
576
577        fn try_from(value: Range<SeqNum>) -> Result<Self, Self::Error> {
578            let Range { start, end } = value;
579            Self::try_new(start, end)
580        }
581    }
582}
583pub use sack_block::{InvalidSackBlockError, SackBlock};
584
585/// The maximum length that the sequence number doesn't wrap around.
586pub const MAX_PAYLOAD_AND_CONTROL_LEN: usize = 1 << 31;
587// The following `as` is sound because it is representable by `u32`.
588const MAX_PAYLOAD_AND_CONTROL_LEN_U32: u32 = MAX_PAYLOAD_AND_CONTROL_LEN as u32;
589
590impl<P: Payload> Segment<P> {
591    /// Creates a new segment with the provided header and data.
592    ///
593    /// Returns the segment along with how many bytes were removed to make sure
594    /// sequence numbers don't wrap around, i.e., `seq.before(seq + seg.len())`.
595    pub fn new(header: SegmentHeader, data: P) -> (Self, usize) {
596        let SegmentHeader { seq, ack, wnd, control, push, options } = header;
597        let has_control_len = control.map(Control::has_sequence_no).unwrap_or(false);
598
599        let data_len = data.len();
600        let discarded_len =
601            data_len.saturating_sub(MAX_PAYLOAD_AND_CONTROL_LEN - usize::from(has_control_len));
602
603        // Only keep the PSH bit if data is not empty.
604        let push = push && data_len != 0;
605
606        let (control, data) = if discarded_len > 0 {
607            // If we have to truncate the segment, the FIN flag must be removed
608            // because it is logically the last octet of the segment.
609            let (control, control_len) = if control == Some(Control::FIN) {
610                (None, 0)
611            } else {
612                (control, has_control_len.into())
613            };
614            // The following slice will not panic because `discarded_len > 0`,
615            // thus `data.len() > MAX_PAYLOAD_AND_CONTROL_LEN - control_len`.
616            (control, data.slice(0..MAX_PAYLOAD_AND_CONTROL_LEN_U32 - control_len))
617        } else {
618            (control, data)
619        };
620
621        (
622            Segment { header: SegmentHeader { seq, ack, wnd, control, push, options }, data: data },
623            discarded_len,
624        )
625    }
626
627    /// Returns a borrow of the segment's header.
628    pub fn header(&self) -> &SegmentHeader {
629        &self.header
630    }
631
632    /// Returns a borrow of the data payload in this segment.
633    pub fn data(&self) -> &P {
634        &self.data
635    }
636
637    /// Destructures self into its inner parts: The segment header and the data
638    /// payload.
639    pub fn into_parts(self) -> (SegmentHeader, P) {
640        let Self { header, data } = self;
641        (header, data)
642    }
643
644    /// Maps the payload in the segment with `f`.
645    pub fn map_payload<R, F: FnOnce(P) -> R>(self, f: F) -> Segment<R> {
646        let Segment { header, data } = self;
647        Segment { header, data: f(data) }
648    }
649
650    /// Returns the length of the segment in sequence number space.
651    ///
652    /// Per RFC 793 (https://tools.ietf.org/html/rfc793#page-25):
653    ///   SEG.LEN = the number of octets occupied by the data in the segment
654    ///   (counting SYN and FIN)
655    pub fn len(&self) -> u32 {
656        self.header.len(self.data.len())
657    }
658
659    /// Returns the part of the incoming segment within the receive window.
660    pub fn overlap(self, rnxt: SeqNum, rwnd: WindowSize) -> Option<Segment<P>> {
661        let len = self.len();
662        let Segment { header: SegmentHeader { seq, ack, wnd, control, options, push }, data } =
663            self;
664
665        // RFC 793 (https://tools.ietf.org/html/rfc793#page-69):
666        //   There are four cases for the acceptability test for an incoming
667        //   segment:
668        //       Segment Receive  Test
669        //       Length  Window
670        //       ------- -------  -------------------------------------------
671        //          0       0     SEG.SEQ = RCV.NXT
672        //          0      >0     RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
673        //         >0       0     not acceptable
674        //         >0      >0     RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
675        //                     or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
676        let overlap = match (len, rwnd) {
677            (0, WindowSize::ZERO) => seq == rnxt,
678            (0, rwnd) => !rnxt.after(seq) && seq.before(rnxt + rwnd),
679            (_len, WindowSize::ZERO) => false,
680            (len, rwnd) => {
681                (!rnxt.after(seq) && seq.before(rnxt + rwnd))
682                    // Note: here we use RCV.NXT <= SEG.SEQ+SEG.LEN instead of
683                    // the condition as quoted above because of the following
684                    // text immediately after the above table:
685                    //   One could tailor actual segments to fit this assumption by
686                    //   trimming off any portions that lie outside the window
687                    //   (including SYN and FIN), and only processing further if
688                    //   the segment then begins at RCV.NXT.
689                    // This is essential for TCP simultaneous open to work,
690                    // otherwise, the state machine would reject the SYN-ACK
691                    // sent by the peer.
692                    || (!(seq + len).before(rnxt) && !(seq + len).after(rnxt + rwnd))
693            }
694        };
695        overlap.then(move || {
696            // We deliberately don't define `PartialOrd` for `SeqNum`, so we use
697            // `cmp` below to utilize `cmp::{max,min}_by`.
698            let cmp = |lhs: &SeqNum, rhs: &SeqNum| (*lhs - *rhs).cmp(&0);
699            let new_seq = core::cmp::max_by(seq, rnxt, cmp);
700            let new_len = core::cmp::min_by(seq + len, rnxt + rwnd, cmp) - new_seq;
701            // The following unwrap won't panic because:
702            // 1. if `seq` is after `rnxt`, then `start` would be 0.
703            // 2. the interesting case is when `rnxt` is after `seq`, in that
704            // case, we have `rnxt - seq > 0`, thus `new_seq - seq > 0`.
705            let start = u32::try_from(new_seq - seq).unwrap();
706            // The following unwrap won't panic because:
707            // 1. The witness on `Segment` and `WindowSize` guarantees that
708            // `len <= 2^31` and `rwnd <= 2^30-1` thus
709            // `seq <= seq + len` and `rnxt <= rnxt + rwnd`.
710            // 2. We are in the closure because `overlap` is true which means
711            // `seq <= rnxt + rwnd` and `rnxt <= seq + len`.
712            // With these two conditions combined, `new_len` can't be negative
713            // so the unwrap can't panic.
714            let new_len = u32::try_from(new_len).unwrap();
715            let (new_control, new_data) = {
716                match control {
717                    Some(Control::SYN) => {
718                        if start == 0 {
719                            (Some(Control::SYN), data.slice(start..start + new_len - 1))
720                        } else {
721                            (None, data.slice(start - 1..start + new_len - 1))
722                        }
723                    }
724                    Some(Control::FIN) => {
725                        if len == start + new_len {
726                            if new_len > 0 {
727                                (Some(Control::FIN), data.slice(start..start + new_len - 1))
728                            } else {
729                                (None, data.slice(start - 1..start - 1))
730                            }
731                        } else {
732                            (None, data.slice(start..start + new_len))
733                        }
734                    }
735                    Some(Control::RST) | None => (control, data.slice(start..start + new_len)),
736                }
737            };
738            Segment {
739                header: SegmentHeader {
740                    seq: new_seq,
741                    ack,
742                    wnd,
743                    control: new_control,
744                    options,
745                    push,
746                },
747                data: new_data,
748            }
749        })
750    }
751
752    /// Creates a segment with no data.
753    pub fn new_empty(header: SegmentHeader) -> Self {
754        // All of the checks on lengths are optimized out:
755        // https://godbolt.org/z/KPd537G6Y
756        let (seg, truncated) = Self::new(header, P::new_empty());
757        debug_assert_eq!(truncated, 0);
758        seg
759    }
760
761    /// Creates an ACK segment.
762    pub fn ack(seq: SeqNum, ack: SeqNum, wnd: UnscaledWindowSize, options: SegmentOptions) -> Self {
763        Segment::new_empty(SegmentHeader {
764            seq,
765            ack: Some(ack),
766            wnd,
767            control: None,
768            push: false,
769            options: options.into(),
770        })
771    }
772
773    /// Creates a SYN segment.
774    pub fn syn(seq: SeqNum, wnd: UnscaledWindowSize, options: HandshakeOptions) -> Self {
775        Segment::new_empty(SegmentHeader {
776            seq,
777            ack: None,
778            wnd,
779            control: Some(Control::SYN),
780            push: false,
781            options: options.into(),
782        })
783    }
784
785    /// Creates a SYN-ACK segment.
786    pub fn syn_ack(
787        seq: SeqNum,
788        ack: SeqNum,
789        wnd: UnscaledWindowSize,
790        options: HandshakeOptions,
791    ) -> Self {
792        Segment::new_empty(SegmentHeader {
793            seq,
794            ack: Some(ack),
795            wnd,
796            control: Some(Control::SYN),
797            push: false,
798            options: options.into(),
799        })
800    }
801
802    /// Creates a RST segment.
803    pub fn rst(seq: SeqNum, options: ResetOptions) -> Self {
804        Segment::new_empty(SegmentHeader {
805            seq,
806            ack: None,
807            wnd: UnscaledWindowSize::from(0),
808            control: Some(Control::RST),
809            push: false,
810            options: options.into(),
811        })
812    }
813
814    /// Creates a RST-ACK segment.
815    pub fn rst_ack(seq: SeqNum, ack: SeqNum, options: ResetOptions) -> Self {
816        Segment::new_empty(SegmentHeader {
817            seq,
818            ack: Some(ack),
819            wnd: UnscaledWindowSize::from(0),
820            control: Some(Control::RST),
821            push: false,
822            options: options.into(),
823        })
824    }
825}
826
827impl Segment<()> {
828    /// Converts this segment with `()` data into any `P` payload's `new_empty`
829    /// form.
830    pub fn into_empty<P: Payload>(self) -> Segment<P> {
831        self.map_payload(|()| P::new_empty())
832    }
833}
834
835impl SegmentHeader {
836    /// Returns the length of the segment in sequence number space.
837    ///
838    /// Per RFC 793 (https://tools.ietf.org/html/rfc793#page-25):
839    ///   SEG.LEN = the number of octets occupied by the data in the segment
840    ///   (counting SYN and FIN)
841    pub fn len(&self, payload_len: usize) -> u32 {
842        // The following unwrap and addition are fine because:
843        // - `u32::from(has_control_len)` is 0 or 1.
844        // - `self.data.len() <= 2^31`.
845        let has_control_len = self.control.map(Control::has_sequence_no).unwrap_or(false);
846        u32::try_from(payload_len).unwrap() + u32::from(has_control_len)
847    }
848
849    /// Create a `SegmentHeader` from the provided builder and data length.  The
850    /// options will be set to their default values.
851    pub fn from_builder<A: IpAddress>(
852        builder: &TcpSegmentBuilder<A>,
853    ) -> Result<Self, MalformedFlags> {
854        let control =
855            Flags { syn: builder.syn_set(), fin: builder.fin_set(), rst: builder.rst_set() }
856                .control()?;
857        let options = Options::new(control.as_ref());
858        Self::from_builder_options(builder, options)
859    }
860
861    /// Create a `SegmentHeader` from the provided builder, options, and data length.
862    pub fn from_builder_options<A: IpAddress>(
863        builder: &TcpSegmentBuilder<A>,
864        options: Options,
865    ) -> Result<Self, MalformedFlags> {
866        Ok(SegmentHeader {
867            seq: SeqNum::new(builder.seq_num()),
868            ack: builder.ack_num().map(SeqNum::new),
869            control: Flags {
870                syn: builder.syn_set(),
871                fin: builder.fin_set(),
872                rst: builder.rst_set(),
873            }
874            .control()?,
875            wnd: UnscaledWindowSize::from(builder.window_size()),
876            push: builder.psh_set(),
877            options: options,
878        })
879    }
880}
881
882/// A TCP payload that only allows for getting the length of the payload.
883pub trait PayloadLen {
884    /// Returns the length of the payload.
885    fn len(&self) -> usize;
886}
887
888/// A TCP payload that operates around `u32` instead of `usize`.
889pub trait Payload: PayloadLen + Sized {
890    /// Creates a slice of the payload, reducing it to only the bytes within
891    /// `range`.
892    ///
893    /// # Panics
894    ///
895    /// Panics if the provided `range` is not within the bounds of this
896    /// `Payload`, or if the range is nonsensical (the end precedes
897    /// the start).
898    fn slice(self, range: Range<u32>) -> Self;
899
900    /// Copies part of the payload beginning at `offset` into `dst`.
901    ///
902    /// # Panics
903    ///
904    /// Panics if offset is too large or we couldn't fill the `dst` slice.
905    fn partial_copy(&self, offset: usize, dst: &mut [u8]);
906
907    /// Copies part of the payload beginning at `offset` into `dst`.
908    ///
909    /// # Panics
910    ///
911    /// Panics if offset is too large or we couldn't fill the `dst` slice.
912    fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]);
913
914    /// Creates a new empty payload.
915    ///
916    /// An empty payload must report 0 as its length.
917    fn new_empty() -> Self;
918}
919
920impl PayloadLen for &[u8] {
921    fn len(&self) -> usize {
922        <[u8]>::len(self)
923    }
924}
925
926impl Payload for &[u8] {
927    fn slice(self, Range { start, end }: Range<u32>) -> Self {
928        // The following `unwrap`s are ok because:
929        // `usize::try_from(x)` fails when `x > usize::MAX`; given that
930        // `self.len() <= usize::MAX`, panic would be expected because `range`
931        // exceeds the bound of `self`.
932        let start = usize::try_from(start).unwrap_or_else(|TryFromIntError { .. }| {
933            panic!("range start index {} out of range for slice of length {}", start, self.len())
934        });
935        let end = usize::try_from(end).unwrap_or_else(|TryFromIntError { .. }| {
936            panic!("range end index {} out of range for slice of length {}", end, self.len())
937        });
938        &self[start..end]
939    }
940
941    fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
942        dst.copy_from_slice(&self[offset..offset + dst.len()])
943    }
944
945    fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]) {
946        // TODO(https://github.com/rust-lang/rust/issues/79995): Replace unsafe
947        // with copy_from_slice when stabiliized.
948        let src = &self[offset..offset + dst.len()];
949        // SAFETY: &[T] and &[MaybeUninit<T>] have the same layout.
950        let uninit_src: &[MaybeUninit<u8>] = unsafe { core::mem::transmute(src) };
951        dst.copy_from_slice(&uninit_src);
952    }
953
954    fn new_empty() -> Self {
955        &[]
956    }
957}
958
959impl PayloadLen for () {
960    fn len(&self) -> usize {
961        0
962    }
963}
964
965impl Payload for () {
966    fn slice(self, Range { start, end }: Range<u32>) -> Self {
967        if start != 0 {
968            panic!("range start index {} out of range for slice of length 0", start);
969        }
970        if end != 0 {
971            panic!("range end index {} out of range for slice of length 0", end);
972        }
973        ()
974    }
975
976    fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
977        if dst.len() != 0 || offset != 0 {
978            panic!(
979                "source slice length (0) does not match destination slice length ({})",
980                dst.len()
981            );
982        }
983    }
984
985    fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]) {
986        if dst.len() != 0 || offset != 0 {
987            panic!(
988                "source slice length (0) does not match destination slice length ({})",
989                dst.len()
990            );
991        }
992    }
993
994    fn new_empty() -> Self {
995        ()
996    }
997}
998
999impl<I: PayloadLen, B> PayloadLen for InnerSerializer<I, B> {
1000    fn len(&self) -> usize {
1001        PayloadLen::len(self.inner())
1002    }
1003}
1004
1005#[derive(Error, Debug, PartialEq, Eq)]
1006#[error("multiple mutually exclusive flags are set: syn: {syn}, fin: {fin}, rst: {rst}")]
1007pub struct MalformedFlags {
1008    syn: bool,
1009    fin: bool,
1010    rst: bool,
1011}
1012
1013struct Flags {
1014    syn: bool,
1015    fin: bool,
1016    rst: bool,
1017}
1018
1019impl Flags {
1020    fn control(&self) -> Result<Option<Control>, MalformedFlags> {
1021        if usize::from(self.syn) + usize::from(self.fin) + usize::from(self.rst) > 1 {
1022            return Err(MalformedFlags { syn: self.syn, fin: self.fin, rst: self.rst });
1023        }
1024
1025        let syn = self.syn.then_some(Control::SYN);
1026        let fin = self.fin.then_some(Control::FIN);
1027        let rst = self.rst.then_some(Control::RST);
1028
1029        Ok(syn.or(fin).or(rst))
1030    }
1031}
1032
1033/// A TCP segment that has been verified to have valid flags. Can be converted
1034/// to a `Segment`.
1035pub struct VerifiedTcpSegment<'a> {
1036    segment: TcpSegment<&'a [u8]>,
1037    control: Option<Control>,
1038}
1039
1040impl<'a> VerifiedTcpSegment<'a> {
1041    /// Returns the underlying [`TcpSegment`].
1042    pub fn tcp_segment(&self) -> &TcpSegment<&'a [u8]> {
1043        &self.segment
1044    }
1045
1046    /// Returns the control flag of the segment.
1047    pub fn control(&self) -> Option<Control> {
1048        self.control
1049    }
1050}
1051
1052impl<'a> TryFrom<TcpSegment<&'a [u8]>> for VerifiedTcpSegment<'a> {
1053    type Error = MalformedFlags;
1054
1055    fn try_from(segment: TcpSegment<&'a [u8]>) -> Result<Self, Self::Error> {
1056        let control =
1057            Flags { syn: segment.syn(), fin: segment.fin(), rst: segment.rst() }.control()?;
1058        Ok(VerifiedTcpSegment { segment, control })
1059    }
1060}
1061
1062impl<'a> From<&'a VerifiedTcpSegment<'a>> for Segment<&'a [u8]> {
1063    fn from(from: &'a VerifiedTcpSegment<'a>) -> Segment<&'a [u8]> {
1064        let VerifiedTcpSegment { segment, control } = from;
1065        let options = Options::from_iter(control.as_ref(), segment.iter_options());
1066        let (to, discarded) = Segment::new(
1067            SegmentHeader {
1068                seq: segment.seq_num().into(),
1069                ack: segment.ack_num().map(Into::into),
1070                wnd: UnscaledWindowSize::from(segment.window_size()),
1071                control: *control,
1072                push: segment.psh(),
1073                options,
1074            },
1075            from.segment.body(),
1076        );
1077        debug_assert_eq!(discarded, 0);
1078        to
1079    }
1080}
1081
1082impl<A> TryFrom<&TcpSegmentBuilder<A>> for SegmentHeader
1083where
1084    A: IpAddress,
1085{
1086    type Error = MalformedFlags;
1087
1088    fn try_from(from: &TcpSegmentBuilder<A>) -> Result<Self, Self::Error> {
1089        SegmentHeader::from_builder(from)
1090    }
1091}
1092
1093impl<'a, A, I> TryFrom<&TcpSegmentBuilderWithOptions<A, OptionSequenceBuilder<TcpOption<'a>, I>>>
1094    for SegmentHeader
1095where
1096    A: IpAddress,
1097    I: Iterator + Clone,
1098    I::Item: Borrow<TcpOption<'a>>,
1099{
1100    type Error = MalformedFlags;
1101
1102    fn try_from(
1103        from: &TcpSegmentBuilderWithOptions<A, OptionSequenceBuilder<TcpOption<'a>, I>>,
1104    ) -> Result<Self, Self::Error> {
1105        let prefix_builder = from.prefix_builder();
1106        Self::from_builder_options(
1107            prefix_builder,
1108            Options::try_from_iter(
1109                &prefix_builder,
1110                from.iter_options().map(|option| option.borrow().to_owned()),
1111            )?,
1112        )
1113    }
1114}
1115
1116#[cfg(any(test, feature = "testutils"))]
1117mod testutils {
1118    use super::*;
1119
1120    /// Provide a handy default implementation for tests only.
1121    impl Default for SegmentHeader {
1122        fn default() -> Self {
1123            Self {
1124                seq: SeqNum::new(0),
1125                ack: None,
1126                control: None,
1127                wnd: UnscaledWindowSize::from(0),
1128                options: Options::new(None),
1129                push: false,
1130            }
1131        }
1132    }
1133
1134    impl<P: Payload> Segment<P> {
1135        /// Like [`Segment::new`] but asserts that no bytes were discarded from
1136        /// `data`.
1137        #[track_caller]
1138        pub fn new_assert_no_discard(header: SegmentHeader, data: P) -> Self {
1139            let (seg, discard) = Self::new(header, data);
1140            assert_eq!(discard, 0);
1141            seg
1142        }
1143    }
1144
1145    impl<'a> Segment<&'a [u8]> {
1146        /// Create a new segment with the given seq, ack, and data.
1147        pub fn with_fake_data(seq: SeqNum, ack: SeqNum, data: &'a [u8]) -> Self {
1148            Self::new_assert_no_discard(
1149                SegmentHeader {
1150                    seq,
1151                    ack: Some(ack),
1152                    control: None,
1153                    wnd: UnscaledWindowSize::from(u16::MAX),
1154                    options: Options::new(None),
1155                    push: false,
1156                },
1157                data,
1158            )
1159        }
1160    }
1161
1162    impl<P: Payload> Segment<P> {
1163        /// Creates a new segment with the provided data.
1164        pub fn with_data(
1165            seq: SeqNum,
1166            ack: SeqNum,
1167            wnd: UnscaledWindowSize,
1168            options: SegmentOptions,
1169            data: P,
1170        ) -> Segment<P> {
1171            Segment::new_assert_no_discard(
1172                SegmentHeader {
1173                    seq,
1174                    ack: Some(ack),
1175                    control: None,
1176                    wnd,
1177                    push: false,
1178                    options: Options::Segment(options),
1179                },
1180                data,
1181            )
1182        }
1183
1184        /// Creates a new FIN segment with the provided data.
1185        pub fn piggybacked_fin(
1186            seq: SeqNum,
1187            ack: SeqNum,
1188            wnd: UnscaledWindowSize,
1189            options: SegmentOptions,
1190            data: P,
1191        ) -> Segment<P> {
1192            Segment::new_assert_no_discard(
1193                SegmentHeader {
1194                    seq,
1195                    ack: Some(ack),
1196                    control: Some(Control::FIN),
1197                    wnd,
1198                    push: false,
1199                    options: Options::Segment(options),
1200                },
1201                data,
1202            )
1203        }
1204
1205        /// Creates a new FIN segment.
1206        pub fn fin(
1207            seq: SeqNum,
1208            ack: SeqNum,
1209            wnd: UnscaledWindowSize,
1210            options: SegmentOptions,
1211        ) -> Self {
1212            Segment::new_empty(SegmentHeader {
1213                seq,
1214                ack: Some(ack),
1215                control: Some(Control::FIN),
1216                wnd,
1217                push: false,
1218                options: Options::Segment(options),
1219            })
1220        }
1221    }
1222}
1223
1224#[cfg(test)]
1225mod test {
1226
1227    use alloc::vec::Vec;
1228    use assert_matches::assert_matches;
1229    use core::num::NonZeroU16;
1230    use ip_test_macro::ip_test;
1231    use net_declare::{net_ip_v4, net_ip_v6};
1232    use net_types::ip::{Ipv4, Ipv6};
1233    use packet_formats::ip::IpExt;
1234    use test_case::{test_case, test_matrix};
1235
1236    use super::*;
1237
1238    #[test_case(None, &[][..] => (0, &[][..]); "empty")]
1239    #[test_case(None, &[1][..] => (1, &[1][..]); "no control")]
1240    #[test_case(Some(Control::SYN), &[][..] => (1, &[][..]); "empty slice with syn")]
1241    #[test_case(Some(Control::SYN), &[1][..] => (2, &[1][..]); "non-empty slice with syn")]
1242    #[test_case(Some(Control::FIN), &[][..] => (1, &[][..]); "empty slice with fin")]
1243    #[test_case(Some(Control::FIN), &[1][..] => (2, &[1][..]); "non-empty slice with fin")]
1244    #[test_case(Some(Control::RST), &[][..] => (0, &[][..]); "empty slice with rst")]
1245    #[test_case(Some(Control::RST), &[1][..] => (1, &[1][..]); "non-empty slice with rst")]
1246    fn segment_len(control: Option<Control>, data: &[u8]) -> (u32, &[u8]) {
1247        let (seg, truncated) = Segment::new(
1248            SegmentHeader {
1249                seq: SeqNum::new(1),
1250                ack: Some(SeqNum::new(1)),
1251                wnd: UnscaledWindowSize::from(0),
1252                control,
1253                push: false,
1254                options: Options::new(None),
1255            },
1256            data,
1257        );
1258        assert_eq!(truncated, 0);
1259        (seg.len(), seg.data)
1260    }
1261
1262    #[test_case(&[1, 2, 3, 4, 5][..], 0..4 => [1, 2, 3, 4])]
1263    #[test_case((), 0..0 => [0, 0, 0, 0])]
1264    fn payload_slice_copy(data: impl Payload, range: Range<u32>) -> [u8; 4] {
1265        let sliced = data.slice(range);
1266        let mut buffer = [0; 4];
1267        sliced.partial_copy(0, &mut buffer[..sliced.len()]);
1268        buffer
1269    }
1270
1271    #[derive(Debug, PartialEq, Eq)]
1272    struct TestPayload(Range<u32>);
1273
1274    impl TestPayload {
1275        fn new(len: usize) -> Self {
1276            Self(0..u32::try_from(len).unwrap())
1277        }
1278    }
1279
1280    impl PayloadLen for TestPayload {
1281        fn len(&self) -> usize {
1282            self.0.len()
1283        }
1284    }
1285
1286    impl Payload for TestPayload {
1287        fn slice(self, range: Range<u32>) -> Self {
1288            let Self(this) = self;
1289            assert!(range.start >= this.start && range.end <= this.end);
1290            TestPayload(range)
1291        }
1292
1293        fn partial_copy(&self, _offset: usize, _dst: &mut [u8]) {
1294            unimplemented!("TestPayload doesn't carry any data");
1295        }
1296
1297        fn partial_copy_uninit(&self, _offset: usize, _dst: &mut [MaybeUninit<u8>]) {
1298            unimplemented!("TestPayload doesn't carry any data");
1299        }
1300
1301        fn new_empty() -> Self {
1302            Self(0..0)
1303        }
1304    }
1305
1306    #[test_case(100, Some(Control::SYN) => (100, Some(Control::SYN), 0))]
1307    #[test_case(100, Some(Control::FIN) => (100, Some(Control::FIN), 0))]
1308    #[test_case(100, Some(Control::RST) => (100, Some(Control::RST), 0))]
1309    #[test_case(100, None => (100, None, 0))]
1310    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN)
1311    => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 0))]
1312    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN)
1313    => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN), 0))]
1314    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST)
1315    => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST), 0))]
1316    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, None
1317    => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, None, 0))]
1318    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::SYN)
1319    => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1))]
1320    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::FIN)
1321    => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
1322    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST)
1323    => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 0))]
1324    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, None
1325    => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 0))]
1326    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::SYN)
1327    => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 2))]
1328    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::FIN)
1329    => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 2))]
1330    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::RST)
1331    => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 1))]
1332    #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, None
1333    => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
1334    #[test_case(u32::MAX as usize, Some(Control::SYN)
1335    => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1 << 31))]
1336    fn segment_truncate(len: usize, control: Option<Control>) -> (usize, Option<Control>, usize) {
1337        let (seg, truncated) = Segment::new(
1338            SegmentHeader {
1339                seq: SeqNum::new(0),
1340                ack: None,
1341                wnd: UnscaledWindowSize::from(0),
1342                control,
1343                push: false,
1344                options: Options::new(None),
1345            },
1346            TestPayload::new(len),
1347        );
1348        (seg.data.len(), seg.header.control, truncated)
1349    }
1350
1351    struct OverlapTestArgs {
1352        seg_seq: u32,
1353        control: Option<Control>,
1354        data_len: u32,
1355        rcv_nxt: u32,
1356        rcv_wnd: usize,
1357    }
1358    #[test_case(OverlapTestArgs{
1359        seg_seq: 1,
1360        control: None,
1361        data_len: 0,
1362        rcv_nxt: 0,
1363        rcv_wnd: 0,
1364    } => None)]
1365    #[test_case(OverlapTestArgs{
1366        seg_seq: 1,
1367        control: None,
1368        data_len: 0,
1369        rcv_nxt: 1,
1370        rcv_wnd: 0,
1371    } => Some((SeqNum::new(1), None, 0..0)))]
1372    #[test_case(OverlapTestArgs{
1373        seg_seq: 1,
1374        control: None,
1375        data_len: 0,
1376        rcv_nxt: 2,
1377        rcv_wnd: 0,
1378    } => None)]
1379    #[test_case(OverlapTestArgs{
1380        seg_seq: 1,
1381        control: Some(Control::SYN),
1382        data_len: 0,
1383        rcv_nxt: 2,
1384        rcv_wnd: 0,
1385    } => None)]
1386    #[test_case(OverlapTestArgs{
1387        seg_seq: 1,
1388        control: Some(Control::SYN),
1389        data_len: 0,
1390        rcv_nxt: 1,
1391        rcv_wnd: 0,
1392    } => None)]
1393    #[test_case(OverlapTestArgs{
1394        seg_seq: 1,
1395        control: Some(Control::SYN),
1396        data_len: 0,
1397        rcv_nxt: 0,
1398        rcv_wnd: 0,
1399    } => None)]
1400    #[test_case(OverlapTestArgs{
1401        seg_seq: 1,
1402        control: Some(Control::FIN),
1403        data_len: 0,
1404        rcv_nxt: 2,
1405        rcv_wnd: 0,
1406    } => None)]
1407    #[test_case(OverlapTestArgs{
1408        seg_seq: 1,
1409        control: Some(Control::FIN),
1410        data_len: 0,
1411        rcv_nxt: 1,
1412        rcv_wnd: 0,
1413    } => None)]
1414    #[test_case(OverlapTestArgs{
1415        seg_seq: 1,
1416        control: Some(Control::FIN),
1417        data_len: 0,
1418        rcv_nxt: 0,
1419        rcv_wnd: 0,
1420    } => None)]
1421    #[test_case(OverlapTestArgs{
1422        seg_seq: 0,
1423        control: None,
1424        data_len: 0,
1425        rcv_nxt: 1,
1426        rcv_wnd: 1,
1427    } => None)]
1428    #[test_case(OverlapTestArgs{
1429        seg_seq: 1,
1430        control: None,
1431        data_len: 0,
1432        rcv_nxt: 1,
1433        rcv_wnd: 1,
1434    } => Some((SeqNum::new(1), None, 0..0)))]
1435    #[test_case(OverlapTestArgs{
1436        seg_seq: 2,
1437        control: None,
1438        data_len: 0,
1439        rcv_nxt: 1,
1440        rcv_wnd: 1,
1441    } => None)]
1442    #[test_case(OverlapTestArgs{
1443        seg_seq: 0,
1444        control: None,
1445        data_len: 1,
1446        rcv_nxt: 1,
1447        rcv_wnd: 1,
1448    } => Some((SeqNum::new(1), None, 1..1)))]
1449    #[test_case(OverlapTestArgs{
1450        seg_seq: 0,
1451        control: Some(Control::SYN),
1452        data_len: 0,
1453        rcv_nxt: 1,
1454        rcv_wnd: 1,
1455    } => Some((SeqNum::new(1), None, 0..0)))]
1456    #[test_case(OverlapTestArgs{
1457        seg_seq: 2,
1458        control: None,
1459        data_len: 1,
1460        rcv_nxt: 1,
1461        rcv_wnd: 1,
1462    } => None)]
1463    #[test_case(OverlapTestArgs{
1464        seg_seq: 0,
1465        control: None,
1466        data_len: 2,
1467        rcv_nxt: 1,
1468        rcv_wnd: 1,
1469    } => Some((SeqNum::new(1), None, 1..2)))]
1470    #[test_case(OverlapTestArgs{
1471        seg_seq: 1,
1472        control: None,
1473        data_len: 2,
1474        rcv_nxt: 1,
1475        rcv_wnd: 1,
1476    } => Some((SeqNum::new(1), None, 0..1)))]
1477    #[test_case(OverlapTestArgs{
1478        seg_seq: 0,
1479        control: Some(Control::SYN),
1480        data_len: 1,
1481        rcv_nxt: 1,
1482        rcv_wnd: 1,
1483    } => Some((SeqNum::new(1), None, 0..1)))]
1484    #[test_case(OverlapTestArgs{
1485        seg_seq: 1,
1486        control: Some(Control::SYN),
1487        data_len: 1,
1488        rcv_nxt: 1,
1489        rcv_wnd: 1,
1490    } => Some((SeqNum::new(1), Some(Control::SYN), 0..0)))]
1491    #[test_case(OverlapTestArgs{
1492        seg_seq: 0,
1493        control: Some(Control::FIN),
1494        data_len: 1,
1495        rcv_nxt: 1,
1496        rcv_wnd: 1,
1497    } => Some((SeqNum::new(1), Some(Control::FIN), 1..1)))]
1498    #[test_case(OverlapTestArgs{
1499        seg_seq: 1,
1500        control: Some(Control::FIN),
1501        data_len: 1,
1502        rcv_nxt: 1,
1503        rcv_wnd: 1,
1504    } => Some((SeqNum::new(1), None, 0..1)))]
1505    #[test_case(OverlapTestArgs{
1506        seg_seq: 1,
1507        control: None,
1508        data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1509        rcv_nxt: 1,
1510        rcv_wnd: 10,
1511    } => Some((SeqNum::new(1), None, 0..10)))]
1512    #[test_case(OverlapTestArgs{
1513        seg_seq: 10,
1514        control: None,
1515        data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1516        rcv_nxt: 1,
1517        rcv_wnd: 10,
1518    } => Some((SeqNum::new(10), None, 0..1)))]
1519    #[test_case(OverlapTestArgs{
1520        seg_seq: 1,
1521        control: None,
1522        data_len: 10,
1523        rcv_nxt: 1,
1524        rcv_wnd: WindowSize::MAX.into(),
1525    } => Some((SeqNum::new(1), None, 0..10)))]
1526    #[test_case(OverlapTestArgs{
1527        seg_seq: 10,
1528        control: None,
1529        data_len: 10,
1530        rcv_nxt: 1,
1531        rcv_wnd: WindowSize::MAX.into(),
1532    } => Some((SeqNum::new(10), None, 0..10)))]
1533    #[test_case(OverlapTestArgs{
1534        seg_seq: 1,
1535        control: Some(Control::FIN),
1536        data_len: 1,
1537        rcv_nxt: 3,
1538        rcv_wnd: 10,
1539    } => Some((SeqNum::new(3), None, 1..1)); "regression test for https://fxbug.dev/42061750")]
1540    fn segment_overlap(
1541        OverlapTestArgs { seg_seq, control, data_len, rcv_nxt, rcv_wnd }: OverlapTestArgs,
1542    ) -> Option<(SeqNum, Option<Control>, Range<u32>)> {
1543        let (seg, discarded) = Segment::new(
1544            SegmentHeader {
1545                seq: SeqNum::new(seg_seq),
1546                ack: None,
1547                control,
1548                wnd: UnscaledWindowSize::from(0),
1549                push: false,
1550                options: Options::new(None),
1551            },
1552            TestPayload(0..data_len),
1553        );
1554        assert_eq!(discarded, 0);
1555        seg.overlap(SeqNum::new(rcv_nxt), WindowSize::new(rcv_wnd).unwrap()).map(
1556            |Segment { header: SegmentHeader { seq, control, .. }, data: TestPayload(range) }| {
1557                (seq, control, range)
1558            },
1559        )
1560    }
1561
1562    pub trait TestIpExt: IpExt {
1563        const SRC_IP: Self::Addr;
1564        const DST_IP: Self::Addr;
1565    }
1566
1567    impl TestIpExt for Ipv4 {
1568        const SRC_IP: Self::Addr = net_ip_v4!("192.0.2.1");
1569        const DST_IP: Self::Addr = net_ip_v4!("192.0.2.2");
1570    }
1571
1572    impl TestIpExt for Ipv6 {
1573        const SRC_IP: Self::Addr = net_ip_v6!("2001:db8::1");
1574        const DST_IP: Self::Addr = net_ip_v6!("2001:db8::2");
1575    }
1576
1577    const SRC_PORT: NonZeroU16 = NonZeroU16::new(1234).unwrap();
1578    const DST_PORT: NonZeroU16 = NonZeroU16::new(9876).unwrap();
1579
1580    #[ip_test(I)]
1581    fn from_segment_builder<I: TestIpExt>() {
1582        let mut builder =
1583            TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1584        builder.syn(true);
1585
1586        let converted_header =
1587            SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1588
1589        let expected_header = SegmentHeader {
1590            seq: SeqNum::new(1),
1591            ack: Some(SeqNum::new(2)),
1592            wnd: UnscaledWindowSize::from(3u16),
1593            control: Some(Control::SYN),
1594            options: HandshakeOptions::default().into(),
1595            push: false,
1596        };
1597
1598        assert_eq!(converted_header, expected_header);
1599    }
1600
1601    #[ip_test(I)]
1602    fn from_segment_builder_failure<I: TestIpExt>() {
1603        let mut builder =
1604            TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1605        builder.syn(true);
1606        builder.fin(true);
1607
1608        assert_matches!(
1609            SegmentHeader::try_from(&builder),
1610            Err(MalformedFlags { syn: true, fin: true, rst: false })
1611        );
1612    }
1613
1614    #[ip_test(I)]
1615    fn from_segment_builder_with_options_handshake<I: TestIpExt>() {
1616        let mut builder =
1617            TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1618        builder.syn(true);
1619
1620        let builder = TcpSegmentBuilderWithOptions::new(
1621            builder,
1622            [
1623                TcpOption::Mss(1024),
1624                TcpOption::WindowScale(10),
1625                TcpOption::SackPermitted,
1626                TcpOption::Timestamp { ts_val: 1, ts_echo_reply: 0 },
1627            ],
1628        )
1629        .expect("failed to create tcp segment builder");
1630
1631        let converted_header =
1632            SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1633
1634        let expected_header = SegmentHeader {
1635            seq: SeqNum::new(1),
1636            ack: Some(SeqNum::new(2)),
1637            wnd: UnscaledWindowSize::from(3u16),
1638            control: Some(Control::SYN),
1639            push: false,
1640            options: HandshakeOptions {
1641                mss: Some(Mss::new(1024).unwrap()),
1642                window_scale: Some(WindowScale::new(10).unwrap()),
1643                sack_permitted: true,
1644                timestamp: Some(TimestampOption {
1645                    ts_val: Timestamp::new(1),
1646                    ts_echo_reply: Timestamp::new(0),
1647                }),
1648            }
1649            .into(),
1650        };
1651
1652        assert_eq!(converted_header, expected_header);
1653    }
1654
1655    #[ip_test(I)]
1656    fn mss_option_clamps_to_minimum<I: TestIpExt>() {
1657        let mut builder =
1658            TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1659        builder.syn(true);
1660
1661        let builder = TcpSegmentBuilderWithOptions::new(
1662            builder,
1663            // An MSS option below the minimum should be increased to the
1664            // minimum.
1665            [TcpOption::Mss(Mss::MIN.get() - 1)],
1666        )
1667        .expect("failed to create tcp segment builder");
1668
1669        let converted_header =
1670            SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1671
1672        let expected_header = SegmentHeader {
1673            seq: SeqNum::new(1),
1674            ack: Some(SeqNum::new(2)),
1675            wnd: UnscaledWindowSize::from(3u16),
1676            control: Some(Control::SYN),
1677            push: false,
1678            options: HandshakeOptions {
1679                mss: Some(Mss::MIN),
1680                window_scale: None,
1681                sack_permitted: false,
1682                timestamp: None,
1683            }
1684            .into(),
1685        };
1686
1687        assert_eq!(converted_header, expected_header);
1688    }
1689
1690    #[ip_test(I)]
1691    fn from_segment_builder_with_options_segment<I: TestIpExt>() {
1692        let mut builder =
1693            TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1694        builder.psh(true);
1695
1696        let sack_blocks = [TcpSackBlock::new(1, 2), TcpSackBlock::new(4, 6)];
1697        let builder = TcpSegmentBuilderWithOptions::new(
1698            builder,
1699            [
1700                TcpOption::Sack(&sack_blocks[..]),
1701                TcpOption::Timestamp { ts_val: 1234, ts_echo_reply: 4321 },
1702            ],
1703        )
1704        .expect("failed to create tcp segment builder");
1705
1706        let converted_header =
1707            SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1708
1709        let expected_header = SegmentHeader {
1710            seq: SeqNum::new(1),
1711            ack: Some(SeqNum::new(2)),
1712            wnd: UnscaledWindowSize::from(3u16),
1713            control: None,
1714            push: true,
1715            options: SegmentOptions {
1716                sack_blocks: SackBlocks::from_iter([
1717                    SackBlock::try_new(SeqNum::new(1), SeqNum::new(2)).unwrap(),
1718                    SackBlock::try_new(SeqNum::new(4), SeqNum::new(6)).unwrap(),
1719                ]),
1720                timestamp: Some(TimestampOption {
1721                    ts_val: Timestamp::new(1234),
1722                    ts_echo_reply: Timestamp::new(4321),
1723                }),
1724            }
1725            .into(),
1726        };
1727
1728        assert_eq!(converted_header, expected_header);
1729    }
1730
1731    #[ip_test(I)]
1732    fn from_segment_builder_with_options_failure<I: TestIpExt>() {
1733        let mut builder =
1734            TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1735        builder.syn(true);
1736        builder.fin(true);
1737
1738        let builder = TcpSegmentBuilderWithOptions::new(
1739            builder,
1740            [TcpOption::Mss(1024), TcpOption::WindowScale(10)],
1741        )
1742        .expect("failed to create tcp segment builder");
1743
1744        assert_matches!(
1745            SegmentHeader::try_from(&builder),
1746            Err(MalformedFlags { syn: true, fin: true, rst: false })
1747        );
1748    }
1749
1750    #[ip_test(I)]
1751    fn from_segment_builder_with_options_reset<I: TestIpExt>() {
1752        let mut builder =
1753            TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1754        builder.rst(true);
1755
1756        let builder = TcpSegmentBuilderWithOptions::new(
1757            builder,
1758            [TcpOption::Timestamp { ts_val: 1234, ts_echo_reply: 4321 }],
1759        )
1760        .expect("failed to create tcp segment builder");
1761
1762        let converted_header =
1763            SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1764
1765        let expected_header = SegmentHeader {
1766            seq: SeqNum::new(1),
1767            ack: Some(SeqNum::new(2)),
1768            wnd: UnscaledWindowSize::from(3u16),
1769            control: Some(Control::RST),
1770            push: false,
1771            options: ResetOptions {
1772                timestamp: Some(TimestampOption {
1773                    ts_val: Timestamp::new(1234),
1774                    ts_echo_reply: Timestamp::new(4321),
1775                }),
1776            }
1777            .into(),
1778        };
1779
1780        assert_eq!(converted_header, expected_header);
1781    }
1782
1783    #[test_case(Flags {
1784            syn: false,
1785            fin: false,
1786            rst: false,
1787        } => Ok(None))]
1788    #[test_case(Flags {
1789            syn: true,
1790            fin: false,
1791            rst: false,
1792        } => Ok(Some(Control::SYN)))]
1793    #[test_case(Flags {
1794            syn: false,
1795            fin: true,
1796            rst: false,
1797        } => Ok(Some(Control::FIN)))]
1798    #[test_case(Flags {
1799            syn: false,
1800            fin: false,
1801            rst: true,
1802        } => Ok(Some(Control::RST)))]
1803    #[test_case(Flags {
1804            syn: true,
1805            fin: true,
1806            rst: false,
1807        } => Err(MalformedFlags {
1808            syn: true,
1809            fin: true,
1810            rst: false,
1811        }))]
1812    #[test_case(Flags {
1813            syn: true,
1814            fin: false,
1815            rst: true,
1816        } => Err(MalformedFlags {
1817            syn: true,
1818            fin: false,
1819            rst: true,
1820        }))]
1821    #[test_case(Flags {
1822            syn: false,
1823            fin: true,
1824            rst: true,
1825        } => Err(MalformedFlags {
1826            syn: false,
1827            fin: true,
1828            rst: true,
1829        }))]
1830    #[test_case(Flags {
1831            syn: true,
1832            fin: true,
1833            rst: true,
1834        } => Err(MalformedFlags {
1835            syn: true,
1836            fin: true,
1837            rst: true,
1838        }))]
1839    fn flags_to_control(input: Flags) -> Result<Option<Control>, MalformedFlags> {
1840        input.control()
1841    }
1842
1843    #[test]
1844    fn sack_block_try_new() {
1845        assert_matches!(SackBlock::try_new(SeqNum::new(1), SeqNum::new(2)), Ok(_));
1846        assert_matches!(
1847            SackBlock::try_new(SeqNum::new(0u32.wrapping_sub(1)), SeqNum::new(2)),
1848            Ok(_)
1849        );
1850        assert_eq!(
1851            SackBlock::try_new(SeqNum::new(1), SeqNum::new(1)),
1852            Err(InvalidSackBlockError(SeqNum::new(1), SeqNum::new(1)))
1853        );
1854        assert_eq!(
1855            SackBlock::try_new(SeqNum::new(2), SeqNum::new(1)),
1856            Err(InvalidSackBlockError(SeqNum::new(2), SeqNum::new(1)))
1857        );
1858        assert_eq!(
1859            SackBlock::try_new(SeqNum::new(0), SeqNum::new(0u32.wrapping_sub(1))),
1860            Err(InvalidSackBlockError(SeqNum::new(0), SeqNum::new(0u32.wrapping_sub(1))))
1861        );
1862    }
1863
1864    #[test]
1865    fn psh_bit_cleared_if_no_data() {
1866        let seg =
1867            Segment::new_assert_no_discard(SegmentHeader { push: true, ..Default::default() }, ());
1868        assert_eq!(seg.header().push, false);
1869        let seg = Segment::new_assert_no_discard(
1870            SegmentHeader { push: true, ..Default::default() },
1871            &[1u8, 2, 3, 4][..],
1872        );
1873        assert_eq!(seg.header().push, true);
1874    }
1875
1876    const FAKE_TIMESTAMP_OPTION: TimestampOption =
1877        TimestampOption { ts_val: Timestamp::new(1234), ts_echo_reply: Timestamp::new(4321) };
1878
1879    #[test_matrix(
1880        [None, Some(Mss::MIN)],
1881        [None, Some(WindowScale::MAX)],
1882        [false, true],
1883        [None, Some(FAKE_TIMESTAMP_OPTION)]
1884    )]
1885    fn iter_handshake_options(
1886        mss: Option<Mss>,
1887        window_scale: Option<WindowScale>,
1888        sack_permitted: bool,
1889        timestamp: Option<TimestampOption>,
1890    ) {
1891        let options = HandshakeOptions { mss, window_scale, sack_permitted, timestamp };
1892
1893        let expected_options = [
1894            mss.map(|mss| TcpOption::Mss(mss.get())),
1895            window_scale.map(|ws| TcpOption::WindowScale(ws.get())),
1896            sack_permitted.then_some(TcpOption::SackPermitted),
1897            timestamp.map(Into::into),
1898        ]
1899        .into_iter()
1900        .flatten()
1901        .collect::<Vec<_>>();
1902
1903        assert_eq!(Options::Handshake(options).iter().collect::<Vec<_>>(), expected_options);
1904    }
1905
1906    #[test_matrix(
1907        [None, Some(FAKE_TIMESTAMP_OPTION)],
1908        [None, Some(SackBlock::try_new(SeqNum::new(1), SeqNum::new(2)).unwrap())]
1909    )]
1910    fn iter_segment_options(timestamp: Option<TimestampOption>, sack_block: Option<SackBlock>) {
1911        let sack_blocks = SackBlocks::from_iter(sack_block);
1912        let options = SegmentOptions { sack_blocks: sack_blocks.clone(), timestamp };
1913
1914        let expected_options = [timestamp.map(Into::into), sack_blocks.as_option()]
1915            .into_iter()
1916            .flatten()
1917            .collect::<Vec<_>>();
1918
1919        assert_eq!(Options::Segment(options).iter().collect::<Vec<_>>(), expected_options);
1920    }
1921
1922    #[test_case(None)]
1923    #[test_case(Some(FAKE_TIMESTAMP_OPTION))]
1924    fn iter_reset_options(timestamp: Option<TimestampOption>) {
1925        let options = ResetOptions { timestamp };
1926
1927        let expected_options = timestamp.map(Into::into).into_iter().collect::<Vec<_>>();
1928
1929        assert_eq!(Options::Reset(options).iter().collect::<Vec<_>>(), expected_options);
1930    }
1931}