1use crate::alloc::borrow::ToOwned;
8use core::borrow::Borrow;
9use core::convert::TryFrom as _;
10use core::fmt::Debug;
11use core::mem::MaybeUninit;
12use core::num::TryFromIntError;
13use core::ops::Range;
14
15use arrayvec::ArrayVec;
16use log::info;
17use net_types::ip::IpAddress;
18use packet::InnerSerializer;
19use packet::records::options::OptionSequenceBuilder;
20use packet_formats::tcp::options::{TcpOption, TcpSackBlock};
21use packet_formats::tcp::{TcpSegment, TcpSegmentBuilder, TcpSegmentBuilderWithOptions};
22use thiserror::Error;
23
24use super::base::{Control, Mss};
25use super::seqnum::{SeqNum, UnscaledWindowSize, WindowScale, WindowSize};
26use super::timestamp::{Timestamp, TimestampOption};
27
28#[derive(Debug, PartialEq, Eq, Clone)]
30pub struct Segment<P> {
31 header: SegmentHeader,
33 data: P,
38}
39
40#[derive(Debug, PartialEq, Eq, Clone)]
42pub struct SegmentHeader {
43 pub seq: SeqNum,
45 pub ack: Option<SeqNum>,
47 pub wnd: UnscaledWindowSize,
49 pub control: Option<Control>,
51 pub push: bool,
53 pub options: Options,
55}
56
57#[derive(Debug, PartialEq, Eq, Clone)]
59pub enum Options {
60 Handshake(HandshakeOptions),
62 Segment(SegmentOptions),
64 Reset(ResetOptions),
66}
67
68impl Options {
69 fn new(control: Option<&Control>) -> Self {
71 match control {
72 None | Some(Control::FIN) => Options::Segment(Default::default()),
73 Some(Control::SYN) => Options::Handshake(Default::default()),
74 Some(Control::RST) => Options::Reset(Default::default()),
75 }
76 }
77}
78
79impl From<HandshakeOptions> for Options {
80 fn from(value: HandshakeOptions) -> Self {
81 Self::Handshake(value)
82 }
83}
84
85impl From<SegmentOptions> for Options {
86 fn from(value: SegmentOptions) -> Self {
87 Self::Segment(value)
88 }
89}
90
91impl From<ResetOptions> for Options {
92 fn from(value: ResetOptions) -> Self {
93 Self::Reset(value)
94 }
95}
96
97impl Options {
98 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Clone + Debug {
100 OptionsIter { inner: self, next: 0 }
101 }
102
103 fn as_handshake(&self) -> Option<&HandshakeOptions> {
104 match self {
105 Self::Handshake(h) => Some(h),
106 Self::Segment(_) | Self::Reset(_) => None,
107 }
108 }
109
110 fn as_handshake_mut(&mut self) -> Option<&mut HandshakeOptions> {
111 match self {
112 Self::Handshake(h) => Some(h),
113 Self::Segment(_) | Self::Reset(_) => None,
114 }
115 }
116
117 fn as_segment(&self) -> Option<&SegmentOptions> {
118 match self {
119 Self::Handshake(_) | Self::Reset(_) => None,
120 Self::Segment(s) => Some(s),
121 }
122 }
123
124 fn as_segment_mut(&mut self) -> Option<&mut SegmentOptions> {
125 match self {
126 Self::Handshake(_) | Self::Reset(_) => None,
127 Self::Segment(s) => Some(s),
128 }
129 }
130
131 pub fn from_iter<'a>(
133 control: Option<&Control>,
134 iter: impl IntoIterator<Item = TcpOption<'a>>,
135 ) -> Self {
136 let mut options = Options::new(control);
137 for option in iter {
138 match option {
139 TcpOption::Mss(mss) => {
140 if let Some(h) = options.as_handshake_mut() {
141 h.mss = Some(Mss::new(mss).unwrap_or(Mss::MIN));
146 }
147 }
148 TcpOption::WindowScale(ws) => {
149 if let Some(h) = options.as_handshake_mut() {
150 if ws > WindowScale::MAX.get() {
155 info!(
156 "received an out-of-range window scale: {}, want < {}",
157 ws,
158 WindowScale::MAX.get()
159 );
160 }
161 h.window_scale = Some(WindowScale::new(ws).unwrap_or(WindowScale::MAX));
162 }
163 }
164 TcpOption::SackPermitted => {
165 if let Some(h) = options.as_handshake_mut() {
166 h.sack_permitted = true;
167 }
168 }
169 TcpOption::Sack(sack) => {
170 if let Some(seg) = options.as_segment_mut() {
171 seg.sack_blocks = SackBlocks::from_option(sack);
172 }
173 }
174 TcpOption::Timestamp { ts_val, ts_echo_reply } => {
175 let timestamp = TimestampOption {
176 ts_val: Timestamp::new(ts_val),
177 ts_echo_reply: Timestamp::new(ts_echo_reply),
178 };
179 match options {
181 Options::Handshake(ref mut h) => h.timestamp = Some(timestamp),
182 Options::Segment(ref mut s) => s.timestamp = Some(timestamp),
183 Options::Reset(ref mut r) => r.timestamp = Some(timestamp),
184 }
185 }
186 }
187 }
188 options
189 }
190
191 pub fn try_from_iter<'a, A: IpAddress>(
193 builder: &TcpSegmentBuilder<A>,
194 iter: impl IntoIterator<Item = TcpOption<'a>>,
195 ) -> Result<Self, MalformedFlags> {
196 let control =
197 Flags { syn: builder.syn_set(), fin: builder.fin_set(), rst: builder.rst_set() }
198 .control()?;
199 Ok(Options::from_iter(control.as_ref(), iter))
200 }
201
202 pub fn window_scale(&self) -> Option<WindowScale> {
204 self.as_handshake().and_then(|h| h.window_scale)
205 }
206
207 pub fn mss(&self) -> Option<Mss> {
209 self.as_handshake().and_then(|h| h.mss)
210 }
211
212 pub fn sack_permitted(&self) -> bool {
215 self.as_handshake().is_some_and(|o| o.sack_permitted)
216 }
217
218 pub fn sack_blocks(&self) -> &SackBlocks {
222 const EMPTY_REF: &'static SackBlocks = &SackBlocks::EMPTY;
223 self.as_segment().map(|s| &s.sack_blocks).unwrap_or(EMPTY_REF)
224 }
225
226 pub fn timestamp(&self) -> &Option<TimestampOption> {
228 match self {
229 Options::Handshake(h) => &h.timestamp,
230 Options::Segment(s) => &s.timestamp,
231 Options::Reset(r) => &r.timestamp,
232 }
233 }
234}
235
236#[derive(Clone, Debug)]
241struct OptionsIter<'a> {
242 inner: &'a Options,
243 next: u8,
244}
245
246impl<'a> Iterator for OptionsIter<'a> {
247 type Item = TcpOption<'a>;
248
249 fn next(&mut self) -> Option<Self::Item> {
250 let Self { inner, next } = self;
251 match inner {
252 Options::Handshake(h) => h.next_option(next),
253 Options::Segment(s) => s.next_option(next),
254 Options::Reset(r) => r.next_option(next),
255 }
256 }
257}
258
259#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
261pub struct HandshakeOptions {
262 pub mss: Option<Mss>,
264
265 pub window_scale: Option<WindowScale>,
267
268 pub sack_permitted: bool,
270
271 pub timestamp: Option<TimestampOption>,
273}
274
275impl HandshakeOptions {
276 fn next_option(&self, next: &mut u8) -> Option<TcpOption<'_>> {
278 let Self { mss, window_scale, sack_permitted, timestamp } = self;
279 loop {
281 match core::mem::replace(next, next.wrapping_add(1)) {
282 0 => {
283 if let Some(mss) = mss {
284 return Some(TcpOption::Mss(mss.get()));
285 }
286 }
287 1 => {
288 if let Some(ws) = window_scale {
289 return Some(TcpOption::WindowScale(ws.get()));
290 }
291 }
292 2 => {
293 if *sack_permitted {
294 return Some(TcpOption::SackPermitted);
295 }
296 }
297 3 => {
298 if let Some(ts) = timestamp {
299 return Some((*ts).into());
300 }
301 }
302 4 => return None, 5.. => panic!("iterator already ended"),
304 }
305 }
306 }
307}
308
309#[derive(Debug, Default, PartialEq, Eq, Clone)]
311pub struct SegmentOptions {
312 pub sack_blocks: SackBlocks,
314
315 pub timestamp: Option<TimestampOption>,
317}
318
319impl SegmentOptions {
320 pub fn iter(&self) -> impl Iterator<Item = TcpOption<'_>> + Clone {
322 SegmentOptionsIter { inner: &self, next: 0 }
323 }
324
325 fn next_option(&self, next: &mut u8) -> Option<TcpOption<'_>> {
327 let Self { timestamp, sack_blocks } = self;
328 loop {
330 match core::mem::replace(next, next.wrapping_add(1)) {
331 0 => {
332 if let Some(ts) = timestamp {
333 return Some((*ts).into());
334 }
335 }
336 1 => {
337 if let Some(sb) = sack_blocks.as_option() {
338 return Some(sb);
339 }
340 }
341 2 => return None, 3.. => panic!("iterator already ended"),
343 }
344 }
345 }
346
347 pub fn is_empty(&self) -> bool {
349 let Self { sack_blocks, timestamp } = self;
350 sack_blocks.is_empty() && timestamp.is_none()
351 }
352}
353
354#[derive(Clone)]
359struct SegmentOptionsIter<'a> {
360 inner: &'a SegmentOptions,
361 next: u8,
362}
363
364impl<'a> Iterator for SegmentOptionsIter<'a> {
365 type Item = TcpOption<'a>;
366
367 fn next(&mut self) -> Option<Self::Item> {
368 let Self { inner, next } = self;
369 inner.next_option(next)
370 }
371}
372
373#[derive(Debug, Default, PartialEq, Eq, Clone)]
375pub struct ResetOptions {
376 pub timestamp: Option<TimestampOption>,
378}
379
380impl ResetOptions {
381 fn next_option(&self, next: &mut u8) -> Option<TcpOption<'_>> {
383 let ResetOptions { timestamp } = self;
384 loop {
386 match core::mem::replace(next, next.wrapping_add(1)) {
387 0 => {
388 if let Some(ts) = timestamp {
389 return Some((*ts).into());
390 }
391 }
392 1 => return None, 2.. => panic!("iterator already ended"),
394 }
395 }
396 }
397}
398
399const MAX_SACK_BLOCKS: usize = 4;
400#[derive(Debug, Default, PartialEq, Eq, Clone)]
402pub struct SackBlocks(ArrayVec<TcpSackBlock, MAX_SACK_BLOCKS>);
403
404impl SackBlocks {
405 pub const EMPTY: Self = SackBlocks(ArrayVec::new_const());
407
408 pub const MAX_BLOCKS: usize = MAX_SACK_BLOCKS;
414
415 pub const MAX_BLOCKS_WITH_TIMESTAMP: usize = 3;
422
423 pub fn as_option(&self) -> Option<TcpOption<'_>> {
427 let Self(inner) = self;
428 if inner.is_empty() {
429 return None;
430 }
431
432 Some(TcpOption::Sack(inner.as_slice()))
433 }
434
435 pub fn iter_skip_invalid(&self) -> impl Iterator<Item = SackBlock> + '_ {
438 self.try_iter().filter_map(|r| match r {
439 Ok(s) => Some(s),
440 Err(InvalidSackBlockError(_, _)) => None,
441 })
442 }
443
444 pub fn try_iter(&self) -> impl Iterator<Item = Result<SackBlock, InvalidSackBlockError>> + '_ {
447 let Self(inner) = self;
448 inner.iter().map(|block| SackBlock::try_from(*block))
449 }
450
451 pub fn from_option(blocks: &[TcpSackBlock]) -> Self {
456 Self(blocks.iter().take(Self::MAX_BLOCKS).copied().collect())
457 }
458
459 pub fn is_empty(&self) -> bool {
461 let Self(inner) = self;
462 inner.is_empty()
463 }
464
465 pub fn clear(&mut self) {
467 let Self(inner) = self;
468 inner.clear()
469 }
470}
471
472impl FromIterator<SackBlock> for SackBlocks {
476 fn from_iter<T: IntoIterator<Item = SackBlock>>(iter: T) -> Self {
477 Self(iter.into_iter().take(Self::MAX_BLOCKS).map(|b| b.into()).collect())
478 }
479}
480
481mod sack_block {
482 use super::*;
483
484 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
489 pub struct SackBlock {
490 left: SeqNum,
492 right: SeqNum,
493 }
494
495 impl SackBlock {
496 pub fn try_new(left: SeqNum, right: SeqNum) -> Result<Self, InvalidSackBlockError> {
500 if right.after(left) {
501 Ok(Self { left, right })
502 } else {
503 Err(InvalidSackBlockError(left, right))
504 }
505 }
506
507 pub unsafe fn new_unchecked(left: SeqNum, right: SeqNum) -> Self {
514 Self { left, right }
515 }
516
517 pub fn into_range(self) -> Range<SeqNum> {
519 let Self { left, right } = self;
520 Range { start: left, end: right }
521 }
522
523 pub fn into_range_u32(self) -> Range<u32> {
526 let Self { left, right } = self;
527 Range { start: left.into(), end: right.into() }
528 }
529
530 pub fn left(&self) -> SeqNum {
532 self.left
533 }
534
535 pub fn right(&self) -> SeqNum {
537 self.right
538 }
539
540 pub fn into_parts(self) -> (SeqNum, SeqNum) {
543 let Self { left, right } = self;
544 (left, right)
545 }
546 }
547
548 #[derive(Debug, Eq, PartialEq, Clone, Copy)]
551 pub struct InvalidSackBlockError(pub SeqNum, pub SeqNum);
552
553 impl From<SackBlock> for TcpSackBlock {
554 fn from(value: SackBlock) -> Self {
555 let SackBlock { left, right } = value;
556 TcpSackBlock::new(left.into(), right.into())
557 }
558 }
559
560 impl TryFrom<TcpSackBlock> for SackBlock {
561 type Error = InvalidSackBlockError;
562
563 fn try_from(value: TcpSackBlock) -> Result<Self, Self::Error> {
564 Self::try_new(value.left_edge().into(), value.right_edge().into())
565 }
566 }
567
568 impl From<SackBlock> for Range<SeqNum> {
569 fn from(value: SackBlock) -> Self {
570 value.into_range()
571 }
572 }
573
574 impl TryFrom<Range<SeqNum>> for SackBlock {
575 type Error = InvalidSackBlockError;
576
577 fn try_from(value: Range<SeqNum>) -> Result<Self, Self::Error> {
578 let Range { start, end } = value;
579 Self::try_new(start, end)
580 }
581 }
582}
583pub use sack_block::{InvalidSackBlockError, SackBlock};
584
585pub const MAX_PAYLOAD_AND_CONTROL_LEN: usize = 1 << 31;
587const MAX_PAYLOAD_AND_CONTROL_LEN_U32: u32 = MAX_PAYLOAD_AND_CONTROL_LEN as u32;
589
590impl<P: Payload> Segment<P> {
591 pub fn new(header: SegmentHeader, data: P) -> (Self, usize) {
596 let SegmentHeader { seq, ack, wnd, control, push, options } = header;
597 let has_control_len = control.map(Control::has_sequence_no).unwrap_or(false);
598
599 let data_len = data.len();
600 let discarded_len =
601 data_len.saturating_sub(MAX_PAYLOAD_AND_CONTROL_LEN - usize::from(has_control_len));
602
603 let push = push && data_len != 0;
605
606 let (control, data) = if discarded_len > 0 {
607 let (control, control_len) = if control == Some(Control::FIN) {
610 (None, 0)
611 } else {
612 (control, has_control_len.into())
613 };
614 (control, data.slice(0..MAX_PAYLOAD_AND_CONTROL_LEN_U32 - control_len))
617 } else {
618 (control, data)
619 };
620
621 (
622 Segment { header: SegmentHeader { seq, ack, wnd, control, push, options }, data: data },
623 discarded_len,
624 )
625 }
626
627 pub fn header(&self) -> &SegmentHeader {
629 &self.header
630 }
631
632 pub fn data(&self) -> &P {
634 &self.data
635 }
636
637 pub fn into_parts(self) -> (SegmentHeader, P) {
640 let Self { header, data } = self;
641 (header, data)
642 }
643
644 pub fn map_payload<R, F: FnOnce(P) -> R>(self, f: F) -> Segment<R> {
646 let Segment { header, data } = self;
647 Segment { header, data: f(data) }
648 }
649
650 pub fn len(&self) -> u32 {
656 self.header.len(self.data.len())
657 }
658
659 pub fn overlap(self, rnxt: SeqNum, rwnd: WindowSize) -> Option<Segment<P>> {
661 let len = self.len();
662 let Segment { header: SegmentHeader { seq, ack, wnd, control, options, push }, data } =
663 self;
664
665 let overlap = match (len, rwnd) {
677 (0, WindowSize::ZERO) => seq == rnxt,
678 (0, rwnd) => !rnxt.after(seq) && seq.before(rnxt + rwnd),
679 (_len, WindowSize::ZERO) => false,
680 (len, rwnd) => {
681 (!rnxt.after(seq) && seq.before(rnxt + rwnd))
682 || (!(seq + len).before(rnxt) && !(seq + len).after(rnxt + rwnd))
693 }
694 };
695 overlap.then(move || {
696 let cmp = |lhs: &SeqNum, rhs: &SeqNum| (*lhs - *rhs).cmp(&0);
699 let new_seq = core::cmp::max_by(seq, rnxt, cmp);
700 let new_len = core::cmp::min_by(seq + len, rnxt + rwnd, cmp) - new_seq;
701 let start = u32::try_from(new_seq - seq).unwrap();
706 let new_len = u32::try_from(new_len).unwrap();
715 let (new_control, new_data) = {
716 match control {
717 Some(Control::SYN) => {
718 if start == 0 {
719 (Some(Control::SYN), data.slice(start..start + new_len - 1))
720 } else {
721 (None, data.slice(start - 1..start + new_len - 1))
722 }
723 }
724 Some(Control::FIN) => {
725 if len == start + new_len {
726 if new_len > 0 {
727 (Some(Control::FIN), data.slice(start..start + new_len - 1))
728 } else {
729 (None, data.slice(start - 1..start - 1))
730 }
731 } else {
732 (None, data.slice(start..start + new_len))
733 }
734 }
735 Some(Control::RST) | None => (control, data.slice(start..start + new_len)),
736 }
737 };
738 Segment {
739 header: SegmentHeader {
740 seq: new_seq,
741 ack,
742 wnd,
743 control: new_control,
744 options,
745 push,
746 },
747 data: new_data,
748 }
749 })
750 }
751
752 pub fn new_empty(header: SegmentHeader) -> Self {
754 let (seg, truncated) = Self::new(header, P::new_empty());
757 debug_assert_eq!(truncated, 0);
758 seg
759 }
760
761 pub fn ack(seq: SeqNum, ack: SeqNum, wnd: UnscaledWindowSize, options: SegmentOptions) -> Self {
763 Segment::new_empty(SegmentHeader {
764 seq,
765 ack: Some(ack),
766 wnd,
767 control: None,
768 push: false,
769 options: options.into(),
770 })
771 }
772
773 pub fn syn(seq: SeqNum, wnd: UnscaledWindowSize, options: HandshakeOptions) -> Self {
775 Segment::new_empty(SegmentHeader {
776 seq,
777 ack: None,
778 wnd,
779 control: Some(Control::SYN),
780 push: false,
781 options: options.into(),
782 })
783 }
784
785 pub fn syn_ack(
787 seq: SeqNum,
788 ack: SeqNum,
789 wnd: UnscaledWindowSize,
790 options: HandshakeOptions,
791 ) -> Self {
792 Segment::new_empty(SegmentHeader {
793 seq,
794 ack: Some(ack),
795 wnd,
796 control: Some(Control::SYN),
797 push: false,
798 options: options.into(),
799 })
800 }
801
802 pub fn rst(seq: SeqNum, options: ResetOptions) -> Self {
804 Segment::new_empty(SegmentHeader {
805 seq,
806 ack: None,
807 wnd: UnscaledWindowSize::from(0),
808 control: Some(Control::RST),
809 push: false,
810 options: options.into(),
811 })
812 }
813
814 pub fn rst_ack(seq: SeqNum, ack: SeqNum, options: ResetOptions) -> Self {
816 Segment::new_empty(SegmentHeader {
817 seq,
818 ack: Some(ack),
819 wnd: UnscaledWindowSize::from(0),
820 control: Some(Control::RST),
821 push: false,
822 options: options.into(),
823 })
824 }
825}
826
827impl Segment<()> {
828 pub fn into_empty<P: Payload>(self) -> Segment<P> {
831 self.map_payload(|()| P::new_empty())
832 }
833}
834
835impl SegmentHeader {
836 pub fn len(&self, payload_len: usize) -> u32 {
842 let has_control_len = self.control.map(Control::has_sequence_no).unwrap_or(false);
846 u32::try_from(payload_len).unwrap() + u32::from(has_control_len)
847 }
848
849 pub fn from_builder<A: IpAddress>(
852 builder: &TcpSegmentBuilder<A>,
853 ) -> Result<Self, MalformedFlags> {
854 let control =
855 Flags { syn: builder.syn_set(), fin: builder.fin_set(), rst: builder.rst_set() }
856 .control()?;
857 let options = Options::new(control.as_ref());
858 Self::from_builder_options(builder, options)
859 }
860
861 pub fn from_builder_options<A: IpAddress>(
863 builder: &TcpSegmentBuilder<A>,
864 options: Options,
865 ) -> Result<Self, MalformedFlags> {
866 Ok(SegmentHeader {
867 seq: SeqNum::new(builder.seq_num()),
868 ack: builder.ack_num().map(SeqNum::new),
869 control: Flags {
870 syn: builder.syn_set(),
871 fin: builder.fin_set(),
872 rst: builder.rst_set(),
873 }
874 .control()?,
875 wnd: UnscaledWindowSize::from(builder.window_size()),
876 push: builder.psh_set(),
877 options: options,
878 })
879 }
880}
881
882pub trait PayloadLen {
884 fn len(&self) -> usize;
886}
887
888pub trait Payload: PayloadLen + Sized {
890 fn slice(self, range: Range<u32>) -> Self;
899
900 fn partial_copy(&self, offset: usize, dst: &mut [u8]);
906
907 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]);
913
914 fn new_empty() -> Self;
918}
919
920impl PayloadLen for &[u8] {
921 fn len(&self) -> usize {
922 <[u8]>::len(self)
923 }
924}
925
926impl Payload for &[u8] {
927 fn slice(self, Range { start, end }: Range<u32>) -> Self {
928 let start = usize::try_from(start).unwrap_or_else(|TryFromIntError { .. }| {
933 panic!("range start index {} out of range for slice of length {}", start, self.len())
934 });
935 let end = usize::try_from(end).unwrap_or_else(|TryFromIntError { .. }| {
936 panic!("range end index {} out of range for slice of length {}", end, self.len())
937 });
938 &self[start..end]
939 }
940
941 fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
942 dst.copy_from_slice(&self[offset..offset + dst.len()])
943 }
944
945 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]) {
946 let src = &self[offset..offset + dst.len()];
949 let uninit_src: &[MaybeUninit<u8>] = unsafe { core::mem::transmute(src) };
951 dst.copy_from_slice(&uninit_src);
952 }
953
954 fn new_empty() -> Self {
955 &[]
956 }
957}
958
959impl PayloadLen for () {
960 fn len(&self) -> usize {
961 0
962 }
963}
964
965impl Payload for () {
966 fn slice(self, Range { start, end }: Range<u32>) -> Self {
967 if start != 0 {
968 panic!("range start index {} out of range for slice of length 0", start);
969 }
970 if end != 0 {
971 panic!("range end index {} out of range for slice of length 0", end);
972 }
973 ()
974 }
975
976 fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
977 if dst.len() != 0 || offset != 0 {
978 panic!(
979 "source slice length (0) does not match destination slice length ({})",
980 dst.len()
981 );
982 }
983 }
984
985 fn partial_copy_uninit(&self, offset: usize, dst: &mut [MaybeUninit<u8>]) {
986 if dst.len() != 0 || offset != 0 {
987 panic!(
988 "source slice length (0) does not match destination slice length ({})",
989 dst.len()
990 );
991 }
992 }
993
994 fn new_empty() -> Self {
995 ()
996 }
997}
998
999impl<I: PayloadLen, B> PayloadLen for InnerSerializer<I, B> {
1000 fn len(&self) -> usize {
1001 PayloadLen::len(self.inner())
1002 }
1003}
1004
1005#[derive(Error, Debug, PartialEq, Eq)]
1006#[error("multiple mutually exclusive flags are set: syn: {syn}, fin: {fin}, rst: {rst}")]
1007pub struct MalformedFlags {
1008 syn: bool,
1009 fin: bool,
1010 rst: bool,
1011}
1012
1013struct Flags {
1014 syn: bool,
1015 fin: bool,
1016 rst: bool,
1017}
1018
1019impl Flags {
1020 fn control(&self) -> Result<Option<Control>, MalformedFlags> {
1021 if usize::from(self.syn) + usize::from(self.fin) + usize::from(self.rst) > 1 {
1022 return Err(MalformedFlags { syn: self.syn, fin: self.fin, rst: self.rst });
1023 }
1024
1025 let syn = self.syn.then_some(Control::SYN);
1026 let fin = self.fin.then_some(Control::FIN);
1027 let rst = self.rst.then_some(Control::RST);
1028
1029 Ok(syn.or(fin).or(rst))
1030 }
1031}
1032
1033pub struct VerifiedTcpSegment<'a> {
1036 segment: TcpSegment<&'a [u8]>,
1037 control: Option<Control>,
1038}
1039
1040impl<'a> VerifiedTcpSegment<'a> {
1041 pub fn tcp_segment(&self) -> &TcpSegment<&'a [u8]> {
1043 &self.segment
1044 }
1045
1046 pub fn control(&self) -> Option<Control> {
1048 self.control
1049 }
1050}
1051
1052impl<'a> TryFrom<TcpSegment<&'a [u8]>> for VerifiedTcpSegment<'a> {
1053 type Error = MalformedFlags;
1054
1055 fn try_from(segment: TcpSegment<&'a [u8]>) -> Result<Self, Self::Error> {
1056 let control =
1057 Flags { syn: segment.syn(), fin: segment.fin(), rst: segment.rst() }.control()?;
1058 Ok(VerifiedTcpSegment { segment, control })
1059 }
1060}
1061
1062impl<'a> From<&'a VerifiedTcpSegment<'a>> for Segment<&'a [u8]> {
1063 fn from(from: &'a VerifiedTcpSegment<'a>) -> Segment<&'a [u8]> {
1064 let VerifiedTcpSegment { segment, control } = from;
1065 let options = Options::from_iter(control.as_ref(), segment.iter_options());
1066 let (to, discarded) = Segment::new(
1067 SegmentHeader {
1068 seq: segment.seq_num().into(),
1069 ack: segment.ack_num().map(Into::into),
1070 wnd: UnscaledWindowSize::from(segment.window_size()),
1071 control: *control,
1072 push: segment.psh(),
1073 options,
1074 },
1075 from.segment.body(),
1076 );
1077 debug_assert_eq!(discarded, 0);
1078 to
1079 }
1080}
1081
1082impl<A> TryFrom<&TcpSegmentBuilder<A>> for SegmentHeader
1083where
1084 A: IpAddress,
1085{
1086 type Error = MalformedFlags;
1087
1088 fn try_from(from: &TcpSegmentBuilder<A>) -> Result<Self, Self::Error> {
1089 SegmentHeader::from_builder(from)
1090 }
1091}
1092
1093impl<'a, A, I> TryFrom<&TcpSegmentBuilderWithOptions<A, OptionSequenceBuilder<TcpOption<'a>, I>>>
1094 for SegmentHeader
1095where
1096 A: IpAddress,
1097 I: Iterator + Clone,
1098 I::Item: Borrow<TcpOption<'a>>,
1099{
1100 type Error = MalformedFlags;
1101
1102 fn try_from(
1103 from: &TcpSegmentBuilderWithOptions<A, OptionSequenceBuilder<TcpOption<'a>, I>>,
1104 ) -> Result<Self, Self::Error> {
1105 let prefix_builder = from.prefix_builder();
1106 Self::from_builder_options(
1107 prefix_builder,
1108 Options::try_from_iter(
1109 &prefix_builder,
1110 from.iter_options().map(|option| option.borrow().to_owned()),
1111 )?,
1112 )
1113 }
1114}
1115
1116#[cfg(any(test, feature = "testutils"))]
1117mod testutils {
1118 use super::*;
1119
1120 impl Default for SegmentHeader {
1122 fn default() -> Self {
1123 Self {
1124 seq: SeqNum::new(0),
1125 ack: None,
1126 control: None,
1127 wnd: UnscaledWindowSize::from(0),
1128 options: Options::new(None),
1129 push: false,
1130 }
1131 }
1132 }
1133
1134 impl<P: Payload> Segment<P> {
1135 #[track_caller]
1138 pub fn new_assert_no_discard(header: SegmentHeader, data: P) -> Self {
1139 let (seg, discard) = Self::new(header, data);
1140 assert_eq!(discard, 0);
1141 seg
1142 }
1143 }
1144
1145 impl<'a> Segment<&'a [u8]> {
1146 pub fn with_fake_data(seq: SeqNum, ack: SeqNum, data: &'a [u8]) -> Self {
1148 Self::new_assert_no_discard(
1149 SegmentHeader {
1150 seq,
1151 ack: Some(ack),
1152 control: None,
1153 wnd: UnscaledWindowSize::from(u16::MAX),
1154 options: Options::new(None),
1155 push: false,
1156 },
1157 data,
1158 )
1159 }
1160 }
1161
1162 impl<P: Payload> Segment<P> {
1163 pub fn with_data(
1165 seq: SeqNum,
1166 ack: SeqNum,
1167 wnd: UnscaledWindowSize,
1168 options: SegmentOptions,
1169 data: P,
1170 ) -> Segment<P> {
1171 Segment::new_assert_no_discard(
1172 SegmentHeader {
1173 seq,
1174 ack: Some(ack),
1175 control: None,
1176 wnd,
1177 push: false,
1178 options: Options::Segment(options),
1179 },
1180 data,
1181 )
1182 }
1183
1184 pub fn piggybacked_fin(
1186 seq: SeqNum,
1187 ack: SeqNum,
1188 wnd: UnscaledWindowSize,
1189 options: SegmentOptions,
1190 data: P,
1191 ) -> Segment<P> {
1192 Segment::new_assert_no_discard(
1193 SegmentHeader {
1194 seq,
1195 ack: Some(ack),
1196 control: Some(Control::FIN),
1197 wnd,
1198 push: false,
1199 options: Options::Segment(options),
1200 },
1201 data,
1202 )
1203 }
1204
1205 pub fn fin(
1207 seq: SeqNum,
1208 ack: SeqNum,
1209 wnd: UnscaledWindowSize,
1210 options: SegmentOptions,
1211 ) -> Self {
1212 Segment::new_empty(SegmentHeader {
1213 seq,
1214 ack: Some(ack),
1215 control: Some(Control::FIN),
1216 wnd,
1217 push: false,
1218 options: Options::Segment(options),
1219 })
1220 }
1221 }
1222}
1223
1224#[cfg(test)]
1225mod test {
1226
1227 use alloc::vec::Vec;
1228 use assert_matches::assert_matches;
1229 use core::num::NonZeroU16;
1230 use ip_test_macro::ip_test;
1231 use net_declare::{net_ip_v4, net_ip_v6};
1232 use net_types::ip::{Ipv4, Ipv6};
1233 use packet_formats::ip::IpExt;
1234 use test_case::{test_case, test_matrix};
1235
1236 use super::*;
1237
1238 #[test_case(None, &[][..] => (0, &[][..]); "empty")]
1239 #[test_case(None, &[1][..] => (1, &[1][..]); "no control")]
1240 #[test_case(Some(Control::SYN), &[][..] => (1, &[][..]); "empty slice with syn")]
1241 #[test_case(Some(Control::SYN), &[1][..] => (2, &[1][..]); "non-empty slice with syn")]
1242 #[test_case(Some(Control::FIN), &[][..] => (1, &[][..]); "empty slice with fin")]
1243 #[test_case(Some(Control::FIN), &[1][..] => (2, &[1][..]); "non-empty slice with fin")]
1244 #[test_case(Some(Control::RST), &[][..] => (0, &[][..]); "empty slice with rst")]
1245 #[test_case(Some(Control::RST), &[1][..] => (1, &[1][..]); "non-empty slice with rst")]
1246 fn segment_len(control: Option<Control>, data: &[u8]) -> (u32, &[u8]) {
1247 let (seg, truncated) = Segment::new(
1248 SegmentHeader {
1249 seq: SeqNum::new(1),
1250 ack: Some(SeqNum::new(1)),
1251 wnd: UnscaledWindowSize::from(0),
1252 control,
1253 push: false,
1254 options: Options::new(None),
1255 },
1256 data,
1257 );
1258 assert_eq!(truncated, 0);
1259 (seg.len(), seg.data)
1260 }
1261
1262 #[test_case(&[1, 2, 3, 4, 5][..], 0..4 => [1, 2, 3, 4])]
1263 #[test_case((), 0..0 => [0, 0, 0, 0])]
1264 fn payload_slice_copy(data: impl Payload, range: Range<u32>) -> [u8; 4] {
1265 let sliced = data.slice(range);
1266 let mut buffer = [0; 4];
1267 sliced.partial_copy(0, &mut buffer[..sliced.len()]);
1268 buffer
1269 }
1270
1271 #[derive(Debug, PartialEq, Eq)]
1272 struct TestPayload(Range<u32>);
1273
1274 impl TestPayload {
1275 fn new(len: usize) -> Self {
1276 Self(0..u32::try_from(len).unwrap())
1277 }
1278 }
1279
1280 impl PayloadLen for TestPayload {
1281 fn len(&self) -> usize {
1282 self.0.len()
1283 }
1284 }
1285
1286 impl Payload for TestPayload {
1287 fn slice(self, range: Range<u32>) -> Self {
1288 let Self(this) = self;
1289 assert!(range.start >= this.start && range.end <= this.end);
1290 TestPayload(range)
1291 }
1292
1293 fn partial_copy(&self, _offset: usize, _dst: &mut [u8]) {
1294 unimplemented!("TestPayload doesn't carry any data");
1295 }
1296
1297 fn partial_copy_uninit(&self, _offset: usize, _dst: &mut [MaybeUninit<u8>]) {
1298 unimplemented!("TestPayload doesn't carry any data");
1299 }
1300
1301 fn new_empty() -> Self {
1302 Self(0..0)
1303 }
1304 }
1305
1306 #[test_case(100, Some(Control::SYN) => (100, Some(Control::SYN), 0))]
1307 #[test_case(100, Some(Control::FIN) => (100, Some(Control::FIN), 0))]
1308 #[test_case(100, Some(Control::RST) => (100, Some(Control::RST), 0))]
1309 #[test_case(100, None => (100, None, 0))]
1310 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN)
1311 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 0))]
1312 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN)
1313 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::FIN), 0))]
1314 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST)
1315 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::RST), 0))]
1316 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN - 1, None
1317 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, None, 0))]
1318 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::SYN)
1319 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1))]
1320 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::FIN)
1321 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
1322 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST)
1323 => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 0))]
1324 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN, None
1325 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 0))]
1326 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::SYN)
1327 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 2))]
1328 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::FIN)
1329 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 2))]
1330 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, Some(Control::RST)
1331 => (MAX_PAYLOAD_AND_CONTROL_LEN, Some(Control::RST), 1))]
1332 #[test_case(MAX_PAYLOAD_AND_CONTROL_LEN + 1, None
1333 => (MAX_PAYLOAD_AND_CONTROL_LEN, None, 1))]
1334 #[test_case(u32::MAX as usize, Some(Control::SYN)
1335 => (MAX_PAYLOAD_AND_CONTROL_LEN - 1, Some(Control::SYN), 1 << 31))]
1336 fn segment_truncate(len: usize, control: Option<Control>) -> (usize, Option<Control>, usize) {
1337 let (seg, truncated) = Segment::new(
1338 SegmentHeader {
1339 seq: SeqNum::new(0),
1340 ack: None,
1341 wnd: UnscaledWindowSize::from(0),
1342 control,
1343 push: false,
1344 options: Options::new(None),
1345 },
1346 TestPayload::new(len),
1347 );
1348 (seg.data.len(), seg.header.control, truncated)
1349 }
1350
1351 struct OverlapTestArgs {
1352 seg_seq: u32,
1353 control: Option<Control>,
1354 data_len: u32,
1355 rcv_nxt: u32,
1356 rcv_wnd: usize,
1357 }
1358 #[test_case(OverlapTestArgs{
1359 seg_seq: 1,
1360 control: None,
1361 data_len: 0,
1362 rcv_nxt: 0,
1363 rcv_wnd: 0,
1364 } => None)]
1365 #[test_case(OverlapTestArgs{
1366 seg_seq: 1,
1367 control: None,
1368 data_len: 0,
1369 rcv_nxt: 1,
1370 rcv_wnd: 0,
1371 } => Some((SeqNum::new(1), None, 0..0)))]
1372 #[test_case(OverlapTestArgs{
1373 seg_seq: 1,
1374 control: None,
1375 data_len: 0,
1376 rcv_nxt: 2,
1377 rcv_wnd: 0,
1378 } => None)]
1379 #[test_case(OverlapTestArgs{
1380 seg_seq: 1,
1381 control: Some(Control::SYN),
1382 data_len: 0,
1383 rcv_nxt: 2,
1384 rcv_wnd: 0,
1385 } => None)]
1386 #[test_case(OverlapTestArgs{
1387 seg_seq: 1,
1388 control: Some(Control::SYN),
1389 data_len: 0,
1390 rcv_nxt: 1,
1391 rcv_wnd: 0,
1392 } => None)]
1393 #[test_case(OverlapTestArgs{
1394 seg_seq: 1,
1395 control: Some(Control::SYN),
1396 data_len: 0,
1397 rcv_nxt: 0,
1398 rcv_wnd: 0,
1399 } => None)]
1400 #[test_case(OverlapTestArgs{
1401 seg_seq: 1,
1402 control: Some(Control::FIN),
1403 data_len: 0,
1404 rcv_nxt: 2,
1405 rcv_wnd: 0,
1406 } => None)]
1407 #[test_case(OverlapTestArgs{
1408 seg_seq: 1,
1409 control: Some(Control::FIN),
1410 data_len: 0,
1411 rcv_nxt: 1,
1412 rcv_wnd: 0,
1413 } => None)]
1414 #[test_case(OverlapTestArgs{
1415 seg_seq: 1,
1416 control: Some(Control::FIN),
1417 data_len: 0,
1418 rcv_nxt: 0,
1419 rcv_wnd: 0,
1420 } => None)]
1421 #[test_case(OverlapTestArgs{
1422 seg_seq: 0,
1423 control: None,
1424 data_len: 0,
1425 rcv_nxt: 1,
1426 rcv_wnd: 1,
1427 } => None)]
1428 #[test_case(OverlapTestArgs{
1429 seg_seq: 1,
1430 control: None,
1431 data_len: 0,
1432 rcv_nxt: 1,
1433 rcv_wnd: 1,
1434 } => Some((SeqNum::new(1), None, 0..0)))]
1435 #[test_case(OverlapTestArgs{
1436 seg_seq: 2,
1437 control: None,
1438 data_len: 0,
1439 rcv_nxt: 1,
1440 rcv_wnd: 1,
1441 } => None)]
1442 #[test_case(OverlapTestArgs{
1443 seg_seq: 0,
1444 control: None,
1445 data_len: 1,
1446 rcv_nxt: 1,
1447 rcv_wnd: 1,
1448 } => Some((SeqNum::new(1), None, 1..1)))]
1449 #[test_case(OverlapTestArgs{
1450 seg_seq: 0,
1451 control: Some(Control::SYN),
1452 data_len: 0,
1453 rcv_nxt: 1,
1454 rcv_wnd: 1,
1455 } => Some((SeqNum::new(1), None, 0..0)))]
1456 #[test_case(OverlapTestArgs{
1457 seg_seq: 2,
1458 control: None,
1459 data_len: 1,
1460 rcv_nxt: 1,
1461 rcv_wnd: 1,
1462 } => None)]
1463 #[test_case(OverlapTestArgs{
1464 seg_seq: 0,
1465 control: None,
1466 data_len: 2,
1467 rcv_nxt: 1,
1468 rcv_wnd: 1,
1469 } => Some((SeqNum::new(1), None, 1..2)))]
1470 #[test_case(OverlapTestArgs{
1471 seg_seq: 1,
1472 control: None,
1473 data_len: 2,
1474 rcv_nxt: 1,
1475 rcv_wnd: 1,
1476 } => Some((SeqNum::new(1), None, 0..1)))]
1477 #[test_case(OverlapTestArgs{
1478 seg_seq: 0,
1479 control: Some(Control::SYN),
1480 data_len: 1,
1481 rcv_nxt: 1,
1482 rcv_wnd: 1,
1483 } => Some((SeqNum::new(1), None, 0..1)))]
1484 #[test_case(OverlapTestArgs{
1485 seg_seq: 1,
1486 control: Some(Control::SYN),
1487 data_len: 1,
1488 rcv_nxt: 1,
1489 rcv_wnd: 1,
1490 } => Some((SeqNum::new(1), Some(Control::SYN), 0..0)))]
1491 #[test_case(OverlapTestArgs{
1492 seg_seq: 0,
1493 control: Some(Control::FIN),
1494 data_len: 1,
1495 rcv_nxt: 1,
1496 rcv_wnd: 1,
1497 } => Some((SeqNum::new(1), Some(Control::FIN), 1..1)))]
1498 #[test_case(OverlapTestArgs{
1499 seg_seq: 1,
1500 control: Some(Control::FIN),
1501 data_len: 1,
1502 rcv_nxt: 1,
1503 rcv_wnd: 1,
1504 } => Some((SeqNum::new(1), None, 0..1)))]
1505 #[test_case(OverlapTestArgs{
1506 seg_seq: 1,
1507 control: None,
1508 data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1509 rcv_nxt: 1,
1510 rcv_wnd: 10,
1511 } => Some((SeqNum::new(1), None, 0..10)))]
1512 #[test_case(OverlapTestArgs{
1513 seg_seq: 10,
1514 control: None,
1515 data_len: MAX_PAYLOAD_AND_CONTROL_LEN_U32,
1516 rcv_nxt: 1,
1517 rcv_wnd: 10,
1518 } => Some((SeqNum::new(10), None, 0..1)))]
1519 #[test_case(OverlapTestArgs{
1520 seg_seq: 1,
1521 control: None,
1522 data_len: 10,
1523 rcv_nxt: 1,
1524 rcv_wnd: WindowSize::MAX.into(),
1525 } => Some((SeqNum::new(1), None, 0..10)))]
1526 #[test_case(OverlapTestArgs{
1527 seg_seq: 10,
1528 control: None,
1529 data_len: 10,
1530 rcv_nxt: 1,
1531 rcv_wnd: WindowSize::MAX.into(),
1532 } => Some((SeqNum::new(10), None, 0..10)))]
1533 #[test_case(OverlapTestArgs{
1534 seg_seq: 1,
1535 control: Some(Control::FIN),
1536 data_len: 1,
1537 rcv_nxt: 3,
1538 rcv_wnd: 10,
1539 } => Some((SeqNum::new(3), None, 1..1)); "regression test for https://fxbug.dev/42061750")]
1540 fn segment_overlap(
1541 OverlapTestArgs { seg_seq, control, data_len, rcv_nxt, rcv_wnd }: OverlapTestArgs,
1542 ) -> Option<(SeqNum, Option<Control>, Range<u32>)> {
1543 let (seg, discarded) = Segment::new(
1544 SegmentHeader {
1545 seq: SeqNum::new(seg_seq),
1546 ack: None,
1547 control,
1548 wnd: UnscaledWindowSize::from(0),
1549 push: false,
1550 options: Options::new(None),
1551 },
1552 TestPayload(0..data_len),
1553 );
1554 assert_eq!(discarded, 0);
1555 seg.overlap(SeqNum::new(rcv_nxt), WindowSize::new(rcv_wnd).unwrap()).map(
1556 |Segment { header: SegmentHeader { seq, control, .. }, data: TestPayload(range) }| {
1557 (seq, control, range)
1558 },
1559 )
1560 }
1561
1562 pub trait TestIpExt: IpExt {
1563 const SRC_IP: Self::Addr;
1564 const DST_IP: Self::Addr;
1565 }
1566
1567 impl TestIpExt for Ipv4 {
1568 const SRC_IP: Self::Addr = net_ip_v4!("192.0.2.1");
1569 const DST_IP: Self::Addr = net_ip_v4!("192.0.2.2");
1570 }
1571
1572 impl TestIpExt for Ipv6 {
1573 const SRC_IP: Self::Addr = net_ip_v6!("2001:db8::1");
1574 const DST_IP: Self::Addr = net_ip_v6!("2001:db8::2");
1575 }
1576
1577 const SRC_PORT: NonZeroU16 = NonZeroU16::new(1234).unwrap();
1578 const DST_PORT: NonZeroU16 = NonZeroU16::new(9876).unwrap();
1579
1580 #[ip_test(I)]
1581 fn from_segment_builder<I: TestIpExt>() {
1582 let mut builder =
1583 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1584 builder.syn(true);
1585
1586 let converted_header =
1587 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1588
1589 let expected_header = SegmentHeader {
1590 seq: SeqNum::new(1),
1591 ack: Some(SeqNum::new(2)),
1592 wnd: UnscaledWindowSize::from(3u16),
1593 control: Some(Control::SYN),
1594 options: HandshakeOptions::default().into(),
1595 push: false,
1596 };
1597
1598 assert_eq!(converted_header, expected_header);
1599 }
1600
1601 #[ip_test(I)]
1602 fn from_segment_builder_failure<I: TestIpExt>() {
1603 let mut builder =
1604 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1605 builder.syn(true);
1606 builder.fin(true);
1607
1608 assert_matches!(
1609 SegmentHeader::try_from(&builder),
1610 Err(MalformedFlags { syn: true, fin: true, rst: false })
1611 );
1612 }
1613
1614 #[ip_test(I)]
1615 fn from_segment_builder_with_options_handshake<I: TestIpExt>() {
1616 let mut builder =
1617 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1618 builder.syn(true);
1619
1620 let builder = TcpSegmentBuilderWithOptions::new(
1621 builder,
1622 [
1623 TcpOption::Mss(1024),
1624 TcpOption::WindowScale(10),
1625 TcpOption::SackPermitted,
1626 TcpOption::Timestamp { ts_val: 1, ts_echo_reply: 0 },
1627 ],
1628 )
1629 .expect("failed to create tcp segment builder");
1630
1631 let converted_header =
1632 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1633
1634 let expected_header = SegmentHeader {
1635 seq: SeqNum::new(1),
1636 ack: Some(SeqNum::new(2)),
1637 wnd: UnscaledWindowSize::from(3u16),
1638 control: Some(Control::SYN),
1639 push: false,
1640 options: HandshakeOptions {
1641 mss: Some(Mss::new(1024).unwrap()),
1642 window_scale: Some(WindowScale::new(10).unwrap()),
1643 sack_permitted: true,
1644 timestamp: Some(TimestampOption {
1645 ts_val: Timestamp::new(1),
1646 ts_echo_reply: Timestamp::new(0),
1647 }),
1648 }
1649 .into(),
1650 };
1651
1652 assert_eq!(converted_header, expected_header);
1653 }
1654
1655 #[ip_test(I)]
1656 fn mss_option_clamps_to_minimum<I: TestIpExt>() {
1657 let mut builder =
1658 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1659 builder.syn(true);
1660
1661 let builder = TcpSegmentBuilderWithOptions::new(
1662 builder,
1663 [TcpOption::Mss(Mss::MIN.get() - 1)],
1666 )
1667 .expect("failed to create tcp segment builder");
1668
1669 let converted_header =
1670 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1671
1672 let expected_header = SegmentHeader {
1673 seq: SeqNum::new(1),
1674 ack: Some(SeqNum::new(2)),
1675 wnd: UnscaledWindowSize::from(3u16),
1676 control: Some(Control::SYN),
1677 push: false,
1678 options: HandshakeOptions {
1679 mss: Some(Mss::MIN),
1680 window_scale: None,
1681 sack_permitted: false,
1682 timestamp: None,
1683 }
1684 .into(),
1685 };
1686
1687 assert_eq!(converted_header, expected_header);
1688 }
1689
1690 #[ip_test(I)]
1691 fn from_segment_builder_with_options_segment<I: TestIpExt>() {
1692 let mut builder =
1693 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1694 builder.psh(true);
1695
1696 let sack_blocks = [TcpSackBlock::new(1, 2), TcpSackBlock::new(4, 6)];
1697 let builder = TcpSegmentBuilderWithOptions::new(
1698 builder,
1699 [
1700 TcpOption::Sack(&sack_blocks[..]),
1701 TcpOption::Timestamp { ts_val: 1234, ts_echo_reply: 4321 },
1702 ],
1703 )
1704 .expect("failed to create tcp segment builder");
1705
1706 let converted_header =
1707 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1708
1709 let expected_header = SegmentHeader {
1710 seq: SeqNum::new(1),
1711 ack: Some(SeqNum::new(2)),
1712 wnd: UnscaledWindowSize::from(3u16),
1713 control: None,
1714 push: true,
1715 options: SegmentOptions {
1716 sack_blocks: SackBlocks::from_iter([
1717 SackBlock::try_new(SeqNum::new(1), SeqNum::new(2)).unwrap(),
1718 SackBlock::try_new(SeqNum::new(4), SeqNum::new(6)).unwrap(),
1719 ]),
1720 timestamp: Some(TimestampOption {
1721 ts_val: Timestamp::new(1234),
1722 ts_echo_reply: Timestamp::new(4321),
1723 }),
1724 }
1725 .into(),
1726 };
1727
1728 assert_eq!(converted_header, expected_header);
1729 }
1730
1731 #[ip_test(I)]
1732 fn from_segment_builder_with_options_failure<I: TestIpExt>() {
1733 let mut builder =
1734 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1735 builder.syn(true);
1736 builder.fin(true);
1737
1738 let builder = TcpSegmentBuilderWithOptions::new(
1739 builder,
1740 [TcpOption::Mss(1024), TcpOption::WindowScale(10)],
1741 )
1742 .expect("failed to create tcp segment builder");
1743
1744 assert_matches!(
1745 SegmentHeader::try_from(&builder),
1746 Err(MalformedFlags { syn: true, fin: true, rst: false })
1747 );
1748 }
1749
1750 #[ip_test(I)]
1751 fn from_segment_builder_with_options_reset<I: TestIpExt>() {
1752 let mut builder =
1753 TcpSegmentBuilder::new(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, 1, Some(2), 3);
1754 builder.rst(true);
1755
1756 let builder = TcpSegmentBuilderWithOptions::new(
1757 builder,
1758 [TcpOption::Timestamp { ts_val: 1234, ts_echo_reply: 4321 }],
1759 )
1760 .expect("failed to create tcp segment builder");
1761
1762 let converted_header =
1763 SegmentHeader::try_from(&builder).expect("failed to convert serializer");
1764
1765 let expected_header = SegmentHeader {
1766 seq: SeqNum::new(1),
1767 ack: Some(SeqNum::new(2)),
1768 wnd: UnscaledWindowSize::from(3u16),
1769 control: Some(Control::RST),
1770 push: false,
1771 options: ResetOptions {
1772 timestamp: Some(TimestampOption {
1773 ts_val: Timestamp::new(1234),
1774 ts_echo_reply: Timestamp::new(4321),
1775 }),
1776 }
1777 .into(),
1778 };
1779
1780 assert_eq!(converted_header, expected_header);
1781 }
1782
1783 #[test_case(Flags {
1784 syn: false,
1785 fin: false,
1786 rst: false,
1787 } => Ok(None))]
1788 #[test_case(Flags {
1789 syn: true,
1790 fin: false,
1791 rst: false,
1792 } => Ok(Some(Control::SYN)))]
1793 #[test_case(Flags {
1794 syn: false,
1795 fin: true,
1796 rst: false,
1797 } => Ok(Some(Control::FIN)))]
1798 #[test_case(Flags {
1799 syn: false,
1800 fin: false,
1801 rst: true,
1802 } => Ok(Some(Control::RST)))]
1803 #[test_case(Flags {
1804 syn: true,
1805 fin: true,
1806 rst: false,
1807 } => Err(MalformedFlags {
1808 syn: true,
1809 fin: true,
1810 rst: false,
1811 }))]
1812 #[test_case(Flags {
1813 syn: true,
1814 fin: false,
1815 rst: true,
1816 } => Err(MalformedFlags {
1817 syn: true,
1818 fin: false,
1819 rst: true,
1820 }))]
1821 #[test_case(Flags {
1822 syn: false,
1823 fin: true,
1824 rst: true,
1825 } => Err(MalformedFlags {
1826 syn: false,
1827 fin: true,
1828 rst: true,
1829 }))]
1830 #[test_case(Flags {
1831 syn: true,
1832 fin: true,
1833 rst: true,
1834 } => Err(MalformedFlags {
1835 syn: true,
1836 fin: true,
1837 rst: true,
1838 }))]
1839 fn flags_to_control(input: Flags) -> Result<Option<Control>, MalformedFlags> {
1840 input.control()
1841 }
1842
1843 #[test]
1844 fn sack_block_try_new() {
1845 assert_matches!(SackBlock::try_new(SeqNum::new(1), SeqNum::new(2)), Ok(_));
1846 assert_matches!(
1847 SackBlock::try_new(SeqNum::new(0u32.wrapping_sub(1)), SeqNum::new(2)),
1848 Ok(_)
1849 );
1850 assert_eq!(
1851 SackBlock::try_new(SeqNum::new(1), SeqNum::new(1)),
1852 Err(InvalidSackBlockError(SeqNum::new(1), SeqNum::new(1)))
1853 );
1854 assert_eq!(
1855 SackBlock::try_new(SeqNum::new(2), SeqNum::new(1)),
1856 Err(InvalidSackBlockError(SeqNum::new(2), SeqNum::new(1)))
1857 );
1858 assert_eq!(
1859 SackBlock::try_new(SeqNum::new(0), SeqNum::new(0u32.wrapping_sub(1))),
1860 Err(InvalidSackBlockError(SeqNum::new(0), SeqNum::new(0u32.wrapping_sub(1))))
1861 );
1862 }
1863
1864 #[test]
1865 fn psh_bit_cleared_if_no_data() {
1866 let seg =
1867 Segment::new_assert_no_discard(SegmentHeader { push: true, ..Default::default() }, ());
1868 assert_eq!(seg.header().push, false);
1869 let seg = Segment::new_assert_no_discard(
1870 SegmentHeader { push: true, ..Default::default() },
1871 &[1u8, 2, 3, 4][..],
1872 );
1873 assert_eq!(seg.header().push, true);
1874 }
1875
1876 const FAKE_TIMESTAMP_OPTION: TimestampOption =
1877 TimestampOption { ts_val: Timestamp::new(1234), ts_echo_reply: Timestamp::new(4321) };
1878
1879 #[test_matrix(
1880 [None, Some(Mss::MIN)],
1881 [None, Some(WindowScale::MAX)],
1882 [false, true],
1883 [None, Some(FAKE_TIMESTAMP_OPTION)]
1884 )]
1885 fn iter_handshake_options(
1886 mss: Option<Mss>,
1887 window_scale: Option<WindowScale>,
1888 sack_permitted: bool,
1889 timestamp: Option<TimestampOption>,
1890 ) {
1891 let options = HandshakeOptions { mss, window_scale, sack_permitted, timestamp };
1892
1893 let expected_options = [
1894 mss.map(|mss| TcpOption::Mss(mss.get())),
1895 window_scale.map(|ws| TcpOption::WindowScale(ws.get())),
1896 sack_permitted.then_some(TcpOption::SackPermitted),
1897 timestamp.map(Into::into),
1898 ]
1899 .into_iter()
1900 .flatten()
1901 .collect::<Vec<_>>();
1902
1903 assert_eq!(Options::Handshake(options).iter().collect::<Vec<_>>(), expected_options);
1904 }
1905
1906 #[test_matrix(
1907 [None, Some(FAKE_TIMESTAMP_OPTION)],
1908 [None, Some(SackBlock::try_new(SeqNum::new(1), SeqNum::new(2)).unwrap())]
1909 )]
1910 fn iter_segment_options(timestamp: Option<TimestampOption>, sack_block: Option<SackBlock>) {
1911 let sack_blocks = SackBlocks::from_iter(sack_block);
1912 let options = SegmentOptions { sack_blocks: sack_blocks.clone(), timestamp };
1913
1914 let expected_options = [timestamp.map(Into::into), sack_blocks.as_option()]
1915 .into_iter()
1916 .flatten()
1917 .collect::<Vec<_>>();
1918
1919 assert_eq!(Options::Segment(options).iter().collect::<Vec<_>>(), expected_options);
1920 }
1921
1922 #[test_case(None)]
1923 #[test_case(Some(FAKE_TIMESTAMP_OPTION))]
1924 fn iter_reset_options(timestamp: Option<TimestampOption>) {
1925 let options = ResetOptions { timestamp };
1926
1927 let expected_options = timestamp.map(Into::into).into_iter().collect::<Vec<_>>();
1928
1929 assert_eq!(Options::Reset(options).iter().collect::<Vec<_>>(), expected_options);
1930 }
1931}