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