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)]
876#[error("multiple mutually exclusive flags are set: syn: {syn}, fin: {fin}, rst: {rst}")]
877pub struct MalformedFlags {
878 syn: bool,
879 fin: bool,
880 rst: bool,
881}
882
883struct Flags {
884 syn: bool,
885 fin: bool,
886 rst: bool,
887}
888
889impl Flags {
890 fn control(&self) -> Result<Option<Control>, MalformedFlags> {
891 if usize::from(self.syn) + usize::from(self.fin) + usize::from(self.rst) > 1 {
892 return Err(MalformedFlags { syn: self.syn, fin: self.fin, rst: self.rst });
893 }
894
895 let syn = self.syn.then_some(Control::SYN);
896 let fin = self.fin.then_some(Control::FIN);
897 let rst = self.rst.then_some(Control::RST);
898
899 Ok(syn.or(fin).or(rst))
900 }
901}
902
903pub struct VerifiedTcpSegment<'a> {
906 segment: TcpSegment<&'a [u8]>,
907 control: Option<Control>,
908}
909
910impl<'a> VerifiedTcpSegment<'a> {
911 pub fn tcp_segment(&self) -> &TcpSegment<&'a [u8]> {
913 &self.segment
914 }
915
916 pub fn control(&self) -> Option<Control> {
918 self.control
919 }
920}
921
922impl<'a> TryFrom<TcpSegment<&'a [u8]>> for VerifiedTcpSegment<'a> {
923 type Error = MalformedFlags;
924
925 fn try_from(segment: TcpSegment<&'a [u8]>) -> Result<Self, Self::Error> {
926 let control =
927 Flags { syn: segment.syn(), fin: segment.fin(), rst: segment.rst() }.control()?;
928 Ok(VerifiedTcpSegment { segment, control })
929 }
930}
931
932impl<'a> From<&'a VerifiedTcpSegment<'a>> for Segment<&'a [u8]> {
933 fn from(from: &'a VerifiedTcpSegment<'a>) -> Segment<&'a [u8]> {
934 let VerifiedTcpSegment { segment, control } = from;
935 let options = Options::from_options(control.as_ref(), segment.options());
936 let (to, discarded) = Segment::new(
937 SegmentHeader {
938 seq: segment.seq_num().into(),
939 ack: segment.ack_num().map(Into::into),
940 wnd: UnscaledWindowSize::from(segment.window_size()),
941 control: *control,
942 push: segment.psh(),
943 options,
944 },
945 from.segment.body(),
946 );
947 debug_assert_eq!(discarded, 0);
948 to
949 }
950}
951
952impl<A> TryFrom<&TcpSegmentBuilder<A>> for SegmentHeader
953where
954 A: IpAddress,
955{
956 type Error = MalformedFlags;
957
958 fn try_from(from: &TcpSegmentBuilder<A>) -> Result<Self, Self::Error> {
959 SegmentHeader::from_builder(from)
960 }
961}
962
963impl<'a, A: IpAddress> TryFrom<&TcpSegmentBuilderWithOptions<A, TcpOptionsBuilder<'a>>>
964 for SegmentHeader
965{
966 type Error = MalformedFlags;
967
968 fn try_from(
969 from: &TcpSegmentBuilderWithOptions<A, TcpOptionsBuilder<'a>>,
970 ) -> Result<Self, Self::Error> {
971 let prefix_builder = from.prefix_builder();
972 let options = Options::try_from_options(&prefix_builder, from.options())?;
973 Self::from_builder_options(prefix_builder, options)
974 }
975}
976
977#[cfg(any(test, feature = "testutils"))]
978mod testutils {
979 use super::*;
980
981 impl Default for SegmentHeader {
983 fn default() -> Self {
984 Self {
985 seq: SeqNum::new(0),
986 ack: None,
987 control: None,
988 wnd: UnscaledWindowSize::from(0),
989 options: Options::new(None),
990 push: false,
991 }
992 }
993 }
994
995 impl<P: Payload> Segment<P> {
996 #[track_caller]
999 pub fn new_assert_no_discard(header: SegmentHeader, data: P) -> Self {
1000 let (seg, discard) = Self::new(header, data);
1001 assert_eq!(discard, 0);
1002 seg
1003 }
1004 }
1005
1006 impl<'a> Segment<&'a [u8]> {
1007 pub fn with_fake_data(seq: SeqNum, ack: SeqNum, data: &'a [u8]) -> Self {
1009 Self::new_assert_no_discard(
1010 SegmentHeader {
1011 seq,
1012 ack: Some(ack),
1013 control: None,
1014 wnd: UnscaledWindowSize::from(u16::MAX),
1015 options: Options::new(None),
1016 push: false,
1017 },
1018 data,
1019 )
1020 }
1021 }
1022
1023 impl<P: Payload> Segment<P> {
1024 pub fn with_data(
1026 seq: SeqNum,
1027 ack: SeqNum,
1028 wnd: UnscaledWindowSize,
1029 options: SegmentOptions,
1030 data: P,
1031 ) -> Segment<P> {
1032 Segment::new_assert_no_discard(
1033 SegmentHeader {
1034 seq,
1035 ack: Some(ack),
1036 control: None,
1037 wnd,
1038 push: false,
1039 options: Options::Segment(options),
1040 },
1041 data,
1042 )
1043 }
1044
1045 pub fn piggybacked_fin(
1047 seq: SeqNum,
1048 ack: SeqNum,
1049 wnd: UnscaledWindowSize,
1050 options: SegmentOptions,
1051 data: P,
1052 ) -> Segment<P> {
1053 Segment::new_assert_no_discard(
1054 SegmentHeader {
1055 seq,
1056 ack: Some(ack),
1057 control: Some(Control::FIN),
1058 wnd,
1059 push: false,
1060 options: Options::Segment(options),
1061 },
1062 data,
1063 )
1064 }
1065
1066 pub fn fin(
1068 seq: SeqNum,
1069 ack: SeqNum,
1070 wnd: UnscaledWindowSize,
1071 options: SegmentOptions,
1072 ) -> Self {
1073 Segment::new_empty(SegmentHeader {
1074 seq,
1075 ack: Some(ack),
1076 control: Some(Control::FIN),
1077 wnd,
1078 push: false,
1079 options: Options::Segment(options),
1080 })
1081 }
1082 }
1083}
1084
1085#[cfg(test)]
1086mod test {
1087
1088 use crate::tcp::timestamp::Timestamp;
1089 use assert_matches::assert_matches;
1090 use core::num::NonZeroU16;
1091 use ip_test_macro::ip_test;
1092 use net_declare::{net_ip_v4, net_ip_v6};
1093 use net_types::ip::{Ipv4, Ipv6};
1094 use packet_formats::ip::IpExt;
1095 use test_case::test_case;
1096
1097 use super::*;
1098
1099 #[test_case(None, &[][..] => (0, &[][..]); "empty")]
1100 #[test_case(None, &[1][..] => (1, &[1][..]); "no control")]
1101 #[test_case(Some(Control::SYN), &[][..] => (1, &[][..]); "empty slice with syn")]
1102 #[test_case(Some(Control::SYN), &[1][..] => (2, &[1][..]); "non-empty slice with syn")]
1103 #[test_case(Some(Control::FIN), &[][..] => (1, &[][..]); "empty slice with fin")]
1104 #[test_case(Some(Control::FIN), &[1][..] => (2, &[1][..]); "non-empty slice with fin")]
1105 #[test_case(Some(Control::RST), &[][..] => (0, &[][..]); "empty slice with rst")]
1106 #[test_case(Some(Control::RST), &[1][..] => (1, &[1][..]); "non-empty slice with rst")]
1107 fn segment_len(control: Option<Control>, data: &[u8]) -> (u32, &[u8]) {
1108 let (seg, truncated) = Segment::new(
1109 SegmentHeader {
1110 seq: SeqNum::new(1),
1111 ack: Some(SeqNum::new(1)),
1112 wnd: UnscaledWindowSize::from(0),
1113 control,
1114 push: false,
1115 options: Options::new(None),
1116 },
1117 data,
1118 );
1119 assert_eq!(truncated, 0);
1120 (seg.len(), seg.data)
1121 }
1122
1123 #[test_case(&[1, 2, 3, 4, 5][..], 0..4 => [1, 2, 3, 4])]
1124 #[test_case((), 0..0 => [0, 0, 0, 0])]
1125 fn payload_slice_copy(data: impl Payload, range: Range<u32>) -> [u8; 4] {
1126 let sliced = data.slice(range);
1127 let mut buffer = [0; 4];
1128 sliced.partial_copy(0, &mut buffer[..sliced.len()]);
1129 buffer
1130 }
1131
1132 #[derive(Debug, PartialEq, Eq)]
1133 struct TestPayload(Range<u32>);
1134
1135 impl TestPayload {
1136 fn new(len: usize) -> Self {
1137 Self(0..u32::try_from(len).unwrap())
1138 }
1139 }
1140
1141 impl PayloadLen for TestPayload {
1142 fn len(&self) -> usize {
1143 self.0.len()
1144 }
1145 }
1146
1147 impl Payload for TestPayload {
1148 fn slice(self, range: Range<u32>) -> Self {
1149 let Self(this) = self;
1150 assert!(range.start >= this.start && range.end <= this.end);
1151 TestPayload(range)
1152 }
1153
1154 fn partial_copy(&self, _offset: usize, _dst: &mut [u8]) {
1155 unimplemented!("TestPayload doesn't carry any data");
1156 }
1157
1158 fn partial_copy_uninit(&self, _offset: usize, _dst: &mut [MaybeUninit<u8>]) {
1159 unimplemented!("TestPayload doesn't carry any data");
1160 }
1161
1162 fn new_empty() -> Self {
1163 Self(0..0)
1164 }
1165 }
1166
1167 #[test_case(100, Some(Control::SYN) => (100, Some(Control::SYN), 0))]
1168 #[test_case(100, Some(Control::FIN) => (100, Some(Control::FIN), 0))]
1169 #[test_case(100, Some(Control::RST) => (100, Some(Control::RST), 0))]
1170 #[test_case(100, None => (100, None, 0))]
1171 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN)
1172 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 0))]
1173 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN)
1174 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN), 0))]
1175 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST)
1176 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST), 0))]
1177 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, None
1178 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, None, 0))]
1179 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::SYN)
1180 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1))]
1181 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::FIN)
1182 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
1183 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST)
1184 => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 0))]
1185 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, None
1186 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 0))]
1187 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::SYN)
1188 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 2))]
1189 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::FIN)
1190 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 2))]
1191 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::RST)
1192 => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 1))]
1193 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, None
1194 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
1195 #[test_case(u32::MAX as usize, Some(Control::SYN)
1196 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1 << 31))]
1197 fn segment_truncate(len: usize, control: Option<Control>) -> (usize, Option<Control>, usize) {
1198 let (seg, truncated) = Segment::new(
1199 SegmentHeader {
1200 seq: SeqNum::new(0),
1201 ack: None,
1202 wnd: UnscaledWindowSize::from(0),
1203 control,
1204 push: false,
1205 options: Options::new(None),
1206 },
1207 TestPayload::new(len),
1208 );
1209 (seg.data.len(), seg.header.control, truncated)
1210 }
1211
1212 struct OverlapTestArgs {
1213 seg_seq: u32,
1214 control: Option<Control>,
1215 data_len: u32,
1216 rcv_nxt: u32,
1217 rcv_wnd: usize,
1218 }
1219 #[test_case(OverlapTestArgs{
1220 seg_seq: 1,
1221 control: None,
1222 data_len: 0,
1223 rcv_nxt: 0,
1224 rcv_wnd: 0,
1225 } => None)]
1226 #[test_case(OverlapTestArgs{
1227 seg_seq: 1,
1228 control: None,
1229 data_len: 0,
1230 rcv_nxt: 1,
1231 rcv_wnd: 0,
1232 } => Some((SeqNum::new(1), None, 0..0)))]
1233 #[test_case(OverlapTestArgs{
1234 seg_seq: 1,
1235 control: None,
1236 data_len: 0,
1237 rcv_nxt: 2,
1238 rcv_wnd: 0,
1239 } => None)]
1240 #[test_case(OverlapTestArgs{
1241 seg_seq: 1,
1242 control: Some(Control::SYN),
1243 data_len: 0,
1244 rcv_nxt: 2,
1245 rcv_wnd: 0,
1246 } => None)]
1247 #[test_case(OverlapTestArgs{
1248 seg_seq: 1,
1249 control: Some(Control::SYN),
1250 data_len: 0,
1251 rcv_nxt: 1,
1252 rcv_wnd: 0,
1253 } => None)]
1254 #[test_case(OverlapTestArgs{
1255 seg_seq: 1,
1256 control: Some(Control::SYN),
1257 data_len: 0,
1258 rcv_nxt: 0,
1259 rcv_wnd: 0,
1260 } => None)]
1261 #[test_case(OverlapTestArgs{
1262 seg_seq: 1,
1263 control: Some(Control::FIN),
1264 data_len: 0,
1265 rcv_nxt: 2,
1266 rcv_wnd: 0,
1267 } => None)]
1268 #[test_case(OverlapTestArgs{
1269 seg_seq: 1,
1270 control: Some(Control::FIN),
1271 data_len: 0,
1272 rcv_nxt: 1,
1273 rcv_wnd: 0,
1274 } => None)]
1275 #[test_case(OverlapTestArgs{
1276 seg_seq: 1,
1277 control: Some(Control::FIN),
1278 data_len: 0,
1279 rcv_nxt: 0,
1280 rcv_wnd: 0,
1281 } => None)]
1282 #[test_case(OverlapTestArgs{
1283 seg_seq: 0,
1284 control: None,
1285 data_len: 0,
1286 rcv_nxt: 1,
1287 rcv_wnd: 1,
1288 } => None)]
1289 #[test_case(OverlapTestArgs{
1290 seg_seq: 1,
1291 control: None,
1292 data_len: 0,
1293 rcv_nxt: 1,
1294 rcv_wnd: 1,
1295 } => Some((SeqNum::new(1), None, 0..0)))]
1296 #[test_case(OverlapTestArgs{
1297 seg_seq: 2,
1298 control: None,
1299 data_len: 0,
1300 rcv_nxt: 1,
1301 rcv_wnd: 1,
1302 } => None)]
1303 #[test_case(OverlapTestArgs{
1304 seg_seq: 0,
1305 control: None,
1306 data_len: 1,
1307 rcv_nxt: 1,
1308 rcv_wnd: 1,
1309 } => Some((SeqNum::new(1), None, 1..1)))]
1310 #[test_case(OverlapTestArgs{
1311 seg_seq: 0,
1312 control: Some(Control::SYN),
1313 data_len: 0,
1314 rcv_nxt: 1,
1315 rcv_wnd: 1,
1316 } => Some((SeqNum::new(1), None, 0..0)))]
1317 #[test_case(OverlapTestArgs{
1318 seg_seq: 2,
1319 control: None,
1320 data_len: 1,
1321 rcv_nxt: 1,
1322 rcv_wnd: 1,
1323 } => None)]
1324 #[test_case(OverlapTestArgs{
1325 seg_seq: 0,
1326 control: None,
1327 data_len: 2,
1328 rcv_nxt: 1,
1329 rcv_wnd: 1,
1330 } => Some((SeqNum::new(1), None, 1..2)))]
1331 #[test_case(OverlapTestArgs{
1332 seg_seq: 1,
1333 control: None,
1334 data_len: 2,
1335 rcv_nxt: 1,
1336 rcv_wnd: 1,
1337 } => Some((SeqNum::new(1), None, 0..1)))]
1338 #[test_case(OverlapTestArgs{
1339 seg_seq: 0,
1340 control: Some(Control::SYN),
1341 data_len: 1,
1342 rcv_nxt: 1,
1343 rcv_wnd: 1,
1344 } => Some((SeqNum::new(1), None, 0..1)))]
1345 #[test_case(OverlapTestArgs{
1346 seg_seq: 1,
1347 control: Some(Control::SYN),
1348 data_len: 1,
1349 rcv_nxt: 1,
1350 rcv_wnd: 1,
1351 } => Some((SeqNum::new(1), Some(Control::SYN), 0..0)))]
1352 #[test_case(OverlapTestArgs{
1353 seg_seq: 0,
1354 control: Some(Control::FIN),
1355 data_len: 1,
1356 rcv_nxt: 1,
1357 rcv_wnd: 1,
1358 } => Some((SeqNum::new(1), Some(Control::FIN), 1..1)))]
1359 #[test_case(OverlapTestArgs{
1360 seg_seq: 1,
1361 control: Some(Control::FIN),
1362 data_len: 1,
1363 rcv_nxt: 1,
1364 rcv_wnd: 1,
1365 } => Some((SeqNum::new(1), None, 0..1)))]
1366 #[test_case(OverlapTestArgs{
1367 seg_seq: 1,
1368 control: None,
1369 data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1370 rcv_nxt: 1,
1371 rcv_wnd: 10,
1372 } => Some((SeqNum::new(1), None, 0..10)))]
1373 #[test_case(OverlapTestArgs{
1374 seg_seq: 10,
1375 control: None,
1376 data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1377 rcv_nxt: 1,
1378 rcv_wnd: 10,
1379 } => Some((SeqNum::new(10), None, 0..1)))]
1380 #[test_case(OverlapTestArgs{
1381 seg_seq: 1,
1382 control: None,
1383 data_len: 10,
1384 rcv_nxt: 1,
1385 rcv_wnd: WindowSize::MAX.into(),
1386 } => Some((SeqNum::new(1), None, 0..10)))]
1387 #[test_case(OverlapTestArgs{
1388 seg_seq: 10,
1389 control: None,
1390 data_len: 10,
1391 rcv_nxt: 1,
1392 rcv_wnd: WindowSize::MAX.into(),
1393 } => Some((SeqNum::new(10), None, 0..10)))]
1394 #[test_case(OverlapTestArgs{
1395 seg_seq: 1,
1396 control: Some(Control::FIN),
1397 data_len: 1,
1398 rcv_nxt: 3,
1399 rcv_wnd: 10,
1400 } => Some((SeqNum::new(3), None, 1..1)); "regression test for https://fxbug.dev/42061750")]
1401 fn segment_overlap(
1402 OverlapTestArgs { seg_seq, control, data_len, rcv_nxt, rcv_wnd }: OverlapTestArgs,
1403 ) -> Option<(SeqNum, Option<Control>, Range<u32>)> {
1404 let (seg, discarded) = Segment::new(
1405 SegmentHeader {
1406 seq: SeqNum::new(seg_seq),
1407 ack: None,
1408 control,
1409 wnd: UnscaledWindowSize::from(0),
1410 push: false,
1411 options: Options::new(None),
1412 },
1413 TestPayload(0..data_len),
1414 );
1415 assert_eq!(discarded, 0);
1416 seg.overlap(SeqNum::new(rcv_nxt), WindowSize::new(rcv_wnd).unwrap()).map(
1417 |Segment { header: SegmentHeader { seq, control, .. }, data: TestPayload(range) }| {
1418 (seq, control, range)
1419 },
1420 )
1421 }
1422
1423 pub trait TestIpExt: IpExt {
1424 const SRC_IP: Self::Addr;
1425 const DST_IP: Self::Addr;
1426 }
1427
1428 impl TestIpExt for Ipv4 {
1429 const SRC_IP: Self::Addr = net_ip_v4!("192.0.2.1");
1430 const DST_IP: Self::Addr = net_ip_v4!("192.0.2.2");
1431 }
1432
1433 impl TestIpExt for Ipv6 {
1434 const SRC_IP: Self::Addr = net_ip_v6!("2001:db8::1");
1435 const DST_IP: Self::Addr = net_ip_v6!("2001:db8::2");
1436 }
1437
1438 const SRC_PORT: NonZeroU16 = NonZeroU16::new(1234).unwrap();
1439 const DST_PORT: NonZeroU16 = NonZeroU16::new(9876).unwrap();
1440
1441 #[ip_test(I)]
1442 fn from_segment_builder<I: TestIpExt>() {
1443 let mut builder =
1444 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1445 builder.syn(true);
1446
1447 let converted_header =
1448 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1449
1450 let expected_header = SegmentHeader {
1451 seq: SeqNum::new(1),
1452 ack: Some(SeqNum::new(2)),
1453 wnd: UnscaledWindowSize::from(3u16),
1454 control: Some(Control::SYN),
1455 options: HandshakeOptions::default().into(),
1456 push: false,
1457 };
1458
1459 assert_eq!(converted_header, expected_header);
1460 }
1461
1462 #[ip_test(I)]
1463 fn from_segment_builder_failure<I: TestIpExt>() {
1464 let mut builder =
1465 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1466 builder.syn(true);
1467 builder.fin(true);
1468
1469 assert_matches!(
1470 SegmentHeader::try_from(&builder),
1471 Err(MalformedFlags { syn: true, fin: true, rst: false })
1472 );
1473 }
1474
1475 #[ip_test(I)]
1476 fn from_segment_builder_with_options_handshake<I: TestIpExt>() {
1477 let mut builder =
1478 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1479 builder.syn(true);
1480
1481 const OPTIONS: HandshakeOptions = HandshakeOptions {
1482 mss: Some(Mss::new(1024).unwrap()),
1483 window_scale: Some(WindowScale::new(10).unwrap()),
1484 sack_permitted: true,
1485 timestamp: Some(TimestampOption {
1486 ts_val: Timestamp::new(1),
1487 ts_echo_reply: Timestamp::new(0),
1488 }),
1489 };
1490
1491 let builder = TcpSegmentBuilderWithOptions::new(builder, OPTIONS.builder())
1492 .expect("failed to create tcp segment builder");
1493
1494 let converted_header =
1495 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1496
1497 let expected_header = SegmentHeader {
1498 seq: SeqNum::new(1),
1499 ack: Some(SeqNum::new(2)),
1500 wnd: UnscaledWindowSize::from(3u16),
1501 control: Some(Control::SYN),
1502 push: false,
1503 options: Options::Handshake(OPTIONS),
1504 };
1505
1506 assert_eq!(converted_header, expected_header);
1507 }
1508
1509 #[ip_test(I)]
1510 fn mss_option_clamps_to_minimum<I: TestIpExt>() {
1511 let mut builder =
1512 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1513 builder.syn(true);
1514
1515 let builder = TcpSegmentBuilderWithOptions::new(
1516 builder,
1517 TcpOptionsBuilder { mss: Some(Mss::MIN.get() - 1), ..Default::default() },
1520 )
1521 .expect("failed to create tcp segment builder");
1522
1523 let converted_header =
1524 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1525
1526 let expected_header = SegmentHeader {
1527 seq: SeqNum::new(1),
1528 ack: Some(SeqNum::new(2)),
1529 wnd: UnscaledWindowSize::from(3u16),
1530 control: Some(Control::SYN),
1531 push: false,
1532 options: HandshakeOptions {
1533 mss: Some(Mss::MIN),
1534 window_scale: None,
1535 sack_permitted: false,
1536 timestamp: None,
1537 }
1538 .into(),
1539 };
1540
1541 assert_eq!(converted_header, expected_header);
1542 }
1543
1544 #[ip_test(I)]
1545 fn from_segment_builder_with_options_segment<I: TestIpExt>() {
1546 let mut builder =
1547 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1548 builder.psh(true);
1549
1550 let sack_blocks = [TcpSackBlock::new(1, 2), TcpSackBlock::new(4, 6)];
1551 let options = SegmentOptions {
1552 timestamp: Some(TimestampOption {
1553 ts_val: Timestamp::new(1234),
1554 ts_echo_reply: Timestamp::new(4321),
1555 }),
1556 sack_blocks: SackBlocks::from_option(&sack_blocks),
1557 };
1558
1559 let builder = TcpSegmentBuilderWithOptions::new(builder, options.builder())
1560 .expect("failed to create tcp segment builder");
1561
1562 let converted_header =
1563 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1564
1565 let expected_header = SegmentHeader {
1566 seq: SeqNum::new(1),
1567 ack: Some(SeqNum::new(2)),
1568 wnd: UnscaledWindowSize::from(3u16),
1569 control: None,
1570 push: true,
1571 options: Options::Segment(options),
1572 };
1573
1574 assert_eq!(converted_header, expected_header);
1575 }
1576
1577 #[ip_test(I)]
1578 fn from_segment_builder_with_options_failure<I: TestIpExt>() {
1579 let mut builder =
1580 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1581 builder.syn(true);
1582 builder.fin(true);
1583
1584 let builder = TcpSegmentBuilderWithOptions::new(
1585 builder,
1586 TcpOptionsBuilder { mss: Some(1024), window_scale: Some(10), ..Default::default() },
1587 )
1588 .expect("failed to create tcp segment builder");
1589
1590 assert_matches!(
1591 SegmentHeader::try_from(&builder),
1592 Err(MalformedFlags { syn: true, fin: true, rst: false })
1593 );
1594 }
1595
1596 #[ip_test(I)]
1597 fn from_segment_builder_with_options_reset<I: TestIpExt>() {
1598 let mut builder =
1599 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1600 builder.rst(true);
1601
1602 const OPTIONS: ResetOptions = ResetOptions {
1603 timestamp: Some(TimestampOption {
1604 ts_val: Timestamp::new(1234),
1605 ts_echo_reply: Timestamp::new(4321),
1606 }),
1607 };
1608
1609 let builder = TcpSegmentBuilderWithOptions::new(builder, OPTIONS.builder())
1610 .expect("failed to create tcp segment builder");
1611
1612 let converted_header =
1613 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1614
1615 let expected_header = SegmentHeader {
1616 seq: SeqNum::new(1),
1617 ack: Some(SeqNum::new(2)),
1618 wnd: UnscaledWindowSize::from(3u16),
1619 control: Some(Control::RST),
1620 push: false,
1621 options: Options::Reset(OPTIONS),
1622 };
1623
1624 assert_eq!(converted_header, expected_header);
1625 }
1626
1627 #[test_case(Flags {
1628 syn: false,
1629 fin: false,
1630 rst: false,
1631 } => Ok(None))]
1632 #[test_case(Flags {
1633 syn: true,
1634 fin: false,
1635 rst: false,
1636 } => Ok(Some(Control::SYN)))]
1637 #[test_case(Flags {
1638 syn: false,
1639 fin: true,
1640 rst: false,
1641 } => Ok(Some(Control::FIN)))]
1642 #[test_case(Flags {
1643 syn: false,
1644 fin: false,
1645 rst: true,
1646 } => Ok(Some(Control::RST)))]
1647 #[test_case(Flags {
1648 syn: true,
1649 fin: true,
1650 rst: false,
1651 } => Err(MalformedFlags {
1652 syn: true,
1653 fin: true,
1654 rst: false,
1655 }))]
1656 #[test_case(Flags {
1657 syn: true,
1658 fin: false,
1659 rst: true,
1660 } => Err(MalformedFlags {
1661 syn: true,
1662 fin: false,
1663 rst: true,
1664 }))]
1665 #[test_case(Flags {
1666 syn: false,
1667 fin: true,
1668 rst: true,
1669 } => Err(MalformedFlags {
1670 syn: false,
1671 fin: true,
1672 rst: true,
1673 }))]
1674 #[test_case(Flags {
1675 syn: true,
1676 fin: true,
1677 rst: true,
1678 } => Err(MalformedFlags {
1679 syn: true,
1680 fin: true,
1681 rst: true,
1682 }))]
1683 fn flags_to_control(input: Flags) -> Result<Option<Control>, MalformedFlags> {
1684 input.control()
1685 }
1686
1687 #[test]
1688 fn sack_block_try_new() {
1689 assert_matches!(SackBlock::try_new(SeqNum::new(1), SeqNum::new(2)), Ok(_));
1690 assert_matches!(
1691 SackBlock::try_new(SeqNum::new(0u32.wrapping_sub(1)), SeqNum::new(2)),
1692 Ok(_)
1693 );
1694 assert_eq!(
1695 SackBlock::try_new(SeqNum::new(1), SeqNum::new(1)),
1696 Err(InvalidSackBlockError(SeqNum::new(1), SeqNum::new(1)))
1697 );
1698 assert_eq!(
1699 SackBlock::try_new(SeqNum::new(2), SeqNum::new(1)),
1700 Err(InvalidSackBlockError(SeqNum::new(2), SeqNum::new(1)))
1701 );
1702 assert_eq!(
1703 SackBlock::try_new(SeqNum::new(0), SeqNum::new(0u32.wrapping_sub(1))),
1704 Err(InvalidSackBlockError(SeqNum::new(0), SeqNum::new(0u32.wrapping_sub(1))))
1705 );
1706 }
1707
1708 #[test]
1709 fn psh_bit_cleared_if_no_data() {
1710 let seg =
1711 Segment::new_assert_no_discard(SegmentHeader { push: true, ..Default::default() }, ());
1712 assert_eq!(seg.header().push, false);
1713 let seg = Segment::new_assert_no_discard(
1714 SegmentHeader { push: true, ..Default::default() },
1715 &[1u8, 2, 3, 4][..],
1716 );
1717 assert_eq!(seg.header().push, true);
1718 }
1719}