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