1use 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#[derive(Debug, PartialEq, Eq, Clone)]
30pub struct Segment<P> {
31 header: SegmentHeader,
33 data: P,
38}
39
40#[derive(Debug, PartialEq, Eq, Clone)]
42pub struct SegmentHeader {
43 pub seq: SeqNum,
45 pub ack: Option<SeqNum>,
47 pub wnd: UnscaledWindowSize,
49 pub control: Option<Control>,
51 pub push: bool,
53 pub options: Options,
55}
56
57#[derive(Debug, PartialEq, Eq, Clone)]
59pub enum Options {
60 Handshake(HandshakeOptions),
62 Segment(SegmentOptions),
64 Reset(ResetOptions),
66}
67
68impl Options {
69 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 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Debug + Clone {
100 match self {
102 Options::Handshake(o) => either::Either::Left(either::Either::Left(o.iter())),
103 Options::Segment(o) => either::Either::Left(either::Either::Right(o.iter())),
104 Options::Reset(o) => either::Either::Right(o.iter()),
105 }
106 }
107
108 fn as_handshake(&self) -> Option<&HandshakeOptions> {
109 match self {
110 Self::Handshake(h) => Some(h),
111 Self::Segment(_) | Self::Reset(_) => None,
112 }
113 }
114
115 fn as_handshake_mut(&mut self) -> Option<&mut HandshakeOptions> {
116 match self {
117 Self::Handshake(h) => Some(h),
118 Self::Segment(_) | Self::Reset(_) => None,
119 }
120 }
121
122 fn as_segment(&self) -> Option<&SegmentOptions> {
123 match self {
124 Self::Handshake(_) | Self::Reset(_) => None,
125 Self::Segment(s) => Some(s),
126 }
127 }
128
129 fn as_segment_mut(&mut self) -> Option<&mut SegmentOptions> {
130 match self {
131 Self::Handshake(_) | Self::Reset(_) => None,
132 Self::Segment(s) => Some(s),
133 }
134 }
135
136 pub fn from_iter<'a>(
138 control: Option<&Control>,
139 iter: impl IntoIterator<Item = TcpOption<'a>>,
140 ) -> Self {
141 let mut options = Options::new(control);
142 for option in iter {
143 match option {
144 TcpOption::Mss(mss) => {
145 if let Some(h) = options.as_handshake_mut() {
146 h.mss = Some(Mss::new(mss).unwrap_or(Mss::MIN));
151 }
152 }
153 TcpOption::WindowScale(ws) => {
154 if let Some(h) = options.as_handshake_mut() {
155 if ws > WindowScale::MAX.get() {
160 info!(
161 "received an out-of-range window scale: {}, want < {}",
162 ws,
163 WindowScale::MAX.get()
164 );
165 }
166 h.window_scale = Some(WindowScale::new(ws).unwrap_or(WindowScale::MAX));
167 }
168 }
169 TcpOption::SackPermitted => {
170 if let Some(h) = options.as_handshake_mut() {
171 h.sack_permitted = true;
172 }
173 }
174 TcpOption::Sack(sack) => {
175 if let Some(seg) = options.as_segment_mut() {
176 seg.sack_blocks = SackBlocks::from_option(sack);
177 }
178 }
179 TcpOption::Timestamp { ts_val, ts_echo_reply } => {
180 let timestamp = TimestampOption {
181 ts_val: Timestamp::new(ts_val),
182 ts_echo_reply: Timestamp::new(ts_echo_reply),
183 };
184 match options {
186 Options::Handshake(ref mut h) => h.timestamp = Some(timestamp),
187 Options::Segment(ref mut s) => s.timestamp = Some(timestamp),
188 Options::Reset(ref mut r) => r.timestamp = Some(timestamp),
189 }
190 }
191 }
192 }
193 options
194 }
195
196 pub fn try_from_iter<'a, A: IpAddress>(
198 builder: &TcpSegmentBuilder<A>,
199 iter: impl IntoIterator<Item = TcpOption<'a>>,
200 ) -> Result<Self, MalformedFlags> {
201 let control =
202 Flags { syn: builder.syn_set(), fin: builder.fin_set(), rst: builder.rst_set() }
203 .control()?;
204 Ok(Options::from_iter(control.as_ref(), iter))
205 }
206
207 pub fn window_scale(&self) -> Option<WindowScale> {
209 self.as_handshake().and_then(|h| h.window_scale)
210 }
211
212 pub fn mss(&self) -> Option<Mss> {
214 self.as_handshake().and_then(|h| h.mss)
215 }
216
217 pub fn sack_permitted(&self) -> bool {
220 self.as_handshake().is_some_and(|o| o.sack_permitted)
221 }
222
223 pub fn sack_blocks(&self) -> &SackBlocks {
227 const EMPTY_REF: &'static SackBlocks = &SackBlocks::EMPTY;
228 self.as_segment().map(|s| &s.sack_blocks).unwrap_or(EMPTY_REF)
229 }
230
231 pub fn timestamp(&self) -> &Option<TimestampOption> {
233 match self {
234 Options::Handshake(h) => &h.timestamp,
235 Options::Segment(s) => &s.timestamp,
236 Options::Reset(r) => &r.timestamp,
237 }
238 }
239}
240
241#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
243pub struct HandshakeOptions {
244 pub mss: Option<Mss>,
246
247 pub window_scale: Option<WindowScale>,
249
250 pub sack_permitted: bool,
252
253 pub timestamp: Option<TimestampOption>,
255}
256
257impl HandshakeOptions {
258 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Debug + Clone {
260 let Self { mss, window_scale, sack_permitted, timestamp } = self;
261 mss.map(|mss| TcpOption::Mss(mss.get()))
262 .into_iter()
263 .chain(window_scale.map(|ws| TcpOption::WindowScale(ws.get())))
264 .chain((*sack_permitted).then_some(TcpOption::SackPermitted))
265 .chain(timestamp.map(Into::into))
266 }
267}
268
269#[derive(Debug, Default, PartialEq, Eq, Clone)]
271pub struct SegmentOptions {
272 pub sack_blocks: SackBlocks,
274
275 pub timestamp: Option<TimestampOption>,
277}
278
279impl SegmentOptions {
280 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Debug + Clone {
282 let Self { sack_blocks, timestamp } = self;
283 sack_blocks.as_option().into_iter().chain(timestamp.map(Into::into))
284 }
285
286 pub fn is_empty(&self) -> bool {
288 let Self { sack_blocks, timestamp } = self;
289 sack_blocks.is_empty() && timestamp.is_none()
290 }
291}
292
293#[derive(Debug, Default, PartialEq, Eq, Clone)]
295pub struct ResetOptions {
296 pub timestamp: Option<TimestampOption>,
298}
299
300impl ResetOptions {
301 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Debug + Clone {
303 let Self { timestamp } = self;
304 timestamp.map(Into::into).into_iter()
305 }
306}
307
308const MAX_SACK_BLOCKS: usize = 4;
309#[derive(Debug, Default, PartialEq, Eq, Clone)]
311pub struct SackBlocks(ArrayVec<TcpSackBlock, MAX_SACK_BLOCKS>);
312
313impl SackBlocks {
314 pub const EMPTY: Self = SackBlocks(ArrayVec::new_const());
316
317 pub const MAX_BLOCKS: usize = MAX_SACK_BLOCKS;
323
324 pub fn as_option(&self) -> Option<TcpOption<'_>> {
328 let Self(inner) = self;
329 if inner.is_empty() {
330 return None;
331 }
332
333 Some(TcpOption::Sack(inner.as_slice()))
334 }
335
336 pub fn iter_skip_invalid(&self) -> impl Iterator<Item = SackBlock> + '_ {
339 self.try_iter().filter_map(|r| match r {
340 Ok(s) => Some(s),
341 Err(InvalidSackBlockError(_, _)) => None,
342 })
343 }
344
345 pub fn try_iter(&self) -> impl Iterator<Item = Result<SackBlock, InvalidSackBlockError>> + '_ {
348 let Self(inner) = self;
349 inner.iter().map(|block| SackBlock::try_from(*block))
350 }
351
352 pub fn from_option(blocks: &[TcpSackBlock]) -> Self {
357 Self(blocks.iter().take(Self::MAX_BLOCKS).copied().collect())
358 }
359
360 pub fn is_empty(&self) -> bool {
362 let Self(inner) = self;
363 inner.is_empty()
364 }
365
366 pub fn clear(&mut self) {
368 let Self(inner) = self;
369 inner.clear()
370 }
371}
372
373impl FromIterator<SackBlock> for SackBlocks {
377 fn from_iter<T: IntoIterator<Item = SackBlock>>(iter: T) -> Self {
378 Self(iter.into_iter().take(Self::MAX_BLOCKS).map(|b| b.into()).collect())
379 }
380}
381
382mod sack_block {
383 use super::*;
384
385 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
390 pub struct SackBlock {
391 left: SeqNum,
393 right: SeqNum,
394 }
395
396 impl SackBlock {
397 pub fn try_new(left: SeqNum, right: SeqNum) -> Result<Self, InvalidSackBlockError> {
401 if right.after(left) {
402 Ok(Self { left, right })
403 } else {
404 Err(InvalidSackBlockError(left, right))
405 }
406 }
407
408 pub unsafe fn new_unchecked(left: SeqNum, right: SeqNum) -> Self {
415 Self { left, right }
416 }
417
418 pub fn into_range(self) -> Range<SeqNum> {
420 let Self { left, right } = self;
421 Range { start: left, end: right }
422 }
423
424 pub fn into_range_u32(self) -> Range<u32> {
427 let Self { left, right } = self;
428 Range { start: left.into(), end: right.into() }
429 }
430
431 pub fn left(&self) -> SeqNum {
433 self.left
434 }
435
436 pub fn right(&self) -> SeqNum {
438 self.right
439 }
440
441 pub fn into_parts(self) -> (SeqNum, SeqNum) {
444 let Self { left, right } = self;
445 (left, right)
446 }
447 }
448
449 #[derive(Debug, Eq, PartialEq, Clone, Copy)]
452 pub struct InvalidSackBlockError(pub SeqNum, pub SeqNum);
453
454 impl From<SackBlock> for TcpSackBlock {
455 fn from(value: SackBlock) -> Self {
456 let SackBlock { left, right } = value;
457 TcpSackBlock::new(left.into(), right.into())
458 }
459 }
460
461 impl TryFrom<TcpSackBlock> for SackBlock {
462 type Error = InvalidSackBlockError;
463
464 fn try_from(value: TcpSackBlock) -> Result<Self, Self::Error> {
465 Self::try_new(value.left_edge().into(), value.right_edge().into())
466 }
467 }
468
469 impl From<SackBlock> for Range<SeqNum> {
470 fn from(value: SackBlock) -> Self {
471 value.into_range()
472 }
473 }
474
475 impl TryFrom<Range<SeqNum>> for SackBlock {
476 type Error = InvalidSackBlockError;
477
478 fn try_from(value: Range<SeqNum>) -> Result<Self, Self::Error> {
479 let Range { start, end } = value;
480 Self::try_new(start, end)
481 }
482 }
483}
484pub use sack_block::{InvalidSackBlockError, SackBlock};
485
486pub const MAX_PAYLOAD_AND_CONTROL_LEN: usize = 1 << 31;
488const MAX_PAYLOAD_AND_CONTROL_LEN_U32: u32 = MAX_PAYLOAD_AND_CONTROL_LEN as u32;
490
491impl<P: Payload> Segment<P> {
492 pub fn new(header: SegmentHeader, data: P) -> (Self, usize) {
497 let SegmentHeader { seq, ack, wnd, control, push, options } = header;
498 let has_control_len = control.map(Control::has_sequence_no).unwrap_or(false);
499
500 let data_len = data.len();
501 let discarded_len =
502 data_len.saturating_sub(MAX_PAYLOAD_AND_CONTROL_LEN - usize::from(has_control_len));
503
504 let push = push && data_len != 0;
506
507 let (control, data) = if discarded_len > 0 {
508 let (control, control_len) = if control == Some(Control::FIN) {
511 (None, 0)
512 } else {
513 (control, has_control_len.into())
514 };
515 (control, data.slice(0..MAX_PAYLOAD_AND_CONTROL_LEN_U32 - control_len))
518 } else {
519 (control, data)
520 };
521
522 (
523 Segment { header: SegmentHeader { seq, ack, wnd, control, push, options }, data: data },
524 discarded_len,
525 )
526 }
527
528 pub fn header(&self) -> &SegmentHeader {
530 &self.header
531 }
532
533 pub fn data(&self) -> &P {
535 &self.data
536 }
537
538 pub fn into_parts(self) -> (SegmentHeader, P) {
541 let Self { header, data } = self;
542 (header, data)
543 }
544
545 pub fn map_payload<R, F: FnOnce(P) -> R>(self, f: F) -> Segment<R> {
547 let Segment { header, data } = self;
548 Segment { header, data: f(data) }
549 }
550
551 pub fn len(&self) -> u32 {
557 self.header.len(self.data.len())
558 }
559
560 pub fn overlap(self, rnxt: SeqNum, rwnd: WindowSize) -> Option<Segment<P>> {
562 let len = self.len();
563 let Segment { header: SegmentHeader { seq, ack, wnd, control, options, push }, data } =
564 self;
565
566 let overlap = match (len, rwnd) {
578 (0, WindowSize::ZERO) => seq == rnxt,
579 (0, rwnd) => !rnxt.after(seq) && seq.before(rnxt + rwnd),
580 (_len, WindowSize::ZERO) => false,
581 (len, rwnd) => {
582 (!rnxt.after(seq) && seq.before(rnxt + rwnd))
583 || (!(seq + len).before(rnxt) && !(seq + len).after(rnxt + rwnd))
594 }
595 };
596 overlap.then(move || {
597 let cmp = |lhs: &SeqNum, rhs: &SeqNum| (*lhs - *rhs).cmp(&0);
600 let new_seq = core::cmp::max_by(seq, rnxt, cmp);
601 let new_len = core::cmp::min_by(seq + len, rnxt + rwnd, cmp) - new_seq;
602 let start = u32::try_from(new_seq - seq).unwrap();
607 let new_len = u32::try_from(new_len).unwrap();
616 let (new_control, new_data) = {
617 match control {
618 Some(Control::SYN) => {
619 if start == 0 {
620 (Some(Control::SYN), data.slice(start..start + new_len - 1))
621 } else {
622 (None, data.slice(start - 1..start + new_len - 1))
623 }
624 }
625 Some(Control::FIN) => {
626 if len == start + new_len {
627 if new_len > 0 {
628 (Some(Control::FIN), data.slice(start..start + new_len - 1))
629 } else {
630 (None, data.slice(start - 1..start - 1))
631 }
632 } else {
633 (None, data.slice(start..start + new_len))
634 }
635 }
636 Some(Control::RST) | None => (control, data.slice(start..start + new_len)),
637 }
638 };
639 Segment {
640 header: SegmentHeader {
641 seq: new_seq,
642 ack,
643 wnd,
644 control: new_control,
645 options,
646 push,
647 },
648 data: new_data,
649 }
650 })
651 }
652
653 pub fn new_empty(header: SegmentHeader) -> Self {
655 let (seg, truncated) = Self::new(header, P::new_empty());
658 debug_assert_eq!(truncated, 0);
659 seg
660 }
661
662 pub fn ack(seq: SeqNum, ack: SeqNum, wnd: UnscaledWindowSize, options: SegmentOptions) -> Self {
664 Segment::new_empty(SegmentHeader {
665 seq,
666 ack: Some(ack),
667 wnd,
668 control: None,
669 push: false,
670 options: options.into(),
671 })
672 }
673
674 pub fn syn(seq: SeqNum, wnd: UnscaledWindowSize, options: HandshakeOptions) -> Self {
676 Segment::new_empty(SegmentHeader {
677 seq,
678 ack: None,
679 wnd,
680 control: Some(Control::SYN),
681 push: false,
682 options: options.into(),
683 })
684 }
685
686 pub fn syn_ack(
688 seq: SeqNum,
689 ack: SeqNum,
690 wnd: UnscaledWindowSize,
691 options: HandshakeOptions,
692 ) -> Self {
693 Segment::new_empty(SegmentHeader {
694 seq,
695 ack: Some(ack),
696 wnd,
697 control: Some(Control::SYN),
698 push: false,
699 options: options.into(),
700 })
701 }
702
703 pub fn rst(seq: SeqNum, options: ResetOptions) -> Self {
705 Segment::new_empty(SegmentHeader {
706 seq,
707 ack: None,
708 wnd: UnscaledWindowSize::from(0),
709 control: Some(Control::RST),
710 push: false,
711 options: options.into(),
712 })
713 }
714
715 pub fn rst_ack(seq: SeqNum, ack: SeqNum, options: ResetOptions) -> Self {
717 Segment::new_empty(SegmentHeader {
718 seq,
719 ack: Some(ack),
720 wnd: UnscaledWindowSize::from(0),
721 control: Some(Control::RST),
722 push: false,
723 options: options.into(),
724 })
725 }
726}
727
728impl Segment<()> {
729 pub fn into_empty<P: Payload>(self) -> Segment<P> {
732 self.map_payload(|()| P::new_empty())
733 }
734}
735
736impl SegmentHeader {
737 pub fn len(&self, payload_len: usize) -> u32 {
743 let has_control_len = self.control.map(Control::has_sequence_no).unwrap_or(false);
747 u32::try_from(payload_len).unwrap() + u32::from(has_control_len)
748 }
749
750 pub fn from_builder<A: IpAddress>(
753 builder: &TcpSegmentBuilder<A>,
754 ) -> Result<Self, MalformedFlags> {
755 let control =
756 Flags { syn: builder.syn_set(), fin: builder.fin_set(), rst: builder.rst_set() }
757 .control()?;
758 let options = Options::new(control.as_ref());
759 Self::from_builder_options(builder, options)
760 }
761
762 pub fn from_builder_options<A: IpAddress>(
764 builder: &TcpSegmentBuilder<A>,
765 options: Options,
766 ) -> Result<Self, MalformedFlags> {
767 Ok(SegmentHeader {
768 seq: SeqNum::new(builder.seq_num()),
769 ack: builder.ack_num().map(SeqNum::new),
770 control: Flags {
771 syn: builder.syn_set(),
772 fin: builder.fin_set(),
773 rst: builder.rst_set(),
774 }
775 .control()?,
776 wnd: UnscaledWindowSize::from(builder.window_size()),
777 push: builder.psh_set(),
778 options: options,
779 })
780 }
781}
782
783pub trait PayloadLen {
785 fn len(&self) -> usize;
787}
788
789pub trait Payload: PayloadLen + Sized {
791 fn slice(self, range: Range<u32>) -> Self;
800
801 fn partial_copy(&self, offset: usize, dst: &mut [u8]);
807
808 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]);
814
815 fn new_empty() -> Self;
819}
820
821impl PayloadLen for &[u8] {
822 fn len(&self) -> usize {
823 <[u8]>::len(self)
824 }
825}
826
827impl Payload for &[u8] {
828 fn slice(self, Range { start, end }: Range<u32>) -> Self {
829 let start = usize::try_from(start).unwrap_or_else(|TryFromIntError { .. }| {
834 panic!("range start index {} out of range for slice of length {}", start, self.len())
835 });
836 let end = usize::try_from(end).unwrap_or_else(|TryFromIntError { .. }| {
837 panic!("range end index {} out of range for slice of length {}", end, self.len())
838 });
839 &self[start..end]
840 }
841
842 fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
843 dst.copy_from_slice(&self[offset..offset + dst.len()])
844 }
845
846 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]) {
847 let src = &self[offset..offset + dst.len()];
850 let uninit_src: &[MaybeUninit<u8>] = unsafe { core::mem::transmute(src) };
852 dst.copy_from_slice(&uninit_src);
853 }
854
855 fn new_empty() -> Self {
856 &[]
857 }
858}
859
860impl PayloadLen for () {
861 fn len(&self) -> usize {
862 0
863 }
864}
865
866impl Payload for () {
867 fn slice(self, Range { start, end }: Range<u32>) -> Self {
868 if start != 0 {
869 panic!("range start index {} out of range for slice of length 0", start);
870 }
871 if end != 0 {
872 panic!("range end index {} out of range for slice of length 0", end);
873 }
874 ()
875 }
876
877 fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
878 if dst.len() != 0 || offset != 0 {
879 panic!(
880 "source slice length (0) does not match destination slice length ({})",
881 dst.len()
882 );
883 }
884 }
885
886 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]) {
887 if dst.len() != 0 || offset != 0 {
888 panic!(
889 "source slice length (0) does not match destination slice length ({})",
890 dst.len()
891 );
892 }
893 }
894
895 fn new_empty() -> Self {
896 ()
897 }
898}
899
900impl<I: PayloadLen, B> PayloadLen for InnerSerializer<I, B> {
901 fn len(&self) -> usize {
902 PayloadLen::len(self.inner())
903 }
904}
905
906#[derive(Error, Debug, PartialEq, Eq)]
907#[error("multiple mutually exclusive flags are set: syn: {syn}, fin: {fin}, rst: {rst}")]
908pub struct MalformedFlags {
909 syn: bool,
910 fin: bool,
911 rst: bool,
912}
913
914struct Flags {
915 syn: bool,
916 fin: bool,
917 rst: bool,
918}
919
920impl Flags {
921 fn control(&self) -> Result<Option<Control>, MalformedFlags> {
922 if usize::from(self.syn) + usize::from(self.fin) + usize::from(self.rst) > 1 {
923 return Err(MalformedFlags { syn: self.syn, fin: self.fin, rst: self.rst });
924 }
925
926 let syn = self.syn.then_some(Control::SYN);
927 let fin = self.fin.then_some(Control::FIN);
928 let rst = self.rst.then_some(Control::RST);
929
930 Ok(syn.or(fin).or(rst))
931 }
932}
933
934pub struct VerifiedTcpSegment<'a> {
937 segment: TcpSegment<&'a [u8]>,
938 control: Option<Control>,
939}
940
941impl<'a> VerifiedTcpSegment<'a> {
942 pub fn tcp_segment(&self) -> &TcpSegment<&'a [u8]> {
944 &self.segment
945 }
946
947 pub fn control(&self) -> Option<Control> {
949 self.control
950 }
951}
952
953impl<'a> TryFrom<TcpSegment<&'a [u8]>> for VerifiedTcpSegment<'a> {
954 type Error = MalformedFlags;
955
956 fn try_from(segment: TcpSegment<&'a [u8]>) -> Result<Self, Self::Error> {
957 let control =
958 Flags { syn: segment.syn(), fin: segment.fin(), rst: segment.rst() }.control()?;
959 Ok(VerifiedTcpSegment { segment, control })
960 }
961}
962
963impl<'a> From<&'a VerifiedTcpSegment<'a>> for Segment<&'a [u8]> {
964 fn from(from: &'a VerifiedTcpSegment<'a>) -> Segment<&'a [u8]> {
965 let VerifiedTcpSegment { segment, control } = from;
966 let options = Options::from_iter(control.as_ref(), segment.iter_options());
967 let (to, discarded) = Segment::new(
968 SegmentHeader {
969 seq: segment.seq_num().into(),
970 ack: segment.ack_num().map(Into::into),
971 wnd: UnscaledWindowSize::from(segment.window_size()),
972 control: *control,
973 push: segment.psh(),
974 options,
975 },
976 from.segment.body(),
977 );
978 debug_assert_eq!(discarded, 0);
979 to
980 }
981}
982
983impl<A> TryFrom<&TcpSegmentBuilder<A>> for SegmentHeader
984where
985 A: IpAddress,
986{
987 type Error = MalformedFlags;
988
989 fn try_from(from: &TcpSegmentBuilder<A>) -> Result<Self, Self::Error> {
990 SegmentHeader::from_builder(from)
991 }
992}
993
994impl<'a, A, I> TryFrom<&TcpSegmentBuilderWithOptions<A, OptionSequenceBuilder<TcpOption<'a>, I>>>
995 for SegmentHeader
996where
997 A: IpAddress,
998 I: Iterator + Clone,
999 I::Item: Borrow<TcpOption<'a>>,
1000{
1001 type Error = MalformedFlags;
1002
1003 fn try_from(
1004 from: &TcpSegmentBuilderWithOptions<A, OptionSequenceBuilder<TcpOption<'a>, I>>,
1005 ) -> Result<Self, Self::Error> {
1006 let prefix_builder = from.prefix_builder();
1007 Self::from_builder_options(
1008 prefix_builder,
1009 Options::try_from_iter(
1010 &prefix_builder,
1011 from.iter_options().map(|option| option.borrow().to_owned()),
1012 )?,
1013 )
1014 }
1015}
1016
1017#[cfg(any(test, feature = "testutils"))]
1018mod testutils {
1019 use super::*;
1020
1021 impl Default for SegmentHeader {
1023 fn default() -> Self {
1024 Self {
1025 seq: SeqNum::new(0),
1026 ack: None,
1027 control: None,
1028 wnd: UnscaledWindowSize::from(0),
1029 options: Options::new(None),
1030 push: false,
1031 }
1032 }
1033 }
1034
1035 impl<P: Payload> Segment<P> {
1036 #[track_caller]
1039 pub fn new_assert_no_discard(header: SegmentHeader, data: P) -> Self {
1040 let (seg, discard) = Self::new(header, data);
1041 assert_eq!(discard, 0);
1042 seg
1043 }
1044 }
1045
1046 impl<'a> Segment<&'a [u8]> {
1047 pub fn with_fake_data(seq: SeqNum, ack: SeqNum, data: &'a [u8]) -> Self {
1049 Self::new_assert_no_discard(
1050 SegmentHeader {
1051 seq,
1052 ack: Some(ack),
1053 control: None,
1054 wnd: UnscaledWindowSize::from(u16::MAX),
1055 options: Options::new(None),
1056 push: false,
1057 },
1058 data,
1059 )
1060 }
1061 }
1062
1063 impl<P: Payload> Segment<P> {
1064 pub fn with_data(
1066 seq: SeqNum,
1067 ack: SeqNum,
1068 wnd: UnscaledWindowSize,
1069 options: SegmentOptions,
1070 data: P,
1071 ) -> Segment<P> {
1072 Segment::new_assert_no_discard(
1073 SegmentHeader {
1074 seq,
1075 ack: Some(ack),
1076 control: None,
1077 wnd,
1078 push: false,
1079 options: Options::Segment(options),
1080 },
1081 data,
1082 )
1083 }
1084
1085 pub fn piggybacked_fin(
1087 seq: SeqNum,
1088 ack: SeqNum,
1089 wnd: UnscaledWindowSize,
1090 options: SegmentOptions,
1091 data: P,
1092 ) -> Segment<P> {
1093 Segment::new_assert_no_discard(
1094 SegmentHeader {
1095 seq,
1096 ack: Some(ack),
1097 control: Some(Control::FIN),
1098 wnd,
1099 push: false,
1100 options: Options::Segment(options),
1101 },
1102 data,
1103 )
1104 }
1105
1106 pub fn fin(
1108 seq: SeqNum,
1109 ack: SeqNum,
1110 wnd: UnscaledWindowSize,
1111 options: SegmentOptions,
1112 ) -> Self {
1113 Segment::new_empty(SegmentHeader {
1114 seq,
1115 ack: Some(ack),
1116 control: Some(Control::FIN),
1117 wnd,
1118 push: false,
1119 options: Options::Segment(options),
1120 })
1121 }
1122 }
1123}
1124
1125#[cfg(test)]
1126mod test {
1127
1128 use assert_matches::assert_matches;
1129 use core::num::NonZeroU16;
1130 use ip_test_macro::ip_test;
1131 use net_declare::{net_ip_v4, net_ip_v6};
1132 use net_types::ip::{Ipv4, Ipv6};
1133 use packet_formats::ip::IpExt;
1134 use test_case::test_case;
1135
1136 use super::*;
1137
1138 #[test_case(None, &[][..] => (0, &[][..]); "empty")]
1139 #[test_case(None, &[1][..] => (1, &[1][..]); "no control")]
1140 #[test_case(Some(Control::SYN), &[][..] => (1, &[][..]); "empty slice with syn")]
1141 #[test_case(Some(Control::SYN), &[1][..] => (2, &[1][..]); "non-empty slice with syn")]
1142 #[test_case(Some(Control::FIN), &[][..] => (1, &[][..]); "empty slice with fin")]
1143 #[test_case(Some(Control::FIN), &[1][..] => (2, &[1][..]); "non-empty slice with fin")]
1144 #[test_case(Some(Control::RST), &[][..] => (0, &[][..]); "empty slice with rst")]
1145 #[test_case(Some(Control::RST), &[1][..] => (1, &[1][..]); "non-empty slice with rst")]
1146 fn segment_len(control: Option<Control>, data: &[u8]) -> (u32, &[u8]) {
1147 let (seg, truncated) = Segment::new(
1148 SegmentHeader {
1149 seq: SeqNum::new(1),
1150 ack: Some(SeqNum::new(1)),
1151 wnd: UnscaledWindowSize::from(0),
1152 control,
1153 push: false,
1154 options: Options::new(None),
1155 },
1156 data,
1157 );
1158 assert_eq!(truncated, 0);
1159 (seg.len(), seg.data)
1160 }
1161
1162 #[test_case(&[1, 2, 3, 4, 5][..], 0..4 => [1, 2, 3, 4])]
1163 #[test_case((), 0..0 => [0, 0, 0, 0])]
1164 fn payload_slice_copy(data: impl Payload, range: Range<u32>) -> [u8; 4] {
1165 let sliced = data.slice(range);
1166 let mut buffer = [0; 4];
1167 sliced.partial_copy(0, &mut buffer[..sliced.len()]);
1168 buffer
1169 }
1170
1171 #[derive(Debug, PartialEq, Eq)]
1172 struct TestPayload(Range<u32>);
1173
1174 impl TestPayload {
1175 fn new(len: usize) -> Self {
1176 Self(0..u32::try_from(len).unwrap())
1177 }
1178 }
1179
1180 impl PayloadLen for TestPayload {
1181 fn len(&self) -> usize {
1182 self.0.len()
1183 }
1184 }
1185
1186 impl Payload for TestPayload {
1187 fn slice(self, range: Range<u32>) -> Self {
1188 let Self(this) = self;
1189 assert!(range.start >= this.start && range.end <= this.end);
1190 TestPayload(range)
1191 }
1192
1193 fn partial_copy(&self, _offset: usize, _dst: &mut [u8]) {
1194 unimplemented!("TestPayload doesn't carry any data");
1195 }
1196
1197 fn partial_copy_uninit(&self, _offset: usize, _dst: &mut [MaybeUninit<u8>]) {
1198 unimplemented!("TestPayload doesn't carry any data");
1199 }
1200
1201 fn new_empty() -> Self {
1202 Self(0..0)
1203 }
1204 }
1205
1206 #[test_case(100, Some(Control::SYN) => (100, Some(Control::SYN), 0))]
1207 #[test_case(100, Some(Control::FIN) => (100, Some(Control::FIN), 0))]
1208 #[test_case(100, Some(Control::RST) => (100, Some(Control::RST), 0))]
1209 #[test_case(100, None => (100, None, 0))]
1210 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN)
1211 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 0))]
1212 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN)
1213 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN), 0))]
1214 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST)
1215 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST), 0))]
1216 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, None
1217 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, None, 0))]
1218 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::SYN)
1219 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1))]
1220 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::FIN)
1221 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
1222 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST)
1223 => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 0))]
1224 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, None
1225 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 0))]
1226 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::SYN)
1227 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 2))]
1228 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::FIN)
1229 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 2))]
1230 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::RST)
1231 => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 1))]
1232 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, None
1233 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
1234 #[test_case(u32::MAX as usize, Some(Control::SYN)
1235 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1 << 31))]
1236 fn segment_truncate(len: usize, control: Option<Control>) -> (usize, Option<Control>, usize) {
1237 let (seg, truncated) = Segment::new(
1238 SegmentHeader {
1239 seq: SeqNum::new(0),
1240 ack: None,
1241 wnd: UnscaledWindowSize::from(0),
1242 control,
1243 push: false,
1244 options: Options::new(None),
1245 },
1246 TestPayload::new(len),
1247 );
1248 (seg.data.len(), seg.header.control, truncated)
1249 }
1250
1251 struct OverlapTestArgs {
1252 seg_seq: u32,
1253 control: Option<Control>,
1254 data_len: u32,
1255 rcv_nxt: u32,
1256 rcv_wnd: usize,
1257 }
1258 #[test_case(OverlapTestArgs{
1259 seg_seq: 1,
1260 control: None,
1261 data_len: 0,
1262 rcv_nxt: 0,
1263 rcv_wnd: 0,
1264 } => None)]
1265 #[test_case(OverlapTestArgs{
1266 seg_seq: 1,
1267 control: None,
1268 data_len: 0,
1269 rcv_nxt: 1,
1270 rcv_wnd: 0,
1271 } => Some((SeqNum::new(1), None, 0..0)))]
1272 #[test_case(OverlapTestArgs{
1273 seg_seq: 1,
1274 control: None,
1275 data_len: 0,
1276 rcv_nxt: 2,
1277 rcv_wnd: 0,
1278 } => None)]
1279 #[test_case(OverlapTestArgs{
1280 seg_seq: 1,
1281 control: Some(Control::SYN),
1282 data_len: 0,
1283 rcv_nxt: 2,
1284 rcv_wnd: 0,
1285 } => None)]
1286 #[test_case(OverlapTestArgs{
1287 seg_seq: 1,
1288 control: Some(Control::SYN),
1289 data_len: 0,
1290 rcv_nxt: 1,
1291 rcv_wnd: 0,
1292 } => None)]
1293 #[test_case(OverlapTestArgs{
1294 seg_seq: 1,
1295 control: Some(Control::SYN),
1296 data_len: 0,
1297 rcv_nxt: 0,
1298 rcv_wnd: 0,
1299 } => None)]
1300 #[test_case(OverlapTestArgs{
1301 seg_seq: 1,
1302 control: Some(Control::FIN),
1303 data_len: 0,
1304 rcv_nxt: 2,
1305 rcv_wnd: 0,
1306 } => None)]
1307 #[test_case(OverlapTestArgs{
1308 seg_seq: 1,
1309 control: Some(Control::FIN),
1310 data_len: 0,
1311 rcv_nxt: 1,
1312 rcv_wnd: 0,
1313 } => None)]
1314 #[test_case(OverlapTestArgs{
1315 seg_seq: 1,
1316 control: Some(Control::FIN),
1317 data_len: 0,
1318 rcv_nxt: 0,
1319 rcv_wnd: 0,
1320 } => None)]
1321 #[test_case(OverlapTestArgs{
1322 seg_seq: 0,
1323 control: None,
1324 data_len: 0,
1325 rcv_nxt: 1,
1326 rcv_wnd: 1,
1327 } => None)]
1328 #[test_case(OverlapTestArgs{
1329 seg_seq: 1,
1330 control: None,
1331 data_len: 0,
1332 rcv_nxt: 1,
1333 rcv_wnd: 1,
1334 } => Some((SeqNum::new(1), None, 0..0)))]
1335 #[test_case(OverlapTestArgs{
1336 seg_seq: 2,
1337 control: None,
1338 data_len: 0,
1339 rcv_nxt: 1,
1340 rcv_wnd: 1,
1341 } => None)]
1342 #[test_case(OverlapTestArgs{
1343 seg_seq: 0,
1344 control: None,
1345 data_len: 1,
1346 rcv_nxt: 1,
1347 rcv_wnd: 1,
1348 } => Some((SeqNum::new(1), None, 1..1)))]
1349 #[test_case(OverlapTestArgs{
1350 seg_seq: 0,
1351 control: Some(Control::SYN),
1352 data_len: 0,
1353 rcv_nxt: 1,
1354 rcv_wnd: 1,
1355 } => Some((SeqNum::new(1), None, 0..0)))]
1356 #[test_case(OverlapTestArgs{
1357 seg_seq: 2,
1358 control: None,
1359 data_len: 1,
1360 rcv_nxt: 1,
1361 rcv_wnd: 1,
1362 } => None)]
1363 #[test_case(OverlapTestArgs{
1364 seg_seq: 0,
1365 control: None,
1366 data_len: 2,
1367 rcv_nxt: 1,
1368 rcv_wnd: 1,
1369 } => Some((SeqNum::new(1), None, 1..2)))]
1370 #[test_case(OverlapTestArgs{
1371 seg_seq: 1,
1372 control: None,
1373 data_len: 2,
1374 rcv_nxt: 1,
1375 rcv_wnd: 1,
1376 } => Some((SeqNum::new(1), None, 0..1)))]
1377 #[test_case(OverlapTestArgs{
1378 seg_seq: 0,
1379 control: Some(Control::SYN),
1380 data_len: 1,
1381 rcv_nxt: 1,
1382 rcv_wnd: 1,
1383 } => Some((SeqNum::new(1), None, 0..1)))]
1384 #[test_case(OverlapTestArgs{
1385 seg_seq: 1,
1386 control: Some(Control::SYN),
1387 data_len: 1,
1388 rcv_nxt: 1,
1389 rcv_wnd: 1,
1390 } => Some((SeqNum::new(1), Some(Control::SYN), 0..0)))]
1391 #[test_case(OverlapTestArgs{
1392 seg_seq: 0,
1393 control: Some(Control::FIN),
1394 data_len: 1,
1395 rcv_nxt: 1,
1396 rcv_wnd: 1,
1397 } => Some((SeqNum::new(1), Some(Control::FIN), 1..1)))]
1398 #[test_case(OverlapTestArgs{
1399 seg_seq: 1,
1400 control: Some(Control::FIN),
1401 data_len: 1,
1402 rcv_nxt: 1,
1403 rcv_wnd: 1,
1404 } => Some((SeqNum::new(1), None, 0..1)))]
1405 #[test_case(OverlapTestArgs{
1406 seg_seq: 1,
1407 control: None,
1408 data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1409 rcv_nxt: 1,
1410 rcv_wnd: 10,
1411 } => Some((SeqNum::new(1), None, 0..10)))]
1412 #[test_case(OverlapTestArgs{
1413 seg_seq: 10,
1414 control: None,
1415 data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1416 rcv_nxt: 1,
1417 rcv_wnd: 10,
1418 } => Some((SeqNum::new(10), None, 0..1)))]
1419 #[test_case(OverlapTestArgs{
1420 seg_seq: 1,
1421 control: None,
1422 data_len: 10,
1423 rcv_nxt: 1,
1424 rcv_wnd: WindowSize::MAX.into(),
1425 } => Some((SeqNum::new(1), None, 0..10)))]
1426 #[test_case(OverlapTestArgs{
1427 seg_seq: 10,
1428 control: None,
1429 data_len: 10,
1430 rcv_nxt: 1,
1431 rcv_wnd: WindowSize::MAX.into(),
1432 } => Some((SeqNum::new(10), None, 0..10)))]
1433 #[test_case(OverlapTestArgs{
1434 seg_seq: 1,
1435 control: Some(Control::FIN),
1436 data_len: 1,
1437 rcv_nxt: 3,
1438 rcv_wnd: 10,
1439 } => Some((SeqNum::new(3), None, 1..1)); "regression test for https://fxbug.dev/42061750")]
1440 fn segment_overlap(
1441 OverlapTestArgs { seg_seq, control, data_len, rcv_nxt, rcv_wnd }: OverlapTestArgs,
1442 ) -> Option<(SeqNum, Option<Control>, Range<u32>)> {
1443 let (seg, discarded) = Segment::new(
1444 SegmentHeader {
1445 seq: SeqNum::new(seg_seq),
1446 ack: None,
1447 control,
1448 wnd: UnscaledWindowSize::from(0),
1449 push: false,
1450 options: Options::new(None),
1451 },
1452 TestPayload(0..data_len),
1453 );
1454 assert_eq!(discarded, 0);
1455 seg.overlap(SeqNum::new(rcv_nxt), WindowSize::new(rcv_wnd).unwrap()).map(
1456 |Segment { header: SegmentHeader { seq, control, .. }, data: TestPayload(range) }| {
1457 (seq, control, range)
1458 },
1459 )
1460 }
1461
1462 pub trait TestIpExt: IpExt {
1463 const SRC_IP: Self::Addr;
1464 const DST_IP: Self::Addr;
1465 }
1466
1467 impl TestIpExt for Ipv4 {
1468 const SRC_IP: Self::Addr = net_ip_v4!("192.0.2.1");
1469 const DST_IP: Self::Addr = net_ip_v4!("192.0.2.2");
1470 }
1471
1472 impl TestIpExt for Ipv6 {
1473 const SRC_IP: Self::Addr = net_ip_v6!("2001:db8::1");
1474 const DST_IP: Self::Addr = net_ip_v6!("2001:db8::2");
1475 }
1476
1477 const SRC_PORT: NonZeroU16 = NonZeroU16::new(1234).unwrap();
1478 const DST_PORT: NonZeroU16 = NonZeroU16::new(9876).unwrap();
1479
1480 #[ip_test(I)]
1481 fn from_segment_builder<I: TestIpExt>() {
1482 let mut builder =
1483 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1484 builder.syn(true);
1485
1486 let converted_header =
1487 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1488
1489 let expected_header = SegmentHeader {
1490 seq: SeqNum::new(1),
1491 ack: Some(SeqNum::new(2)),
1492 wnd: UnscaledWindowSize::from(3u16),
1493 control: Some(Control::SYN),
1494 options: HandshakeOptions::default().into(),
1495 push: false,
1496 };
1497
1498 assert_eq!(converted_header, expected_header);
1499 }
1500
1501 #[ip_test(I)]
1502 fn from_segment_builder_failure<I: TestIpExt>() {
1503 let mut builder =
1504 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1505 builder.syn(true);
1506 builder.fin(true);
1507
1508 assert_matches!(
1509 SegmentHeader::try_from(&builder),
1510 Err(MalformedFlags { syn: true, fin: true, rst: false })
1511 );
1512 }
1513
1514 #[ip_test(I)]
1515 fn from_segment_builder_with_options_handshake<I: TestIpExt>() {
1516 let mut builder =
1517 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1518 builder.syn(true);
1519
1520 let builder = TcpSegmentBuilderWithOptions::new(
1521 builder,
1522 [
1523 TcpOption::Mss(1024),
1524 TcpOption::WindowScale(10),
1525 TcpOption::SackPermitted,
1526 TcpOption::Timestamp { ts_val: 1, ts_echo_reply: 0 },
1527 ],
1528 )
1529 .expect("failed to create tcp segment builder");
1530
1531 let converted_header =
1532 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1533
1534 let expected_header = SegmentHeader {
1535 seq: SeqNum::new(1),
1536 ack: Some(SeqNum::new(2)),
1537 wnd: UnscaledWindowSize::from(3u16),
1538 control: Some(Control::SYN),
1539 push: false,
1540 options: HandshakeOptions {
1541 mss: Some(Mss::new(1024).unwrap()),
1542 window_scale: Some(WindowScale::new(10).unwrap()),
1543 sack_permitted: true,
1544 timestamp: Some(TimestampOption {
1545 ts_val: Timestamp::new(1),
1546 ts_echo_reply: Timestamp::new(0),
1547 }),
1548 }
1549 .into(),
1550 };
1551
1552 assert_eq!(converted_header, expected_header);
1553 }
1554
1555 #[ip_test(I)]
1556 fn mss_option_clamps_to_minimum<I: TestIpExt>() {
1557 let mut builder =
1558 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1559 builder.syn(true);
1560
1561 let builder = TcpSegmentBuilderWithOptions::new(
1562 builder,
1563 [TcpOption::Mss(Mss::MIN.get() - 1)],
1566 )
1567 .expect("failed to create tcp segment builder");
1568
1569 let converted_header =
1570 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1571
1572 let expected_header = SegmentHeader {
1573 seq: SeqNum::new(1),
1574 ack: Some(SeqNum::new(2)),
1575 wnd: UnscaledWindowSize::from(3u16),
1576 control: Some(Control::SYN),
1577 push: false,
1578 options: HandshakeOptions {
1579 mss: Some(Mss::MIN),
1580 window_scale: None,
1581 sack_permitted: false,
1582 timestamp: None,
1583 }
1584 .into(),
1585 };
1586
1587 assert_eq!(converted_header, expected_header);
1588 }
1589
1590 #[ip_test(I)]
1591 fn from_segment_builder_with_options_segment<I: TestIpExt>() {
1592 let mut builder =
1593 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1594 builder.psh(true);
1595
1596 let sack_blocks = [TcpSackBlock::new(1, 2), TcpSackBlock::new(4, 6)];
1597 let builder = TcpSegmentBuilderWithOptions::new(
1598 builder,
1599 [
1600 TcpOption::Sack(&sack_blocks[..]),
1601 TcpOption::Timestamp { ts_val: 1234, ts_echo_reply: 4321 },
1602 ],
1603 )
1604 .expect("failed to create tcp segment builder");
1605
1606 let converted_header =
1607 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1608
1609 let expected_header = SegmentHeader {
1610 seq: SeqNum::new(1),
1611 ack: Some(SeqNum::new(2)),
1612 wnd: UnscaledWindowSize::from(3u16),
1613 control: None,
1614 push: true,
1615 options: SegmentOptions {
1616 sack_blocks: SackBlocks::from_iter([
1617 SackBlock::try_new(SeqNum::new(1), SeqNum::new(2)).unwrap(),
1618 SackBlock::try_new(SeqNum::new(4), SeqNum::new(6)).unwrap(),
1619 ]),
1620 timestamp: Some(TimestampOption {
1621 ts_val: Timestamp::new(1234),
1622 ts_echo_reply: Timestamp::new(4321),
1623 }),
1624 }
1625 .into(),
1626 };
1627
1628 assert_eq!(converted_header, expected_header);
1629 }
1630
1631 #[ip_test(I)]
1632 fn from_segment_builder_with_options_failure<I: TestIpExt>() {
1633 let mut builder =
1634 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1635 builder.syn(true);
1636 builder.fin(true);
1637
1638 let builder = TcpSegmentBuilderWithOptions::new(
1639 builder,
1640 [TcpOption::Mss(1024), TcpOption::WindowScale(10)],
1641 )
1642 .expect("failed to create tcp segment builder");
1643
1644 assert_matches!(
1645 SegmentHeader::try_from(&builder),
1646 Err(MalformedFlags { syn: true, fin: true, rst: false })
1647 );
1648 }
1649
1650 #[ip_test(I)]
1651 fn from_segment_builder_with_options_reset<I: TestIpExt>() {
1652 let mut builder =
1653 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1654 builder.rst(true);
1655
1656 let builder = TcpSegmentBuilderWithOptions::new(
1657 builder,
1658 [TcpOption::Timestamp { ts_val: 1234, ts_echo_reply: 4321 }],
1659 )
1660 .expect("failed to create tcp segment builder");
1661
1662 let converted_header =
1663 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1664
1665 let expected_header = SegmentHeader {
1666 seq: SeqNum::new(1),
1667 ack: Some(SeqNum::new(2)),
1668 wnd: UnscaledWindowSize::from(3u16),
1669 control: Some(Control::RST),
1670 push: false,
1671 options: ResetOptions {
1672 timestamp: Some(TimestampOption {
1673 ts_val: Timestamp::new(1234),
1674 ts_echo_reply: Timestamp::new(4321),
1675 }),
1676 }
1677 .into(),
1678 };
1679
1680 assert_eq!(converted_header, expected_header);
1681 }
1682
1683 #[test_case(Flags {
1684 syn: false,
1685 fin: false,
1686 rst: false,
1687 } => Ok(None))]
1688 #[test_case(Flags {
1689 syn: true,
1690 fin: false,
1691 rst: false,
1692 } => Ok(Some(Control::SYN)))]
1693 #[test_case(Flags {
1694 syn: false,
1695 fin: true,
1696 rst: false,
1697 } => Ok(Some(Control::FIN)))]
1698 #[test_case(Flags {
1699 syn: false,
1700 fin: false,
1701 rst: true,
1702 } => Ok(Some(Control::RST)))]
1703 #[test_case(Flags {
1704 syn: true,
1705 fin: true,
1706 rst: false,
1707 } => Err(MalformedFlags {
1708 syn: true,
1709 fin: true,
1710 rst: false,
1711 }))]
1712 #[test_case(Flags {
1713 syn: true,
1714 fin: false,
1715 rst: true,
1716 } => Err(MalformedFlags {
1717 syn: true,
1718 fin: false,
1719 rst: true,
1720 }))]
1721 #[test_case(Flags {
1722 syn: false,
1723 fin: true,
1724 rst: true,
1725 } => Err(MalformedFlags {
1726 syn: false,
1727 fin: true,
1728 rst: true,
1729 }))]
1730 #[test_case(Flags {
1731 syn: true,
1732 fin: true,
1733 rst: true,
1734 } => Err(MalformedFlags {
1735 syn: true,
1736 fin: true,
1737 rst: true,
1738 }))]
1739 fn flags_to_control(input: Flags) -> Result<Option<Control>, MalformedFlags> {
1740 input.control()
1741 }
1742
1743 #[test]
1744 fn sack_block_try_new() {
1745 assert_matches!(SackBlock::try_new(SeqNum::new(1), SeqNum::new(2)), Ok(_));
1746 assert_matches!(
1747 SackBlock::try_new(SeqNum::new(0u32.wrapping_sub(1)), SeqNum::new(2)),
1748 Ok(_)
1749 );
1750 assert_eq!(
1751 SackBlock::try_new(SeqNum::new(1), SeqNum::new(1)),
1752 Err(InvalidSackBlockError(SeqNum::new(1), SeqNum::new(1)))
1753 );
1754 assert_eq!(
1755 SackBlock::try_new(SeqNum::new(2), SeqNum::new(1)),
1756 Err(InvalidSackBlockError(SeqNum::new(2), SeqNum::new(1)))
1757 );
1758 assert_eq!(
1759 SackBlock::try_new(SeqNum::new(0), SeqNum::new(0u32.wrapping_sub(1))),
1760 Err(InvalidSackBlockError(SeqNum::new(0), SeqNum::new(0u32.wrapping_sub(1))))
1761 );
1762 }
1763
1764 #[test]
1765 fn psh_bit_cleared_if_no_data() {
1766 let seg =
1767 Segment::new_assert_no_discard(SegmentHeader { push: true, ..Default::default() }, ());
1768 assert_eq!(seg.header().push, false);
1769 let seg = Segment::new_assert_no_discard(
1770 SegmentHeader { push: true, ..Default::default() },
1771 &[1u8, 2, 3, 4][..],
1772 );
1773 assert_eq!(seg.header().push, true);
1774 }
1775}