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