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};
26
27#[derive(Debug, PartialEq, Eq, Clone)]
29pub struct Segment<P> {
30 header: SegmentHeader,
32 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 push: bool,
52 pub options: Options,
54}
55
56#[derive(Debug, PartialEq, Eq, Clone)]
58pub enum Options {
59 Handshake(HandshakeOptions),
61 Segment(SegmentOptions),
63 Reset(ResetOptions),
65}
66
67impl Options {
68 fn new(control: Option<&Control>) -> Self {
70 match control {
71 None | Some(Control::FIN) => Options::Segment(Default::default()),
72 Some(Control::SYN) => Options::Handshake(Default::default()),
73 Some(Control::RST) => Options::Reset(Default::default()),
74 }
75 }
76}
77
78impl From<HandshakeOptions> for Options {
79 fn from(value: HandshakeOptions) -> Self {
80 Self::Handshake(value)
81 }
82}
83
84impl From<SegmentOptions> for Options {
85 fn from(value: SegmentOptions) -> Self {
86 Self::Segment(value)
87 }
88}
89
90impl From<ResetOptions> for Options {
91 fn from(value: ResetOptions) -> Self {
92 Self::Reset(value)
93 }
94}
95
96impl Options {
97 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Debug + Clone {
99 match self {
101 Options::Handshake(o) => either::Either::Left(either::Either::Left(o.iter())),
102 Options::Segment(o) => either::Either::Left(either::Either::Right(o.iter())),
103 Options::Reset(o) => either::Either::Right(o.iter()),
104 }
105 }
106
107 fn as_handshake(&self) -> Option<&HandshakeOptions> {
108 match self {
109 Self::Handshake(h) => Some(h),
110 Self::Segment(_) | Self::Reset(_) => None,
111 }
112 }
113
114 fn as_handshake_mut(&mut self) -> Option<&mut HandshakeOptions> {
115 match self {
116 Self::Handshake(h) => Some(h),
117 Self::Segment(_) | Self::Reset(_) => None,
118 }
119 }
120
121 fn as_segment(&self) -> Option<&SegmentOptions> {
122 match self {
123 Self::Handshake(_) | Self::Reset(_) => None,
124 Self::Segment(s) => Some(s),
125 }
126 }
127
128 fn as_segment_mut(&mut self) -> Option<&mut SegmentOptions> {
129 match self {
130 Self::Handshake(_) | Self::Reset(_) => None,
131 Self::Segment(s) => Some(s),
132 }
133 }
134
135 pub fn from_iter<'a>(
137 control: Option<&Control>,
138 iter: impl IntoIterator<Item = TcpOption<'a>>,
139 ) -> Self {
140 let mut options = Options::new(control);
141 for option in iter {
142 match option {
143 TcpOption::Mss(mss) => {
144 if let Some(h) = options.as_handshake_mut() {
145 h.mss = Some(Mss::new(mss).unwrap_or(Mss::MIN));
150 }
151 }
152 TcpOption::WindowScale(ws) => {
153 if let Some(h) = options.as_handshake_mut() {
154 if ws > WindowScale::MAX.get() {
159 info!(
160 "received an out-of-range window scale: {}, want < {}",
161 ws,
162 WindowScale::MAX.get()
163 );
164 }
165 h.window_scale = Some(WindowScale::new(ws).unwrap_or(WindowScale::MAX));
166 }
167 }
168 TcpOption::SackPermitted => {
169 if let Some(h) = options.as_handshake_mut() {
170 h.sack_permitted = true;
171 }
172 }
173 TcpOption::Sack(sack) => {
174 if let Some(seg) = options.as_segment_mut() {
175 seg.sack_blocks = SackBlocks::from_option(sack);
176 }
177 }
178 TcpOption::Timestamp { ts_val: _, ts_echo_reply: _ } => {}
180 }
181 }
182 options
183 }
184
185 pub fn try_from_iter<'a, A: IpAddress>(
187 builder: &TcpSegmentBuilder<A>,
188 iter: impl IntoIterator<Item = TcpOption<'a>>,
189 ) -> Result<Self, MalformedFlags> {
190 let control =
191 Flags { syn: builder.syn_set(), fin: builder.fin_set(), rst: builder.rst_set() }
192 .control()?;
193 Ok(Options::from_iter(control.as_ref(), iter))
194 }
195
196 pub fn window_scale(&self) -> Option<WindowScale> {
198 self.as_handshake().and_then(|h| h.window_scale)
199 }
200
201 pub fn mss(&self) -> Option<Mss> {
203 self.as_handshake().and_then(|h| h.mss)
204 }
205
206 pub fn sack_permitted(&self) -> bool {
209 self.as_handshake().is_some_and(|o| o.sack_permitted)
210 }
211
212 pub fn sack_blocks(&self) -> &SackBlocks {
216 const EMPTY_REF: &'static SackBlocks = &SackBlocks::EMPTY;
217 self.as_segment().map(|s| &s.sack_blocks).unwrap_or(EMPTY_REF)
218 }
219}
220
221#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
223pub struct HandshakeOptions {
224 pub mss: Option<Mss>,
226
227 pub window_scale: Option<WindowScale>,
229
230 pub sack_permitted: bool,
232}
233
234impl HandshakeOptions {
235 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Debug + Clone {
237 let Self { mss, window_scale, sack_permitted } = self;
238 mss.map(|mss| TcpOption::Mss(mss.get()))
239 .into_iter()
240 .chain(window_scale.map(|ws| TcpOption::WindowScale(ws.get())))
241 .chain((*sack_permitted).then_some(TcpOption::SackPermitted))
242 }
243}
244
245#[derive(Debug, Default, PartialEq, Eq, Clone)]
247pub struct SegmentOptions {
248 pub sack_blocks: SackBlocks,
250}
251
252impl SegmentOptions {
253 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Debug + Clone {
255 let Self { sack_blocks } = self;
256 sack_blocks.as_option().into_iter()
257 }
258
259 pub fn is_empty(&self) -> bool {
261 let Self { sack_blocks } = self;
262 sack_blocks.is_empty()
263 }
264}
265
266#[derive(Debug, Default, PartialEq, Eq, Clone)]
268pub struct ResetOptions {
269 }
271
272impl ResetOptions {
273 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Debug + Clone {
275 core::iter::empty()
276 }
277}
278
279const MAX_SACK_BLOCKS: usize = 4;
280#[derive(Debug, Default, PartialEq, Eq, Clone)]
282pub struct SackBlocks(ArrayVec<TcpSackBlock, MAX_SACK_BLOCKS>);
283
284impl SackBlocks {
285 pub const EMPTY: Self = SackBlocks(ArrayVec::new_const());
287
288 pub const MAX_BLOCKS: usize = MAX_SACK_BLOCKS;
294
295 pub fn as_option(&self) -> Option<TcpOption<'_>> {
299 let Self(inner) = self;
300 if inner.is_empty() {
301 return None;
302 }
303
304 Some(TcpOption::Sack(inner.as_slice()))
305 }
306
307 pub fn iter_skip_invalid(&self) -> impl Iterator<Item = SackBlock> + '_ {
310 self.try_iter().filter_map(|r| match r {
311 Ok(s) => Some(s),
312 Err(InvalidSackBlockError(_, _)) => None,
313 })
314 }
315
316 pub fn try_iter(&self) -> impl Iterator<Item = Result<SackBlock, InvalidSackBlockError>> + '_ {
319 let Self(inner) = self;
320 inner.iter().map(|block| SackBlock::try_from(*block))
321 }
322
323 pub fn from_option(blocks: &[TcpSackBlock]) -> Self {
328 Self(blocks.iter().take(Self::MAX_BLOCKS).copied().collect())
329 }
330
331 pub fn is_empty(&self) -> bool {
333 let Self(inner) = self;
334 inner.is_empty()
335 }
336
337 pub fn clear(&mut self) {
339 let Self(inner) = self;
340 inner.clear()
341 }
342}
343
344impl FromIterator<SackBlock> for SackBlocks {
348 fn from_iter<T: IntoIterator<Item = SackBlock>>(iter: T) -> Self {
349 Self(iter.into_iter().take(Self::MAX_BLOCKS).map(|b| b.into()).collect())
350 }
351}
352
353mod sack_block {
354 use super::*;
355
356 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
361 pub struct SackBlock {
362 left: SeqNum,
364 right: SeqNum,
365 }
366
367 impl SackBlock {
368 pub fn try_new(left: SeqNum, right: SeqNum) -> Result<Self, InvalidSackBlockError> {
372 if right.after(left) {
373 Ok(Self { left, right })
374 } else {
375 Err(InvalidSackBlockError(left, right))
376 }
377 }
378
379 pub unsafe fn new_unchecked(left: SeqNum, right: SeqNum) -> Self {
386 Self { left, right }
387 }
388
389 pub fn into_range(self) -> Range<SeqNum> {
391 let Self { left, right } = self;
392 Range { start: left, end: right }
393 }
394
395 pub fn into_range_u32(self) -> Range<u32> {
398 let Self { left, right } = self;
399 Range { start: left.into(), end: right.into() }
400 }
401
402 pub fn left(&self) -> SeqNum {
404 self.left
405 }
406
407 pub fn right(&self) -> SeqNum {
409 self.right
410 }
411
412 pub fn into_parts(self) -> (SeqNum, SeqNum) {
415 let Self { left, right } = self;
416 (left, right)
417 }
418 }
419
420 #[derive(Debug, Eq, PartialEq, Clone, Copy)]
423 pub struct InvalidSackBlockError(pub SeqNum, pub SeqNum);
424
425 impl From<SackBlock> for TcpSackBlock {
426 fn from(value: SackBlock) -> Self {
427 let SackBlock { left, right } = value;
428 TcpSackBlock::new(left.into(), right.into())
429 }
430 }
431
432 impl TryFrom<TcpSackBlock> for SackBlock {
433 type Error = InvalidSackBlockError;
434
435 fn try_from(value: TcpSackBlock) -> Result<Self, Self::Error> {
436 Self::try_new(value.left_edge().into(), value.right_edge().into())
437 }
438 }
439
440 impl From<SackBlock> for Range<SeqNum> {
441 fn from(value: SackBlock) -> Self {
442 value.into_range()
443 }
444 }
445
446 impl TryFrom<Range<SeqNum>> for SackBlock {
447 type Error = InvalidSackBlockError;
448
449 fn try_from(value: Range<SeqNum>) -> Result<Self, Self::Error> {
450 let Range { start, end } = value;
451 Self::try_new(start, end)
452 }
453 }
454}
455pub use sack_block::{InvalidSackBlockError, SackBlock};
456
457pub const MAX_PAYLOAD_AND_CONTROL_LEN: usize = 1 << 31;
459const MAX_PAYLOAD_AND_CONTROL_LEN_U32: u32 = MAX_PAYLOAD_AND_CONTROL_LEN as u32;
461
462impl<P: Payload> Segment<P> {
463 pub fn new(header: SegmentHeader, data: P) -> (Self, usize) {
468 let SegmentHeader { seq, ack, wnd, control, push, options } = header;
469 let has_control_len = control.map(Control::has_sequence_no).unwrap_or(false);
470
471 let data_len = data.len();
472 let discarded_len =
473 data_len.saturating_sub(MAX_PAYLOAD_AND_CONTROL_LEN - usize::from(has_control_len));
474
475 let push = push && data_len != 0;
477
478 let (control, data) = if discarded_len > 0 {
479 let (control, control_len) = if control == Some(Control::FIN) {
482 (None, 0)
483 } else {
484 (control, has_control_len.into())
485 };
486 (control, data.slice(0..MAX_PAYLOAD_AND_CONTROL_LEN_U32 - control_len))
489 } else {
490 (control, data)
491 };
492
493 (
494 Segment { header: SegmentHeader { seq, ack, wnd, control, push, options }, data: data },
495 discarded_len,
496 )
497 }
498
499 pub fn header(&self) -> &SegmentHeader {
501 &self.header
502 }
503
504 pub fn data(&self) -> &P {
506 &self.data
507 }
508
509 pub fn into_parts(self) -> (SegmentHeader, P) {
512 let Self { header, data } = self;
513 (header, data)
514 }
515
516 pub fn map_payload<R, F: FnOnce(P) -> R>(self, f: F) -> Segment<R> {
518 let Segment { header, data } = self;
519 Segment { header, data: f(data) }
520 }
521
522 pub fn len(&self) -> u32 {
528 self.header.len(self.data.len())
529 }
530
531 pub fn overlap(self, rnxt: SeqNum, rwnd: WindowSize) -> Option<Segment<P>> {
533 let len = self.len();
534 let Segment { header: SegmentHeader { seq, ack, wnd, control, options, push }, data } =
535 self;
536
537 let overlap = match (len, rwnd) {
549 (0, WindowSize::ZERO) => seq == rnxt,
550 (0, rwnd) => !rnxt.after(seq) && seq.before(rnxt + rwnd),
551 (_len, WindowSize::ZERO) => false,
552 (len, rwnd) => {
553 (!rnxt.after(seq) && seq.before(rnxt + rwnd))
554 || (!(seq + len).before(rnxt) && !(seq + len).after(rnxt + rwnd))
565 }
566 };
567 overlap.then(move || {
568 let cmp = |lhs: &SeqNum, rhs: &SeqNum| (*lhs - *rhs).cmp(&0);
571 let new_seq = core::cmp::max_by(seq, rnxt, cmp);
572 let new_len = core::cmp::min_by(seq + len, rnxt + rwnd, cmp) - new_seq;
573 let start = u32::try_from(new_seq - seq).unwrap();
578 let new_len = u32::try_from(new_len).unwrap();
587 let (new_control, new_data) = {
588 match control {
589 Some(Control::SYN) => {
590 if start == 0 {
591 (Some(Control::SYN), data.slice(start..start + new_len - 1))
592 } else {
593 (None, data.slice(start - 1..start + new_len - 1))
594 }
595 }
596 Some(Control::FIN) => {
597 if len == start + new_len {
598 if new_len > 0 {
599 (Some(Control::FIN), data.slice(start..start + new_len - 1))
600 } else {
601 (None, data.slice(start - 1..start - 1))
602 }
603 } else {
604 (None, data.slice(start..start + new_len))
605 }
606 }
607 Some(Control::RST) | None => (control, data.slice(start..start + new_len)),
608 }
609 };
610 Segment {
611 header: SegmentHeader {
612 seq: new_seq,
613 ack,
614 wnd,
615 control: new_control,
616 options,
617 push,
618 },
619 data: new_data,
620 }
621 })
622 }
623
624 pub fn new_empty(header: SegmentHeader) -> Self {
626 let (seg, truncated) = Self::new(header, P::new_empty());
629 debug_assert_eq!(truncated, 0);
630 seg
631 }
632
633 pub fn ack_with_options(
635 seq: SeqNum,
636 ack: SeqNum,
637 wnd: UnscaledWindowSize,
638 options: SegmentOptions,
639 ) -> Self {
640 Segment::new_empty(SegmentHeader {
641 seq,
642 ack: Some(ack),
643 wnd,
644 control: None,
645 push: false,
646 options: options.into(),
647 })
648 }
649
650 pub fn syn(seq: SeqNum, wnd: UnscaledWindowSize, options: HandshakeOptions) -> Self {
652 Segment::new_empty(SegmentHeader {
653 seq,
654 ack: None,
655 wnd,
656 control: Some(Control::SYN),
657 push: false,
658 options: options.into(),
659 })
660 }
661
662 pub fn syn_ack(
664 seq: SeqNum,
665 ack: SeqNum,
666 wnd: UnscaledWindowSize,
667 options: HandshakeOptions,
668 ) -> Self {
669 Segment::new_empty(SegmentHeader {
670 seq,
671 ack: Some(ack),
672 wnd,
673 control: Some(Control::SYN),
674 push: false,
675 options: options.into(),
676 })
677 }
678
679 pub fn rst(seq: SeqNum, options: ResetOptions) -> Self {
681 Segment::new_empty(SegmentHeader {
682 seq,
683 ack: None,
684 wnd: UnscaledWindowSize::from(0),
685 control: Some(Control::RST),
686 push: false,
687 options: options.into(),
688 })
689 }
690
691 pub fn rst_ack(seq: SeqNum, ack: SeqNum, options: ResetOptions) -> Self {
693 Segment::new_empty(SegmentHeader {
694 seq,
695 ack: Some(ack),
696 wnd: UnscaledWindowSize::from(0),
697 control: Some(Control::RST),
698 push: false,
699 options: options.into(),
700 })
701 }
702}
703
704impl Segment<()> {
705 pub fn into_empty<P: Payload>(self) -> Segment<P> {
708 self.map_payload(|()| P::new_empty())
709 }
710}
711
712impl SegmentHeader {
713 pub fn len(&self, payload_len: usize) -> u32 {
719 let has_control_len = self.control.map(Control::has_sequence_no).unwrap_or(false);
723 u32::try_from(payload_len).unwrap() + u32::from(has_control_len)
724 }
725
726 pub fn from_builder<A: IpAddress>(
729 builder: &TcpSegmentBuilder<A>,
730 ) -> Result<Self, MalformedFlags> {
731 let control =
732 Flags { syn: builder.syn_set(), fin: builder.fin_set(), rst: builder.rst_set() }
733 .control()?;
734 let options = Options::new(control.as_ref());
735 Self::from_builder_options(builder, options)
736 }
737
738 pub fn from_builder_options<A: IpAddress>(
740 builder: &TcpSegmentBuilder<A>,
741 options: Options,
742 ) -> Result<Self, MalformedFlags> {
743 Ok(SegmentHeader {
744 seq: SeqNum::new(builder.seq_num()),
745 ack: builder.ack_num().map(SeqNum::new),
746 control: Flags {
747 syn: builder.syn_set(),
748 fin: builder.fin_set(),
749 rst: builder.rst_set(),
750 }
751 .control()?,
752 wnd: UnscaledWindowSize::from(builder.window_size()),
753 push: builder.psh_set(),
754 options: options,
755 })
756 }
757}
758
759pub trait PayloadLen {
761 fn len(&self) -> usize;
763}
764
765pub trait Payload: PayloadLen + Sized {
767 fn slice(self, range: Range<u32>) -> Self;
776
777 fn partial_copy(&self, offset: usize, dst: &mut [u8]);
783
784 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]);
790
791 fn new_empty() -> Self;
795}
796
797impl PayloadLen for &[u8] {
798 fn len(&self) -> usize {
799 <[u8]>::len(self)
800 }
801}
802
803impl Payload for &[u8] {
804 fn slice(self, Range { start, end }: Range<u32>) -> Self {
805 let start = usize::try_from(start).unwrap_or_else(|TryFromIntError { .. }| {
810 panic!("range start index {} out of range for slice of length {}", start, self.len())
811 });
812 let end = usize::try_from(end).unwrap_or_else(|TryFromIntError { .. }| {
813 panic!("range end index {} out of range for slice of length {}", end, self.len())
814 });
815 &self[start..end]
816 }
817
818 fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
819 dst.copy_from_slice(&self[offset..offset + dst.len()])
820 }
821
822 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]) {
823 let src = &self[offset..offset + dst.len()];
826 let uninit_src: &[MaybeUninit<u8>] = unsafe { core::mem::transmute(src) };
828 dst.copy_from_slice(&uninit_src);
829 }
830
831 fn new_empty() -> Self {
832 &[]
833 }
834}
835
836impl PayloadLen for () {
837 fn len(&self) -> usize {
838 0
839 }
840}
841
842impl Payload for () {
843 fn slice(self, Range { start, end }: Range<u32>) -> Self {
844 if start != 0 {
845 panic!("range start index {} out of range for slice of length 0", start);
846 }
847 if end != 0 {
848 panic!("range end index {} out of range for slice of length 0", end);
849 }
850 ()
851 }
852
853 fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
854 if dst.len() != 0 || offset != 0 {
855 panic!(
856 "source slice length (0) does not match destination slice length ({})",
857 dst.len()
858 );
859 }
860 }
861
862 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]) {
863 if dst.len() != 0 || offset != 0 {
864 panic!(
865 "source slice length (0) does not match destination slice length ({})",
866 dst.len()
867 );
868 }
869 }
870
871 fn new_empty() -> Self {
872 ()
873 }
874}
875
876impl<I: PayloadLen, B> PayloadLen for InnerSerializer<I, B> {
877 fn len(&self) -> usize {
878 PayloadLen::len(self.inner())
879 }
880}
881
882#[derive(Error, Debug, PartialEq, Eq)]
883#[error("multiple mutually exclusive flags are set: syn: {syn}, fin: {fin}, rst: {rst}")]
884pub struct MalformedFlags {
885 syn: bool,
886 fin: bool,
887 rst: bool,
888}
889
890struct Flags {
891 syn: bool,
892 fin: bool,
893 rst: bool,
894}
895
896impl Flags {
897 fn control(&self) -> Result<Option<Control>, MalformedFlags> {
898 if usize::from(self.syn) + usize::from(self.fin) + usize::from(self.rst) > 1 {
899 return Err(MalformedFlags { syn: self.syn, fin: self.fin, rst: self.rst });
900 }
901
902 let syn = self.syn.then_some(Control::SYN);
903 let fin = self.fin.then_some(Control::FIN);
904 let rst = self.rst.then_some(Control::RST);
905
906 Ok(syn.or(fin).or(rst))
907 }
908}
909
910pub struct VerifiedTcpSegment<'a> {
913 segment: TcpSegment<&'a [u8]>,
914 control: Option<Control>,
915}
916
917impl<'a> VerifiedTcpSegment<'a> {
918 pub fn tcp_segment(&self) -> &TcpSegment<&'a [u8]> {
920 &self.segment
921 }
922
923 pub fn control(&self) -> Option<Control> {
925 self.control
926 }
927}
928
929impl<'a> TryFrom<TcpSegment<&'a [u8]>> for VerifiedTcpSegment<'a> {
930 type Error = MalformedFlags;
931
932 fn try_from(segment: TcpSegment<&'a [u8]>) -> Result<Self, Self::Error> {
933 let control =
934 Flags { syn: segment.syn(), fin: segment.fin(), rst: segment.rst() }.control()?;
935 Ok(VerifiedTcpSegment { segment, control })
936 }
937}
938
939impl<'a> From<&'a VerifiedTcpSegment<'a>> for Segment<&'a [u8]> {
940 fn from(from: &'a VerifiedTcpSegment<'a>) -> Segment<&'a [u8]> {
941 let VerifiedTcpSegment { segment, control } = from;
942 let options = Options::from_iter(control.as_ref(), segment.iter_options());
943 let (to, discarded) = Segment::new(
944 SegmentHeader {
945 seq: segment.seq_num().into(),
946 ack: segment.ack_num().map(Into::into),
947 wnd: UnscaledWindowSize::from(segment.window_size()),
948 control: *control,
949 push: segment.psh(),
950 options,
951 },
952 from.segment.body(),
953 );
954 debug_assert_eq!(discarded, 0);
955 to
956 }
957}
958
959impl<A> TryFrom<&TcpSegmentBuilder<A>> for SegmentHeader
960where
961 A: IpAddress,
962{
963 type Error = MalformedFlags;
964
965 fn try_from(from: &TcpSegmentBuilder<A>) -> Result<Self, Self::Error> {
966 SegmentHeader::from_builder(from)
967 }
968}
969
970impl<'a, A, I> TryFrom<&TcpSegmentBuilderWithOptions<A, OptionSequenceBuilder<TcpOption<'a>, I>>>
971 for SegmentHeader
972where
973 A: IpAddress,
974 I: Iterator + Clone,
975 I::Item: Borrow<TcpOption<'a>>,
976{
977 type Error = MalformedFlags;
978
979 fn try_from(
980 from: &TcpSegmentBuilderWithOptions<A, OptionSequenceBuilder<TcpOption<'a>, I>>,
981 ) -> Result<Self, Self::Error> {
982 let prefix_builder = from.prefix_builder();
983 Self::from_builder_options(
984 prefix_builder,
985 Options::try_from_iter(
986 &prefix_builder,
987 from.iter_options().map(|option| option.borrow().to_owned()),
988 )?,
989 )
990 }
991}
992
993#[cfg(any(test, feature = "testutils"))]
994mod testutils {
995 use super::*;
996
997 impl Default for SegmentHeader {
999 fn default() -> Self {
1000 Self {
1001 seq: SeqNum::new(0),
1002 ack: None,
1003 control: None,
1004 wnd: UnscaledWindowSize::from(0),
1005 options: Options::new(None),
1006 push: false,
1007 }
1008 }
1009 }
1010
1011 impl<P: Payload> Segment<P> {
1012 #[track_caller]
1015 pub fn new_assert_no_discard(header: SegmentHeader, data: P) -> Self {
1016 let (seg, discard) = Self::new(header, data);
1017 assert_eq!(discard, 0);
1018 seg
1019 }
1020 }
1021
1022 impl<'a> Segment<&'a [u8]> {
1023 pub fn with_fake_data(seq: SeqNum, ack: SeqNum, data: &'a [u8]) -> Self {
1025 Self::new_assert_no_discard(
1026 SegmentHeader {
1027 seq,
1028 ack: Some(ack),
1029 control: None,
1030 wnd: UnscaledWindowSize::from(u16::MAX),
1031 options: Options::new(None),
1032 push: false,
1033 },
1034 data,
1035 )
1036 }
1037 }
1038
1039 impl<P: Payload> Segment<P> {
1040 pub fn with_data(seq: SeqNum, ack: SeqNum, wnd: UnscaledWindowSize, data: P) -> Segment<P> {
1042 Segment::new_assert_no_discard(
1043 SegmentHeader {
1044 seq,
1045 ack: Some(ack),
1046 control: None,
1047 wnd,
1048 push: false,
1049 options: Options::new(None),
1050 },
1051 data,
1052 )
1053 }
1054
1055 pub fn ack(seq: SeqNum, ack: SeqNum, wnd: UnscaledWindowSize) -> Self {
1057 Self::ack_with_options(seq, ack, wnd, SegmentOptions::default())
1058 }
1059
1060 pub fn piggybacked_fin(
1062 seq: SeqNum,
1063 ack: SeqNum,
1064 wnd: UnscaledWindowSize,
1065 data: P,
1066 ) -> Segment<P> {
1067 Segment::new_assert_no_discard(
1068 SegmentHeader {
1069 seq,
1070 ack: Some(ack),
1071 control: Some(Control::FIN),
1072 wnd,
1073 push: false,
1074 options: Options::new(None),
1075 },
1076 data,
1077 )
1078 }
1079
1080 pub fn fin(seq: SeqNum, ack: SeqNum, wnd: UnscaledWindowSize) -> Self {
1082 Segment::new_empty(SegmentHeader {
1083 seq,
1084 ack: Some(ack),
1085 control: Some(Control::FIN),
1086 wnd,
1087 push: false,
1088 options: Options::new(None),
1089 })
1090 }
1091 }
1092}
1093
1094#[cfg(test)]
1095mod test {
1096
1097 use assert_matches::assert_matches;
1098 use core::num::NonZeroU16;
1099 use ip_test_macro::ip_test;
1100 use net_declare::{net_ip_v4, net_ip_v6};
1101 use net_types::ip::{Ipv4, Ipv6};
1102 use packet_formats::ip::IpExt;
1103 use test_case::test_case;
1104
1105 use super::*;
1106
1107 #[test_case(None, &[][..] => (0, &[][..]); "empty")]
1108 #[test_case(None, &[1][..] => (1, &[1][..]); "no control")]
1109 #[test_case(Some(Control::SYN), &[][..] => (1, &[][..]); "empty slice with syn")]
1110 #[test_case(Some(Control::SYN), &[1][..] => (2, &[1][..]); "non-empty slice with syn")]
1111 #[test_case(Some(Control::FIN), &[][..] => (1, &[][..]); "empty slice with fin")]
1112 #[test_case(Some(Control::FIN), &[1][..] => (2, &[1][..]); "non-empty slice with fin")]
1113 #[test_case(Some(Control::RST), &[][..] => (0, &[][..]); "empty slice with rst")]
1114 #[test_case(Some(Control::RST), &[1][..] => (1, &[1][..]); "non-empty slice with rst")]
1115 fn segment_len(control: Option<Control>, data: &[u8]) -> (u32, &[u8]) {
1116 let (seg, truncated) = Segment::new(
1117 SegmentHeader {
1118 seq: SeqNum::new(1),
1119 ack: Some(SeqNum::new(1)),
1120 wnd: UnscaledWindowSize::from(0),
1121 control,
1122 push: false,
1123 options: Options::new(None),
1124 },
1125 data,
1126 );
1127 assert_eq!(truncated, 0);
1128 (seg.len(), seg.data)
1129 }
1130
1131 #[test_case(&[1, 2, 3, 4, 5][..], 0..4 => [1, 2, 3, 4])]
1132 #[test_case((), 0..0 => [0, 0, 0, 0])]
1133 fn payload_slice_copy(data: impl Payload, range: Range<u32>) -> [u8; 4] {
1134 let sliced = data.slice(range);
1135 let mut buffer = [0; 4];
1136 sliced.partial_copy(0, &mut buffer[..sliced.len()]);
1137 buffer
1138 }
1139
1140 #[derive(Debug, PartialEq, Eq)]
1141 struct TestPayload(Range<u32>);
1142
1143 impl TestPayload {
1144 fn new(len: usize) -> Self {
1145 Self(0..u32::try_from(len).unwrap())
1146 }
1147 }
1148
1149 impl PayloadLen for TestPayload {
1150 fn len(&self) -> usize {
1151 self.0.len()
1152 }
1153 }
1154
1155 impl Payload for TestPayload {
1156 fn slice(self, range: Range<u32>) -> Self {
1157 let Self(this) = self;
1158 assert!(range.start >= this.start && range.end <= this.end);
1159 TestPayload(range)
1160 }
1161
1162 fn partial_copy(&self, _offset: usize, _dst: &mut [u8]) {
1163 unimplemented!("TestPayload doesn't carry any data");
1164 }
1165
1166 fn partial_copy_uninit(&self, _offset: usize, _dst: &mut [MaybeUninit<u8>]) {
1167 unimplemented!("TestPayload doesn't carry any data");
1168 }
1169
1170 fn new_empty() -> Self {
1171 Self(0..0)
1172 }
1173 }
1174
1175 #[test_case(100, Some(Control::SYN) => (100, Some(Control::SYN), 0))]
1176 #[test_case(100, Some(Control::FIN) => (100, Some(Control::FIN), 0))]
1177 #[test_case(100, Some(Control::RST) => (100, Some(Control::RST), 0))]
1178 #[test_case(100, None => (100, None, 0))]
1179 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN)
1180 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 0))]
1181 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN)
1182 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN), 0))]
1183 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST)
1184 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST), 0))]
1185 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, None
1186 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, None, 0))]
1187 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::SYN)
1188 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1))]
1189 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::FIN)
1190 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
1191 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST)
1192 => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 0))]
1193 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, None
1194 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 0))]
1195 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::SYN)
1196 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 2))]
1197 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::FIN)
1198 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 2))]
1199 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::RST)
1200 => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 1))]
1201 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, None
1202 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
1203 #[test_case(u32::MAX as usize, Some(Control::SYN)
1204 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1 << 31))]
1205 fn segment_truncate(len: usize, control: Option<Control>) -> (usize, Option<Control>, usize) {
1206 let (seg, truncated) = Segment::new(
1207 SegmentHeader {
1208 seq: SeqNum::new(0),
1209 ack: None,
1210 wnd: UnscaledWindowSize::from(0),
1211 control,
1212 push: false,
1213 options: Options::new(None),
1214 },
1215 TestPayload::new(len),
1216 );
1217 (seg.data.len(), seg.header.control, truncated)
1218 }
1219
1220 struct OverlapTestArgs {
1221 seg_seq: u32,
1222 control: Option<Control>,
1223 data_len: u32,
1224 rcv_nxt: u32,
1225 rcv_wnd: usize,
1226 }
1227 #[test_case(OverlapTestArgs{
1228 seg_seq: 1,
1229 control: None,
1230 data_len: 0,
1231 rcv_nxt: 0,
1232 rcv_wnd: 0,
1233 } => None)]
1234 #[test_case(OverlapTestArgs{
1235 seg_seq: 1,
1236 control: None,
1237 data_len: 0,
1238 rcv_nxt: 1,
1239 rcv_wnd: 0,
1240 } => Some((SeqNum::new(1), None, 0..0)))]
1241 #[test_case(OverlapTestArgs{
1242 seg_seq: 1,
1243 control: None,
1244 data_len: 0,
1245 rcv_nxt: 2,
1246 rcv_wnd: 0,
1247 } => None)]
1248 #[test_case(OverlapTestArgs{
1249 seg_seq: 1,
1250 control: Some(Control::SYN),
1251 data_len: 0,
1252 rcv_nxt: 2,
1253 rcv_wnd: 0,
1254 } => None)]
1255 #[test_case(OverlapTestArgs{
1256 seg_seq: 1,
1257 control: Some(Control::SYN),
1258 data_len: 0,
1259 rcv_nxt: 1,
1260 rcv_wnd: 0,
1261 } => None)]
1262 #[test_case(OverlapTestArgs{
1263 seg_seq: 1,
1264 control: Some(Control::SYN),
1265 data_len: 0,
1266 rcv_nxt: 0,
1267 rcv_wnd: 0,
1268 } => None)]
1269 #[test_case(OverlapTestArgs{
1270 seg_seq: 1,
1271 control: Some(Control::FIN),
1272 data_len: 0,
1273 rcv_nxt: 2,
1274 rcv_wnd: 0,
1275 } => None)]
1276 #[test_case(OverlapTestArgs{
1277 seg_seq: 1,
1278 control: Some(Control::FIN),
1279 data_len: 0,
1280 rcv_nxt: 1,
1281 rcv_wnd: 0,
1282 } => None)]
1283 #[test_case(OverlapTestArgs{
1284 seg_seq: 1,
1285 control: Some(Control::FIN),
1286 data_len: 0,
1287 rcv_nxt: 0,
1288 rcv_wnd: 0,
1289 } => None)]
1290 #[test_case(OverlapTestArgs{
1291 seg_seq: 0,
1292 control: None,
1293 data_len: 0,
1294 rcv_nxt: 1,
1295 rcv_wnd: 1,
1296 } => None)]
1297 #[test_case(OverlapTestArgs{
1298 seg_seq: 1,
1299 control: None,
1300 data_len: 0,
1301 rcv_nxt: 1,
1302 rcv_wnd: 1,
1303 } => Some((SeqNum::new(1), None, 0..0)))]
1304 #[test_case(OverlapTestArgs{
1305 seg_seq: 2,
1306 control: None,
1307 data_len: 0,
1308 rcv_nxt: 1,
1309 rcv_wnd: 1,
1310 } => None)]
1311 #[test_case(OverlapTestArgs{
1312 seg_seq: 0,
1313 control: None,
1314 data_len: 1,
1315 rcv_nxt: 1,
1316 rcv_wnd: 1,
1317 } => Some((SeqNum::new(1), None, 1..1)))]
1318 #[test_case(OverlapTestArgs{
1319 seg_seq: 0,
1320 control: Some(Control::SYN),
1321 data_len: 0,
1322 rcv_nxt: 1,
1323 rcv_wnd: 1,
1324 } => Some((SeqNum::new(1), None, 0..0)))]
1325 #[test_case(OverlapTestArgs{
1326 seg_seq: 2,
1327 control: None,
1328 data_len: 1,
1329 rcv_nxt: 1,
1330 rcv_wnd: 1,
1331 } => None)]
1332 #[test_case(OverlapTestArgs{
1333 seg_seq: 0,
1334 control: None,
1335 data_len: 2,
1336 rcv_nxt: 1,
1337 rcv_wnd: 1,
1338 } => Some((SeqNum::new(1), None, 1..2)))]
1339 #[test_case(OverlapTestArgs{
1340 seg_seq: 1,
1341 control: None,
1342 data_len: 2,
1343 rcv_nxt: 1,
1344 rcv_wnd: 1,
1345 } => Some((SeqNum::new(1), None, 0..1)))]
1346 #[test_case(OverlapTestArgs{
1347 seg_seq: 0,
1348 control: Some(Control::SYN),
1349 data_len: 1,
1350 rcv_nxt: 1,
1351 rcv_wnd: 1,
1352 } => Some((SeqNum::new(1), None, 0..1)))]
1353 #[test_case(OverlapTestArgs{
1354 seg_seq: 1,
1355 control: Some(Control::SYN),
1356 data_len: 1,
1357 rcv_nxt: 1,
1358 rcv_wnd: 1,
1359 } => Some((SeqNum::new(1), Some(Control::SYN), 0..0)))]
1360 #[test_case(OverlapTestArgs{
1361 seg_seq: 0,
1362 control: Some(Control::FIN),
1363 data_len: 1,
1364 rcv_nxt: 1,
1365 rcv_wnd: 1,
1366 } => Some((SeqNum::new(1), Some(Control::FIN), 1..1)))]
1367 #[test_case(OverlapTestArgs{
1368 seg_seq: 1,
1369 control: Some(Control::FIN),
1370 data_len: 1,
1371 rcv_nxt: 1,
1372 rcv_wnd: 1,
1373 } => Some((SeqNum::new(1), None, 0..1)))]
1374 #[test_case(OverlapTestArgs{
1375 seg_seq: 1,
1376 control: None,
1377 data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1378 rcv_nxt: 1,
1379 rcv_wnd: 10,
1380 } => Some((SeqNum::new(1), None, 0..10)))]
1381 #[test_case(OverlapTestArgs{
1382 seg_seq: 10,
1383 control: None,
1384 data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1385 rcv_nxt: 1,
1386 rcv_wnd: 10,
1387 } => Some((SeqNum::new(10), None, 0..1)))]
1388 #[test_case(OverlapTestArgs{
1389 seg_seq: 1,
1390 control: None,
1391 data_len: 10,
1392 rcv_nxt: 1,
1393 rcv_wnd: WindowSize::MAX.into(),
1394 } => Some((SeqNum::new(1), None, 0..10)))]
1395 #[test_case(OverlapTestArgs{
1396 seg_seq: 10,
1397 control: None,
1398 data_len: 10,
1399 rcv_nxt: 1,
1400 rcv_wnd: WindowSize::MAX.into(),
1401 } => Some((SeqNum::new(10), None, 0..10)))]
1402 #[test_case(OverlapTestArgs{
1403 seg_seq: 1,
1404 control: Some(Control::FIN),
1405 data_len: 1,
1406 rcv_nxt: 3,
1407 rcv_wnd: 10,
1408 } => Some((SeqNum::new(3), None, 1..1)); "regression test for https://fxbug.dev/42061750")]
1409 fn segment_overlap(
1410 OverlapTestArgs { seg_seq, control, data_len, rcv_nxt, rcv_wnd }: OverlapTestArgs,
1411 ) -> Option<(SeqNum, Option<Control>, Range<u32>)> {
1412 let (seg, discarded) = Segment::new(
1413 SegmentHeader {
1414 seq: SeqNum::new(seg_seq),
1415 ack: None,
1416 control,
1417 wnd: UnscaledWindowSize::from(0),
1418 push: false,
1419 options: Options::new(None),
1420 },
1421 TestPayload(0..data_len),
1422 );
1423 assert_eq!(discarded, 0);
1424 seg.overlap(SeqNum::new(rcv_nxt), WindowSize::new(rcv_wnd).unwrap()).map(
1425 |Segment { header: SegmentHeader { seq, control, .. }, data: TestPayload(range) }| {
1426 (seq, control, range)
1427 },
1428 )
1429 }
1430
1431 pub trait TestIpExt: IpExt {
1432 const SRC_IP: Self::Addr;
1433 const DST_IP: Self::Addr;
1434 }
1435
1436 impl TestIpExt for Ipv4 {
1437 const SRC_IP: Self::Addr = net_ip_v4!("192.0.2.1");
1438 const DST_IP: Self::Addr = net_ip_v4!("192.0.2.2");
1439 }
1440
1441 impl TestIpExt for Ipv6 {
1442 const SRC_IP: Self::Addr = net_ip_v6!("2001:db8::1");
1443 const DST_IP: Self::Addr = net_ip_v6!("2001:db8::2");
1444 }
1445
1446 const SRC_PORT: NonZeroU16 = NonZeroU16::new(1234).unwrap();
1447 const DST_PORT: NonZeroU16 = NonZeroU16::new(9876).unwrap();
1448
1449 #[ip_test(I)]
1450 fn from_segment_builder<I: TestIpExt>() {
1451 let mut builder =
1452 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1453 builder.syn(true);
1454
1455 let converted_header =
1456 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1457
1458 let expected_header = SegmentHeader {
1459 seq: SeqNum::new(1),
1460 ack: Some(SeqNum::new(2)),
1461 wnd: UnscaledWindowSize::from(3u16),
1462 control: Some(Control::SYN),
1463 options: HandshakeOptions::default().into(),
1464 push: false,
1465 };
1466
1467 assert_eq!(converted_header, expected_header);
1468 }
1469
1470 #[ip_test(I)]
1471 fn from_segment_builder_failure<I: TestIpExt>() {
1472 let mut builder =
1473 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1474 builder.syn(true);
1475 builder.fin(true);
1476
1477 assert_matches!(
1478 SegmentHeader::try_from(&builder),
1479 Err(MalformedFlags { syn: true, fin: true, rst: false })
1480 );
1481 }
1482
1483 #[ip_test(I)]
1484 fn from_segment_builder_with_options_handshake<I: TestIpExt>() {
1485 let mut builder =
1486 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1487 builder.syn(true);
1488
1489 let builder = TcpSegmentBuilderWithOptions::new(
1490 builder,
1491 [TcpOption::Mss(1024), TcpOption::WindowScale(10), TcpOption::SackPermitted],
1492 )
1493 .expect("failed to create tcp segment builder");
1494
1495 let converted_header =
1496 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1497
1498 let expected_header = SegmentHeader {
1499 seq: SeqNum::new(1),
1500 ack: Some(SeqNum::new(2)),
1501 wnd: UnscaledWindowSize::from(3u16),
1502 control: Some(Control::SYN),
1503 push: false,
1504 options: HandshakeOptions {
1505 mss: Some(Mss::new(1024).unwrap()),
1506 window_scale: Some(WindowScale::new(10).unwrap()),
1507 sack_permitted: true,
1508 }
1509 .into(),
1510 };
1511
1512 assert_eq!(converted_header, expected_header);
1513 }
1514
1515 #[ip_test(I)]
1516 fn mss_option_clamps_to_minimum<I: TestIpExt>() {
1517 let mut builder =
1518 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1519 builder.syn(true);
1520
1521 let builder = TcpSegmentBuilderWithOptions::new(
1522 builder,
1523 [TcpOption::Mss(Mss::MIN.get() - 1)],
1526 )
1527 .expect("failed to create tcp segment builder");
1528
1529 let converted_header =
1530 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1531
1532 let expected_header = SegmentHeader {
1533 seq: SeqNum::new(1),
1534 ack: Some(SeqNum::new(2)),
1535 wnd: UnscaledWindowSize::from(3u16),
1536 control: Some(Control::SYN),
1537 push: false,
1538 options: HandshakeOptions {
1539 mss: Some(Mss::MIN),
1540 window_scale: None,
1541 sack_permitted: false,
1542 }
1543 .into(),
1544 };
1545
1546 assert_eq!(converted_header, expected_header);
1547 }
1548
1549 #[ip_test(I)]
1550 fn from_segment_builder_with_options_segment<I: TestIpExt>() {
1551 let mut builder =
1552 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1553 builder.psh(true);
1554
1555 let sack_blocks = [TcpSackBlock::new(1, 2), TcpSackBlock::new(4, 6)];
1556 let builder =
1557 TcpSegmentBuilderWithOptions::new(builder, [TcpOption::Sack(&sack_blocks[..])])
1558 .expect("failed to create tcp segment builder");
1559
1560 let converted_header =
1561 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1562
1563 let expected_header = SegmentHeader {
1564 seq: SeqNum::new(1),
1565 ack: Some(SeqNum::new(2)),
1566 wnd: UnscaledWindowSize::from(3u16),
1567 control: None,
1568 push: true,
1569 options: SegmentOptions {
1570 sack_blocks: SackBlocks::from_iter([
1571 SackBlock::try_new(SeqNum::new(1), SeqNum::new(2)).unwrap(),
1572 SackBlock::try_new(SeqNum::new(4), SeqNum::new(6)).unwrap(),
1573 ]),
1574 }
1575 .into(),
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 [TcpOption::Mss(1024), TcpOption::WindowScale(10)],
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 #[test_case(Flags {
1601 syn: false,
1602 fin: false,
1603 rst: false,
1604 } => Ok(None))]
1605 #[test_case(Flags {
1606 syn: true,
1607 fin: false,
1608 rst: false,
1609 } => Ok(Some(Control::SYN)))]
1610 #[test_case(Flags {
1611 syn: false,
1612 fin: true,
1613 rst: false,
1614 } => Ok(Some(Control::FIN)))]
1615 #[test_case(Flags {
1616 syn: false,
1617 fin: false,
1618 rst: true,
1619 } => Ok(Some(Control::RST)))]
1620 #[test_case(Flags {
1621 syn: true,
1622 fin: true,
1623 rst: false,
1624 } => Err(MalformedFlags {
1625 syn: true,
1626 fin: true,
1627 rst: false,
1628 }))]
1629 #[test_case(Flags {
1630 syn: true,
1631 fin: false,
1632 rst: true,
1633 } => Err(MalformedFlags {
1634 syn: true,
1635 fin: false,
1636 rst: true,
1637 }))]
1638 #[test_case(Flags {
1639 syn: false,
1640 fin: true,
1641 rst: true,
1642 } => Err(MalformedFlags {
1643 syn: false,
1644 fin: true,
1645 rst: true,
1646 }))]
1647 #[test_case(Flags {
1648 syn: true,
1649 fin: true,
1650 rst: true,
1651 } => Err(MalformedFlags {
1652 syn: true,
1653 fin: true,
1654 rst: true,
1655 }))]
1656 fn flags_to_control(input: Flags) -> Result<Option<Control>, MalformedFlags> {
1657 input.control()
1658 }
1659
1660 #[test]
1661 fn sack_block_try_new() {
1662 assert_matches!(SackBlock::try_new(SeqNum::new(1), SeqNum::new(2)), Ok(_));
1663 assert_matches!(
1664 SackBlock::try_new(SeqNum::new(0u32.wrapping_sub(1)), SeqNum::new(2)),
1665 Ok(_)
1666 );
1667 assert_eq!(
1668 SackBlock::try_new(SeqNum::new(1), SeqNum::new(1)),
1669 Err(InvalidSackBlockError(SeqNum::new(1), SeqNum::new(1)))
1670 );
1671 assert_eq!(
1672 SackBlock::try_new(SeqNum::new(2), SeqNum::new(1)),
1673 Err(InvalidSackBlockError(SeqNum::new(2), SeqNum::new(1)))
1674 );
1675 assert_eq!(
1676 SackBlock::try_new(SeqNum::new(0), SeqNum::new(0u32.wrapping_sub(1))),
1677 Err(InvalidSackBlockError(SeqNum::new(0), SeqNum::new(0u32.wrapping_sub(1))))
1678 );
1679 }
1680
1681 #[test]
1682 fn psh_bit_cleared_if_no_data() {
1683 let seg =
1684 Segment::new_assert_no_discard(SegmentHeader { push: true, ..Default::default() }, ());
1685 assert_eq!(seg.header().push, false);
1686 let seg = Segment::new_assert_no_discard(
1687 SegmentHeader { push: true, ..Default::default() },
1688 &[1u8, 2, 3, 4][..],
1689 );
1690 assert_eq!(seg.header().push, true);
1691 }
1692}