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::{NonZeroU16, TryFromIntError};
13use core::ops::Range;
14
15use arrayvec::ArrayVec;
16use log::info;
17use net_types::ip::IpAddress;
18use packet::records::options::OptionSequenceBuilder;
19use packet::InnerSerializer;
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};
26
27#[derive(Debug, PartialEq, Eq, Clone)]
29pub struct Segment<P> {
30 pub header: SegmentHeader,
32 pub data: P,
37}
38
39#[derive(Debug, PartialEq, Eq, Clone)]
41pub struct SegmentHeader {
42 pub seq: SeqNum,
44 pub ack: Option<SeqNum>,
46 pub wnd: UnscaledWindowSize,
48 pub control: Option<Control>,
50 pub options: Options,
52}
53
54#[derive(Debug, PartialEq, Eq, Clone)]
56pub enum Options {
57 Handshake(HandshakeOptions),
59 Segment(SegmentOptions),
61}
62
63impl Default for Options {
64 fn default() -> Self {
65 Self::Segment(SegmentOptions::default())
68 }
69}
70
71impl From<HandshakeOptions> for Options {
72 fn from(value: HandshakeOptions) -> Self {
73 Self::Handshake(value)
74 }
75}
76
77impl From<SegmentOptions> for Options {
78 fn from(value: SegmentOptions) -> Self {
79 Self::Segment(value)
80 }
81}
82
83impl Options {
84 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Debug + Clone {
86 match self {
87 Options::Handshake(o) => either::Either::Left(o.iter()),
88 Options::Segment(o) => either::Either::Right(o.iter()),
89 }
90 }
91
92 fn as_handshake(&self) -> Option<&HandshakeOptions> {
93 match self {
94 Self::Handshake(h) => Some(h),
95 Self::Segment(_) => None,
96 }
97 }
98
99 fn as_handshake_mut(&mut self) -> Option<&mut HandshakeOptions> {
100 match self {
101 Self::Handshake(h) => Some(h),
102 Self::Segment(_) => None,
103 }
104 }
105
106 fn as_segment_mut(&mut self) -> Option<&mut SegmentOptions> {
107 match self {
108 Self::Handshake(_) => None,
109 Self::Segment(s) => Some(s),
110 }
111 }
112
113 pub fn new_with_handshake(handshake: bool) -> Self {
116 if handshake {
117 Self::Handshake(Default::default())
118 } else {
119 Self::Segment(Default::default())
120 }
121 }
122
123 pub fn from_iter<'a>(handshake: bool, iter: impl IntoIterator<Item = TcpOption<'a>>) -> Self {
128 let mut options = Self::new_with_handshake(handshake);
129 for option in iter {
130 match option {
131 TcpOption::Mss(mss) => {
132 if let Some(h) = options.as_handshake_mut() {
133 h.mss = NonZeroU16::new(mss).map(Mss);
134 }
135 }
136 TcpOption::WindowScale(ws) => {
137 if let Some(h) = options.as_handshake_mut() {
138 if ws > WindowScale::MAX.get() {
143 info!(
144 "received an out-of-range window scale: {}, want < {}",
145 ws,
146 WindowScale::MAX.get()
147 );
148 }
149 h.window_scale = Some(WindowScale::new(ws).unwrap_or(WindowScale::MAX));
150 }
151 }
152 TcpOption::SackPermitted => {
153 if let Some(h) = options.as_handshake_mut() {
154 h.sack_permitted = true;
155 }
156 }
157 TcpOption::Sack(sack) => {
158 if let Some(seg) = options.as_segment_mut() {
159 seg.sack_blocks = SackBlocks::from_option(sack);
160 }
161 }
162 TcpOption::Timestamp { ts_val: _, ts_echo_reply: _ } => {}
164 }
165 }
166 options
167 }
168
169 pub fn window_scale(&self) -> Option<WindowScale> {
171 self.as_handshake().and_then(|h| h.window_scale)
172 }
173
174 pub fn mss(&self) -> Option<Mss> {
176 self.as_handshake().and_then(|h| h.mss)
177 }
178
179 pub fn sack_permitted(&self) -> bool {
182 self.as_handshake().is_some_and(|o| o.sack_permitted)
183 }
184}
185
186#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
188pub struct HandshakeOptions {
189 pub mss: Option<Mss>,
191
192 pub window_scale: Option<WindowScale>,
194
195 pub sack_permitted: bool,
197}
198
199impl HandshakeOptions {
200 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Debug + Clone {
202 let Self { mss, window_scale, sack_permitted } = self;
203 mss.map(|mss| TcpOption::Mss(mss.get().get()))
204 .into_iter()
205 .chain(window_scale.map(|ws| TcpOption::WindowScale(ws.get())))
206 .chain((*sack_permitted).then_some(TcpOption::SackPermitted))
207 }
208}
209
210#[derive(Debug, Default, PartialEq, Eq, Clone)]
212pub struct SegmentOptions {
213 pub sack_blocks: SackBlocks,
215}
216
217impl SegmentOptions {
218 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Debug + Clone {
220 let Self { sack_blocks } = self;
221 sack_blocks.as_option().into_iter()
222 }
223}
224
225const MAX_SACK_BLOCKS: usize = 4;
226#[derive(Debug, Default, PartialEq, Eq, Clone)]
228pub struct SackBlocks(ArrayVec<TcpSackBlock, MAX_SACK_BLOCKS>);
229
230impl SackBlocks {
231 pub const MAX_BLOCKS: usize = MAX_SACK_BLOCKS;
237
238 pub fn as_option(&self) -> Option<TcpOption<'_>> {
242 let Self(inner) = self;
243 if inner.is_empty() {
244 return None;
245 }
246
247 Some(TcpOption::Sack(inner.as_slice()))
248 }
249
250 pub fn iter(&self) -> impl Iterator<Item = SackBlock> + '_ {
252 let Self(inner) = self;
253 inner.iter().map(|block| SackBlock(block.left_edge().into(), block.right_edge().into()))
254 }
255
256 pub fn from_option(blocks: &[TcpSackBlock]) -> Self {
261 Self(blocks.iter().take(Self::MAX_BLOCKS).copied().collect())
262 }
263
264 pub fn from_iter(iter: impl IntoIterator<Item = SackBlock>) -> Self {
268 Self(
269 iter.into_iter()
270 .take(Self::MAX_BLOCKS)
271 .map(|SackBlock(left, right)| TcpSackBlock::new(left.into(), right.into()))
272 .collect(),
273 )
274 }
275
276 pub fn clear(&mut self) {
278 let Self(inner) = self;
279 inner.clear()
280 }
281}
282
283#[derive(Debug, PartialEq, Eq, Clone, Copy)]
287pub struct SackBlock(pub SeqNum, pub SeqNum);
288
289pub const MAX_PAYLOAD_AND_CONTROL_LEN: usize = 1 << 31;
291const MAX_PAYLOAD_AND_CONTROL_LEN_U32: u32 = MAX_PAYLOAD_AND_CONTROL_LEN as u32;
293
294impl<P: Payload> Segment<P> {
295 pub fn with_data_options(
300 seq: SeqNum,
301 ack: Option<SeqNum>,
302 control: Option<Control>,
303 wnd: UnscaledWindowSize,
304 data: P,
305 options: Options,
306 ) -> (Self, usize) {
307 let has_control_len = control.map(Control::has_sequence_no).unwrap_or(false);
308
309 let discarded_len =
310 data.len().saturating_sub(MAX_PAYLOAD_AND_CONTROL_LEN - usize::from(has_control_len));
311
312 let (control, data) = if discarded_len > 0 {
313 let (control, control_len) = if control == Some(Control::FIN) {
316 (None, 0)
317 } else {
318 (control, has_control_len.into())
319 };
320 (control, data.slice(0..MAX_PAYLOAD_AND_CONTROL_LEN_U32 - control_len))
323 } else {
324 (control, data)
325 };
326
327 (
328 Segment { header: SegmentHeader { seq, ack, wnd, control, options }, data: data },
329 discarded_len,
330 )
331 }
332
333 pub fn with_data(
338 seq: SeqNum,
339 ack: Option<SeqNum>,
340 control: Option<Control>,
341 wnd: UnscaledWindowSize,
342 data: P,
343 ) -> (Self, usize) {
344 Self::with_data_options(seq, ack, control, wnd, data, Options::default())
345 }
346
347 pub fn map_payload<R, F: FnOnce(P) -> R>(self, f: F) -> Segment<R> {
349 let Segment { header, data } = self;
350 Segment { header, data: f(data) }
351 }
352
353 pub fn len(&self) -> u32 {
359 self.header.len(self.data.len())
360 }
361
362 pub fn overlap(self, rnxt: SeqNum, rwnd: WindowSize) -> Option<Segment<P>> {
364 let len = self.len();
365 let Segment { header: SegmentHeader { seq, ack, wnd, control, options }, data } = self;
366
367 let overlap = match (len, rwnd) {
379 (0, WindowSize::ZERO) => seq == rnxt,
380 (0, rwnd) => !rnxt.after(seq) && seq.before(rnxt + rwnd),
381 (_len, WindowSize::ZERO) => false,
382 (len, rwnd) => {
383 (!rnxt.after(seq) && seq.before(rnxt + rwnd))
384 || (!(seq + len).before(rnxt) && !(seq + len).after(rnxt + rwnd))
395 }
396 };
397 overlap.then(move || {
398 let cmp = |lhs: &SeqNum, rhs: &SeqNum| (*lhs - *rhs).cmp(&0);
401 let new_seq = core::cmp::max_by(seq, rnxt, cmp);
402 let new_len = core::cmp::min_by(seq + len, rnxt + rwnd, cmp) - new_seq;
403 let start = u32::try_from(new_seq - seq).unwrap();
408 let new_len = u32::try_from(new_len).unwrap();
417 let (new_control, new_data) = {
418 match control {
419 Some(Control::SYN) => {
420 if start == 0 {
421 (Some(Control::SYN), data.slice(start..start + new_len - 1))
422 } else {
423 (None, data.slice(start - 1..start + new_len - 1))
424 }
425 }
426 Some(Control::FIN) => {
427 if len == start + new_len {
428 if new_len > 0 {
429 (Some(Control::FIN), data.slice(start..start + new_len - 1))
430 } else {
431 (None, data.slice(start - 1..start - 1))
432 }
433 } else {
434 (None, data.slice(start..start + new_len))
435 }
436 }
437 Some(Control::RST) | None => (control, data.slice(start..start + new_len)),
438 }
439 };
440 Segment {
441 header: SegmentHeader { seq: new_seq, ack, wnd, control: new_control, options },
442 data: new_data,
443 }
444 })
445 }
446
447 pub fn new(
449 seq: SeqNum,
450 ack: Option<SeqNum>,
451 control: Option<Control>,
452 wnd: UnscaledWindowSize,
453 ) -> Self {
454 Self::with_options(seq, ack, control, wnd, Options::default())
455 }
456
457 pub fn with_options(
459 seq: SeqNum,
460 ack: Option<SeqNum>,
461 control: Option<Control>,
462 wnd: UnscaledWindowSize,
463 options: Options,
464 ) -> Self {
465 let (seg, truncated) =
468 Segment::with_data_options(seq, ack, control, wnd, P::new_empty(), options);
469 debug_assert_eq!(truncated, 0);
470 seg
471 }
472
473 pub fn ack(seq: SeqNum, ack: SeqNum, wnd: UnscaledWindowSize) -> Self {
475 Self::ack_with_options(seq, ack, wnd, Options::default())
476 }
477
478 pub fn ack_with_options(
480 seq: SeqNum,
481 ack: SeqNum,
482 wnd: UnscaledWindowSize,
483 options: Options,
484 ) -> Self {
485 Segment::with_options(seq, Some(ack), None, wnd, options)
486 }
487
488 pub fn syn(seq: SeqNum, wnd: UnscaledWindowSize, options: Options) -> Self {
490 Segment::with_options(seq, None, Some(Control::SYN), wnd, options)
491 }
492
493 pub fn syn_ack(seq: SeqNum, ack: SeqNum, wnd: UnscaledWindowSize, options: Options) -> Self {
495 Segment::with_options(seq, Some(ack), Some(Control::SYN), wnd, options)
496 }
497
498 pub fn rst(seq: SeqNum) -> Self {
500 Segment::new(seq, None, Some(Control::RST), UnscaledWindowSize::from(0))
501 }
502
503 pub fn rst_ack(seq: SeqNum, ack: SeqNum) -> Self {
505 Segment::new(seq, Some(ack), Some(Control::RST), UnscaledWindowSize::from(0))
506 }
507}
508
509impl Segment<()> {
510 pub fn into_empty<P: Payload>(self) -> Segment<P> {
513 self.map_payload(|()| P::new_empty())
514 }
515}
516
517impl SegmentHeader {
518 pub fn len(&self, payload_len: usize) -> u32 {
524 let has_control_len = self.control.map(Control::has_sequence_no).unwrap_or(false);
528 u32::try_from(payload_len).unwrap() + u32::from(has_control_len)
529 }
530
531 pub fn from_builder<A: IpAddress>(
534 builder: &TcpSegmentBuilder<A>,
535 ) -> Result<Self, MalformedFlags> {
536 Self::from_builder_options(builder, Options::new_with_handshake(builder.syn_set()))
537 }
538
539 pub fn from_builder_options<A: IpAddress>(
541 builder: &TcpSegmentBuilder<A>,
542 options: Options,
543 ) -> Result<Self, MalformedFlags> {
544 Ok(SegmentHeader {
545 seq: SeqNum::new(builder.seq_num()),
546 ack: builder.ack_num().map(SeqNum::new),
547 control: Flags {
548 syn: builder.syn_set(),
549 fin: builder.fin_set(),
550 rst: builder.rst_set(),
551 }
552 .control()?,
553 wnd: UnscaledWindowSize::from(builder.window_size()),
554 options: options,
555 })
556 }
557}
558
559pub trait PayloadLen {
561 fn len(&self) -> usize;
563}
564
565pub trait Payload: PayloadLen + Sized {
567 fn slice(self, range: Range<u32>) -> Self;
576
577 fn partial_copy(&self, offset: usize, dst: &mut [u8]);
583
584 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]);
590
591 fn new_empty() -> Self;
595}
596
597impl PayloadLen for &[u8] {
598 fn len(&self) -> usize {
599 <[u8]>::len(self)
600 }
601}
602
603impl Payload for &[u8] {
604 fn slice(self, Range { start, end }: Range<u32>) -> Self {
605 let start = usize::try_from(start).unwrap_or_else(|TryFromIntError { .. }| {
610 panic!("range start index {} out of range for slice of length {}", start, self.len())
611 });
612 let end = usize::try_from(end).unwrap_or_else(|TryFromIntError { .. }| {
613 panic!("range end index {} out of range for slice of length {}", end, self.len())
614 });
615 &self[start..end]
616 }
617
618 fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
619 dst.copy_from_slice(&self[offset..offset + dst.len()])
620 }
621
622 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]) {
623 let src = &self[offset..offset + dst.len()];
626 let uninit_src: &[MaybeUninit<u8>] = unsafe { core::mem::transmute(src) };
628 dst.copy_from_slice(&uninit_src);
629 }
630
631 fn new_empty() -> Self {
632 &[]
633 }
634}
635
636impl PayloadLen for () {
637 fn len(&self) -> usize {
638 0
639 }
640}
641
642impl Payload for () {
643 fn slice(self, Range { start, end }: Range<u32>) -> Self {
644 if start != 0 {
645 panic!("range start index {} out of range for slice of length 0", start);
646 }
647 if end != 0 {
648 panic!("range end index {} out of range for slice of length 0", end);
649 }
650 ()
651 }
652
653 fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
654 if dst.len() != 0 || offset != 0 {
655 panic!(
656 "source slice length (0) does not match destination slice length ({})",
657 dst.len()
658 );
659 }
660 }
661
662 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]) {
663 if dst.len() != 0 || offset != 0 {
664 panic!(
665 "source slice length (0) does not match destination slice length ({})",
666 dst.len()
667 );
668 }
669 }
670
671 fn new_empty() -> Self {
672 ()
673 }
674}
675
676impl<I: PayloadLen, B> PayloadLen for InnerSerializer<I, B> {
677 fn len(&self) -> usize {
678 PayloadLen::len(self.inner())
679 }
680}
681
682#[derive(Error, Debug, PartialEq, Eq)]
683#[error("multiple mutually exclusive flags are set: syn: {syn}, fin: {fin}, rst: {rst}")]
684pub struct MalformedFlags {
685 syn: bool,
686 fin: bool,
687 rst: bool,
688}
689
690struct Flags {
691 syn: bool,
692 fin: bool,
693 rst: bool,
694}
695
696impl Flags {
697 fn control(&self) -> Result<Option<Control>, MalformedFlags> {
698 if usize::from(self.syn) + usize::from(self.fin) + usize::from(self.rst) > 1 {
699 return Err(MalformedFlags { syn: self.syn, fin: self.fin, rst: self.rst });
700 }
701
702 let syn = self.syn.then_some(Control::SYN);
703 let fin = self.fin.then_some(Control::FIN);
704 let rst = self.rst.then_some(Control::RST);
705
706 Ok(syn.or(fin).or(rst))
707 }
708}
709
710impl<'a> TryFrom<TcpSegment<&'a [u8]>> for Segment<&'a [u8]> {
711 type Error = MalformedFlags;
712
713 fn try_from(from: TcpSegment<&'a [u8]>) -> Result<Self, Self::Error> {
714 let syn = from.syn();
715 let options = Options::from_iter(syn, from.iter_options());
716 let (to, discarded) = Segment::with_data_options(
717 from.seq_num().into(),
718 from.ack_num().map(Into::into),
719 Flags { syn, fin: from.fin(), rst: from.rst() }.control()?,
720 UnscaledWindowSize::from(from.window_size()),
721 from.into_body(),
722 options,
723 );
724 debug_assert_eq!(discarded, 0);
725 Ok(to)
726 }
727}
728
729impl<A> TryFrom<&TcpSegmentBuilder<A>> for SegmentHeader
730where
731 A: IpAddress,
732{
733 type Error = MalformedFlags;
734
735 fn try_from(from: &TcpSegmentBuilder<A>) -> Result<Self, Self::Error> {
736 SegmentHeader::from_builder(from)
737 }
738}
739
740impl<'a, A, I> TryFrom<&TcpSegmentBuilderWithOptions<A, OptionSequenceBuilder<TcpOption<'a>, I>>>
741 for SegmentHeader
742where
743 A: IpAddress,
744 I: Iterator + Clone,
745 I::Item: Borrow<TcpOption<'a>>,
746{
747 type Error = MalformedFlags;
748
749 fn try_from(
750 from: &TcpSegmentBuilderWithOptions<A, OptionSequenceBuilder<TcpOption<'a>, I>>,
751 ) -> Result<Self, Self::Error> {
752 let prefix_builder = from.prefix_builder();
753 let handshake = prefix_builder.syn_set();
754 Self::from_builder_options(
755 prefix_builder,
756 Options::from_iter(
757 handshake,
758 from.iter_options().map(|option| option.borrow().to_owned()),
759 ),
760 )
761 }
762}
763
764#[cfg(feature = "testutils")]
765mod testutils {
766 use super::*;
767
768 impl<'a> Segment<&'a [u8]> {
769 pub fn with_fake_data(seq: SeqNum, ack: SeqNum, data: &'a [u8]) -> Self {
771 let (segment, discarded) =
772 Self::with_data(seq, Some(ack), None, UnscaledWindowSize::from(u16::MAX), data);
773 assert_eq!(discarded, 0);
774 segment
775 }
776 }
777
778 impl<P: Payload> Segment<P> {
779 pub fn data(seq: SeqNum, ack: SeqNum, wnd: UnscaledWindowSize, data: P) -> Segment<P> {
781 let (seg, truncated) = Segment::with_data(seq, Some(ack), None, wnd, data);
782 assert_eq!(truncated, 0);
783 seg
784 }
785
786 pub fn piggybacked_fin(
788 seq: SeqNum,
789 ack: SeqNum,
790 wnd: UnscaledWindowSize,
791 data: P,
792 ) -> Segment<P> {
793 let (seg, truncated) =
794 Segment::with_data(seq, Some(ack), Some(Control::FIN), wnd, data);
795 assert_eq!(truncated, 0);
796 seg
797 }
798
799 pub fn fin(seq: SeqNum, ack: SeqNum, wnd: UnscaledWindowSize) -> Self {
801 Segment::new(seq, Some(ack), Some(Control::FIN), wnd)
802 }
803 }
804}
805
806#[cfg(test)]
807mod test {
808 use assert_matches::assert_matches;
809 use ip_test_macro::ip_test;
810 use net_declare::{net_ip_v4, net_ip_v6};
811 use net_types::ip::{Ipv4, Ipv6};
812 use packet_formats::ip::IpExt;
813 use test_case::test_case;
814
815 use super::*;
816
817 #[test_case(None, &[][..] => (0, &[][..]); "empty")]
818 #[test_case(None, &[1][..] => (1, &[1][..]); "no control")]
819 #[test_case(Some(Control::SYN), &[][..] => (1, &[][..]); "empty slice with syn")]
820 #[test_case(Some(Control::SYN), &[1][..] => (2, &[1][..]); "non-empty slice with syn")]
821 #[test_case(Some(Control::FIN), &[][..] => (1, &[][..]); "empty slice with fin")]
822 #[test_case(Some(Control::FIN), &[1][..] => (2, &[1][..]); "non-empty slice with fin")]
823 #[test_case(Some(Control::RST), &[][..] => (0, &[][..]); "empty slice with rst")]
824 #[test_case(Some(Control::RST), &[1][..] => (1, &[1][..]); "non-empty slice with rst")]
825 fn segment_len(control: Option<Control>, data: &[u8]) -> (u32, &[u8]) {
826 let (seg, truncated) = Segment::with_data(
827 SeqNum::new(1),
828 Some(SeqNum::new(1)),
829 control,
830 UnscaledWindowSize::from(0),
831 data,
832 );
833 assert_eq!(truncated, 0);
834 (seg.len(), seg.data)
835 }
836
837 #[test_case(&[1, 2, 3, 4, 5][..], 0..4 => [1, 2, 3, 4])]
838 #[test_case((), 0..0 => [0, 0, 0, 0])]
839 fn payload_slice_copy(data: impl Payload, range: Range<u32>) -> [u8; 4] {
840 let sliced = data.slice(range);
841 let mut buffer = [0; 4];
842 sliced.partial_copy(0, &mut buffer[..sliced.len()]);
843 buffer
844 }
845
846 #[derive(Debug, PartialEq, Eq)]
847 struct TestPayload(Range<u32>);
848
849 impl TestPayload {
850 fn new(len: usize) -> Self {
851 Self(0..u32::try_from(len).unwrap())
852 }
853 }
854
855 impl PayloadLen for TestPayload {
856 fn len(&self) -> usize {
857 self.0.len()
858 }
859 }
860
861 impl Payload for TestPayload {
862 fn slice(self, range: Range<u32>) -> Self {
863 let Self(this) = self;
864 assert!(range.start >= this.start && range.end <= this.end);
865 TestPayload(range)
866 }
867
868 fn partial_copy(&self, _offset: usize, _dst: &mut [u8]) {
869 unimplemented!("TestPayload doesn't carry any data");
870 }
871
872 fn partial_copy_uninit(&self, _offset: usize, _dst: &mut [MaybeUninit<u8>]) {
873 unimplemented!("TestPayload doesn't carry any data");
874 }
875
876 fn new_empty() -> Self {
877 Self(0..0)
878 }
879 }
880
881 #[test_case(100, Some(Control::SYN) => (100, Some(Control::SYN), 0))]
882 #[test_case(100, Some(Control::FIN) => (100, Some(Control::FIN), 0))]
883 #[test_case(100, Some(Control::RST) => (100, Some(Control::RST), 0))]
884 #[test_case(100, None => (100, None, 0))]
885 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN)
886 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 0))]
887 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN)
888 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN), 0))]
889 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST)
890 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST), 0))]
891 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, None
892 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, None, 0))]
893 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::SYN)
894 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1))]
895 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::FIN)
896 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
897 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST)
898 => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 0))]
899 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, None
900 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 0))]
901 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::SYN)
902 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 2))]
903 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::FIN)
904 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 2))]
905 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::RST)
906 => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 1))]
907 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, None
908 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
909 #[test_case(u32::MAX as usize, Some(Control::SYN)
910 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1 << 31))]
911 fn segment_truncate(len: usize, control: Option<Control>) -> (usize, Option<Control>, usize) {
912 let (seg, truncated) = Segment::with_data(
913 SeqNum::new(0),
914 None,
915 control,
916 UnscaledWindowSize::from(0),
917 TestPayload::new(len),
918 );
919 (seg.data.len(), seg.header.control, truncated)
920 }
921
922 struct OverlapTestArgs {
923 seg_seq: u32,
924 control: Option<Control>,
925 data_len: u32,
926 rcv_nxt: u32,
927 rcv_wnd: usize,
928 }
929 #[test_case(OverlapTestArgs{
930 seg_seq: 1,
931 control: None,
932 data_len: 0,
933 rcv_nxt: 0,
934 rcv_wnd: 0,
935 } => None)]
936 #[test_case(OverlapTestArgs{
937 seg_seq: 1,
938 control: None,
939 data_len: 0,
940 rcv_nxt: 1,
941 rcv_wnd: 0,
942 } => Some((SeqNum::new(1), None, 0..0)))]
943 #[test_case(OverlapTestArgs{
944 seg_seq: 1,
945 control: None,
946 data_len: 0,
947 rcv_nxt: 2,
948 rcv_wnd: 0,
949 } => None)]
950 #[test_case(OverlapTestArgs{
951 seg_seq: 1,
952 control: Some(Control::SYN),
953 data_len: 0,
954 rcv_nxt: 2,
955 rcv_wnd: 0,
956 } => None)]
957 #[test_case(OverlapTestArgs{
958 seg_seq: 1,
959 control: Some(Control::SYN),
960 data_len: 0,
961 rcv_nxt: 1,
962 rcv_wnd: 0,
963 } => None)]
964 #[test_case(OverlapTestArgs{
965 seg_seq: 1,
966 control: Some(Control::SYN),
967 data_len: 0,
968 rcv_nxt: 0,
969 rcv_wnd: 0,
970 } => None)]
971 #[test_case(OverlapTestArgs{
972 seg_seq: 1,
973 control: Some(Control::FIN),
974 data_len: 0,
975 rcv_nxt: 2,
976 rcv_wnd: 0,
977 } => None)]
978 #[test_case(OverlapTestArgs{
979 seg_seq: 1,
980 control: Some(Control::FIN),
981 data_len: 0,
982 rcv_nxt: 1,
983 rcv_wnd: 0,
984 } => None)]
985 #[test_case(OverlapTestArgs{
986 seg_seq: 1,
987 control: Some(Control::FIN),
988 data_len: 0,
989 rcv_nxt: 0,
990 rcv_wnd: 0,
991 } => None)]
992 #[test_case(OverlapTestArgs{
993 seg_seq: 0,
994 control: None,
995 data_len: 0,
996 rcv_nxt: 1,
997 rcv_wnd: 1,
998 } => None)]
999 #[test_case(OverlapTestArgs{
1000 seg_seq: 1,
1001 control: None,
1002 data_len: 0,
1003 rcv_nxt: 1,
1004 rcv_wnd: 1,
1005 } => Some((SeqNum::new(1), None, 0..0)))]
1006 #[test_case(OverlapTestArgs{
1007 seg_seq: 2,
1008 control: None,
1009 data_len: 0,
1010 rcv_nxt: 1,
1011 rcv_wnd: 1,
1012 } => None)]
1013 #[test_case(OverlapTestArgs{
1014 seg_seq: 0,
1015 control: None,
1016 data_len: 1,
1017 rcv_nxt: 1,
1018 rcv_wnd: 1,
1019 } => Some((SeqNum::new(1), None, 1..1)))]
1020 #[test_case(OverlapTestArgs{
1021 seg_seq: 0,
1022 control: Some(Control::SYN),
1023 data_len: 0,
1024 rcv_nxt: 1,
1025 rcv_wnd: 1,
1026 } => Some((SeqNum::new(1), None, 0..0)))]
1027 #[test_case(OverlapTestArgs{
1028 seg_seq: 2,
1029 control: None,
1030 data_len: 1,
1031 rcv_nxt: 1,
1032 rcv_wnd: 1,
1033 } => None)]
1034 #[test_case(OverlapTestArgs{
1035 seg_seq: 0,
1036 control: None,
1037 data_len: 2,
1038 rcv_nxt: 1,
1039 rcv_wnd: 1,
1040 } => Some((SeqNum::new(1), None, 1..2)))]
1041 #[test_case(OverlapTestArgs{
1042 seg_seq: 1,
1043 control: None,
1044 data_len: 2,
1045 rcv_nxt: 1,
1046 rcv_wnd: 1,
1047 } => Some((SeqNum::new(1), None, 0..1)))]
1048 #[test_case(OverlapTestArgs{
1049 seg_seq: 0,
1050 control: Some(Control::SYN),
1051 data_len: 1,
1052 rcv_nxt: 1,
1053 rcv_wnd: 1,
1054 } => Some((SeqNum::new(1), None, 0..1)))]
1055 #[test_case(OverlapTestArgs{
1056 seg_seq: 1,
1057 control: Some(Control::SYN),
1058 data_len: 1,
1059 rcv_nxt: 1,
1060 rcv_wnd: 1,
1061 } => Some((SeqNum::new(1), Some(Control::SYN), 0..0)))]
1062 #[test_case(OverlapTestArgs{
1063 seg_seq: 0,
1064 control: Some(Control::FIN),
1065 data_len: 1,
1066 rcv_nxt: 1,
1067 rcv_wnd: 1,
1068 } => Some((SeqNum::new(1), Some(Control::FIN), 1..1)))]
1069 #[test_case(OverlapTestArgs{
1070 seg_seq: 1,
1071 control: Some(Control::FIN),
1072 data_len: 1,
1073 rcv_nxt: 1,
1074 rcv_wnd: 1,
1075 } => Some((SeqNum::new(1), None, 0..1)))]
1076 #[test_case(OverlapTestArgs{
1077 seg_seq: 1,
1078 control: None,
1079 data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1080 rcv_nxt: 1,
1081 rcv_wnd: 10,
1082 } => Some((SeqNum::new(1), None, 0..10)))]
1083 #[test_case(OverlapTestArgs{
1084 seg_seq: 10,
1085 control: None,
1086 data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1087 rcv_nxt: 1,
1088 rcv_wnd: 10,
1089 } => Some((SeqNum::new(10), None, 0..1)))]
1090 #[test_case(OverlapTestArgs{
1091 seg_seq: 1,
1092 control: None,
1093 data_len: 10,
1094 rcv_nxt: 1,
1095 rcv_wnd: 1 << 30 - 1,
1096 } => Some((SeqNum::new(1), None, 0..10)))]
1097 #[test_case(OverlapTestArgs{
1098 seg_seq: 10,
1099 control: None,
1100 data_len: 10,
1101 rcv_nxt: 1,
1102 rcv_wnd: 1 << 30 - 1,
1103 } => Some((SeqNum::new(10), None, 0..10)))]
1104 #[test_case(OverlapTestArgs{
1105 seg_seq: 1,
1106 control: Some(Control::FIN),
1107 data_len: 1,
1108 rcv_nxt: 3,
1109 rcv_wnd: 10,
1110 } => Some((SeqNum::new(3), None, 1..1)); "regression test for https://fxbug.dev/42061750")]
1111 fn segment_overlap(
1112 OverlapTestArgs { seg_seq, control, data_len, rcv_nxt, rcv_wnd }: OverlapTestArgs,
1113 ) -> Option<(SeqNum, Option<Control>, Range<u32>)> {
1114 let (seg, discarded) = Segment::with_data(
1115 SeqNum::new(seg_seq),
1116 None,
1117 control,
1118 UnscaledWindowSize::from(0),
1119 TestPayload(0..data_len),
1120 );
1121 assert_eq!(discarded, 0);
1122 seg.overlap(SeqNum::new(rcv_nxt), WindowSize::new(rcv_wnd).unwrap()).map(
1123 |Segment { header: SegmentHeader { seq, control, .. }, data: TestPayload(range) }| {
1124 (seq, control, range)
1125 },
1126 )
1127 }
1128
1129 pub trait TestIpExt: IpExt {
1130 const SRC_IP: Self::Addr;
1131 const DST_IP: Self::Addr;
1132 }
1133
1134 impl TestIpExt for Ipv4 {
1135 const SRC_IP: Self::Addr = net_ip_v4!("192.0.2.1");
1136 const DST_IP: Self::Addr = net_ip_v4!("192.0.2.2");
1137 }
1138
1139 impl TestIpExt for Ipv6 {
1140 const SRC_IP: Self::Addr = net_ip_v6!("2001:db8::1");
1141 const DST_IP: Self::Addr = net_ip_v6!("2001:db8::2");
1142 }
1143
1144 const SRC_PORT: NonZeroU16 = NonZeroU16::new(1234).unwrap();
1145 const DST_PORT: NonZeroU16 = NonZeroU16::new(9876).unwrap();
1146
1147 #[ip_test(I)]
1148 fn from_segment_builder<I: TestIpExt>() {
1149 let mut builder =
1150 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1151 builder.syn(true);
1152
1153 let converted_header =
1154 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1155
1156 let expected_header = SegmentHeader {
1157 seq: SeqNum::new(1),
1158 ack: Some(SeqNum::new(2)),
1159 wnd: UnscaledWindowSize::from(3u16),
1160 control: Some(Control::SYN),
1161 options: HandshakeOptions::default().into(),
1162 };
1163
1164 assert_eq!(converted_header, expected_header);
1165 }
1166
1167 #[ip_test(I)]
1168 fn from_segment_builder_failure<I: TestIpExt>() {
1169 let mut builder =
1170 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1171 builder.syn(true);
1172 builder.fin(true);
1173
1174 assert_matches!(
1175 SegmentHeader::try_from(&builder),
1176 Err(MalformedFlags { syn: true, fin: true, rst: false })
1177 );
1178 }
1179
1180 #[ip_test(I)]
1181 fn from_segment_builder_with_options_handshake<I: TestIpExt>() {
1182 let mut builder =
1183 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1184 builder.syn(true);
1185
1186 let builder = TcpSegmentBuilderWithOptions::new(
1187 builder,
1188 [TcpOption::Mss(1024), TcpOption::WindowScale(10), TcpOption::SackPermitted],
1189 )
1190 .expect("failed to create tcp segment builder");
1191
1192 let converted_header =
1193 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1194
1195 let expected_header = SegmentHeader {
1196 seq: SeqNum::new(1),
1197 ack: Some(SeqNum::new(2)),
1198 wnd: UnscaledWindowSize::from(3u16),
1199 control: Some(Control::SYN),
1200 options: HandshakeOptions {
1201 mss: Some(Mss(NonZeroU16::new(1024).unwrap())),
1202 window_scale: Some(WindowScale::new(10).unwrap()),
1203 sack_permitted: true,
1204 }
1205 .into(),
1206 };
1207
1208 assert_eq!(converted_header, expected_header);
1209 }
1210
1211 #[ip_test(I)]
1212 fn from_segment_builder_with_options_segment<I: TestIpExt>() {
1213 let builder =
1214 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1215
1216 let sack_blocks = [TcpSackBlock::new(1, 2), TcpSackBlock::new(4, 6)];
1217 let builder =
1218 TcpSegmentBuilderWithOptions::new(builder, [TcpOption::Sack(&sack_blocks[..])])
1219 .expect("failed to create tcp segment builder");
1220
1221 let converted_header =
1222 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1223
1224 let expected_header = SegmentHeader {
1225 seq: SeqNum::new(1),
1226 ack: Some(SeqNum::new(2)),
1227 wnd: UnscaledWindowSize::from(3u16),
1228 control: None,
1229 options: SegmentOptions {
1230 sack_blocks: SackBlocks::from_iter([
1231 SackBlock(SeqNum::new(1), SeqNum::new(2)),
1232 SackBlock(SeqNum::new(4), SeqNum::new(6)),
1233 ]),
1234 }
1235 .into(),
1236 };
1237
1238 assert_eq!(converted_header, expected_header);
1239 }
1240
1241 #[ip_test(I)]
1242 fn from_segment_builder_with_options_failure<I: TestIpExt>() {
1243 let mut builder =
1244 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1245 builder.syn(true);
1246 builder.fin(true);
1247
1248 let builder = TcpSegmentBuilderWithOptions::new(
1249 builder,
1250 [TcpOption::Mss(1024), TcpOption::WindowScale(10)],
1251 )
1252 .expect("failed to create tcp segment builder");
1253
1254 assert_matches!(
1255 SegmentHeader::try_from(&builder),
1256 Err(MalformedFlags { syn: true, fin: true, rst: false })
1257 );
1258 }
1259
1260 #[test_case(Flags {
1261 syn: false,
1262 fin: false,
1263 rst: false,
1264 } => Ok(None))]
1265 #[test_case(Flags {
1266 syn: true,
1267 fin: false,
1268 rst: false,
1269 } => Ok(Some(Control::SYN)))]
1270 #[test_case(Flags {
1271 syn: false,
1272 fin: true,
1273 rst: false,
1274 } => Ok(Some(Control::FIN)))]
1275 #[test_case(Flags {
1276 syn: false,
1277 fin: false,
1278 rst: true,
1279 } => Ok(Some(Control::RST)))]
1280 #[test_case(Flags {
1281 syn: true,
1282 fin: true,
1283 rst: false,
1284 } => Err(MalformedFlags {
1285 syn: true,
1286 fin: true,
1287 rst: false,
1288 }))]
1289 #[test_case(Flags {
1290 syn: true,
1291 fin: false,
1292 rst: true,
1293 } => Err(MalformedFlags {
1294 syn: true,
1295 fin: false,
1296 rst: true,
1297 }))]
1298 #[test_case(Flags {
1299 syn: false,
1300 fin: true,
1301 rst: true,
1302 } => Err(MalformedFlags {
1303 syn: false,
1304 fin: true,
1305 rst: true,
1306 }))]
1307 #[test_case(Flags {
1308 syn: true,
1309 fin: true,
1310 rst: true,
1311 } => Err(MalformedFlags {
1312 syn: true,
1313 fin: true,
1314 rst: true,
1315 }))]
1316 fn flags_to_control(input: Flags) -> Result<Option<Control>, MalformedFlags> {
1317 input.control()
1318 }
1319}