1use core::convert::{Infallible, TryFrom as _};
11use core::fmt::Debug;
12use core::num::{NonZeroU32, NonZeroU8, NonZeroUsize, TryFromIntError};
13use core::ops::{Deref, DerefMut};
14use core::time::Duration;
15
16use assert_matches::assert_matches;
17use derivative::Derivative;
18use explicit::ResultExt as _;
19use netstack3_base::{
20 Control, HandshakeOptions, IcmpErrorCode, Instant, Mss, Options, Payload, PayloadLen as _,
21 SackBlocks, Segment, SegmentHeader, SegmentOptions, SeqNum, UnscaledWindowSize, WindowScale,
22 WindowSize,
23};
24use netstack3_trace::{trace_instant, TraceResourceId};
25use packet_formats::utils::NonZeroDuration;
26use replace_with::{replace_with, replace_with_and};
27
28use crate::internal::base::{
29 BufferSizes, BuffersRefMut, ConnectionError, IcmpErrorResult, KeepAlive, SocketOptions,
30};
31use crate::internal::buffer::{Assembler, BufferLimits, IntoBuffers, ReceiveBuffer, SendBuffer};
32use crate::internal::congestion::CongestionControl;
33use crate::internal::counters::TcpCountersRefs;
34use crate::internal::rtt::{Estimator, Rto, RttSampler};
35
36pub(super) const MSL: Duration = Duration::from_secs(2 * 60);
41
42const DEFAULT_MAX_RETRIES: NonZeroU8 = NonZeroU8::new(15).unwrap();
49
50pub(super) const DEFAULT_MAX_SYN_RETRIES: NonZeroU8 = NonZeroU8::new(6).unwrap();
53const DEFAULT_MAX_SYNACK_RETRIES: NonZeroU8 = NonZeroU8::new(5).unwrap();
54
55const ACK_DELAY_THRESHOLD: Duration = Duration::from_millis(40);
63const SWS_PROBE_TIMEOUT: Duration = Duration::from_millis(100);
70const SWS_BUFFER_FACTOR: u32 = 2;
74
75const SACK_PERMITTED: bool = false;
78
79pub(crate) trait StateMachineDebugId: Debug {
84 fn trace_id(&self) -> TraceResourceId<'_>;
85}
86
87#[derive(Debug)]
100#[cfg_attr(test, derive(PartialEq, Eq))]
101pub struct Closed<Error> {
102 pub(crate) reason: Error,
104}
105
106pub(crate) enum Initial {}
109
110impl Closed<Initial> {
111 pub(crate) fn connect<I: Instant, ActiveOpen>(
117 iss: SeqNum,
118 now: I,
119 active_open: ActiveOpen,
120 buffer_sizes: BufferSizes,
121 device_mss: Mss,
122 default_mss: Mss,
123 SocketOptions {
124 keep_alive: _,
125 nagle_enabled: _,
126 user_timeout,
127 delayed_ack: _,
128 fin_wait2_timeout: _,
129 max_syn_retries,
130 ip_options: _,
131 }: &SocketOptions,
132 ) -> (SynSent<I, ActiveOpen>, Segment<()>) {
133 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
134 let rwnd = buffer_sizes.rwnd_unscaled();
138 (
139 SynSent {
140 iss,
141 timestamp: Some(now),
142 retrans_timer: RetransTimer::new(
143 now,
144 Rto::DEFAULT,
145 *user_timeout,
146 *max_syn_retries,
147 ),
148 active_open,
149 buffer_sizes,
150 device_mss,
151 default_mss,
152 rcv_wnd_scale,
153 },
154 Segment::syn(
155 iss,
156 rwnd,
157 HandshakeOptions {
158 mss: Some(device_mss),
159 window_scale: Some(rcv_wnd_scale),
160 sack_permitted: SACK_PERMITTED,
161 }
162 .into(),
163 ),
164 )
165 }
166
167 pub(crate) fn listen(
168 iss: SeqNum,
169 buffer_sizes: BufferSizes,
170 device_mss: Mss,
171 default_mss: Mss,
172 user_timeout: Option<NonZeroDuration>,
173 ) -> Listen {
174 Listen { iss, buffer_sizes, device_mss, default_mss, user_timeout }
175 }
176}
177
178impl<Error> Closed<Error> {
179 pub(crate) fn on_segment(&self, segment: &Segment<impl Payload>) -> Option<Segment<()>> {
183 let segment_len = segment.len();
184 let Segment {
185 header: SegmentHeader { seq: seg_seq, ack: seg_ack, wnd: _, control, options: _ },
186 data: _,
187 } = segment;
188
189 if *control == Some(Control::RST) {
203 return None;
204 }
205 Some(match seg_ack {
206 Some(seg_ack) => Segment::rst(*seg_ack),
207 None => Segment::rst_ack(SeqNum::from(0), *seg_seq + segment_len),
208 })
209 }
210}
211
212#[derive(Debug)]
226#[cfg_attr(test, derive(PartialEq, Eq))]
227pub struct Listen {
228 iss: SeqNum,
229 buffer_sizes: BufferSizes,
230 device_mss: Mss,
231 default_mss: Mss,
232 user_timeout: Option<NonZeroDuration>,
233}
234
235#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
237enum ListenOnSegmentDisposition<I: Instant> {
238 SendSynAckAndEnterSynRcvd(Segment<()>, SynRcvd<I, Infallible>),
239 SendRst(Segment<()>),
240 Ignore,
241}
242
243impl Listen {
244 fn on_segment<I: Instant>(
245 &self,
246 Segment { header: SegmentHeader { seq, ack, wnd: _, control, options }, data: _ }: Segment<
247 impl Payload,
248 >,
249 now: I,
250 ) -> ListenOnSegmentDisposition<I> {
251 let Listen { iss, buffer_sizes, device_mss, default_mss, user_timeout } = *self;
252 let smss = options.mss().unwrap_or(default_mss).min(device_mss);
253 if control == Some(Control::RST) {
257 return ListenOnSegmentDisposition::Ignore;
258 }
259 if let Some(ack) = ack {
260 return ListenOnSegmentDisposition::SendRst(Segment::rst(ack));
269 }
270 if control == Some(Control::SYN) {
271 let sack_permitted = options.sack_permitted();
272 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
286 let rwnd = buffer_sizes.rwnd_unscaled();
290 return ListenOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
291 Segment::syn_ack(
292 iss,
293 seq + 1,
294 rwnd,
295 HandshakeOptions {
296 mss: Some(smss),
297 window_scale: options.window_scale().map(|_| rcv_wnd_scale),
302 sack_permitted: SACK_PERMITTED,
303 }
304 .into(),
305 ),
306 SynRcvd {
307 iss,
308 irs: seq,
309 timestamp: Some(now),
310 retrans_timer: RetransTimer::new(
311 now,
312 Rto::DEFAULT,
313 user_timeout,
314 DEFAULT_MAX_SYNACK_RETRIES,
315 ),
316 simultaneous_open: None,
317 buffer_sizes,
318 smss,
319 rcv_wnd_scale,
320 snd_wnd_scale: options.window_scale(),
321 sack_permitted,
322 },
323 );
324 }
325 ListenOnSegmentDisposition::Ignore
326 }
327}
328
329#[derive(Debug)]
343#[cfg_attr(test, derive(PartialEq, Eq))]
344pub struct SynSent<I, ActiveOpen> {
345 iss: SeqNum,
346 timestamp: Option<I>,
350 retrans_timer: RetransTimer<I>,
351 active_open: ActiveOpen,
352 buffer_sizes: BufferSizes,
353 device_mss: Mss,
354 default_mss: Mss,
355 rcv_wnd_scale: WindowScale,
356}
357
358#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
360enum SynSentOnSegmentDisposition<I: Instant, ActiveOpen> {
361 SendAckAndEnterEstablished(Established<I, (), ()>),
362 SendSynAckAndEnterSynRcvd(Segment<()>, SynRcvd<I, ActiveOpen>),
363 SendRst(Segment<()>),
364 EnterClosed(Closed<Option<ConnectionError>>),
365 Ignore,
366}
367
368impl<I: Instant + 'static, ActiveOpen> SynSent<I, ActiveOpen> {
369 fn on_segment(
375 &self,
376 Segment {
377 header: SegmentHeader { seq: seg_seq, ack: seg_ack, wnd: seg_wnd, control, options },
378 data: _,
379 }: Segment<impl Payload>,
380 now: I,
381 ) -> SynSentOnSegmentDisposition<I, ActiveOpen> {
382 let SynSent {
383 iss,
384 timestamp: syn_sent_ts,
385 retrans_timer: RetransTimer { user_timeout_until, remaining_retries: _, at: _, rto: _ },
386 active_open: _,
387 buffer_sizes,
388 device_mss,
389 default_mss,
390 rcv_wnd_scale,
391 } = *self;
392 let has_ack = match seg_ack {
401 Some(ack) => {
402 if ack.before(iss) || ack.after(iss + 1) {
405 return if control == Some(Control::RST) {
406 SynSentOnSegmentDisposition::Ignore
407 } else {
408 SynSentOnSegmentDisposition::SendRst(Segment::rst(ack))
409 };
410 }
411 true
412 }
413 None => false,
414 };
415
416 match control {
417 Some(Control::RST) => {
418 if has_ack {
426 SynSentOnSegmentDisposition::EnterClosed(Closed {
427 reason: Some(ConnectionError::ConnectionRefused),
428 })
429 } else {
430 SynSentOnSegmentDisposition::Ignore
431 }
432 }
433 Some(Control::SYN) => {
434 let smss = options.mss().unwrap_or(default_mss).min(device_mss);
435 let sack_permitted = options.sack_permitted();
436 match seg_ack {
441 Some(seg_ack) => {
442 if seg_ack.after(iss) {
460 let irs = seg_seq;
461 let mut rtt_estimator = Estimator::default();
462 if let Some(syn_sent_ts) = syn_sent_ts {
463 rtt_estimator.sample(now.saturating_duration_since(syn_sent_ts));
464 }
465 let (rcv_wnd_scale, snd_wnd_scale) = options
466 .window_scale()
467 .map(|snd_wnd_scale| (rcv_wnd_scale, snd_wnd_scale))
468 .unwrap_or_default();
469 let established = Established {
470 snd: Send {
471 nxt: iss + 1,
472 max: iss + 1,
473 una: seg_ack,
474 wnd: seg_wnd << WindowScale::default(),
476 wl1: seg_seq,
477 wl2: seg_ack,
478 buffer: (),
479 rtt_sampler: RttSampler::default(),
480 rtt_estimator,
481 timer: None,
482 congestion_control: CongestionControl::cubic_with_mss(smss),
483 wnd_scale: snd_wnd_scale,
484 wnd_max: seg_wnd << WindowScale::default(),
485 }
486 .into(),
487 rcv: Recv {
488 buffer: RecvBufferState::Open {
489 buffer: (),
490 assembler: Assembler::new(irs + 1),
491 },
492 remaining_quickacks: quickack_counter(
493 buffer_sizes.rcv_limits(),
494 smss,
495 ),
496 last_segment_at: None,
497 timer: None,
498 mss: smss,
499 wnd_scale: rcv_wnd_scale,
500 last_window_update: (irs + 1, buffer_sizes.rwnd()),
501 sack_permitted,
502 }
503 .into(),
504 };
505 SynSentOnSegmentDisposition::SendAckAndEnterEstablished(established)
506 } else {
507 SynSentOnSegmentDisposition::Ignore
508 }
509 }
510 None => {
511 if user_timeout_until.is_none_or(|t| now < t) {
512 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
520 let rwnd = buffer_sizes.rwnd_unscaled();
525 SynSentOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
526 Segment::syn_ack(
527 iss,
528 seg_seq + 1,
529 rwnd,
530 HandshakeOptions {
531 mss: Some(smss),
532 window_scale: options.window_scale().map(|_| rcv_wnd_scale),
533 sack_permitted: SACK_PERMITTED,
534 }
535 .into(),
536 ),
537 SynRcvd {
538 iss,
539 irs: seg_seq,
540 timestamp: Some(now),
541 retrans_timer: RetransTimer::new_with_user_deadline(
542 now,
543 Rto::DEFAULT,
544 user_timeout_until,
545 DEFAULT_MAX_SYNACK_RETRIES,
546 ),
547 simultaneous_open: None,
549 buffer_sizes,
550 smss,
551 rcv_wnd_scale,
552 snd_wnd_scale: options.window_scale(),
553 sack_permitted,
554 },
555 )
556 } else {
557 SynSentOnSegmentDisposition::EnterClosed(Closed { reason: None })
558 }
559 }
560 }
561 }
562 Some(Control::FIN) | None => SynSentOnSegmentDisposition::Ignore,
566 }
567 }
568}
569
570#[derive(Debug)]
585#[cfg_attr(test, derive(PartialEq, Eq))]
586pub struct SynRcvd<I, ActiveOpen> {
587 iss: SeqNum,
588 irs: SeqNum,
589 timestamp: Option<I>,
593 retrans_timer: RetransTimer<I>,
594 simultaneous_open: Option<ActiveOpen>,
598 buffer_sizes: BufferSizes,
599 smss: Mss,
603 rcv_wnd_scale: WindowScale,
604 snd_wnd_scale: Option<WindowScale>,
605 sack_permitted: bool,
606}
607
608impl<I: Instant, R: ReceiveBuffer, S: SendBuffer, ActiveOpen> From<SynRcvd<I, Infallible>>
609 for State<I, R, S, ActiveOpen>
610{
611 fn from(
612 SynRcvd {
613 iss,
614 irs,
615 timestamp,
616 retrans_timer,
617 simultaneous_open,
618 buffer_sizes,
619 smss,
620 rcv_wnd_scale,
621 snd_wnd_scale,
622 sack_permitted,
623 }: SynRcvd<I, Infallible>,
624 ) -> Self {
625 match simultaneous_open {
626 None => State::SynRcvd(SynRcvd {
627 iss,
628 irs,
629 timestamp,
630 retrans_timer,
631 simultaneous_open: None,
632 buffer_sizes,
633 smss,
634 rcv_wnd_scale,
635 snd_wnd_scale,
636 sack_permitted,
637 }),
638 }
639 }
640}
641enum FinQueued {}
642
643impl FinQueued {
644 const YES: bool = true;
648 const NO: bool = false;
649}
650
651#[derive(Derivative)]
653#[derivative(Debug)]
654#[cfg_attr(test, derivative(PartialEq, Eq))]
655pub(crate) struct Send<I, S, const FIN_QUEUED: bool> {
656 nxt: SeqNum,
657 pub(crate) max: SeqNum,
658 una: SeqNum,
659 wnd: WindowSize,
660 wnd_scale: WindowScale,
661 wnd_max: WindowSize,
662 wl1: SeqNum,
663 wl2: SeqNum,
664 rtt_sampler: RttSampler<I>,
665 rtt_estimator: Estimator,
666 timer: Option<SendTimer<I>>,
667 #[derivative(PartialEq = "ignore")]
668 congestion_control: CongestionControl<I>,
669 buffer: S,
670}
671
672impl<I> Send<I, (), false> {
673 fn with_buffer<S>(self, buffer: S) -> Send<I, S, false> {
674 let Self {
675 nxt,
676 max,
677 una,
678 wnd,
679 wnd_scale,
680 wnd_max,
681 wl1,
682 wl2,
683 rtt_sampler,
684 rtt_estimator,
685 timer,
686 congestion_control,
687 buffer: _,
688 } = self;
689 Send {
690 nxt,
691 max,
692 una,
693 wnd,
694 wnd_scale,
695 wnd_max,
696 wl1,
697 wl2,
698 rtt_sampler,
699 rtt_estimator,
700 timer,
701 congestion_control,
702 buffer,
703 }
704 }
705}
706
707#[derive(Debug, Clone, Copy)]
708#[cfg_attr(test, derive(PartialEq, Eq))]
709struct RetransTimer<I> {
710 user_timeout_until: Option<I>,
711 remaining_retries: Option<NonZeroU8>,
712 at: I,
713 rto: Rto,
714}
715
716impl<I: Instant> RetransTimer<I> {
717 fn new(
718 now: I,
719 rto: Rto,
720 user_timeout: Option<NonZeroDuration>,
721 max_retries: NonZeroU8,
722 ) -> Self {
723 let user_timeout_until = user_timeout.map(|t| now.saturating_add(t.get()));
724 Self::new_with_user_deadline(now, rto, user_timeout_until, max_retries)
725 }
726
727 fn new_with_user_deadline(
728 now: I,
729 rto: Rto,
730 user_timeout_until: Option<I>,
731 max_retries: NonZeroU8,
732 ) -> Self {
733 let rto_at = now.panicking_add(rto.get());
734 let at = user_timeout_until.map(|i| i.min(rto_at)).unwrap_or(rto_at);
735 Self { at, rto, user_timeout_until, remaining_retries: Some(max_retries) }
736 }
737
738 fn backoff(&mut self, now: I) {
739 let Self { at, rto, user_timeout_until, remaining_retries } = self;
740 *remaining_retries = remaining_retries.and_then(|r| NonZeroU8::new(r.get() - 1));
741 *rto = rto.double();
742 let rto_at = now.panicking_add(rto.get());
743 *at = user_timeout_until.map(|i| i.min(rto_at)).unwrap_or(rto_at);
744 }
745
746 fn timed_out(&self, now: I) -> bool {
747 let RetransTimer { user_timeout_until, remaining_retries, at, rto: _ } = self;
748 (remaining_retries.is_none() && now >= *at) || user_timeout_until.is_some_and(|t| now >= t)
749 }
750}
751
752#[derive(Debug, Clone, Copy)]
754#[cfg_attr(test, derive(PartialEq, Eq))]
755enum SendTimer<I> {
756 Retrans(RetransTimer<I>),
759 KeepAlive(KeepAliveTimer<I>),
762 ZeroWindowProbe(RetransTimer<I>),
770 SWSProbe { at: I },
778}
779
780#[derive(Debug, Clone, Copy)]
781#[cfg_attr(test, derive(PartialEq, Eq))]
782enum ReceiveTimer<I> {
783 DelayedAck { at: I },
784}
785
786#[derive(Debug, Clone, Copy)]
787#[cfg_attr(test, derive(PartialEq, Eq))]
788struct KeepAliveTimer<I> {
789 at: I,
790 already_sent: u8,
791}
792
793impl<I: Instant> KeepAliveTimer<I> {
794 fn idle(now: I, keep_alive: &KeepAlive) -> Self {
795 let at = now.saturating_add(keep_alive.idle.into());
796 Self { at, already_sent: 0 }
797 }
798}
799
800impl<I: Instant> SendTimer<I> {
801 fn expiry(&self) -> I {
802 match self {
803 SendTimer::Retrans(RetransTimer {
804 at,
805 rto: _,
806 user_timeout_until: _,
807 remaining_retries: _,
808 })
809 | SendTimer::KeepAlive(KeepAliveTimer { at, already_sent: _ })
810 | SendTimer::ZeroWindowProbe(RetransTimer {
811 at,
812 rto: _,
813 user_timeout_until: _,
814 remaining_retries: _,
815 }) => *at,
816 SendTimer::SWSProbe { at } => *at,
817 }
818 }
819}
820
821impl<I: Instant> ReceiveTimer<I> {
822 fn expiry(&self) -> I {
823 match self {
824 ReceiveTimer::DelayedAck { at } => *at,
825 }
826 }
827}
828
829#[derive(Debug)]
831#[cfg_attr(test, derive(PartialEq, Eq))]
832enum RecvBufferState<R> {
833 Open { buffer: R, assembler: Assembler },
834 Closed { buffer_size: usize, nxt: SeqNum },
835}
836
837impl<R: ReceiveBuffer> RecvBufferState<R> {
838 fn is_closed(&self) -> bool {
839 matches!(self, Self::Closed { .. })
840 }
841
842 fn has_out_of_order(&self) -> bool {
843 match self {
844 Self::Open { assembler, .. } => assembler.has_out_of_order(),
845 Self::Closed { .. } => false,
846 }
847 }
848
849 fn close(&mut self) {
850 let new_state = match self {
851 Self::Open { buffer, assembler } => {
852 Self::Closed { nxt: assembler.nxt(), buffer_size: buffer.limits().capacity }
853 }
854 Self::Closed { .. } => return,
855 };
856 *self = new_state;
857 }
858
859 fn limits(&self) -> BufferLimits {
860 match self {
861 RecvBufferState::Open { buffer, .. } => buffer.limits(),
862 RecvBufferState::Closed { buffer_size, .. } => {
863 BufferLimits { capacity: *buffer_size, len: 0 }
864 }
865 }
866 }
867}
868
869fn quickack_counter(rcv_limits: BufferLimits, mss: Mss) -> usize {
871 const MIN_QUICKACK: usize = 2;
873 const MAX_QUICKACK: usize = 32;
877
878 let BufferLimits { capacity, len } = rcv_limits;
879 let window = capacity - len;
880 (window / (2 * usize::from(mss))).clamp(MIN_QUICKACK, MAX_QUICKACK)
891}
892
893#[derive(Debug)]
895#[cfg_attr(test, derive(PartialEq, Eq))]
896pub(crate) struct Recv<I, R> {
897 timer: Option<ReceiveTimer<I>>,
898 mss: Mss,
899 wnd_scale: WindowScale,
900 last_window_update: (SeqNum, WindowSize),
901 remaining_quickacks: usize,
902 last_segment_at: Option<I>,
903 sack_permitted: bool,
906
907 buffer: RecvBufferState<R>,
909}
910
911impl<I> Recv<I, ()> {
912 fn with_buffer<R>(self, buffer: R) -> Recv<I, R> {
913 let Self {
914 timer,
915 mss,
916 wnd_scale,
917 last_window_update,
918 buffer: old_buffer,
919 remaining_quickacks,
920 last_segment_at,
921 sack_permitted,
922 } = self;
923 let nxt = match old_buffer {
924 RecvBufferState::Open { assembler, .. } => assembler.nxt(),
925 RecvBufferState::Closed { .. } => unreachable!(),
926 };
927 Recv {
928 timer,
929 mss,
930 wnd_scale,
931 last_window_update,
932 remaining_quickacks,
933 last_segment_at,
934 buffer: RecvBufferState::Open { buffer, assembler: Assembler::new(nxt) },
935 sack_permitted,
936 }
937 }
938}
939
940impl<I, R> Recv<I, R> {
941 fn sack_blocks(&self) -> SackBlocks {
942 if self.sack_permitted {
943 match &self.buffer {
944 RecvBufferState::Open { buffer: _, assembler } => assembler.sack_blocks(),
945 RecvBufferState::Closed { buffer_size: _, nxt: _ } => SackBlocks::default(),
946 }
947 } else {
948 SackBlocks::default()
950 }
951 }
952}
953
954struct WindowSizeCalculation {
956 rcv_nxt: SeqNum,
959 window_size: WindowSize,
961 threshold: usize,
967}
968
969impl<I: Instant, R: ReceiveBuffer> Recv<I, R> {
970 fn calculate_window_size(&self) -> WindowSizeCalculation {
972 let rcv_nxt = self.nxt();
973 let Self {
974 buffer,
975 timer: _,
976 mss,
977 wnd_scale: _,
978 last_window_update: (rcv_wup, last_wnd),
979 remaining_quickacks: _,
980 last_segment_at: _,
981 sack_permitted: _,
982 } = self;
983
984 let BufferLimits { capacity, len } = buffer.limits();
996
997 let unused_window = u32::try_from(*rcv_wup + *last_wnd - rcv_nxt).unwrap_or(0);
1003 let unused_window = WindowSize::from_u32(unused_window).unwrap_or(WindowSize::MAX);
1005
1006 let reduction = capacity.saturating_sub(len.saturating_add(usize::from(unused_window)));
1010 let threshold = usize::min(capacity / 2, usize::from(mss.get().get()));
1011 let window_size = if reduction >= threshold {
1012 WindowSize::new(capacity - len).unwrap_or(WindowSize::MAX)
1014 } else {
1015 unused_window
1018 };
1019 WindowSizeCalculation { rcv_nxt, window_size, threshold }
1020 }
1021
1022 fn poll_receive_data_dequeued(&mut self, snd_max: SeqNum) -> Option<Segment<()>> {
1025 let WindowSizeCalculation { rcv_nxt, window_size: calculated_window_size, threshold } =
1026 self.calculate_window_size();
1027 let (rcv_wup, last_window_size) = self.last_window_update;
1028
1029 let rcv_diff = rcv_nxt - rcv_wup;
1035 debug_assert!(rcv_diff >= 0, "invalid RCV.NXT change: {rcv_nxt:?} < {rcv_wup:?}");
1036 let last_window_size =
1037 last_window_size.saturating_sub(usize::try_from(rcv_diff).unwrap_or(0));
1038
1039 let effective_window_size = (calculated_window_size >> self.wnd_scale) << self.wnd_scale;
1044 let effective_window_size_usize: usize = effective_window_size.into();
1047 let last_window_size_usize: usize = last_window_size.into();
1048
1049 if last_window_size_usize < threshold && effective_window_size_usize >= threshold {
1055 self.last_window_update = (rcv_nxt, calculated_window_size);
1056 self.timer = None;
1059 Some(Segment::ack(snd_max, self.nxt(), calculated_window_size >> self.wnd_scale))
1060 } else {
1061 None
1062 }
1063 }
1064
1065 pub(crate) fn nxt(&self) -> SeqNum {
1066 match &self.buffer {
1067 RecvBufferState::Open { assembler, .. } => assembler.nxt(),
1068 RecvBufferState::Closed { nxt, .. } => *nxt,
1069 }
1070 }
1071
1072 fn poll_send(&mut self, snd_max: SeqNum, now: I) -> Option<Segment<()>> {
1073 match self.timer {
1074 Some(ReceiveTimer::DelayedAck { at }) => (at <= now).then(|| {
1075 self.timer = None;
1076 self.make_ack(snd_max)
1077 }),
1078 None => None,
1079 }
1080 }
1081
1082 fn handle_fin(&self) -> RecvParams {
1084 let WindowSizeCalculation { rcv_nxt, window_size, threshold: _ } =
1085 self.calculate_window_size();
1086 RecvParams {
1087 ack: rcv_nxt + 1,
1088 wnd: window_size.checked_sub(1).unwrap_or(WindowSize::ZERO),
1089 wnd_scale: self.wnd_scale,
1090 }
1091 }
1092
1093 fn reset_quickacks(&mut self) {
1094 let Self {
1095 timer: _,
1096 mss,
1097 wnd_scale: _,
1098 last_window_update: _,
1099 remaining_quickacks,
1100 buffer,
1101 last_segment_at: _,
1102 sack_permitted: _,
1103 } = self;
1104 let new_remaining = quickack_counter(buffer.limits(), *mss);
1105 *remaining_quickacks = new_remaining.max(*remaining_quickacks);
1107 }
1108}
1109
1110impl<'a, I: Instant, R: ReceiveBuffer> RecvSegmentArgumentsProvider for &'a mut Recv<I, R> {
1111 fn take_rcv_segment_args(self) -> (SeqNum, UnscaledWindowSize, SackBlocks) {
1112 let WindowSizeCalculation { rcv_nxt, window_size, threshold: _ } =
1113 self.calculate_window_size();
1114 self.last_window_update = (rcv_nxt, window_size);
1115 (rcv_nxt, window_size >> self.wnd_scale, self.sack_blocks())
1116 }
1117}
1118
1119#[derive(Debug, Clone)]
1122#[cfg_attr(test, derive(PartialEq, Eq))]
1123pub(super) struct RecvParams {
1124 pub(super) ack: SeqNum,
1125 pub(super) wnd_scale: WindowScale,
1126 pub(super) wnd: WindowSize,
1127}
1128
1129impl<'a> RecvSegmentArgumentsProvider for &'a RecvParams {
1130 fn take_rcv_segment_args(self) -> (SeqNum, UnscaledWindowSize, SackBlocks) {
1131 (self.ack, self.wnd >> self.wnd_scale, SackBlocks::default())
1132 }
1133}
1134
1135struct CalculatedRecvParams<'a, I, R> {
1138 params: RecvParams,
1139 recv: Option<&'a mut Recv<I, R>>,
1140}
1141
1142impl<'a, I, R> CalculatedRecvParams<'a, I, R> {
1143 fn from_params(params: RecvParams) -> Self {
1148 Self { params, recv: None }
1149 }
1150
1151 fn nxt(&self) -> SeqNum {
1152 self.params.ack
1153 }
1154
1155 fn wnd(&self) -> WindowSize {
1156 self.params.wnd
1157 }
1158}
1159
1160impl<'a, I, R> RecvSegmentArgumentsProvider for CalculatedRecvParams<'a, I, R> {
1161 fn take_rcv_segment_args(self) -> (SeqNum, UnscaledWindowSize, SackBlocks) {
1162 let Self { params, recv } = self;
1163 let RecvParams { ack, wnd_scale, wnd } = params;
1164 let sack_blocks = if let Some(recv) = recv {
1165 recv.last_window_update = (ack, wnd);
1167 recv.sack_blocks()
1168 } else {
1169 SackBlocks::default()
1170 };
1171 (ack, wnd >> wnd_scale, sack_blocks)
1172 }
1173}
1174
1175impl<'a, I: Instant, R: ReceiveBuffer> CalculatedRecvParams<'a, I, R> {
1176 fn from_recv(recv: &'a mut Recv<I, R>) -> Self {
1177 let WindowSizeCalculation { rcv_nxt: ack, window_size: wnd, threshold: _ } =
1178 recv.calculate_window_size();
1179 let wnd_scale = recv.wnd_scale;
1180 Self { params: RecvParams { ack, wnd_scale, wnd }, recv: Some(recv) }
1181 }
1182}
1183
1184trait RecvSegmentArgumentsProvider: Sized {
1185 fn take_rcv_segment_args(self) -> (SeqNum, UnscaledWindowSize, SackBlocks);
1191
1192 fn make_segment<P, F: FnOnce(SeqNum, UnscaledWindowSize, SackBlocks) -> Segment<P>>(
1195 self,
1196 f: F,
1197 ) -> Segment<P> {
1198 let (ack, wnd, sack) = self.take_rcv_segment_args();
1199 f(ack, wnd, sack)
1200 }
1201
1202 fn make_ack<P: Payload>(self, seq: SeqNum) -> Segment<P> {
1205 let (ack, wnd, sack_blocks) = self.take_rcv_segment_args();
1206 Segment::ack_with_options(seq, ack, wnd, Options::Segment(SegmentOptions { sack_blocks }))
1207 }
1208}
1209
1210#[derive(Debug)]
1225#[cfg_attr(test, derive(PartialEq, Eq))]
1226pub struct Established<I, R, S> {
1227 pub(crate) snd: Takeable<Send<I, S, { FinQueued::NO }>>,
1228 pub(crate) rcv: Takeable<Recv<I, R>>,
1229}
1230
1231#[derive(Debug, Clone, Copy, PartialEq)]
1234pub(crate) enum DataAcked {
1235 Yes,
1236 No,
1237}
1238
1239impl<I: Instant, S: SendBuffer, const FIN_QUEUED: bool> Send<I, S, FIN_QUEUED> {
1240 fn timed_out(&self, now: I, keep_alive: &KeepAlive) -> bool {
1242 match self.timer {
1243 Some(SendTimer::KeepAlive(keep_alive_timer)) => {
1244 keep_alive.enabled && keep_alive_timer.already_sent >= keep_alive.count.get()
1245 }
1246 Some(SendTimer::Retrans(timer)) | Some(SendTimer::ZeroWindowProbe(timer)) => {
1247 timer.timed_out(now)
1248 }
1249 Some(SendTimer::SWSProbe { at: _ }) | None => false,
1250 }
1251 }
1252
1253 fn poll_send(
1259 &mut self,
1260 id: &impl StateMachineDebugId,
1261 counters: &TcpCountersRefs<'_>,
1262 rcv: impl RecvSegmentArgumentsProvider,
1263 limit: u32,
1264 now: I,
1265 SocketOptions {
1266 keep_alive,
1267 nagle_enabled,
1268 user_timeout,
1269 delayed_ack: _,
1270 fin_wait2_timeout: _,
1271 max_syn_retries: _,
1272 ip_options: _,
1273 }: &SocketOptions,
1274 ) -> Option<Segment<S::Payload<'_>>> {
1275 let Self {
1276 nxt: snd_nxt,
1277 max: snd_max,
1278 una: snd_una,
1279 wnd: snd_wnd,
1280 buffer,
1281 wl1: _,
1282 wl2: _,
1283 rtt_sampler,
1284 rtt_estimator,
1285 timer,
1286 congestion_control,
1287 wnd_scale: _,
1288 wnd_max: snd_wnd_max,
1289 } = self;
1290 let BufferLimits { capacity: _, len: readable_bytes } = buffer.limits();
1291 let mss = u32::from(congestion_control.mss());
1292 let mut zero_window_probe = false;
1293 let mut override_sws = false;
1294
1295 let increment_retransmit_counters = |congestion_control: &CongestionControl<I>| {
1296 counters.increment(|c| &c.retransmits);
1297 if congestion_control.in_fast_recovery() {
1298 counters.increment(|c| &c.fast_retransmits);
1299 }
1300 if congestion_control.in_slow_start() {
1301 counters.increment(|c| &c.slow_start_retransmits);
1302 }
1303 };
1304
1305 match timer {
1306 Some(SendTimer::Retrans(retrans_timer)) => {
1307 if retrans_timer.at <= now {
1308 *snd_nxt = *snd_una;
1320 retrans_timer.backoff(now);
1321 congestion_control.on_retransmission_timeout();
1322 counters.increment(|c| &c.timeouts);
1323 increment_retransmit_counters(congestion_control);
1324 }
1325 }
1326 Some(SendTimer::ZeroWindowProbe(retrans_timer)) => {
1327 debug_assert!(readable_bytes > 0 || FIN_QUEUED);
1328 if retrans_timer.at <= now {
1329 zero_window_probe = true;
1330 *snd_nxt = *snd_una;
1331 retrans_timer.backoff(now);
1335 }
1336 }
1337 Some(SendTimer::KeepAlive(KeepAliveTimer { at, already_sent })) => {
1338 if keep_alive.enabled && !FIN_QUEUED && readable_bytes == 0 {
1343 if *at <= now {
1344 *at = now.saturating_add(keep_alive.interval.into());
1345 *already_sent = already_sent.saturating_add(1);
1346 return Some(rcv.make_ack(*snd_max - 1));
1349 }
1350 } else {
1351 *timer = None;
1352 }
1353 }
1354 Some(SendTimer::SWSProbe { at }) => {
1355 if *at <= now {
1356 override_sws = true;
1357 *timer = None;
1358 }
1359 }
1360 None => {}
1361 };
1362
1363 if *snd_wnd == WindowSize::ZERO && readable_bytes > 0 {
1366 match timer {
1367 Some(SendTimer::ZeroWindowProbe(_)) => {}
1368 _ => {
1369 *timer = Some(SendTimer::ZeroWindowProbe(RetransTimer::new(
1370 now,
1371 rtt_estimator.rto(),
1372 *user_timeout,
1373 DEFAULT_MAX_RETRIES,
1374 )));
1375
1376 return None;
1385 }
1386 }
1387 }
1388
1389 let (next_seg, loss_recovery) = match congestion_control.fast_retransmit() {
1392 None => (*snd_nxt, false),
1393 Some(seg) => {
1394 increment_retransmit_counters(congestion_control);
1395 (seg, true)
1396 }
1397 };
1398 let unused_window =
1402 u32::try_from(*snd_una + *snd_wnd - next_seg).ok_checked::<TryFromIntError>()?;
1403 let cwnd = congestion_control.cwnd();
1404 let unused_congestion_window =
1406 u32::try_from(*snd_una + cwnd - next_seg).ok_checked::<TryFromIntError>()?;
1407 let offset =
1408 usize::try_from(next_seg - *snd_una).unwrap_or_else(|TryFromIntError { .. }| {
1409 panic!("next_seg({:?}) should never fall behind snd.una({:?})", *snd_nxt, *snd_una);
1410 });
1411 let available = u32::try_from(readable_bytes + usize::from(FIN_QUEUED) - offset)
1412 .unwrap_or_else(|_| WindowSize::MAX.into());
1413 let can_send = unused_window
1417 .min(unused_congestion_window)
1418 .min(available)
1419 .min(mss)
1420 .min(limit)
1421 .max(u32::from(zero_window_probe));
1422
1423 if can_send == 0 {
1424 if available == 0 && offset == 0 && timer.is_none() && keep_alive.enabled {
1425 *timer = Some(SendTimer::KeepAlive(KeepAliveTimer::idle(now, keep_alive)));
1426 }
1427 return None;
1428 }
1429
1430 let has_fin = FIN_QUEUED && can_send == available;
1431 let seg = buffer.peek_with(offset, |readable| {
1432 let bytes_to_send = u32::min(
1433 can_send - u32::from(has_fin),
1434 u32::try_from(readable.len()).unwrap_or(u32::MAX),
1435 );
1436 let has_fin = has_fin && bytes_to_send == can_send - u32::from(has_fin);
1437
1438 if bytes_to_send < mss && !has_fin && !loss_recovery {
1446 if bytes_to_send == 0 {
1447 return None;
1448 }
1449 if *nagle_enabled && snd_nxt.after(*snd_una) {
1457 return None;
1458 }
1459 if available > unused_window
1488 && unused_window < u32::min(mss, u32::from(*snd_wnd_max) / SWS_BUFFER_FACTOR)
1489 && !override_sws
1490 && !zero_window_probe
1491 {
1492 if timer.is_none() {
1493 *timer =
1494 Some(SendTimer::SWSProbe { at: now.panicking_add(SWS_PROBE_TIMEOUT) })
1495 }
1496 return None;
1497 }
1498 }
1499
1500 let seg = rcv.make_segment(|ack, wnd, mut sack_blocks| {
1501 let bytes_to_send = match sack_blocks.as_option() {
1502 Some(option) => {
1504 let options_len = u32::try_from(
1508 packet_formats::tcp::aligned_options_length(core::iter::once(option)),
1509 )
1510 .unwrap();
1511 if options_len < mss {
1512 bytes_to_send.min(mss - options_len)
1513 } else {
1514 sack_blocks.clear();
1522 bytes_to_send
1523 }
1524 }
1525 None => bytes_to_send,
1527 };
1528 let (seg, discarded) = Segment::with_data_options(
1529 next_seg,
1530 Some(ack),
1531 has_fin.then_some(Control::FIN),
1532 wnd,
1533 readable.slice(0..bytes_to_send),
1534 Options::Segment(SegmentOptions { sack_blocks }),
1535 );
1536 debug_assert_eq!(discarded, 0);
1537 seg
1538 });
1539 Some(seg)
1540 })?;
1541 trace_instant!(c"tcp::Send::poll_send/segment",
1542 "id" => id.trace_id(),
1543 "seq" => u32::from(next_seg),
1544 "len" => seg.len(),
1545 "can_send" => can_send,
1546 "snd_wnd" => u32::from(*snd_wnd),
1547 "cwnd" => u32::from(cwnd),
1548 "unused_window" => unused_window,
1549 "available" => available,
1550 );
1551 let seq_max = next_seg + seg.len();
1552 rtt_sampler.on_will_send_segment(now, next_seg..seq_max, *snd_max);
1553
1554 if seq_max.after(*snd_nxt) {
1555 *snd_nxt = seq_max;
1556 }
1557 if seq_max.after(*snd_max) {
1558 *snd_max = seq_max;
1559 }
1560 match timer {
1566 Some(SendTimer::Retrans(_)) | Some(SendTimer::ZeroWindowProbe(_)) => {}
1567 Some(SendTimer::KeepAlive(_)) | Some(SendTimer::SWSProbe { at: _ }) | None => {
1568 *timer = Some(SendTimer::Retrans(RetransTimer::new(
1569 now,
1570 rtt_estimator.rto(),
1571 *user_timeout,
1572 DEFAULT_MAX_RETRIES,
1573 )))
1574 }
1575 }
1576 Some(seg)
1577 }
1578
1579 fn process_ack<R: RecvSegmentArgumentsProvider>(
1582 &mut self,
1583 id: &impl StateMachineDebugId,
1584 counters: &TcpCountersRefs<'_>,
1585 seg_seq: SeqNum,
1586 seg_ack: SeqNum,
1587 seg_wnd: UnscaledWindowSize,
1588 seg_sack_blocks: &SackBlocks,
1589 pure_ack: bool,
1590 rcv: R,
1591 now: I,
1592 SocketOptions {
1593 keep_alive,
1594 nagle_enabled: _,
1595 user_timeout,
1596 delayed_ack: _,
1597 fin_wait2_timeout: _,
1598 max_syn_retries: _,
1599 ip_options: _,
1600 }: &SocketOptions,
1601 ) -> (Option<Segment<()>>, DataAcked) {
1602 let Self {
1603 nxt: snd_nxt,
1604 max: snd_max,
1605 una: snd_una,
1606 wnd: snd_wnd,
1607 wl1: snd_wl1,
1608 wl2: snd_wl2,
1609 wnd_max,
1610 buffer,
1611 rtt_sampler,
1612 rtt_estimator,
1613 timer,
1614 congestion_control,
1615 wnd_scale,
1616 } = self;
1617 let seg_wnd = seg_wnd << *wnd_scale;
1618 match timer {
1619 Some(SendTimer::KeepAlive(_)) | None => {
1620 if keep_alive.enabled {
1621 *timer = Some(SendTimer::KeepAlive(KeepAliveTimer::idle(now, keep_alive)));
1622 }
1623 }
1624 Some(SendTimer::Retrans(retrans_timer)) => {
1625 if seg_ack == *snd_max {
1633 *timer = None;
1634 } else if seg_ack.before(*snd_max) && seg_ack.after(*snd_una) {
1635 *retrans_timer = RetransTimer::new(
1636 now,
1637 rtt_estimator.rto(),
1638 *user_timeout,
1639 DEFAULT_MAX_RETRIES,
1640 );
1641 }
1642 }
1643 Some(SendTimer::ZeroWindowProbe(_)) | Some(SendTimer::SWSProbe { at: _ }) => {}
1644 }
1645 if seg_ack.after(*snd_max) {
1649 return (Some(rcv.make_ack(*snd_max)), DataAcked::No);
1654 }
1655
1656 if SACK_PERMITTED {
1659 let _is_dup_ack_by_sack =
1662 congestion_control.preprocess_ack(seg_ack, *snd_nxt, seg_sack_blocks);
1663 }
1664
1665 let (trace, data_acked) = if seg_ack.after(*snd_una) {
1666 let acked = u32::try_from(seg_ack - *snd_una)
1668 .ok_checked::<TryFromIntError>()
1669 .and_then(NonZeroU32::new)
1670 .unwrap_or_else(|| {
1671 panic!("seg_ack({:?}) - snd_una({:?}) must be positive", seg_ack, snd_una);
1672 });
1673 let BufferLimits { len, capacity: _ } = buffer.limits();
1674 let fin_acked = FIN_QUEUED && seg_ack == *snd_una + len + 1;
1675 buffer.mark_read(
1680 NonZeroUsize::try_from(acked)
1681 .unwrap_or_else(|TryFromIntError { .. }| {
1682 panic!(
1686 "acked({:?}) must be smaller than isize::MAX({:?})",
1687 acked,
1688 isize::MAX
1689 )
1690 })
1691 .get()
1692 - usize::from(fin_acked),
1693 );
1694 *snd_una = seg_ack;
1695 if seg_ack.after(*snd_nxt) {
1699 *snd_nxt = seg_ack;
1700 }
1701 if let Some(rtt) = rtt_sampler.on_ack(now, seg_ack) {
1704 rtt_estimator.sample(rtt);
1705 }
1706
1707 if let Some(rtt) = rtt_estimator.srtt() {
1713 congestion_control.on_ack(acked, now, rtt);
1714 }
1715
1716 (true, DataAcked::Yes)
1718 } else {
1719 let is_dup_ack = {
1729 snd_nxt.after(*snd_una) && pure_ack && seg_ack == *snd_una && seg_wnd == *snd_wnd };
1734 if is_dup_ack {
1735 let fast_recovery_initiated = congestion_control.on_dup_ack(seg_ack);
1736 if fast_recovery_initiated {
1737 counters.increment(|c| &c.fast_recovery);
1738 }
1739 }
1740 (is_dup_ack, DataAcked::No)
1744 };
1745
1746 if !snd_una.after(seg_ack)
1753 && (snd_wl1.before(seg_seq) || (seg_seq == *snd_wl1 && !snd_wl2.after(seg_ack)))
1754 {
1755 *snd_wnd = seg_wnd;
1756 *snd_wl1 = seg_seq;
1757 *snd_wl2 = seg_ack;
1758 *wnd_max = seg_wnd.max(*wnd_max);
1759 if seg_wnd != WindowSize::ZERO && matches!(timer, Some(SendTimer::ZeroWindowProbe(_))) {
1760 *timer = None;
1761 *snd_nxt = *snd_una;
1765 }
1766 }
1767
1768 if trace {
1770 trace_instant!(c"tcp::Send::process_ack",
1771 "id" => id.trace_id(),
1772 "seg_ack" => u32::from(seg_ack),
1773 "snd_nxt" => u32::from(*snd_nxt),
1774 "snd_wnd" => u32::from(*snd_wnd),
1775 "rtt_ms" => u32::try_from(
1776 rtt_estimator.srtt().unwrap_or(Duration::ZERO).as_millis()
1779 ).unwrap_or(u32::MAX),
1780 "cwnd" => u32::from(congestion_control.cwnd()),
1781 "ssthresh" => congestion_control.slow_start_threshold(),
1782 "fast_recovery" => congestion_control.in_fast_recovery(),
1783 "acked" => data_acked == DataAcked::Yes,
1784 );
1785 }
1786
1787 (None, data_acked)
1788 }
1789
1790 fn update_mss(&mut self, mss: Mss, seq: SeqNum) -> ShouldRetransmit {
1791 if mss >= self.congestion_control.mss() {
1803 return ShouldRetransmit::No;
1804 }
1805
1806 self.congestion_control.update_mss(mss);
1809
1810 self.nxt = seq;
1830
1831 ShouldRetransmit::Yes(mss)
1840 }
1841
1842 #[cfg(test)]
1843 pub(crate) fn congestion_control(&self) -> &CongestionControl<I> {
1844 &self.congestion_control
1845 }
1846}
1847
1848impl<I: Instant, S: SendBuffer> Send<I, S, { FinQueued::NO }> {
1849 fn queue_fin(self) -> Send<I, S, { FinQueued::YES }> {
1850 let Self {
1851 nxt,
1852 max,
1853 una,
1854 wnd,
1855 wl1,
1856 wl2,
1857 buffer,
1858 rtt_sampler,
1859 rtt_estimator,
1860 timer,
1861 congestion_control,
1862 wnd_scale,
1863 wnd_max,
1864 } = self;
1865 Send {
1866 nxt,
1867 max,
1868 una,
1869 wnd,
1870 wl1,
1871 wl2,
1872 buffer,
1873 rtt_sampler,
1874 rtt_estimator,
1875 timer,
1876 congestion_control,
1877 wnd_scale,
1878 wnd_max,
1879 }
1880 }
1881}
1882
1883#[derive(Debug)]
1897#[cfg_attr(test, derive(PartialEq, Eq))]
1898pub struct CloseWait<I, S> {
1899 snd: Takeable<Send<I, S, { FinQueued::NO }>>,
1900 closed_rcv: RecvParams,
1901}
1902
1903#[derive(Debug)]
1919#[cfg_attr(test, derive(PartialEq, Eq))]
1920pub struct LastAck<I, S> {
1921 snd: Send<I, S, { FinQueued::YES }>,
1922 closed_rcv: RecvParams,
1923}
1924
1925#[derive(Debug)]
1940#[cfg_attr(test, derive(PartialEq, Eq))]
1941pub struct FinWait1<I, R, S> {
1942 snd: Takeable<Send<I, S, { FinQueued::YES }>>,
1943 rcv: Takeable<Recv<I, R>>,
1944}
1945
1946#[derive(Debug)]
1947#[cfg_attr(test, derive(PartialEq, Eq))]
1948pub struct FinWait2<I, R> {
1962 last_seq: SeqNum,
1963 rcv: Recv<I, R>,
1964 timeout_at: Option<I>,
1965}
1966
1967#[derive(Debug)]
1968#[cfg_attr(test, derive(PartialEq, Eq))]
1969pub struct Closing<I, S> {
1983 snd: Send<I, S, { FinQueued::YES }>,
1984 closed_rcv: RecvParams,
1985}
1986
1987#[derive(Debug)]
2002#[cfg_attr(test, derive(PartialEq, Eq))]
2003pub struct TimeWait<I> {
2004 pub(super) last_seq: SeqNum,
2005 pub(super) expiry: I,
2006 pub(super) closed_rcv: RecvParams,
2007}
2008
2009fn new_time_wait_expiry<I: Instant>(now: I) -> I {
2010 now.panicking_add(MSL * 2)
2011}
2012
2013#[derive(Debug)]
2014#[cfg_attr(test, derive(PartialEq, Eq))]
2015pub enum State<I, R, S, ActiveOpen> {
2016 Closed(Closed<Option<ConnectionError>>),
2017 Listen(Listen),
2018 SynRcvd(SynRcvd<I, ActiveOpen>),
2019 SynSent(SynSent<I, ActiveOpen>),
2020 Established(Established<I, R, S>),
2021 CloseWait(CloseWait<I, S>),
2022 LastAck(LastAck<I, S>),
2023 FinWait1(FinWait1<I, R, S>),
2024 FinWait2(FinWait2<I, R>),
2025 Closing(Closing<I, S>),
2026 TimeWait(TimeWait<I>),
2027}
2028
2029impl<I, R, S, ActiveOpen> core::fmt::Display for State<I, R, S, ActiveOpen> {
2030 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
2031 let name = match self {
2032 State::Closed(_) => "Closed",
2033 State::Listen(_) => "Listen",
2034 State::SynRcvd(_) => "SynRcvd",
2035 State::SynSent(_) => "SynSent",
2036 State::Established(_) => "Established",
2037 State::CloseWait(_) => "CloseWait",
2038 State::LastAck(_) => "LastAck",
2039 State::FinWait1(_) => "FinWait1",
2040 State::FinWait2(_) => "FinWait2",
2041 State::Closing(_) => "Closing",
2042 State::TimeWait(_) => "TimeWait",
2043 };
2044 write!(f, "{name}")
2045 }
2046}
2047
2048#[derive(Debug, PartialEq, Eq)]
2049pub(super) enum CloseError {
2051 Closing,
2053 NoConnection,
2055}
2056
2057pub(crate) trait BufferProvider<R: ReceiveBuffer, S: SendBuffer> {
2060 type PassiveOpen;
2063
2064 type ActiveOpen: IntoBuffers<R, S>;
2067
2068 fn new_passive_open_buffers(buffer_sizes: BufferSizes) -> (R, S, Self::PassiveOpen);
2071}
2072
2073#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2085pub(crate) struct Takeable<T>(Option<T>);
2086
2087impl<T> From<T> for Takeable<T> {
2088 fn from(value: T) -> Self {
2089 Self(Some(value))
2090 }
2091}
2092
2093impl<T> Takeable<T> {
2094 pub(crate) fn get(&self) -> &T {
2095 let Self(i) = self;
2096 i.as_ref().expect("accessed taken takeable")
2097 }
2098
2099 pub(crate) fn get_mut(&mut self) -> &mut T {
2100 let Self(i) = self;
2101 i.as_mut().expect("accessed taken takeable")
2102 }
2103
2104 pub(crate) fn new(v: T) -> Self {
2105 Self(Some(v))
2106 }
2107
2108 pub(crate) fn to_ref(&mut self) -> TakeableRef<'_, T> {
2109 TakeableRef(self)
2110 }
2111
2112 pub(crate) fn from_ref(t: TakeableRef<'_, T>) -> Self {
2113 let TakeableRef(Self(t)) = t;
2114 Self(Some(t.take().expect("accessed taken takeable")))
2115 }
2116
2117 pub(crate) fn into_inner(self) -> T {
2118 let Self(i) = self;
2119 i.expect("accessed taken takeable")
2120 }
2121
2122 pub(crate) fn map<R, F: FnOnce(T) -> R>(self, f: F) -> Takeable<R> {
2123 Takeable(Some(f(self.into_inner())))
2124 }
2125}
2126
2127impl<T> Deref for Takeable<T> {
2128 type Target = T;
2129
2130 fn deref(&self) -> &Self::Target {
2131 self.get()
2132 }
2133}
2134
2135impl<T> DerefMut for Takeable<T> {
2136 fn deref_mut(&mut self) -> &mut Self::Target {
2137 self.get_mut()
2138 }
2139}
2140
2141pub(crate) struct TakeableRef<'a, T>(&'a mut Takeable<T>);
2143
2144impl<'a, T> TakeableRef<'a, T> {
2145 pub(crate) fn take(self) -> T {
2146 let Self(Takeable(t)) = self;
2147 t.take().expect("accessed taken takeable")
2148 }
2149
2150 pub(crate) fn to_takeable(self) -> Takeable<T> {
2151 Takeable::new(self.take())
2152 }
2153}
2154
2155#[must_use = "must check to determine if the socket needs to be removed from the demux state"]
2156#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2157pub(crate) enum NewlyClosed {
2158 No,
2159 Yes,
2160}
2161
2162pub(crate) enum ShouldRetransmit {
2163 No,
2164 Yes(Mss),
2165}
2166
2167impl<I: Instant + 'static, R: ReceiveBuffer, S: SendBuffer, ActiveOpen: Debug>
2168 State<I, R, S, ActiveOpen>
2169{
2170 fn transition_to_state(
2172 &mut self,
2173 counters: &TcpCountersRefs<'_>,
2174 new_state: State<I, R, S, ActiveOpen>,
2175 ) -> NewlyClosed {
2176 log::debug!("transition to state {} => {}", self, new_state);
2177 let newly_closed = if let State::Closed(Closed { reason }) = &new_state {
2178 let (was_established, was_closed) = match self {
2179 State::Closed(_) => (false, true),
2180 State::Listen(_) | State::SynRcvd(_) | State::SynSent(_) => (false, false),
2181 State::Established(_)
2182 | State::CloseWait(_)
2183 | State::LastAck(_)
2184 | State::FinWait1(_)
2185 | State::FinWait2(_)
2186 | State::Closing(_)
2187 | State::TimeWait(_) => (true, false),
2188 };
2189 if was_established {
2190 counters.increment(|c| &c.established_closed);
2191 match reason {
2192 Some(ConnectionError::ConnectionRefused)
2193 | Some(ConnectionError::ConnectionReset) => {
2194 counters.increment(|c| &c.established_resets);
2195 }
2196 Some(ConnectionError::TimedOut) => {
2197 counters.increment(|c| &c.established_timedout);
2198 }
2199 _ => {}
2200 }
2201 }
2202 (!was_closed).then_some(NewlyClosed::Yes).unwrap_or(NewlyClosed::No)
2203 } else {
2204 NewlyClosed::No
2205 };
2206 *self = new_state;
2207 newly_closed
2208 }
2209 pub(crate) fn on_segment<P: Payload, BP: BufferProvider<R, S, ActiveOpen = ActiveOpen>>(
2216 &mut self,
2217 id: &impl StateMachineDebugId,
2218 counters: &TcpCountersRefs<'_>,
2219 incoming: Segment<P>,
2220 now: I,
2221 options @ SocketOptions {
2222 keep_alive: _,
2223 nagle_enabled: _,
2224 user_timeout: _,
2225 delayed_ack,
2226 fin_wait2_timeout,
2227 max_syn_retries: _,
2228 ip_options: _,
2229 }: &SocketOptions,
2230 defunct: bool,
2231 ) -> (Option<Segment<()>>, Option<BP::PassiveOpen>, DataAcked, NewlyClosed)
2232 where
2233 BP::PassiveOpen: Debug,
2234 ActiveOpen: IntoBuffers<R, S>,
2235 {
2236 let mut passive_open = None;
2237 let mut data_acked = DataAcked::No;
2238 let (seg, newly_closed) = (|| {
2239 let (mut rcv, snd_max, rst_on_new_data) = match self {
2240 State::Closed(closed) => return (closed.on_segment(&incoming), NewlyClosed::No),
2241 State::Listen(listen) => {
2242 return (
2243 match listen.on_segment(incoming, now) {
2244 ListenOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
2245 syn_ack,
2246 SynRcvd {
2247 iss,
2248 irs,
2249 timestamp,
2250 retrans_timer,
2251 simultaneous_open,
2252 buffer_sizes,
2253 smss,
2254 rcv_wnd_scale,
2255 snd_wnd_scale,
2256 sack_permitted,
2257 },
2258 ) => {
2259 match simultaneous_open {
2260 None => {
2261 assert_eq!(
2262 self.transition_to_state(
2263 counters,
2264 State::SynRcvd(SynRcvd {
2265 iss,
2266 irs,
2267 timestamp,
2268 retrans_timer,
2269 simultaneous_open: None,
2270 buffer_sizes,
2271 smss,
2272 rcv_wnd_scale,
2273 snd_wnd_scale,
2274 sack_permitted,
2275 }),
2276 ),
2277 NewlyClosed::No
2278 )
2279 }
2280 }
2281 Some(syn_ack)
2282 }
2283 ListenOnSegmentDisposition::SendRst(rst) => Some(rst),
2284 ListenOnSegmentDisposition::Ignore => None,
2285 },
2286 NewlyClosed::No,
2287 );
2288 }
2289 State::SynSent(synsent) => {
2290 return match synsent.on_segment(incoming, now) {
2291 SynSentOnSegmentDisposition::SendAckAndEnterEstablished(established) => (
2292 replace_with_and(self, |this| {
2293 assert_matches!(this, State::SynSent(SynSent {
2294 active_open,
2295 buffer_sizes,
2296 ..
2297 }) => {
2298 let Established {snd, rcv} = established;
2299 let (rcv_buffer, snd_buffer) =
2300 active_open.into_buffers(buffer_sizes);
2301 let mut established = Established {
2302 snd: snd.map(|s| s.with_buffer(snd_buffer)),
2303 rcv: rcv.map(|s| s.with_buffer(rcv_buffer)),
2304 };
2305 let ack = Some(established.rcv.make_ack(established.snd.max));
2306 (State::Established(established), ack)
2307 })
2308 }),
2309 NewlyClosed::No,
2310 ),
2311 SynSentOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
2312 syn_ack,
2313 mut syn_rcvd,
2314 ) => {
2315 replace_with(self, |this| {
2316 assert_matches!(this, State::SynSent(SynSent {
2317 active_open,
2318 ..
2319 }) => {
2320 assert_matches!(syn_rcvd.simultaneous_open.replace(active_open), None);
2321 State::SynRcvd(syn_rcvd)
2322 })
2323 });
2324 (Some(syn_ack), NewlyClosed::No)
2325 }
2326 SynSentOnSegmentDisposition::SendRst(rst) => (Some(rst), NewlyClosed::No),
2327 SynSentOnSegmentDisposition::EnterClosed(closed) => {
2328 assert_eq!(
2329 self.transition_to_state(counters, State::Closed(closed)),
2330 NewlyClosed::Yes,
2331 );
2332 (None, NewlyClosed::Yes)
2333 }
2334 SynSentOnSegmentDisposition::Ignore => (None, NewlyClosed::No),
2335 }
2336 }
2337 State::SynRcvd(SynRcvd {
2338 iss,
2339 irs,
2340 timestamp: _,
2341 retrans_timer: _,
2342 simultaneous_open: _,
2343 buffer_sizes,
2344 smss: _,
2345 rcv_wnd_scale: _,
2346 snd_wnd_scale: _,
2347 sack_permitted: _,
2348 }) => {
2349 let advertised = buffer_sizes.rwnd_unscaled();
2353 (
2354 CalculatedRecvParams::from_params(RecvParams {
2355 ack: *irs + 1,
2356 wnd: advertised << WindowScale::default(),
2357 wnd_scale: WindowScale::default(),
2358 }),
2359 *iss + 1,
2360 false,
2361 )
2362 }
2363 State::Established(Established { rcv, snd }) => {
2364 (CalculatedRecvParams::from_recv(rcv.get_mut()), snd.max, false)
2365 }
2366 State::CloseWait(CloseWait { snd, closed_rcv }) => {
2367 (CalculatedRecvParams::from_params(closed_rcv.clone()), snd.max, true)
2368 }
2369 State::LastAck(LastAck { snd, closed_rcv })
2370 | State::Closing(Closing { snd, closed_rcv }) => {
2371 (CalculatedRecvParams::from_params(closed_rcv.clone()), snd.max, true)
2372 }
2373 State::FinWait1(FinWait1 { rcv, snd }) => {
2374 let closed = rcv.buffer.is_closed();
2375 (CalculatedRecvParams::from_recv(rcv.get_mut()), snd.max, closed)
2376 }
2377 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _ }) => {
2378 let closed = rcv.buffer.is_closed();
2379 (CalculatedRecvParams::from_recv(rcv), *last_seq, closed)
2380 }
2381 State::TimeWait(TimeWait { last_seq, expiry: _, closed_rcv }) => {
2382 (CalculatedRecvParams::from_params(closed_rcv.clone()), *last_seq, true)
2383 }
2384 };
2385
2386 if rst_on_new_data && (incoming.header.seq + incoming.data.len()).after(rcv.nxt()) {
2389 return (
2390 Some(Segment::rst(snd_max)),
2391 self.transition_to_state(
2392 counters,
2393 State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }),
2394 ),
2395 );
2396 }
2397
2398 let is_rst = incoming.header.control == Some(Control::RST);
2404 let pure_ack = incoming.len() == 0;
2406 let needs_ack = !pure_ack;
2407 let Segment {
2408 header:
2409 SegmentHeader {
2410 seq: seg_seq,
2411 ack: seg_ack,
2412 wnd: seg_wnd,
2413 control,
2414 options: seg_options,
2415 },
2416 data,
2417 } = match incoming.overlap(rcv.nxt(), rcv.wnd()) {
2418 Some(incoming) => incoming,
2419 None => {
2420 let segment = if is_rst {
2428 None
2429 } else {
2430 if let Some(recv) = rcv.recv.as_mut() {
2431 recv.reset_quickacks();
2434 }
2435 Some(rcv.make_ack(snd_max))
2436 };
2437
2438 return (segment, NewlyClosed::No);
2439 }
2440 };
2441 if control == Some(Control::RST) {
2449 return (
2450 None,
2451 self.transition_to_state(
2452 counters,
2453 State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }),
2454 ),
2455 );
2456 }
2457 if control == Some(Control::SYN) {
2468 return (
2469 Some(Segment::rst(snd_max)),
2470 self.transition_to_state(
2471 counters,
2472 State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }),
2473 ),
2474 );
2475 }
2476 match seg_ack {
2479 Some(seg_ack) => match self {
2480 State::Closed(_) | State::Listen(_) | State::SynSent(_) => {
2481 unreachable!("encountered an already-handled state: {:?}", self)
2483 }
2484 State::SynRcvd(SynRcvd {
2485 iss,
2486 irs,
2487 timestamp: syn_rcvd_ts,
2488 retrans_timer: _,
2489 simultaneous_open,
2490 buffer_sizes,
2491 smss,
2492 rcv_wnd_scale,
2493 snd_wnd_scale,
2494 sack_permitted,
2495 }) => {
2496 if seg_ack != *iss + 1 {
2509 return (Some(Segment::rst(seg_ack)), NewlyClosed::No);
2510 } else {
2511 let mut rtt_estimator = Estimator::default();
2512 if let Some(syn_rcvd_ts) = syn_rcvd_ts {
2513 rtt_estimator.sample(now.saturating_duration_since(*syn_rcvd_ts));
2514 }
2515 let (rcv_buffer, snd_buffer) = match simultaneous_open.take() {
2516 None => {
2517 let (rcv_buffer, snd_buffer, client) =
2518 BP::new_passive_open_buffers(*buffer_sizes);
2519 assert_matches!(passive_open.replace(client), None);
2520 (rcv_buffer, snd_buffer)
2521 }
2522 Some(active_open) => active_open.into_buffers(*buffer_sizes),
2523 };
2524 let (snd_wnd_scale, rcv_wnd_scale) = snd_wnd_scale
2525 .map(|snd_wnd_scale| (snd_wnd_scale, *rcv_wnd_scale))
2526 .unwrap_or_default();
2527 let established = Established {
2528 snd: Send {
2529 nxt: *iss + 1,
2530 max: *iss + 1,
2531 una: seg_ack,
2532 wnd: seg_wnd << snd_wnd_scale,
2533 wl1: seg_seq,
2534 wl2: seg_ack,
2535 buffer: snd_buffer,
2536 rtt_sampler: RttSampler::default(),
2537 rtt_estimator,
2538 timer: None,
2539 congestion_control: CongestionControl::cubic_with_mss(*smss),
2540 wnd_scale: snd_wnd_scale,
2541 wnd_max: seg_wnd << snd_wnd_scale,
2542 }
2543 .into(),
2544 rcv: Recv {
2545 buffer: RecvBufferState::Open {
2546 buffer: rcv_buffer,
2547 assembler: Assembler::new(*irs + 1),
2548 },
2549 timer: None,
2550 mss: *smss,
2551 wnd_scale: rcv_wnd_scale,
2552 last_segment_at: None,
2553 remaining_quickacks: quickack_counter(
2554 buffer_sizes.rcv_limits(),
2555 *smss,
2556 ),
2557 last_window_update: (*irs + 1, buffer_sizes.rwnd()),
2558 sack_permitted: *sack_permitted,
2559 }
2560 .into(),
2561 };
2562 assert_eq!(
2563 self.transition_to_state(counters, State::Established(established)),
2564 NewlyClosed::No
2565 );
2566 }
2567 }
2571 State::Established(Established { snd, rcv }) => {
2572 let (ack, segment_acked_data) = snd.process_ack(
2573 id,
2574 counters,
2575 seg_seq,
2576 seg_ack,
2577 seg_wnd,
2578 seg_options.sack_blocks(),
2579 pure_ack,
2580 rcv.get_mut(),
2581 now,
2582 options,
2583 );
2584 data_acked = segment_acked_data;
2585 if let Some(ack) = ack {
2586 return (Some(ack), NewlyClosed::No);
2587 }
2588 }
2589 State::CloseWait(CloseWait { snd, closed_rcv }) => {
2590 let (ack, segment_acked_data) = snd.process_ack(
2591 id,
2592 counters,
2593 seg_seq,
2594 seg_ack,
2595 seg_wnd,
2596 seg_options.sack_blocks(),
2597 pure_ack,
2598 &*closed_rcv,
2599 now,
2600 options,
2601 );
2602 data_acked = segment_acked_data;
2603 if let Some(ack) = ack {
2604 return (Some(ack), NewlyClosed::No);
2605 }
2606 }
2607 State::LastAck(LastAck { snd, closed_rcv }) => {
2608 let BufferLimits { len, capacity: _ } = snd.buffer.limits();
2609 let fin_seq = snd.una + len + 1;
2610 let (ack, segment_acked_data) = snd.process_ack(
2611 id,
2612 counters,
2613 seg_seq,
2614 seg_ack,
2615 seg_wnd,
2616 seg_options.sack_blocks(),
2617 pure_ack,
2618 &*closed_rcv,
2619 now,
2620 options,
2621 );
2622 data_acked = segment_acked_data;
2623 if let Some(ack) = ack {
2624 return (Some(ack), NewlyClosed::No);
2625 } else if seg_ack == fin_seq {
2626 return (
2627 None,
2628 self.transition_to_state(
2629 counters,
2630 State::Closed(Closed { reason: None }),
2631 ),
2632 );
2633 }
2634 }
2635 State::FinWait1(FinWait1 { snd, rcv }) => {
2636 let BufferLimits { len, capacity: _ } = snd.buffer.limits();
2637 let fin_seq = snd.una + len + 1;
2638 let (ack, segment_acked_data) = snd.process_ack(
2639 id,
2640 counters,
2641 seg_seq,
2642 seg_ack,
2643 seg_wnd,
2644 seg_options.sack_blocks(),
2645 pure_ack,
2646 rcv.get_mut(),
2647 now,
2648 options,
2649 );
2650 data_acked = segment_acked_data;
2651 if let Some(ack) = ack {
2652 return (Some(ack), NewlyClosed::No);
2653 } else if seg_ack == fin_seq {
2654 let last_seq = snd.nxt;
2660 let finwait2 = FinWait2 {
2661 last_seq,
2662 rcv: rcv.to_ref().take(),
2663 timeout_at: fin_wait2_timeout.and_then(|timeout| {
2667 defunct.then_some(now.saturating_add(timeout))
2668 }),
2669 };
2670 assert_eq!(
2671 self.transition_to_state(counters, State::FinWait2(finwait2)),
2672 NewlyClosed::No
2673 );
2674 }
2675 }
2676 State::Closing(Closing { snd, closed_rcv }) => {
2677 let BufferLimits { len, capacity: _ } = snd.buffer.limits();
2678 let fin_seq = snd.una + len + 1;
2679 let (ack, segment_acked_data) = snd.process_ack(
2680 id,
2681 counters,
2682 seg_seq,
2683 seg_ack,
2684 seg_wnd,
2685 seg_options.sack_blocks(),
2686 pure_ack,
2687 &*closed_rcv,
2688 now,
2689 options,
2690 );
2691 data_acked = segment_acked_data;
2692 if let Some(ack) = ack {
2693 data_acked = segment_acked_data;
2694 return (Some(ack), NewlyClosed::No);
2695 } else if seg_ack == fin_seq {
2696 let timewait = TimeWait {
2701 last_seq: snd.nxt,
2702 expiry: new_time_wait_expiry(now),
2703 closed_rcv: closed_rcv.clone(),
2704 };
2705 assert_eq!(
2706 self.transition_to_state(counters, State::TimeWait(timewait)),
2707 NewlyClosed::No
2708 );
2709 }
2710 }
2711 State::FinWait2(_) | State::TimeWait(_) => {}
2712 },
2713 None => return (None, NewlyClosed::No),
2716 }
2717 let maybe_ack_to_text = |rcv: &mut Recv<I, R>, rto: Rto| {
2739 if !needs_ack {
2740 return (None, rcv.nxt());
2741 }
2742
2743 if let Some(last) = rcv.last_segment_at.replace(now) {
2747 if now.saturating_duration_since(last) >= rto.get() {
2748 rcv.reset_quickacks();
2749 }
2750 }
2751
2752 let had_out_of_order = rcv.buffer.has_out_of_order();
2755 if data.len() > 0 {
2756 let offset = usize::try_from(seg_seq - rcv.nxt()).unwrap_or_else(|TryFromIntError {..}| {
2757 panic!("The segment was trimmed to fit the window, thus seg.seq({:?}) must not come before rcv.nxt({:?})", seg_seq, rcv.nxt());
2758 });
2759 match &mut rcv.buffer {
2760 RecvBufferState::Open { buffer, assembler } => {
2761 let nwritten = buffer.write_at(offset, &data);
2762 let readable = assembler.insert(seg_seq..seg_seq + nwritten);
2763 buffer.make_readable(readable, assembler.has_outstanding());
2764 }
2765 RecvBufferState::Closed { nxt, .. } => *nxt = seg_seq + data.len(),
2766 }
2767 }
2768 let immediate_ack = !*delayed_ack
2774 || had_out_of_order
2775 || rcv.buffer.has_out_of_order()
2776 || rcv.remaining_quickacks != 0
2778 || rcv.timer.is_some();
2803
2804 if immediate_ack {
2805 rcv.timer = None;
2806 } else {
2807 rcv.timer = Some(ReceiveTimer::DelayedAck {
2808 at: now.panicking_add(ACK_DELAY_THRESHOLD),
2809 });
2810 }
2811 let segment =
2812 (!matches!(rcv.timer, Some(ReceiveTimer::DelayedAck { .. }))).then(|| {
2813 rcv.remaining_quickacks = rcv.remaining_quickacks.saturating_sub(1);
2814 rcv.make_ack(snd_max)
2815 });
2816 (segment, rcv.nxt())
2817 };
2818
2819 let (ack_to_text, rcv_nxt) = match self {
2820 State::Closed(_) | State::Listen(_) | State::SynRcvd(_) | State::SynSent(_) => {
2821 unreachable!("encountered an already-handled state: {:?}", self)
2823 }
2824 State::Established(Established { snd, rcv }) => {
2825 maybe_ack_to_text(rcv.get_mut(), snd.rtt_estimator.rto())
2826 }
2827 State::FinWait1(FinWait1 { snd, rcv }) => {
2828 maybe_ack_to_text(rcv.get_mut(), snd.rtt_estimator.rto())
2829 }
2830 State::FinWait2(FinWait2 { last_seq: _, rcv, timeout_at: _ }) => {
2831 maybe_ack_to_text(rcv, Rto::DEFAULT)
2832 }
2833 State::CloseWait(CloseWait { closed_rcv, .. })
2834 | State::LastAck(LastAck { closed_rcv, .. })
2835 | State::Closing(Closing { closed_rcv, .. })
2836 | State::TimeWait(TimeWait { closed_rcv, .. }) => {
2837 (None, closed_rcv.ack)
2841 }
2842 };
2843 let ack_to_fin = if control == Some(Control::FIN) && rcv_nxt == seg_seq + data.len() {
2846 match self {
2851 State::Closed(_) | State::Listen(_) | State::SynRcvd(_) | State::SynSent(_) => {
2852 unreachable!("encountered an already-handled state: {:?}", self)
2854 }
2855 State::Established(Established { snd, rcv }) => {
2856 let params = rcv.handle_fin();
2859 let segment = params.make_ack(snd_max);
2860 let closewait =
2861 CloseWait { snd: snd.to_ref().to_takeable(), closed_rcv: params };
2862 assert_eq!(
2863 self.transition_to_state(counters, State::CloseWait(closewait)),
2864 NewlyClosed::No
2865 );
2866 Some(segment)
2867 }
2868 State::CloseWait(_) | State::LastAck(_) | State::Closing(_) => {
2869 None
2877 }
2878 State::FinWait1(FinWait1 { snd, rcv }) => {
2879 let params = rcv.handle_fin();
2880 let segment = params.make_ack(snd_max);
2881 let closing = Closing { snd: snd.to_ref().take(), closed_rcv: params };
2882 assert_eq!(
2883 self.transition_to_state(counters, State::Closing(closing)),
2884 NewlyClosed::No
2885 );
2886 Some(segment)
2887 }
2888 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _ }) => {
2889 let params = rcv.handle_fin();
2890 let segment = params.make_ack(snd_max);
2891 let timewait = TimeWait {
2892 last_seq: *last_seq,
2893 expiry: new_time_wait_expiry(now),
2894 closed_rcv: params,
2895 };
2896 assert_eq!(
2897 self.transition_to_state(counters, State::TimeWait(timewait)),
2898 NewlyClosed::No,
2899 );
2900 Some(segment)
2901 }
2902 State::TimeWait(TimeWait { last_seq, expiry, closed_rcv }) => {
2903 *expiry = new_time_wait_expiry(now);
2908 Some(closed_rcv.make_ack(*last_seq))
2909 }
2910 }
2911 } else {
2912 None
2913 };
2914 (ack_to_fin.or(ack_to_text), NewlyClosed::No)
2917 })();
2918 (seg, passive_open, data_acked, newly_closed)
2919 }
2920
2921 pub(crate) fn poll_receive_data_dequeued(&mut self) -> Option<Segment<()>> {
2925 let (rcv, snd_max) = match self {
2926 State::Closed(_)
2927 | State::Listen(_)
2928 | State::SynRcvd(_)
2929 | State::SynSent(_)
2930 | State::CloseWait(_)
2931 | State::LastAck(_)
2932 | State::Closing(_)
2933 | State::TimeWait(_) => return None,
2934 State::Established(Established { snd, rcv }) => (rcv.get_mut(), snd.max),
2935 State::FinWait1(FinWait1 { snd, rcv }) => (rcv.get_mut(), snd.max),
2936 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _ }) => (rcv, *last_seq),
2937 };
2938
2939 rcv.poll_receive_data_dequeued(snd_max)
2940 }
2941
2942 pub(crate) fn poll_send(
2950 &mut self,
2951 id: &impl StateMachineDebugId,
2952 counters: &TcpCountersRefs<'_>,
2953 limit: u32,
2954 now: I,
2955 socket_options: &SocketOptions,
2956 ) -> Result<Segment<S::Payload<'_>>, NewlyClosed> {
2957 let newly_closed = self.poll_close(counters, now, socket_options);
2958 if matches!(self, State::Closed(_)) {
2959 return Err(newly_closed);
2960 }
2961 fn poll_rcv_then_snd<
2962 'a,
2963 I: Instant,
2964 R: ReceiveBuffer,
2965 S: SendBuffer,
2966 M: StateMachineDebugId,
2967 const FIN_QUEUED: bool,
2968 >(
2969 id: &M,
2970 counters: &TcpCountersRefs<'_>,
2971 snd: &'a mut Send<I, S, FIN_QUEUED>,
2972 rcv: &'a mut Recv<I, R>,
2973 limit: u32,
2974 now: I,
2975 socket_options: &SocketOptions,
2976 ) -> Option<Segment<S::Payload<'a>>> {
2977 let seg = rcv
2983 .poll_send(snd.max, now)
2984 .map(|seg| seg.into_empty())
2985 .or_else(|| snd.poll_send(id, counters, &mut *rcv, limit, now, socket_options));
2986 if seg.is_some() && matches!(rcv.timer, Some(ReceiveTimer::DelayedAck { .. })) {
2988 rcv.timer = None;
2989 }
2990 seg
2991 }
2992 let seg = match self {
2993 State::SynSent(SynSent {
2994 iss,
2995 timestamp,
2996 retrans_timer,
2997 active_open: _,
2998 buffer_sizes: _,
2999 device_mss,
3000 default_mss: _,
3001 rcv_wnd_scale,
3002 }) => (retrans_timer.at <= now).then(|| {
3003 *timestamp = None;
3004 retrans_timer.backoff(now);
3005 Segment::syn(
3006 *iss,
3007 UnscaledWindowSize::from(u16::MAX),
3008 HandshakeOptions {
3009 mss: Some(*device_mss),
3010 window_scale: Some(*rcv_wnd_scale),
3011 sack_permitted: SACK_PERMITTED,
3012 }
3013 .into(),
3014 )
3015 }),
3016 State::SynRcvd(SynRcvd {
3017 iss,
3018 irs,
3019 timestamp,
3020 retrans_timer,
3021 simultaneous_open: _,
3022 buffer_sizes: _,
3023 smss,
3024 rcv_wnd_scale,
3025 snd_wnd_scale,
3026 sack_permitted: _,
3027 }) => (retrans_timer.at <= now).then(|| {
3028 *timestamp = None;
3029 retrans_timer.backoff(now);
3030 Segment::syn_ack(
3031 *iss,
3032 *irs + 1,
3033 UnscaledWindowSize::from(u16::MAX),
3034 HandshakeOptions {
3035 mss: Some(*smss),
3036 window_scale: snd_wnd_scale.map(|_| *rcv_wnd_scale),
3037 sack_permitted: SACK_PERMITTED,
3038 }
3039 .into(),
3040 )
3041 }),
3042 State::Established(Established { snd, rcv }) => {
3043 poll_rcv_then_snd(id, counters, snd, rcv, limit, now, socket_options)
3044 }
3045 State::CloseWait(CloseWait { snd, closed_rcv }) => {
3046 snd.poll_send(id, counters, &*closed_rcv, limit, now, socket_options)
3047 }
3048 State::LastAck(LastAck { snd, closed_rcv })
3049 | State::Closing(Closing { snd, closed_rcv }) => {
3050 snd.poll_send(id, counters, &*closed_rcv, limit, now, socket_options)
3051 }
3052 State::FinWait1(FinWait1 { snd, rcv }) => {
3053 poll_rcv_then_snd(id, counters, snd, rcv, limit, now, socket_options)
3054 }
3055 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _ }) => {
3056 rcv.poll_send(*last_seq, now).map(|seg| seg.into_empty())
3057 }
3058 State::Closed(_) | State::Listen(_) | State::TimeWait(_) => None,
3059 };
3060 seg.ok_or(NewlyClosed::No)
3061 }
3062
3063 fn poll_close(
3067 &mut self,
3068 counters: &TcpCountersRefs<'_>,
3069 now: I,
3070 SocketOptions {
3071 keep_alive,
3072 nagle_enabled: _,
3073 user_timeout: _,
3074 delayed_ack: _,
3075 fin_wait2_timeout: _,
3076 max_syn_retries: _,
3077 ip_options: _,
3078 }: &SocketOptions,
3079 ) -> NewlyClosed {
3080 let timed_out = match self {
3081 State::Established(Established { snd, rcv: _ }) => snd.timed_out(now, keep_alive),
3082 State::CloseWait(CloseWait { snd, closed_rcv: _ }) => snd.timed_out(now, keep_alive),
3083 State::LastAck(LastAck { snd, closed_rcv: _ })
3084 | State::Closing(Closing { snd, closed_rcv: _ }) => snd.timed_out(now, keep_alive),
3085 State::FinWait1(FinWait1 { snd, rcv: _ }) => snd.timed_out(now, keep_alive),
3086 State::SynSent(SynSent {
3087 iss: _,
3088 timestamp: _,
3089 retrans_timer,
3090 active_open: _,
3091 buffer_sizes: _,
3092 device_mss: _,
3093 default_mss: _,
3094 rcv_wnd_scale: _,
3095 })
3096 | State::SynRcvd(SynRcvd {
3097 iss: _,
3098 irs: _,
3099 timestamp: _,
3100 retrans_timer,
3101 simultaneous_open: _,
3102 buffer_sizes: _,
3103 smss: _,
3104 rcv_wnd_scale: _,
3105 snd_wnd_scale: _,
3106 sack_permitted: _,
3107 }) => retrans_timer.timed_out(now),
3108
3109 State::Closed(_) | State::Listen(_) | State::TimeWait(_) => false,
3110 State::FinWait2(FinWait2 { last_seq: _, rcv: _, timeout_at }) => {
3111 timeout_at.map(|at| now >= at).unwrap_or(false)
3112 }
3113 };
3114 if timed_out {
3115 return self.transition_to_state(
3116 counters,
3117 State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }),
3118 );
3119 } else if let State::TimeWait(tw) = self {
3120 if tw.expiry <= now {
3121 return self.transition_to_state(counters, State::Closed(Closed { reason: None }));
3122 }
3123 }
3124 NewlyClosed::No
3125 }
3126
3127 pub(crate) fn poll_send_at(&self) -> Option<I> {
3146 let combine_expiry = |e1: Option<I>, e2: Option<I>| match (e1, e2) {
3147 (None, None) => None,
3148 (None, Some(e2)) => Some(e2),
3149 (Some(e1), None) => Some(e1),
3150 (Some(e1), Some(e2)) => Some(e1.min(e2)),
3151 };
3152 match self {
3153 State::Established(Established { snd, rcv }) => combine_expiry(
3154 snd.timer.as_ref().map(SendTimer::expiry),
3155 rcv.timer.as_ref().map(ReceiveTimer::expiry),
3156 ),
3157 State::CloseWait(CloseWait { snd, closed_rcv: _ }) => Some(snd.timer?.expiry()),
3158 State::LastAck(LastAck { snd, closed_rcv: _ })
3159 | State::Closing(Closing { snd, closed_rcv: _ }) => Some(snd.timer?.expiry()),
3160 State::FinWait1(FinWait1 { snd, rcv }) => combine_expiry(
3161 snd.timer.as_ref().map(SendTimer::expiry),
3162 rcv.timer.as_ref().map(ReceiveTimer::expiry),
3163 ),
3164 State::FinWait2(FinWait2 { last_seq: _, rcv, timeout_at }) => {
3165 combine_expiry(*timeout_at, rcv.timer.as_ref().map(ReceiveTimer::expiry))
3166 }
3167 State::SynRcvd(syn_rcvd) => Some(syn_rcvd.retrans_timer.at),
3168 State::SynSent(syn_sent) => Some(syn_sent.retrans_timer.at),
3169 State::Closed(_) | State::Listen(_) => None,
3170 State::TimeWait(TimeWait { last_seq: _, expiry, closed_rcv: _ }) => Some(*expiry),
3171 }
3172 }
3173
3174 pub(super) fn close(
3181 &mut self,
3182 counters: &TcpCountersRefs<'_>,
3183 close_reason: CloseReason<I>,
3184 socket_options: &SocketOptions,
3185 ) -> Result<NewlyClosed, CloseError>
3186 where
3187 ActiveOpen: IntoBuffers<R, S>,
3188 {
3189 match self {
3190 State::Closed(_) => Err(CloseError::NoConnection),
3191 State::Listen(_) | State::SynSent(_) => {
3192 Ok(self.transition_to_state(counters, State::Closed(Closed { reason: None })))
3193 }
3194 State::SynRcvd(SynRcvd {
3195 iss,
3196 irs,
3197 timestamp: _,
3198 retrans_timer: _,
3199 simultaneous_open,
3200 buffer_sizes,
3201 smss,
3202 rcv_wnd_scale,
3203 snd_wnd_scale,
3204 sack_permitted,
3205 }) => {
3206 let (rcv_buffer, snd_buffer) = simultaneous_open
3226 .take()
3227 .expect(
3228 "a SYN-RCVD state that is in the pending queue \
3229 should call abort instead of close",
3230 )
3231 .into_buffers(*buffer_sizes);
3232 let (snd_wnd_scale, rcv_wnd_scale) = snd_wnd_scale
3236 .map(|snd_wnd_scale| (snd_wnd_scale, *rcv_wnd_scale))
3237 .unwrap_or_default();
3238 let finwait1 = FinWait1 {
3239 snd: Send {
3240 nxt: *iss + 1,
3241 max: *iss + 1,
3242 una: *iss + 1,
3243 wnd: WindowSize::DEFAULT,
3244 wl1: *iss,
3245 wl2: *irs,
3246 buffer: snd_buffer,
3247 rtt_sampler: RttSampler::default(),
3248 rtt_estimator: Estimator::NoSample,
3249 timer: None,
3250 congestion_control: CongestionControl::cubic_with_mss(*smss),
3251 wnd_scale: snd_wnd_scale,
3252 wnd_max: WindowSize::DEFAULT,
3253 }
3254 .into(),
3255 rcv: Recv {
3256 buffer: RecvBufferState::Open {
3257 buffer: rcv_buffer,
3258 assembler: Assembler::new(*irs + 1),
3259 },
3260 timer: None,
3261 mss: *smss,
3262 remaining_quickacks: quickack_counter(buffer_sizes.rcv_limits(), *smss),
3263 last_segment_at: None,
3264 wnd_scale: rcv_wnd_scale,
3265 last_window_update: (*irs + 1, buffer_sizes.rwnd()),
3266 sack_permitted: *sack_permitted,
3267 }
3268 .into(),
3269 };
3270 Ok(self.transition_to_state(counters, State::FinWait1(finwait1)))
3271 }
3272 State::Established(Established { snd, rcv }) => {
3273 let finwait1 = FinWait1 {
3279 snd: snd.to_ref().take().queue_fin().into(),
3280 rcv: rcv.to_ref().to_takeable(),
3281 };
3282 Ok(self.transition_to_state(counters, State::FinWait1(finwait1)))
3283 }
3284 State::CloseWait(CloseWait { snd, closed_rcv }) => {
3285 let lastack = LastAck {
3286 snd: snd.to_ref().take().queue_fin(),
3287 closed_rcv: closed_rcv.clone(),
3288 };
3289 Ok(self.transition_to_state(counters, State::LastAck(lastack)))
3290 }
3291 State::LastAck(_) | State::FinWait1(_) | State::Closing(_) | State::TimeWait(_) => {
3292 Err(CloseError::Closing)
3293 }
3294 State::FinWait2(FinWait2 { last_seq: _, rcv: _, timeout_at }) => {
3295 if let (CloseReason::Close { now }, Some(fin_wait2_timeout)) =
3296 (close_reason, socket_options.fin_wait2_timeout)
3297 {
3298 assert_eq!(timeout_at.replace(now.saturating_add(fin_wait2_timeout)), None);
3299 }
3300 Err(CloseError::Closing)
3301 }
3302 }
3303 }
3304
3305 pub(super) fn shutdown_recv(&mut self) -> Result<(), CloseError> {
3306 match self {
3307 State::Closed(_) => Err(CloseError::NoConnection),
3308
3309 State::Listen(_)
3310 | State::SynSent(_)
3311 | State::SynRcvd(_)
3312 | State::CloseWait(_)
3313 | State::LastAck(_)
3314 | State::Closing(_)
3315 | State::TimeWait(_) => Ok(()),
3316
3317 State::Established(Established { rcv, .. }) | State::FinWait1(FinWait1 { rcv, .. }) => {
3319 rcv.buffer.close();
3320 Ok(())
3321 }
3322 State::FinWait2(FinWait2 { rcv, .. }) => {
3323 rcv.buffer.close();
3324 Ok(())
3325 }
3326 }
3327 }
3328
3329 pub(crate) fn abort(
3332 &mut self,
3333 counters: &TcpCountersRefs<'_>,
3334 ) -> (Option<Segment<()>>, NewlyClosed) {
3335 let reply = match self {
3336 State::Closed(_)
3349 | State::Listen(_)
3350 | State::SynSent(_)
3351 | State::Closing(_)
3352 | State::LastAck(_)
3353 | State::TimeWait(_) => None,
3354 State::SynRcvd(SynRcvd {
3366 iss,
3367 irs,
3368 timestamp: _,
3369 retrans_timer: _,
3370 simultaneous_open: _,
3371 buffer_sizes: _,
3372 smss: _,
3373 rcv_wnd_scale: _,
3374 snd_wnd_scale: _,
3375 sack_permitted: _,
3376 }) => {
3377 Some(Segment::rst_ack(*iss + 1, *irs + 1))
3380 }
3381 State::Established(Established { snd, rcv }) => {
3382 Some(Segment::rst_ack(snd.nxt, rcv.nxt()))
3383 }
3384 State::FinWait1(FinWait1 { snd, rcv }) => Some(Segment::rst_ack(snd.nxt, rcv.nxt())),
3385 State::FinWait2(FinWait2 { rcv, last_seq, timeout_at: _ }) => {
3386 Some(Segment::rst_ack(*last_seq, rcv.nxt()))
3387 }
3388 State::CloseWait(CloseWait { snd, closed_rcv }) => {
3389 Some(Segment::rst_ack(snd.nxt, closed_rcv.ack))
3390 }
3391 };
3392 (
3393 reply,
3394 self.transition_to_state(
3395 counters,
3396 State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }),
3397 ),
3398 )
3399 }
3400
3401 pub(crate) fn buffers_mut(&mut self) -> BuffersRefMut<'_, R, S> {
3402 match self {
3403 State::TimeWait(_) | State::Closed(_) => BuffersRefMut::NoBuffers,
3404 State::Listen(Listen { buffer_sizes, .. })
3405 | State::SynRcvd(SynRcvd { buffer_sizes, .. })
3406 | State::SynSent(SynSent { buffer_sizes, .. }) => BuffersRefMut::Sizes(buffer_sizes),
3407 State::Established(Established { snd, rcv }) => match &mut rcv.buffer {
3408 RecvBufferState::Open { buffer: ref mut recv_buf, .. } => {
3409 BuffersRefMut::Both { send: &mut snd.buffer, recv: recv_buf }
3410 }
3411 RecvBufferState::Closed { .. } => BuffersRefMut::SendOnly(&mut snd.buffer),
3412 },
3413 State::FinWait1(FinWait1 { snd, rcv }) => match &mut rcv.buffer {
3414 RecvBufferState::Open { buffer: ref mut recv_buf, .. } => {
3415 BuffersRefMut::Both { send: &mut snd.buffer, recv: recv_buf }
3416 }
3417 RecvBufferState::Closed { .. } => BuffersRefMut::SendOnly(&mut snd.buffer),
3418 },
3419 State::FinWait2(FinWait2::<I, R> { rcv, .. }) => match &mut rcv.buffer {
3420 RecvBufferState::Open { buffer: ref mut recv_buf, .. } => {
3421 BuffersRefMut::RecvOnly(recv_buf)
3422 }
3423 RecvBufferState::Closed { .. } => BuffersRefMut::NoBuffers,
3424 },
3425 State::Closing(Closing::<I, S> { snd, .. })
3426 | State::LastAck(LastAck::<I, S> { snd, .. }) => {
3427 BuffersRefMut::SendOnly(&mut snd.buffer)
3428 }
3429 State::CloseWait(CloseWait::<I, S> { snd, .. }) => {
3430 BuffersRefMut::SendOnly(&mut snd.buffer)
3431 }
3432 }
3433 }
3434
3435 pub(super) fn on_icmp_error(
3438 &mut self,
3439 counters: &TcpCountersRefs<'_>,
3440 err: IcmpErrorCode,
3441 seq: SeqNum,
3442 ) -> (Option<ConnectionError>, NewlyClosed, ShouldRetransmit) {
3443 let Some(result) = IcmpErrorResult::try_from_icmp_error(err) else {
3444 return (None, NewlyClosed::No, ShouldRetransmit::No);
3445 };
3446 let err = match result {
3447 IcmpErrorResult::ConnectionError(err) => err,
3448 IcmpErrorResult::PmtuUpdate(mms) => {
3449 let should_send = if let Some(mss) = Mss::from_mms(mms) {
3450 self.on_pmtu_update(mss, seq)
3451 } else {
3452 ShouldRetransmit::No
3453 };
3454 return (None, NewlyClosed::No, should_send);
3455 }
3456 };
3457 let connect_error = match self {
3478 State::Closed(_) => None,
3479 State::Listen(listen) => unreachable!(
3480 "ICMP errors should not be delivered on a listener, received code {:?} on {:?}",
3481 err, listen
3482 ),
3483 State::SynRcvd(SynRcvd {
3484 iss,
3485 irs: _,
3486 timestamp: _,
3487 retrans_timer: _,
3488 simultaneous_open: _,
3489 buffer_sizes: _,
3490 smss: _,
3491 rcv_wnd_scale: _,
3492 snd_wnd_scale: _,
3493 sack_permitted: _,
3494 })
3495 | State::SynSent(SynSent {
3496 iss,
3497 timestamp: _,
3498 retrans_timer: _,
3499 active_open: _,
3500 buffer_sizes: _,
3501 device_mss: _,
3502 default_mss: _,
3503 rcv_wnd_scale: _,
3504 }) => {
3505 if *iss == seq {
3506 return (
3507 None,
3508 self.transition_to_state(
3509 counters,
3510 State::Closed(Closed { reason: Some(err) }),
3511 ),
3512 ShouldRetransmit::No,
3513 );
3514 }
3515 None
3516 }
3517 State::Established(Established { snd, rcv: _ })
3518 | State::CloseWait(CloseWait { snd, closed_rcv: _ }) => {
3519 (!snd.una.after(seq) && seq.before(snd.nxt)).then_some(err)
3520 }
3521 State::LastAck(LastAck { snd, closed_rcv: _ })
3522 | State::Closing(Closing { snd, closed_rcv: _ }) => {
3523 (!snd.una.after(seq) && seq.before(snd.nxt)).then_some(err)
3524 }
3525 State::FinWait1(FinWait1 { snd, rcv: _ }) => {
3526 (!snd.una.after(seq) && seq.before(snd.nxt)).then_some(err)
3527 }
3528 State::FinWait2(_) | State::TimeWait(_) => None,
3531 };
3532 (connect_error, NewlyClosed::No, ShouldRetransmit::No)
3533 }
3534
3535 fn on_pmtu_update(&mut self, mss: Mss, seq: SeqNum) -> ShouldRetransmit {
3536 match self {
3539 State::Listen(listen) => unreachable!(
3540 "PMTU updates should not be delivered to a listener, received {mss:?} on {listen:?}"
3541 ),
3542 State::Closed(_)
3543 | State::SynRcvd(_)
3544 | State::SynSent(_)
3545 | State::FinWait2(_)
3546 | State::TimeWait(_) => {}
3547 State::Established(Established { snd, .. })
3548 | State::CloseWait(CloseWait { snd, .. }) => {
3549 if !snd.una.after(seq) && seq.before(snd.nxt) {
3550 return snd.update_mss(mss, seq);
3551 }
3552 }
3553 State::LastAck(LastAck { snd, .. }) | State::Closing(Closing { snd, .. }) => {
3554 if !snd.una.after(seq) && seq.before(snd.nxt) {
3555 return snd.update_mss(mss, seq);
3556 }
3557 }
3558 State::FinWait1(FinWait1 { snd, .. }) => {
3559 if !snd.una.after(seq) && seq.before(snd.nxt) {
3560 return snd.update_mss(mss, seq);
3561 }
3562 }
3563 }
3564 ShouldRetransmit::No
3565 }
3566}
3567
3568pub(super) enum CloseReason<I: Instant> {
3572 Shutdown,
3573 Close { now: I },
3574}
3575
3576#[cfg(test)]
3577mod test {
3578 use alloc::vec;
3579 use core::fmt::Debug;
3580 use core::num::NonZeroU16;
3581 use core::time::Duration;
3582
3583 use assert_matches::assert_matches;
3584 use net_types::ip::Ipv4;
3585 use netstack3_base::testutil::{FakeInstant, FakeInstantCtx};
3586 use netstack3_base::{FragmentedPayload, InstantContext as _, Options, SackBlock};
3587 use test_case::test_case;
3588
3589 use super::*;
3590 use crate::internal::base::testutil::{
3591 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE, DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE_USIZE,
3592 };
3593 use crate::internal::base::DEFAULT_FIN_WAIT2_TIMEOUT;
3594 use crate::internal::buffer::testutil::RingBuffer;
3595 use crate::internal::buffer::Buffer;
3596 use crate::internal::congestion::DUP_ACK_THRESHOLD;
3597 use crate::internal::counters::testutil::CounterExpectations;
3598 use crate::internal::counters::TcpCountersWithSocketInner;
3599
3600 const ISS_1: SeqNum = SeqNum::new(100);
3601 const ISS_2: SeqNum = SeqNum::new(300);
3602
3603 const RTT: Duration = Duration::from_millis(500);
3604
3605 const DEVICE_MAXIMUM_SEGMENT_SIZE: Mss = Mss(NonZeroU16::new(1400 as u16).unwrap());
3606
3607 fn default_quickack_counter() -> usize {
3608 quickack_counter(
3609 BufferLimits { capacity: WindowSize::DEFAULT.into(), len: 0 },
3610 DEVICE_MAXIMUM_SEGMENT_SIZE,
3611 )
3612 }
3613
3614 impl SocketOptions {
3615 fn default_for_state_tests() -> Self {
3616 Self { delayed_ack: false, nagle_enabled: false, ..Default::default() }
3619 }
3620 }
3621
3622 enum ClientlessBufferProvider {}
3625
3626 impl<R: ReceiveBuffer + Default, S: SendBuffer + Default> BufferProvider<R, S>
3627 for ClientlessBufferProvider
3628 {
3629 type PassiveOpen = ();
3630 type ActiveOpen = ();
3631
3632 fn new_passive_open_buffers(_buffer_sizes: BufferSizes) -> (R, S, Self::PassiveOpen) {
3633 (R::default(), S::default(), ())
3634 }
3635 }
3636
3637 impl RingBuffer {
3638 fn with_data<'a>(cap: usize, data: &'a [u8]) -> Self {
3639 let mut buffer = RingBuffer::new(cap);
3640 let nwritten = buffer.write_at(0, &data);
3641 assert_eq!(nwritten, data.len());
3642 buffer.make_readable(nwritten, false);
3643 buffer
3644 }
3645 }
3646
3647 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
3649 struct NullBuffer;
3650
3651 impl Buffer for NullBuffer {
3652 fn capacity_range() -> (usize, usize) {
3653 (usize::MIN, usize::MAX)
3654 }
3655
3656 fn limits(&self) -> BufferLimits {
3657 BufferLimits { len: 0, capacity: 0 }
3658 }
3659
3660 fn target_capacity(&self) -> usize {
3661 0
3662 }
3663
3664 fn request_capacity(&mut self, _size: usize) {}
3665 }
3666
3667 impl ReceiveBuffer for NullBuffer {
3668 fn write_at<P: Payload>(&mut self, _offset: usize, _data: &P) -> usize {
3669 0
3670 }
3671
3672 fn make_readable(&mut self, count: usize, has_outstanding: bool) {
3673 assert_eq!(count, 0);
3674 assert_eq!(has_outstanding, false);
3675 }
3676 }
3677
3678 impl SendBuffer for NullBuffer {
3679 type Payload<'a> = &'a [u8];
3680
3681 fn mark_read(&mut self, count: usize) {
3682 assert_eq!(count, 0);
3683 }
3684
3685 fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
3686 where
3687 F: FnOnce(Self::Payload<'a>) -> R,
3688 {
3689 assert_eq!(offset, 0);
3690 f(&[])
3691 }
3692 }
3693
3694 #[derive(Debug)]
3695 struct FakeStateMachineDebugId;
3696
3697 impl StateMachineDebugId for FakeStateMachineDebugId {
3698 fn trace_id(&self) -> TraceResourceId<'_> {
3699 TraceResourceId::new(0)
3700 }
3701 }
3702
3703 impl<R: ReceiveBuffer, S: SendBuffer> State<FakeInstant, R, S, ()> {
3704 fn poll_send_with_default_options(
3705 &mut self,
3706 mss: u32,
3707 now: FakeInstant,
3708 counters: &TcpCountersRefs<'_>,
3709 ) -> Option<Segment<S::Payload<'_>>> {
3710 self.poll_send(
3711 &FakeStateMachineDebugId,
3712 counters,
3713 mss,
3714 now,
3715 &SocketOptions::default_for_state_tests(),
3716 )
3717 .ok()
3718 }
3719
3720 fn on_segment_with_default_options<P: Payload, BP: BufferProvider<R, S, ActiveOpen = ()>>(
3721 &mut self,
3722 incoming: Segment<P>,
3723 now: FakeInstant,
3724 counters: &TcpCountersRefs<'_>,
3725 ) -> (Option<Segment<()>>, Option<BP::PassiveOpen>)
3726 where
3727 BP::PassiveOpen: Debug,
3728 R: Default,
3729 S: Default,
3730 {
3731 self.on_segment_with_options::<_, BP>(
3732 incoming,
3733 now,
3734 counters,
3735 &SocketOptions::default_for_state_tests(),
3736 )
3737 }
3738
3739 fn on_segment_with_options<P: Payload, BP: BufferProvider<R, S, ActiveOpen = ()>>(
3740 &mut self,
3741 incoming: Segment<P>,
3742 now: FakeInstant,
3743 counters: &TcpCountersRefs<'_>,
3744 options: &SocketOptions,
3745 ) -> (Option<Segment<()>>, Option<BP::PassiveOpen>)
3746 where
3747 BP::PassiveOpen: Debug,
3748 R: Default,
3749 S: Default,
3750 {
3751 let (segment, passive_open, _data_acked, _newly_closed) = self.on_segment::<P, BP>(
3752 &FakeStateMachineDebugId,
3753 counters,
3754 incoming,
3755 now,
3756 options,
3757 false, );
3759 (segment, passive_open)
3760 }
3761
3762 fn recv_mut(&mut self) -> Option<&mut Recv<FakeInstant, R>> {
3763 match self {
3764 State::Closed(_)
3765 | State::Listen(_)
3766 | State::SynRcvd(_)
3767 | State::SynSent(_)
3768 | State::CloseWait(_)
3769 | State::LastAck(_)
3770 | State::Closing(_)
3771 | State::TimeWait(_) => None,
3772 State::Established(Established { rcv, .. })
3773 | State::FinWait1(FinWait1 { rcv, .. }) => Some(rcv.get_mut()),
3774 State::FinWait2(FinWait2 { rcv, .. }) => Some(rcv),
3775 }
3776 }
3777
3778 #[track_caller]
3779 fn assert_established(&mut self) -> &mut Established<FakeInstant, R, S> {
3780 assert_matches!(self, State::Established(e) => e)
3781 }
3782 }
3783
3784 impl<S: SendBuffer + Debug> State<FakeInstant, RingBuffer, S, ()> {
3785 fn read_with(&mut self, f: impl for<'b> FnOnce(&'b [&'_ [u8]]) -> usize) -> usize {
3786 match self {
3787 State::Closed(_)
3788 | State::Listen(_)
3789 | State::SynRcvd(_)
3790 | State::SynSent(_)
3791 | State::CloseWait(_)
3792 | State::LastAck(_)
3793 | State::Closing(_)
3794 | State::TimeWait(_) => {
3795 panic!("No receive state in {:?}", self);
3796 }
3797 State::Established(Established { snd: _, rcv })
3798 | State::FinWait1(FinWait1 { snd: _, rcv }) => {
3799 assert_matches!(&mut rcv.buffer, RecvBufferState::Open{ buffer, .. } => buffer.read_with(f))
3800 }
3801 State::FinWait2(FinWait2 { last_seq: _, rcv, timeout_at: _ }) => {
3802 assert_matches!(&mut rcv.buffer, RecvBufferState::Open{ buffer, .. } => buffer.read_with(f))
3803 }
3804 }
3805 }
3806 }
3807
3808 impl State<FakeInstant, RingBuffer, NullBuffer, ()> {
3809 fn new_syn_rcvd(instant: FakeInstant) -> Self {
3810 State::SynRcvd(SynRcvd {
3811 iss: ISS_2,
3812 irs: ISS_1,
3813 timestamp: Some(instant),
3814 retrans_timer: RetransTimer::new(instant, Rto::DEFAULT, None, DEFAULT_MAX_RETRIES),
3815 simultaneous_open: Some(()),
3816 buffer_sizes: Default::default(),
3817 smss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
3818 rcv_wnd_scale: WindowScale::default(),
3819 snd_wnd_scale: Some(WindowScale::default()),
3820 sack_permitted: SACK_PERMITTED,
3821 })
3822 }
3823 }
3824
3825 #[derive(Default)]
3826 struct FakeTcpCounters {
3827 stack_wide: TcpCountersWithSocketInner,
3828 per_socket: TcpCountersWithSocketInner,
3829 }
3830
3831 impl FakeTcpCounters {
3832 fn refs<'a>(&'a self) -> TcpCountersRefs<'a> {
3833 let Self { stack_wide, per_socket } = self;
3834 TcpCountersRefs { stack_wide, per_socket }
3835 }
3836 }
3837
3838 impl CounterExpectations {
3839 #[track_caller]
3840 fn assert_counters(&self, FakeTcpCounters { stack_wide, per_socket }: &FakeTcpCounters) {
3841 assert_eq!(self, &CounterExpectations::from(stack_wide), "stack-wide counter mismatch");
3842 assert_eq!(self, &CounterExpectations::from(per_socket), "per-socket counter mismatch");
3843 }
3844 }
3845
3846 #[test_case(Segment::rst(ISS_1) => None; "drop RST")]
3847 #[test_case(Segment::rst_ack(ISS_1, ISS_2) => None; "drop RST|ACK")]
3848 #[test_case(Segment::syn(ISS_1, UnscaledWindowSize::from(0), HandshakeOptions::default().into()) => Some(Segment::rst_ack(SeqNum::new(0), ISS_1 + 1)); "reset SYN")]
3849 #[test_case(Segment::syn_ack(ISS_1, ISS_2, UnscaledWindowSize::from(0), HandshakeOptions::default().into()) => Some(Segment::rst(ISS_2)); "reset SYN|ACK")]
3850 #[test_case(Segment::data(ISS_1, ISS_2, UnscaledWindowSize::from(0), &[0, 1, 2][..]) => Some(Segment::rst(ISS_2)); "reset data segment")]
3851 fn segment_arrives_when_closed(
3852 incoming: impl Into<Segment<&'static [u8]>>,
3853 ) -> Option<Segment<()>> {
3854 let closed = Closed { reason: () };
3855 closed.on_segment(&incoming.into())
3856 }
3857
3858 #[test_case(
3859 Segment::rst_ack(ISS_2, ISS_1 - 1), RTT
3860 => SynSentOnSegmentDisposition::Ignore; "unacceptable ACK with RST")]
3861 #[test_case(
3862 Segment::ack(ISS_2, ISS_1 - 1, UnscaledWindowSize::from(u16::MAX)), RTT
3863 => SynSentOnSegmentDisposition::SendRst(
3864 Segment::rst(ISS_1-1),
3865 ); "unacceptable ACK without RST")]
3866 #[test_case(
3867 Segment::rst_ack(ISS_2, ISS_1), RTT
3868 => SynSentOnSegmentDisposition::EnterClosed(
3869 Closed { reason: Some(ConnectionError::ConnectionRefused) },
3870 ); "acceptable ACK(ISS) with RST")]
3871 #[test_case(
3872 Segment::rst_ack(ISS_2, ISS_1 + 1), RTT
3873 => SynSentOnSegmentDisposition::EnterClosed(
3874 Closed { reason: Some(ConnectionError::ConnectionRefused) },
3875 ); "acceptable ACK(ISS+1) with RST")]
3876 #[test_case(
3877 Segment::rst(ISS_2), RTT
3878 => SynSentOnSegmentDisposition::Ignore; "RST without ack")]
3879 #[test_case(
3880 Segment::syn(
3881 ISS_2,
3882 UnscaledWindowSize::from(u16::MAX),
3883 HandshakeOptions {
3884 window_scale: Some(WindowScale::default()),
3885 ..Default::default() }.into()
3886 ), RTT
3887 => SynSentOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
3888 Segment::syn_ack(
3889 ISS_1,
3890 ISS_2 + 1,
3891 UnscaledWindowSize::from(u16::MAX),
3892 HandshakeOptions {
3893 mss: Some(Mss::default::<Ipv4>()),
3894 window_scale: Some(WindowScale::default()),
3895 ..Default::default()
3896 }.into()),
3897 SynRcvd {
3898 iss: ISS_1,
3899 irs: ISS_2,
3900 timestamp: Some(FakeInstant::from(RTT)),
3901 retrans_timer: RetransTimer::new(
3902 FakeInstant::from(RTT),
3903 Rto::DEFAULT,
3904 NonZeroDuration::new(TEST_USER_TIMEOUT.get() - RTT),
3905 DEFAULT_MAX_SYNACK_RETRIES
3906 ),
3907 simultaneous_open: None,
3908 buffer_sizes: BufferSizes::default(),
3909 smss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
3910 rcv_wnd_scale: WindowScale::default(),
3911 snd_wnd_scale: Some(WindowScale::default()),
3912 sack_permitted: SACK_PERMITTED,
3913 }
3914 ); "SYN only")]
3915 #[test_case(
3916 Segment::fin(ISS_2, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX)), RTT
3917 => SynSentOnSegmentDisposition::Ignore; "acceptable ACK with FIN")]
3918 #[test_case(
3919 Segment::ack(ISS_2, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX)), RTT
3920 => SynSentOnSegmentDisposition::Ignore; "acceptable ACK(ISS+1) with nothing")]
3921 #[test_case(
3922 Segment::ack(ISS_2, ISS_1, UnscaledWindowSize::from(u16::MAX)), RTT
3923 => SynSentOnSegmentDisposition::Ignore; "acceptable ACK(ISS) without RST")]
3924 #[test_case(
3925 Segment::syn(ISS_2, UnscaledWindowSize::from(u16::MAX), HandshakeOptions::default().into()),
3926 TEST_USER_TIMEOUT.get()
3927 => SynSentOnSegmentDisposition::EnterClosed(Closed {
3928 reason: None
3929 }); "syn but timed out")]
3930 fn segment_arrives_when_syn_sent(
3931 incoming: Segment<()>,
3932 delay: Duration,
3933 ) -> SynSentOnSegmentDisposition<FakeInstant, ()> {
3934 let syn_sent = SynSent {
3935 iss: ISS_1,
3936 timestamp: Some(FakeInstant::default()),
3937 retrans_timer: RetransTimer::new(
3938 FakeInstant::default(),
3939 Rto::DEFAULT,
3940 Some(TEST_USER_TIMEOUT),
3941 DEFAULT_MAX_RETRIES,
3942 ),
3943 active_open: (),
3944 buffer_sizes: BufferSizes::default(),
3945 default_mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
3946 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
3947 rcv_wnd_scale: WindowScale::default(),
3948 };
3949 syn_sent.on_segment(incoming, FakeInstant::from(delay))
3950 }
3951
3952 #[test_case(Segment::rst(ISS_2) => ListenOnSegmentDisposition::Ignore; "ignore RST")]
3953 #[test_case(Segment::ack(ISS_2, ISS_1, UnscaledWindowSize::from(u16::MAX)) =>
3954 ListenOnSegmentDisposition::SendRst(Segment::rst(ISS_1)); "reject ACK")]
3955 #[test_case(Segment::syn(ISS_2, UnscaledWindowSize::from(u16::MAX),
3956 HandshakeOptions {
3957 window_scale: Some(WindowScale::default()),
3958 ..Default::default()
3959 }.into()) =>
3960 ListenOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
3961 Segment::syn_ack(
3962 ISS_1,
3963 ISS_2 + 1,
3964 UnscaledWindowSize::from(u16::MAX),
3965 HandshakeOptions {
3966 mss: Some(Mss::default::<Ipv4>()),
3967 window_scale: Some(WindowScale::default()),
3968 ..Default::default()
3969 }.into()),
3970 SynRcvd {
3971 iss: ISS_1,
3972 irs: ISS_2,
3973 timestamp: Some(FakeInstant::default()),
3974 retrans_timer: RetransTimer::new(
3975 FakeInstant::default(),
3976 Rto::DEFAULT,
3977 None,
3978 DEFAULT_MAX_SYNACK_RETRIES,
3979 ),
3980 simultaneous_open: None,
3981 buffer_sizes: BufferSizes::default(),
3982 smss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
3983 sack_permitted: SACK_PERMITTED,
3984 rcv_wnd_scale: WindowScale::default(),
3985 snd_wnd_scale: Some(WindowScale::default()),
3986 }); "accept syn")]
3987 fn segment_arrives_when_listen(
3988 incoming: Segment<()>,
3989 ) -> ListenOnSegmentDisposition<FakeInstant> {
3990 let listen = Closed::<Initial>::listen(
3991 ISS_1,
3992 Default::default(),
3993 DEVICE_MAXIMUM_SEGMENT_SIZE,
3994 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
3995 None,
3996 );
3997 listen.on_segment(incoming, FakeInstant::default())
3998 }
3999
4000 #[test_case(
4001 Segment::ack(ISS_1, ISS_2, UnscaledWindowSize::from(u16::MAX)),
4002 None
4003 => Some(
4004 Segment::ack(ISS_2 + 1, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX))
4005 ); "OTW segment")]
4006 #[test_case(
4007 Segment::rst_ack(ISS_1, ISS_2),
4008 None
4009 => None; "OTW RST")]
4010 #[test_case(
4011 Segment::rst_ack(ISS_1 + 1, ISS_2),
4012 Some(State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }))
4013 => None; "acceptable RST")]
4014 #[test_case(
4015 Segment::syn(ISS_1 + 1, UnscaledWindowSize::from(u16::MAX),
4016 HandshakeOptions { window_scale: Some(WindowScale::default()), ..Default::default() }.into()),
4017 Some(State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }))
4018 => Some(
4019 Segment::rst(ISS_2 + 1)
4020 ); "duplicate syn")]
4021 #[test_case(
4022 Segment::ack(ISS_1 + 1, ISS_2, UnscaledWindowSize::from(u16::MAX)),
4023 None
4024 => Some(
4025 Segment::rst(ISS_2)
4026 ); "unacceptable ack (ISS)")]
4027 #[test_case(
4028 Segment::ack(ISS_1 + 1, ISS_2 + 1, UnscaledWindowSize::from(u16::MAX)),
4029 Some(State::Established(
4030 Established {
4031 snd: Send {
4032 nxt: ISS_2 + 1,
4033 max: ISS_2 + 1,
4034 una: ISS_2 + 1,
4035 wnd: WindowSize::DEFAULT,
4036 wnd_max: WindowSize::DEFAULT,
4037 buffer: NullBuffer,
4038 wl1: ISS_1 + 1,
4039 wl2: ISS_2 + 1,
4040 rtt_estimator: Estimator::Measured {
4041 srtt: RTT,
4042 rtt_var: RTT / 2,
4043 },
4044 rtt_sampler: RttSampler::default(),
4045 timer: None,
4046 congestion_control: CongestionControl::cubic_with_mss(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
4047 wnd_scale: WindowScale::default(),
4048 }.into(),
4049 rcv: Recv {
4050 buffer: RecvBufferState::Open {
4051 buffer: RingBuffer::default(),
4052 assembler: Assembler::new(ISS_1 + 1),
4053 },
4054 remaining_quickacks: quickack_counter(BufferLimits {
4055 capacity: WindowSize::DEFAULT.into(),
4056 len: 0,
4057 }, DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
4058 last_segment_at: None,
4059 timer: None,
4060 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4061 wnd_scale: WindowScale::default(),
4062 last_window_update: (ISS_1 + 1, WindowSize::DEFAULT),
4063 sack_permitted: SACK_PERMITTED,
4064 }.into(),
4065 }
4066 ))
4067 => None; "acceptable ack (ISS + 1)")]
4068 #[test_case(
4069 Segment::ack(ISS_1 + 1, ISS_2 + 2, UnscaledWindowSize::from(u16::MAX)),
4070 None
4071 => Some(
4072 Segment::rst(ISS_2 + 2)
4073 ); "unacceptable ack (ISS + 2)")]
4074 #[test_case(
4075 Segment::ack(ISS_1 + 1, ISS_2 - 1, UnscaledWindowSize::from(u16::MAX)),
4076 None
4077 => Some(
4078 Segment::rst(ISS_2 - 1)
4079 ); "unacceptable ack (ISS - 1)")]
4080 #[test_case(
4081 Segment::new(ISS_1 + 1, None, None, UnscaledWindowSize::from(u16::MAX)),
4082 None
4083 => None; "no ack")]
4084 #[test_case(
4085 Segment::fin(ISS_1 + 1, ISS_2 + 1, UnscaledWindowSize::from(u16::MAX)),
4086 Some(State::CloseWait(CloseWait {
4087 snd: Send {
4088 nxt: ISS_2 + 1,
4089 max: ISS_2 + 1,
4090 una: ISS_2 + 1,
4091 wnd: WindowSize::DEFAULT,
4092 wnd_max: WindowSize::DEFAULT,
4093 buffer: NullBuffer,
4094 wl1: ISS_1 + 1,
4095 wl2: ISS_2 + 1,
4096 rtt_estimator: Estimator::Measured{
4097 srtt: RTT,
4098 rtt_var: RTT / 2,
4099 },
4100 rtt_sampler: RttSampler::default(),
4101 timer: None,
4102 congestion_control: CongestionControl::cubic_with_mss(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
4103 wnd_scale: WindowScale::default(),
4104 }.into(),
4105 closed_rcv: RecvParams {
4106 ack: ISS_1 + 2,
4107 wnd: WindowSize::from_u32(u32::from(u16::MAX - 1)).unwrap(),
4108 wnd_scale: WindowScale::ZERO,
4109 }
4110 }))
4111 => Some(
4112 Segment::ack(ISS_2 + 1, ISS_1 + 2, UnscaledWindowSize::from(u16::MAX - 1))
4113 ); "fin")]
4114 fn segment_arrives_when_syn_rcvd(
4115 incoming: Segment<()>,
4116 expected: Option<State<FakeInstant, RingBuffer, NullBuffer, ()>>,
4117 ) -> Option<Segment<()>> {
4118 let mut clock = FakeInstantCtx::default();
4119 let counters = FakeTcpCounters::default();
4120 let mut state = State::new_syn_rcvd(clock.now());
4121 clock.sleep(RTT);
4122 let (seg, _passive_open) = state
4123 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4124 incoming,
4125 clock.now(),
4126 &counters.refs(),
4127 );
4128 match expected {
4129 Some(new_state) => assert_eq!(new_state, state),
4130 None => assert_matches!(state, State::SynRcvd(_)),
4131 };
4132 seg
4133 }
4134
4135 #[test]
4136 fn abort_when_syn_rcvd() {
4137 let clock = FakeInstantCtx::default();
4138 let counters = FakeTcpCounters::default();
4139 let mut state = State::new_syn_rcvd(clock.now());
4140 let segment = assert_matches!(
4141 state.abort(&counters.refs()),
4142 (Some(seg), NewlyClosed::Yes) => seg
4143 );
4144 assert_eq!(segment.header.control, Some(Control::RST));
4145 assert_eq!(segment.header.seq, ISS_2 + 1);
4146 assert_eq!(segment.header.ack, Some(ISS_1 + 1));
4147 }
4148
4149 #[test_case(
4150 Segment::syn(ISS_2 + 1, UnscaledWindowSize::from(u16::MAX), HandshakeOptions::default().into()),
4151 Some(State::Closed (
4152 Closed { reason: Some(ConnectionError::ConnectionReset) },
4153 ))
4154 => Some(Segment::rst(ISS_1 + 1)); "duplicate syn")]
4155 #[test_case(
4156 Segment::rst(ISS_2 + 1),
4157 Some(State::Closed (
4158 Closed { reason: Some(ConnectionError::ConnectionReset) },
4159 ))
4160 => None; "accepatable rst")]
4161 #[test_case(
4162 Segment::ack(ISS_2 + 1, ISS_1 + 2, UnscaledWindowSize::from(u16::MAX)),
4163 None
4164 => Some(
4165 Segment::ack(ISS_1 + 1, ISS_2 + 1, UnscaledWindowSize::from(2))
4166 ); "unacceptable ack")]
4167 #[test_case(
4168 Segment::ack(ISS_2 + 1, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX)),
4169 None
4170 => None; "pure ack")]
4171 #[test_case(
4172 Segment::fin(ISS_2 + 1, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX)),
4173 Some(State::CloseWait(CloseWait {
4174 snd: Send {
4175 nxt: ISS_1 + 1,
4176 max: ISS_1 + 1,
4177 una: ISS_1 + 1,
4178 wnd: WindowSize::DEFAULT,
4179 wnd_max: WindowSize::DEFAULT,
4180 buffer: NullBuffer,
4181 wl1: ISS_2 + 1,
4182 wl2: ISS_1 + 1,
4183 rtt_estimator: Estimator::default(),
4184 rtt_sampler: RttSampler::default(),
4185 timer: None,
4186 congestion_control: CongestionControl::cubic_with_mss(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
4187 wnd_scale: WindowScale::default(),
4188 }.into(),
4189 closed_rcv: RecvParams {
4190 ack: ISS_2 + 2,
4191 wnd: WindowSize::new(1).unwrap(),
4192 wnd_scale: WindowScale::ZERO,
4193 }
4194 }))
4195 => Some(
4196 Segment::ack(ISS_1 + 1, ISS_2 + 2, UnscaledWindowSize::from(1))
4197 ); "pure fin")]
4198 #[test_case(
4199 Segment::piggybacked_fin(ISS_2 + 1, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX), "A".as_bytes()),
4200 Some(State::CloseWait(CloseWait {
4201 snd: Send {
4202 nxt: ISS_1 + 1,
4203 max: ISS_1 + 1,
4204 una: ISS_1 + 1,
4205 wnd: WindowSize::DEFAULT,
4206 wnd_max: WindowSize::DEFAULT,
4207 buffer: NullBuffer,
4208 wl1: ISS_2 + 1,
4209 wl2: ISS_1 + 1,
4210 rtt_estimator: Estimator::default(),
4211 rtt_sampler: RttSampler::default(),
4212 timer: None,
4213 congestion_control: CongestionControl::cubic_with_mss(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
4214 wnd_scale: WindowScale::default(),
4215 }.into(),
4216 closed_rcv: RecvParams {
4217 ack: ISS_2 + 3,
4218 wnd: WindowSize::ZERO,
4219 wnd_scale: WindowScale::ZERO,
4220 }
4221 }))
4222 => Some(
4223 Segment::ack(ISS_1 + 1, ISS_2 + 3, UnscaledWindowSize::from(0))
4224 ); "fin with 1 byte")]
4225 #[test_case(
4226 Segment::piggybacked_fin(ISS_2 + 1, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX), "AB".as_bytes()),
4227 None
4228 => Some(
4229 Segment::ack(ISS_1 + 1, ISS_2 + 3, UnscaledWindowSize::from(0))
4230 ); "fin with 2 bytes")]
4231 fn segment_arrives_when_established(
4232 incoming: Segment<&[u8]>,
4233 expected: Option<State<FakeInstant, RingBuffer, NullBuffer, ()>>,
4234 ) -> Option<Segment<()>> {
4235 let counters = FakeTcpCounters::default();
4236 let mut state = State::Established(Established {
4237 snd: Send {
4238 nxt: ISS_1 + 1,
4239 max: ISS_1 + 1,
4240 una: ISS_1 + 1,
4241 wnd: WindowSize::DEFAULT,
4242 wnd_max: WindowSize::DEFAULT,
4243 buffer: NullBuffer,
4244 wl1: ISS_2 + 1,
4245 wl2: ISS_1 + 1,
4246 rtt_estimator: Estimator::default(),
4247 rtt_sampler: RttSampler::default(),
4248 timer: None,
4249 congestion_control: CongestionControl::cubic_with_mss(
4250 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4251 ),
4252 wnd_scale: WindowScale::default(),
4253 }
4254 .into(),
4255 rcv: Recv {
4256 buffer: RecvBufferState::Open {
4257 buffer: RingBuffer::new(2),
4258 assembler: Assembler::new(ISS_2 + 1),
4259 },
4260 timer: None,
4261 remaining_quickacks: 0,
4262 last_segment_at: None,
4263 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4264 wnd_scale: WindowScale::default(),
4265 last_window_update: (ISS_2 + 1, WindowSize::new(2).unwrap()),
4266 sack_permitted: SACK_PERMITTED,
4267 }
4268 .into(),
4269 });
4270 let (seg, passive_open) = state
4271 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4272 incoming,
4273 FakeInstant::default(),
4274 &counters.refs(),
4275 );
4276 assert_eq!(passive_open, None);
4277 match expected {
4278 Some(new_state) => assert_eq!(new_state, state),
4279 None => assert_matches!(state, State::Established(_)),
4280 };
4281 seg
4282 }
4283
4284 #[test]
4285 fn common_rcv_data_segment_arrives() {
4286 let counters = FakeTcpCounters::default();
4287 let new_snd = || Send {
4290 nxt: ISS_1 + 1,
4291 max: ISS_1 + 1,
4292 una: ISS_1 + 1,
4293 wnd: WindowSize::DEFAULT,
4294 wnd_max: WindowSize::DEFAULT,
4295 buffer: NullBuffer,
4296 wl1: ISS_2 + 1,
4297 wl2: ISS_1 + 1,
4298 rtt_estimator: Estimator::default(),
4299 rtt_sampler: RttSampler::default(),
4300 timer: None,
4301 congestion_control: CongestionControl::cubic_with_mss(
4302 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4303 ),
4304 wnd_scale: WindowScale::default(),
4305 };
4306 let new_rcv = || Recv {
4307 buffer: RecvBufferState::Open {
4308 buffer: RingBuffer::new(TEST_BYTES.len()),
4309 assembler: Assembler::new(ISS_2 + 1),
4310 },
4311 timer: None,
4312 remaining_quickacks: 0,
4313 last_segment_at: None,
4314 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4315 wnd_scale: WindowScale::default(),
4316 last_window_update: (ISS_2 + 1, WindowSize::new(TEST_BYTES.len()).unwrap()),
4317 sack_permitted: SACK_PERMITTED,
4318 };
4319 for mut state in [
4320 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
4321 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
4322 State::FinWait2(FinWait2 { last_seq: ISS_1 + 1, rcv: new_rcv(), timeout_at: None }),
4323 ] {
4324 assert_eq!(
4325 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
4326 Segment::data(
4327 ISS_2 + 1,
4328 ISS_1 + 1,
4329 UnscaledWindowSize::from(u16::MAX),
4330 TEST_BYTES
4331 ),
4332 FakeInstant::default(),
4333 &counters.refs(),
4334 ),
4335 (
4336 Some(Segment::ack(
4337 ISS_1 + 1,
4338 ISS_2 + 1 + TEST_BYTES.len(),
4339 UnscaledWindowSize::from(0)
4340 )),
4341 None
4342 )
4343 );
4344 assert_eq!(
4345 state.read_with(|bytes| {
4346 assert_eq!(bytes.concat(), TEST_BYTES);
4347 TEST_BYTES.len()
4348 }),
4349 TEST_BYTES.len()
4350 );
4351 }
4352 }
4353
4354 #[test]
4355 fn common_snd_ack_segment_arrives() {
4356 let counters = FakeTcpCounters::default();
4357 let new_snd = || Send {
4360 nxt: ISS_1 + 1,
4361 max: ISS_1 + 1,
4362 una: ISS_1 + 1,
4363 wnd: WindowSize::DEFAULT,
4364 wnd_max: WindowSize::DEFAULT,
4365 buffer: RingBuffer::with_data(TEST_BYTES.len(), TEST_BYTES),
4366 wl1: ISS_2 + 1,
4367 wl2: ISS_1 + 1,
4368 rtt_estimator: Estimator::default(),
4369 rtt_sampler: RttSampler::default(),
4370 timer: None,
4371 congestion_control: CongestionControl::cubic_with_mss(
4372 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4373 ),
4374 wnd_scale: WindowScale::default(),
4375 };
4376 let new_rcv = || Recv {
4377 buffer: RecvBufferState::Open {
4378 buffer: NullBuffer,
4379 assembler: Assembler::new(ISS_2 + 1),
4380 },
4381 timer: None,
4382 remaining_quickacks: 0,
4383 last_segment_at: None,
4384 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4385 wnd_scale: WindowScale::default(),
4386 last_window_update: (ISS_2 + 1, WindowSize::ZERO),
4387 sack_permitted: SACK_PERMITTED,
4388 };
4389 for mut state in [
4390 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
4391 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
4392 State::Closing(Closing {
4393 snd: new_snd().queue_fin(),
4394 closed_rcv: RecvParams {
4395 ack: ISS_2 + 1,
4396 wnd: WindowSize::ZERO,
4397 wnd_scale: WindowScale::default(),
4398 },
4399 }),
4400 State::CloseWait(CloseWait {
4401 snd: new_snd().into(),
4402 closed_rcv: RecvParams {
4403 ack: ISS_2 + 1,
4404 wnd: WindowSize::ZERO,
4405 wnd_scale: WindowScale::default(),
4406 },
4407 }),
4408 State::LastAck(LastAck {
4409 snd: new_snd().queue_fin(),
4410 closed_rcv: RecvParams {
4411 ack: ISS_2 + 1,
4412 wnd: WindowSize::ZERO,
4413 wnd_scale: WindowScale::default(),
4414 },
4415 }),
4416 ] {
4417 assert_eq!(
4418 state.poll_send_with_default_options(
4419 u32::try_from(TEST_BYTES.len()).unwrap(),
4420 FakeInstant::default(),
4421 &counters.refs(),
4422 ),
4423 Some(Segment::data(
4424 ISS_1 + 1,
4425 ISS_2 + 1,
4426 UnscaledWindowSize::from(0),
4427 FragmentedPayload::new_contiguous(TEST_BYTES)
4428 ))
4429 );
4430 assert_eq!(
4431 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
4432 Segment::<()>::ack(
4433 ISS_2 + 1,
4434 ISS_1 + 1 + TEST_BYTES.len(),
4435 UnscaledWindowSize::from(u16::MAX)
4436 ),
4437 FakeInstant::default(),
4438 &counters.refs(),
4439 ),
4440 (None, None),
4441 );
4442 assert_eq!(state.poll_send_at(), None);
4443 let snd = match state {
4444 State::Closed(_)
4445 | State::Listen(_)
4446 | State::SynRcvd(_)
4447 | State::SynSent(_)
4448 | State::FinWait2(_)
4449 | State::TimeWait(_) => unreachable!("Unexpected state {:?}", state),
4450 State::Established(e) => e.snd.into_inner().queue_fin(),
4451 State::CloseWait(c) => c.snd.into_inner().queue_fin(),
4452 State::LastAck(l) => l.snd,
4453 State::FinWait1(f) => f.snd.into_inner(),
4454 State::Closing(c) => c.snd,
4455 };
4456 assert_eq!(snd.nxt, ISS_1 + 1 + TEST_BYTES.len());
4457 assert_eq!(snd.max, ISS_1 + 1 + TEST_BYTES.len());
4458 assert_eq!(snd.una, ISS_1 + 1 + TEST_BYTES.len());
4459 assert_eq!(snd.buffer.limits().len, 0);
4460 }
4461 }
4462
4463 #[test_case(
4464 Segment::syn(ISS_2 + 2, UnscaledWindowSize::from(u16::MAX),
4465 HandshakeOptions::default().into()),
4466 Some(State::Closed (
4467 Closed { reason: Some(ConnectionError::ConnectionReset) },
4468 ))
4469 => Some(Segment::rst(ISS_1 + 1)); "syn")]
4470 #[test_case(
4471 Segment::rst(ISS_2 + 2),
4472 Some(State::Closed (
4473 Closed { reason: Some(ConnectionError::ConnectionReset) },
4474 ))
4475 => None; "rst")]
4476 #[test_case(
4477 Segment::fin(ISS_2 + 2, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX)),
4478 None
4479 => None; "ignore fin")]
4480 #[test_case(
4481 Segment::data(ISS_2, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX), "a".as_bytes()),
4482 None => Some(Segment::ack(ISS_1 + 1, ISS_2 + 2, UnscaledWindowSize::from(u16::MAX)));
4483 "ack old data")]
4484 #[test_case(
4485 Segment::data(ISS_2 + 2, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX), "Hello".as_bytes()),
4486 Some(State::Closed (
4487 Closed { reason: Some(ConnectionError::ConnectionReset) },
4488 ))
4489 => Some(Segment::rst(ISS_1 + 1)); "reset on new data")]
4490 fn segment_arrives_when_close_wait(
4491 incoming: Segment<&[u8]>,
4492 expected: Option<State<FakeInstant, RingBuffer, NullBuffer, ()>>,
4493 ) -> Option<Segment<()>> {
4494 let counters = FakeTcpCounters::default();
4495 let mut state = State::CloseWait(CloseWait {
4496 snd: Send {
4497 nxt: ISS_1 + 1,
4498 max: ISS_1 + 1,
4499 una: ISS_1 + 1,
4500 wnd: WindowSize::DEFAULT,
4501 wnd_max: WindowSize::DEFAULT,
4502 buffer: NullBuffer,
4503 wl1: ISS_2 + 1,
4504 wl2: ISS_1 + 1,
4505 rtt_estimator: Estimator::default(),
4506 rtt_sampler: RttSampler::default(),
4507 timer: None,
4508 congestion_control: CongestionControl::cubic_with_mss(
4509 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4510 ),
4511 wnd_scale: WindowScale::default(),
4512 }
4513 .into(),
4514 closed_rcv: RecvParams {
4515 ack: ISS_2 + 2,
4516 wnd: WindowSize::DEFAULT,
4517 wnd_scale: WindowScale::ZERO,
4518 },
4519 });
4520 let (seg, _passive_open) = state
4521 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4522 incoming,
4523 FakeInstant::default(),
4524 &counters.refs(),
4525 );
4526 match expected {
4527 Some(new_state) => assert_eq!(new_state, state),
4528 None => assert_matches!(state, State::CloseWait(_)),
4529 };
4530 seg
4531 }
4532
4533 #[test_case(true; "sack")]
4534 #[test_case(false; "no sack")]
4535 fn active_passive_open(sack_permitted: bool) {
4536 let mut clock = FakeInstantCtx::default();
4537 let counters = FakeTcpCounters::default();
4538 let (syn_sent, mut syn_seg) = Closed::<Initial>::connect(
4539 ISS_1,
4540 clock.now(),
4541 (),
4542 Default::default(),
4543 DEVICE_MAXIMUM_SEGMENT_SIZE,
4544 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4545 &SocketOptions::default_for_state_tests(),
4546 );
4547 assert_eq!(
4548 syn_seg,
4549 Segment::syn(
4550 ISS_1,
4551 UnscaledWindowSize::from(u16::MAX),
4552 HandshakeOptions {
4553 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
4554 window_scale: Some(WindowScale::default()),
4555 sack_permitted: SACK_PERMITTED,
4557 }
4558 .into(),
4559 )
4560 );
4561 assert_eq!(
4562 syn_sent,
4563 SynSent {
4564 iss: ISS_1,
4565 timestamp: Some(clock.now()),
4566 retrans_timer: RetransTimer::new(
4567 clock.now(),
4568 Rto::DEFAULT,
4569 None,
4570 DEFAULT_MAX_SYN_RETRIES,
4571 ),
4572 active_open: (),
4573 buffer_sizes: BufferSizes::default(),
4574 default_mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4575 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
4576 rcv_wnd_scale: WindowScale::default(),
4577 }
4578 );
4579 let mut active = State::SynSent(syn_sent);
4580 let mut passive = State::Listen(Closed::<Initial>::listen(
4581 ISS_2,
4582 Default::default(),
4583 DEVICE_MAXIMUM_SEGMENT_SIZE,
4584 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4585 None,
4586 ));
4587 clock.sleep(RTT / 2);
4588
4589 {
4591 let opt = assert_matches!(&mut syn_seg.header.options, Options::Handshake(o) => o);
4592 opt.sack_permitted = sack_permitted;
4593 }
4594
4595 let (seg, passive_open) = passive
4596 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4597 syn_seg,
4598 clock.now(),
4599 &counters.refs(),
4600 );
4601 let mut syn_ack = seg.expect("failed to generate a syn-ack segment");
4602 assert_eq!(passive_open, None);
4603 assert_eq!(
4604 syn_ack,
4605 Segment::syn_ack(
4606 ISS_2,
4607 ISS_1 + 1,
4608 UnscaledWindowSize::from(u16::MAX),
4609 HandshakeOptions {
4610 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
4611 window_scale: Some(WindowScale::default()),
4612 sack_permitted: SACK_PERMITTED,
4614 }
4615 .into(),
4616 )
4617 );
4618 assert_matches!(passive, State::SynRcvd(ref syn_rcvd) if syn_rcvd == &SynRcvd {
4619 iss: ISS_2,
4620 irs: ISS_1,
4621 timestamp: Some(clock.now()),
4622 retrans_timer: RetransTimer::new(
4623 clock.now(),
4624 Rto::DEFAULT,
4625 None,
4626 DEFAULT_MAX_SYNACK_RETRIES,
4627 ),
4628 simultaneous_open: None,
4629 buffer_sizes: Default::default(),
4630 smss: DEVICE_MAXIMUM_SEGMENT_SIZE,
4631 rcv_wnd_scale: WindowScale::default(),
4632 snd_wnd_scale: Some(WindowScale::default()),
4633 sack_permitted,
4634 });
4635 clock.sleep(RTT / 2);
4636
4637 {
4639 let opt = assert_matches!(&mut syn_ack.header.options, Options::Handshake(o) => o);
4640 opt.sack_permitted = sack_permitted;
4641 }
4642
4643 let (seg, passive_open) = active
4644 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4645 syn_ack,
4646 clock.now(),
4647 &counters.refs(),
4648 );
4649 let ack_seg = seg.expect("failed to generate a ack segment");
4650 assert_eq!(passive_open, None);
4651 assert_eq!(ack_seg, Segment::ack(ISS_1 + 1, ISS_2 + 1, UnscaledWindowSize::from(u16::MAX)));
4652 let established = assert_matches!(&active, State::Established(e) => e);
4653 assert_eq!(
4654 established,
4655 &Established {
4656 snd: Send {
4657 nxt: ISS_1 + 1,
4658 max: ISS_1 + 1,
4659 una: ISS_1 + 1,
4660 wnd: WindowSize::DEFAULT,
4661 wnd_max: WindowSize::DEFAULT,
4662 buffer: RingBuffer::default(),
4663 wl1: ISS_2,
4664 wl2: ISS_1 + 1,
4665 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
4666 rtt_sampler: RttSampler::default(),
4667 timer: None,
4668 congestion_control: CongestionControl::cubic_with_mss(
4669 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE
4670 ),
4671 wnd_scale: WindowScale::default(),
4672 }
4673 .into(),
4674 rcv: Recv {
4675 buffer: RecvBufferState::Open {
4676 buffer: RingBuffer::default(),
4677 assembler: Assembler::new(ISS_2 + 1),
4678 },
4679 timer: None,
4680 remaining_quickacks: default_quickack_counter(),
4681 last_segment_at: None,
4682 mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
4683 wnd_scale: WindowScale::default(),
4684 last_window_update: (ISS_2 + 1, WindowSize::DEFAULT),
4685 sack_permitted,
4686 }
4687 .into()
4688 }
4689 );
4690 clock.sleep(RTT / 2);
4691 assert_eq!(
4692 passive.on_segment_with_default_options::<_, ClientlessBufferProvider>(
4693 ack_seg,
4694 clock.now(),
4695 &counters.refs(),
4696 ),
4697 (None, Some(())),
4698 );
4699 let established = assert_matches!(&passive, State::Established(e) => e);
4700 assert_eq!(
4701 established,
4702 &Established {
4703 snd: Send {
4704 nxt: ISS_2 + 1,
4705 max: ISS_2 + 1,
4706 una: ISS_2 + 1,
4707 wnd: WindowSize::DEFAULT,
4708 wnd_max: WindowSize::DEFAULT,
4709 buffer: RingBuffer::default(),
4710 wl1: ISS_1 + 1,
4711 wl2: ISS_2 + 1,
4712 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
4713 rtt_sampler: RttSampler::default(),
4714 timer: None,
4715 congestion_control: CongestionControl::cubic_with_mss(
4716 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE
4717 ),
4718 wnd_scale: WindowScale::default(),
4719 }
4720 .into(),
4721 rcv: Recv {
4722 buffer: RecvBufferState::Open {
4723 buffer: RingBuffer::default(),
4724 assembler: Assembler::new(ISS_1 + 1),
4725 },
4726 timer: None,
4727 remaining_quickacks: default_quickack_counter(),
4728 last_segment_at: None,
4729 mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
4730 wnd_scale: WindowScale::default(),
4731 last_window_update: (ISS_1 + 1, WindowSize::DEFAULT),
4732 sack_permitted,
4733 }
4734 .into()
4735 }
4736 )
4737 }
4738
4739 #[test]
4740 fn simultaneous_open() {
4741 let mut clock = FakeInstantCtx::default();
4742 let counters = FakeTcpCounters::default();
4743 let (syn_sent1, syn1) = Closed::<Initial>::connect(
4744 ISS_1,
4745 clock.now(),
4746 (),
4747 Default::default(),
4748 DEVICE_MAXIMUM_SEGMENT_SIZE,
4749 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4750 &SocketOptions::default_for_state_tests(),
4751 );
4752 let (syn_sent2, syn2) = Closed::<Initial>::connect(
4753 ISS_2,
4754 clock.now(),
4755 (),
4756 Default::default(),
4757 DEVICE_MAXIMUM_SEGMENT_SIZE,
4758 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
4759 &SocketOptions::default_for_state_tests(),
4760 );
4761
4762 assert_eq!(
4763 syn1,
4764 Segment::syn(
4765 ISS_1,
4766 UnscaledWindowSize::from(u16::MAX),
4767 HandshakeOptions {
4768 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
4769 window_scale: Some(WindowScale::default()),
4770 sack_permitted: SACK_PERMITTED,
4771 }
4772 .into(),
4773 )
4774 );
4775 assert_eq!(
4776 syn2,
4777 Segment::syn(
4778 ISS_2,
4779 UnscaledWindowSize::from(u16::MAX),
4780 HandshakeOptions {
4781 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
4782 window_scale: Some(WindowScale::default()),
4783 sack_permitted: SACK_PERMITTED,
4784 }
4785 .into(),
4786 )
4787 );
4788
4789 let mut state1 = State::SynSent(syn_sent1);
4790 let mut state2 = State::SynSent(syn_sent2);
4791
4792 clock.sleep(RTT);
4793 let (seg, passive_open) = state1
4794 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4795 syn2,
4796 clock.now(),
4797 &counters.refs(),
4798 );
4799 let syn_ack1 = seg.expect("failed to generate syn ack");
4800 assert_eq!(passive_open, None);
4801 let (seg, passive_open) = state2
4802 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4803 syn1,
4804 clock.now(),
4805 &counters.refs(),
4806 );
4807 let syn_ack2 = seg.expect("failed to generate syn ack");
4808 assert_eq!(passive_open, None);
4809
4810 assert_eq!(
4811 syn_ack1,
4812 Segment::syn_ack(
4813 ISS_1,
4814 ISS_2 + 1,
4815 UnscaledWindowSize::from(u16::MAX),
4816 HandshakeOptions {
4817 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
4818 window_scale: Some(WindowScale::default()),
4819 sack_permitted: SACK_PERMITTED,
4820 }
4821 .into()
4822 )
4823 );
4824 assert_eq!(
4825 syn_ack2,
4826 Segment::syn_ack(
4827 ISS_2,
4828 ISS_1 + 1,
4829 UnscaledWindowSize::from(u16::MAX),
4830 HandshakeOptions {
4831 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
4832 window_scale: Some(WindowScale::default()),
4833 sack_permitted: SACK_PERMITTED,
4834 }
4835 .into()
4836 )
4837 );
4838
4839 assert_matches!(state1, State::SynRcvd(ref syn_rcvd) if syn_rcvd == &SynRcvd {
4840 iss: ISS_1,
4841 irs: ISS_2,
4842 timestamp: Some(clock.now()),
4843 retrans_timer: RetransTimer::new(
4844 clock.now(),
4845 Rto::DEFAULT,
4846 None,
4847 DEFAULT_MAX_SYNACK_RETRIES,
4848 ),
4849 simultaneous_open: Some(()),
4850 buffer_sizes: BufferSizes::default(),
4851 smss: DEVICE_MAXIMUM_SEGMENT_SIZE,
4852 rcv_wnd_scale: WindowScale::default(),
4853 snd_wnd_scale: Some(WindowScale::default()),
4854 sack_permitted: SACK_PERMITTED,
4855 });
4856 assert_matches!(state2, State::SynRcvd(ref syn_rcvd) if syn_rcvd == &SynRcvd {
4857 iss: ISS_2,
4858 irs: ISS_1,
4859 timestamp: Some(clock.now()),
4860 retrans_timer: RetransTimer::new(
4861 clock.now(),
4862 Rto::DEFAULT,
4863 None,
4864 DEFAULT_MAX_SYNACK_RETRIES,
4865 ),
4866 simultaneous_open: Some(()),
4867 buffer_sizes: BufferSizes::default(),
4868 smss: DEVICE_MAXIMUM_SEGMENT_SIZE,
4869 rcv_wnd_scale: WindowScale::default(),
4870 snd_wnd_scale: Some(WindowScale::default()),
4871 sack_permitted: SACK_PERMITTED,
4872 });
4873
4874 clock.sleep(RTT);
4875 assert_eq!(
4876 state1.on_segment_with_default_options::<_, ClientlessBufferProvider>(
4877 syn_ack2,
4878 clock.now(),
4879 &counters.refs(),
4880 ),
4881 (Some(Segment::ack(ISS_1 + 1, ISS_2 + 1, UnscaledWindowSize::from(u16::MAX))), None)
4882 );
4883 assert_eq!(
4884 state2.on_segment_with_default_options::<_, ClientlessBufferProvider>(
4885 syn_ack1,
4886 clock.now(),
4887 &counters.refs(),
4888 ),
4889 (Some(Segment::ack(ISS_2 + 1, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX))), None)
4890 );
4891
4892 let established = assert_matches!(state1, State::Established(e) => e);
4893 assert_eq!(
4894 established,
4895 Established {
4896 snd: Send {
4897 nxt: ISS_1 + 1,
4898 max: ISS_1 + 1,
4899 una: ISS_1 + 1,
4900 wnd: WindowSize::DEFAULT,
4901 wnd_max: WindowSize::DEFAULT,
4902 buffer: RingBuffer::default(),
4903 wl1: ISS_2 + 1,
4904 wl2: ISS_1 + 1,
4905 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
4906 rtt_sampler: RttSampler::default(),
4907 timer: None,
4908 congestion_control: CongestionControl::cubic_with_mss(
4909 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE
4910 ),
4911 wnd_scale: WindowScale::default(),
4912 }
4913 .into(),
4914 rcv: Recv {
4915 buffer: RecvBufferState::Open {
4916 buffer: RingBuffer::default(),
4917 assembler: Assembler::new(ISS_2 + 1),
4918 },
4919 timer: None,
4920 remaining_quickacks: default_quickack_counter() - 1,
4921 last_segment_at: Some(clock.now()),
4922 mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
4923 wnd_scale: WindowScale::default(),
4924 last_window_update: (ISS_2 + 1, WindowSize::DEFAULT),
4925 sack_permitted: SACK_PERMITTED,
4926 }
4927 .into()
4928 }
4929 );
4930
4931 let established = assert_matches!(state2, State::Established(e) => e);
4932 assert_eq!(
4933 established,
4934 Established {
4935 snd: Send {
4936 nxt: ISS_2 + 1,
4937 max: ISS_2 + 1,
4938 una: ISS_2 + 1,
4939 wnd: WindowSize::DEFAULT,
4940 wnd_max: WindowSize::DEFAULT,
4941 buffer: RingBuffer::default(),
4942 wl1: ISS_1 + 1,
4943 wl2: ISS_2 + 1,
4944 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
4945 rtt_sampler: RttSampler::default(),
4946 timer: None,
4947 congestion_control: CongestionControl::cubic_with_mss(
4948 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE
4949 ),
4950 wnd_scale: WindowScale::default(),
4951 }
4952 .into(),
4953 rcv: Recv {
4954 buffer: RecvBufferState::Open {
4955 buffer: RingBuffer::default(),
4956 assembler: Assembler::new(ISS_1 + 1),
4957 },
4958 timer: None,
4959 remaining_quickacks: default_quickack_counter() - 1,
4960 last_segment_at: Some(clock.now()),
4961 mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
4962 wnd_scale: WindowScale::default(),
4963 last_window_update: (ISS_1 + 1, WindowSize::DEFAULT),
4964 sack_permitted: SACK_PERMITTED,
4965 }
4966 .into()
4967 }
4968 );
4969 }
4970
4971 const BUFFER_SIZE: usize = 16;
4972 const TEST_BYTES: &[u8] = "Hello".as_bytes();
4973
4974 #[test]
4975 fn established_receive() {
4976 let clock = FakeInstantCtx::default();
4977 let counters = FakeTcpCounters::default();
4978 let mut established = State::Established(Established {
4979 snd: Send {
4980 nxt: ISS_1 + 1,
4981 max: ISS_1 + 1,
4982 una: ISS_1 + 1,
4983 wnd: WindowSize::ZERO,
4984 wnd_max: WindowSize::ZERO,
4985 buffer: NullBuffer,
4986 wl1: ISS_2 + 1,
4987 wl2: ISS_1 + 1,
4988 rtt_estimator: Estimator::default(),
4989 rtt_sampler: RttSampler::default(),
4990 timer: None,
4991 congestion_control: CongestionControl::cubic_with_mss(Mss(
4992 NonZeroU16::new(5).unwrap()
4993 )),
4994 wnd_scale: WindowScale::default(),
4995 }
4996 .into(),
4997 rcv: Recv {
4998 buffer: RecvBufferState::Open {
4999 buffer: RingBuffer::new(BUFFER_SIZE),
5000 assembler: Assembler::new(ISS_2 + 1),
5001 },
5002 timer: None,
5003 remaining_quickacks: 0,
5004 last_segment_at: None,
5005 mss: Mss(NonZeroU16::new(5).unwrap()),
5006 wnd_scale: WindowScale::default(),
5007 last_window_update: (ISS_2 + 1, WindowSize::new(BUFFER_SIZE).unwrap()),
5008 sack_permitted: SACK_PERMITTED,
5009 }
5010 .into(),
5011 });
5012
5013 assert_eq!(
5015 established.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5016 Segment::data(ISS_2 + 1, ISS_1 + 1, UnscaledWindowSize::from(0), TEST_BYTES,),
5017 clock.now(),
5018 &counters.refs(),
5019 ),
5020 (
5021 Some(Segment::ack(
5022 ISS_1 + 1,
5023 ISS_2 + 1 + TEST_BYTES.len(),
5024 UnscaledWindowSize::from((BUFFER_SIZE - TEST_BYTES.len()) as u16),
5025 )),
5026 None
5027 ),
5028 );
5029 assert_eq!(
5030 established.read_with(|available| {
5031 assert_eq!(available, &[TEST_BYTES]);
5032 available[0].len()
5033 }),
5034 TEST_BYTES.len()
5035 );
5036
5037 assert_eq!(
5039 established.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5040 Segment::data(
5041 ISS_2 + 1 + TEST_BYTES.len() * 2,
5042 ISS_1 + 1,
5043 UnscaledWindowSize::from(0),
5044 TEST_BYTES,
5045 ),
5046 clock.now(),
5047 &counters.refs()
5048 ),
5049 (
5050 Some(Segment::ack(
5051 ISS_1 + 1,
5052 ISS_2 + 1 + TEST_BYTES.len(),
5053 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
5054 )),
5055 None
5056 ),
5057 );
5058 assert_eq!(
5059 established.read_with(|available| {
5060 let empty: &[u8] = &[];
5061 assert_eq!(available, &[empty]);
5062 0
5063 }),
5064 0
5065 );
5066
5067 assert_eq!(
5069 established.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5070 Segment::data(
5071 ISS_2 + 1 + TEST_BYTES.len(),
5072 ISS_1 + 1,
5073 UnscaledWindowSize::from(0),
5074 TEST_BYTES,
5075 ),
5076 clock.now(),
5077 &counters.refs()
5078 ),
5079 (
5080 Some(Segment::ack(
5081 ISS_1 + 1,
5082 ISS_2 + 1 + 3 * TEST_BYTES.len(),
5083 UnscaledWindowSize::from_usize(BUFFER_SIZE - 2 * TEST_BYTES.len()),
5084 )),
5085 None
5086 ),
5087 );
5088 assert_eq!(
5089 established.read_with(|available| {
5090 assert_eq!(available, &[[TEST_BYTES, TEST_BYTES].concat()]);
5091 available[0].len()
5092 }),
5093 10
5094 );
5095 }
5096
5097 #[test]
5098 fn established_send() {
5099 let clock = FakeInstantCtx::default();
5100 let counters = FakeTcpCounters::default();
5101 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
5102 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), 5);
5103 let mut established = State::Established(Established {
5104 snd: Send {
5105 nxt: ISS_1 + 1,
5106 max: ISS_1 + 1,
5107 una: ISS_1,
5108 wnd: WindowSize::ZERO,
5109 wnd_max: WindowSize::ZERO,
5110 buffer: send_buffer,
5111 wl1: ISS_2,
5112 wl2: ISS_1,
5113 rtt_sampler: RttSampler::default(),
5114 rtt_estimator: Estimator::default(),
5115 timer: None,
5116 congestion_control: CongestionControl::cubic_with_mss(
5117 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
5118 ),
5119 wnd_scale: WindowScale::default(),
5120 }
5121 .into(),
5122 rcv: Recv {
5123 buffer: RecvBufferState::Open {
5124 buffer: RingBuffer::new(BUFFER_SIZE),
5125 assembler: Assembler::new(ISS_2 + 1),
5126 },
5127 timer: None,
5128 remaining_quickacks: 0,
5129 last_segment_at: None,
5130 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
5131 wnd_scale: WindowScale::default(),
5132 last_window_update: (ISS_2 + 1, WindowSize::new(BUFFER_SIZE).unwrap()),
5133 sack_permitted: SACK_PERMITTED,
5134 }
5135 .into(),
5136 });
5137 assert_eq!(
5139 established.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5140 None
5141 );
5142 let open_window = |established: &mut State<FakeInstant, RingBuffer, RingBuffer, ()>,
5143 ack: SeqNum,
5144 win: usize,
5145 now: FakeInstant,
5146 counters: &TcpCountersRefs<'_>| {
5147 assert_eq!(
5148 established.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5149 Segment::ack(ISS_2 + 1, ack, UnscaledWindowSize::from_usize(win)),
5150 now,
5151 counters
5152 ),
5153 (None, None),
5154 );
5155 };
5156 open_window(&mut established, ISS_1 + 1, 1, clock.now(), &counters.refs());
5158 assert_eq!(
5159 established.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5160 Some(Segment::data(
5161 ISS_1 + 1,
5162 ISS_2 + 1,
5163 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5164 FragmentedPayload::new_contiguous(&TEST_BYTES[1..2]),
5165 ))
5166 );
5167
5168 open_window(&mut established, ISS_1 + 2, 10, clock.now(), &counters.refs());
5170 assert_eq!(
5171 established.poll_send_with_default_options(2, clock.now(), &counters.refs()),
5172 Some(Segment::data(
5173 ISS_1 + 2,
5174 ISS_2 + 1,
5175 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5176 FragmentedPayload::new_contiguous(&TEST_BYTES[2..4]),
5177 ))
5178 );
5179
5180 assert_eq!(
5181 established.poll_send(
5182 &FakeStateMachineDebugId,
5183 &counters.refs(),
5184 1,
5185 clock.now(),
5186 &SocketOptions { nagle_enabled: false, ..SocketOptions::default_for_state_tests() }
5187 ),
5188 Ok(Segment::data(
5189 ISS_1 + 4,
5190 ISS_2 + 1,
5191 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5192 FragmentedPayload::new_contiguous(&TEST_BYTES[4..5]),
5193 ))
5194 );
5195
5196 assert_eq!(
5198 established.poll_send_with_default_options(1, clock.now(), &counters.refs()),
5199 None
5200 );
5201 }
5202
5203 #[test]
5204 fn self_connect_retransmission() {
5205 let mut clock = FakeInstantCtx::default();
5206 let counters = FakeTcpCounters::default();
5207 let (syn_sent, syn) = Closed::<Initial>::connect(
5208 ISS_1,
5209 clock.now(),
5210 (),
5211 Default::default(),
5212 DEVICE_MAXIMUM_SEGMENT_SIZE,
5213 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
5214 &SocketOptions::default_for_state_tests(),
5215 );
5216 let mut state = State::<_, RingBuffer, RingBuffer, ()>::SynSent(syn_sent);
5217 assert_eq!(state.poll_send_at(), Some(FakeInstant::from(Rto::DEFAULT.get())));
5219 clock.sleep(Rto::DEFAULT.get());
5220 assert_eq!(
5222 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5223 Some(syn.clone().into_empty())
5224 );
5225
5226 let (seg, passive_open) = state
5228 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5229 syn,
5230 clock.now(),
5231 &counters.refs(),
5232 );
5233 let syn_ack = seg.expect("expected SYN-ACK");
5234 assert_eq!(passive_open, None);
5235 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
5237 clock.sleep(Rto::DEFAULT.get());
5238 assert_eq!(
5240 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5241 Some(syn_ack.clone().into_empty())
5242 );
5243
5244 assert_eq!(
5246 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5247 syn_ack,
5248 clock.now(),
5249 &counters.refs(),
5250 ),
5251 (Some(Segment::ack(ISS_1 + 1, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX))), None)
5252 );
5253 match state {
5254 State::Closed(_)
5255 | State::Listen(_)
5256 | State::SynRcvd(_)
5257 | State::SynSent(_)
5258 | State::LastAck(_)
5259 | State::FinWait1(_)
5260 | State::FinWait2(_)
5261 | State::Closing(_)
5262 | State::TimeWait(_) => {
5263 panic!("expected that we have entered established state, but got {:?}", state)
5264 }
5265 State::Established(Established { ref mut snd, rcv: _ })
5266 | State::CloseWait(CloseWait { ref mut snd, closed_rcv: _ }) => {
5267 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
5268 }
5269 }
5270 assert_eq!(state.poll_send_at(), None);
5272 for i in 0..3 {
5274 assert_eq!(
5275 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5276 Some(Segment::data(
5277 ISS_1 + 1,
5278 ISS_1 + 1,
5279 UnscaledWindowSize::from(u16::MAX),
5280 FragmentedPayload::new_contiguous(TEST_BYTES),
5281 ))
5282 );
5283 assert_eq!(state.poll_send_at(), Some(clock.now() + (1 << i) * Rto::DEFAULT.get()));
5284 clock.sleep((1 << i) * Rto::DEFAULT.get());
5285 CounterExpectations {
5286 retransmits: i,
5287 slow_start_retransmits: i,
5288 timeouts: i,
5289 ..Default::default()
5290 }
5291 .assert_counters(&counters);
5292 }
5293 assert_eq!(
5295 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5296 Segment::ack(
5297 ISS_1 + 1 + TEST_BYTES.len(),
5298 ISS_1 + 1 + 1,
5299 UnscaledWindowSize::from(u16::MAX)
5300 ),
5301 clock.now(),
5302 &counters.refs(),
5303 ),
5304 (None, None),
5305 );
5306 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
5309 clock.sleep(Rto::DEFAULT.get());
5310 assert_eq!(
5311 state.poll_send_with_default_options(1, clock.now(), &counters.refs(),),
5312 Some(Segment::data(
5313 ISS_1 + 1 + 1,
5314 ISS_1 + 1,
5315 UnscaledWindowSize::from(u16::MAX),
5316 FragmentedPayload::new_contiguous(&TEST_BYTES[1..2]),
5317 ))
5318 );
5319 assert_eq!(
5322 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5323 Segment::ack(
5324 ISS_1 + 1 + TEST_BYTES.len(),
5325 ISS_1 + 1 + 3,
5326 UnscaledWindowSize::from(u16::MAX)
5327 ),
5328 clock.now(),
5329 &counters.refs(),
5330 ),
5331 (None, None)
5332 );
5333 CounterExpectations {
5336 retransmits: 3,
5337 slow_start_retransmits: 3,
5338 timeouts: 3,
5339 ..Default::default()
5340 }
5341 .assert_counters(&counters);
5342 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
5343 assert_eq!(
5344 state.poll_send_with_default_options(1, clock.now(), &counters.refs()),
5345 Some(Segment::data(
5346 ISS_1 + 1 + 3,
5347 ISS_1 + 1,
5348 UnscaledWindowSize::from(u16::MAX),
5349 FragmentedPayload::new_contiguous(&TEST_BYTES[3..4]),
5350 ))
5351 );
5352 assert_eq!(
5354 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5355 Segment::ack(
5356 ISS_1 + 1 + TEST_BYTES.len(),
5357 ISS_1 + 1 + TEST_BYTES.len(),
5358 UnscaledWindowSize::from(u16::MAX)
5359 ),
5360 clock.now(),
5361 &counters.refs()
5362 ),
5363 (None, None)
5364 );
5365 assert_eq!(state.poll_send_at(), None);
5367 }
5368
5369 #[test]
5370 fn passive_close() {
5371 let mut clock = FakeInstantCtx::default();
5372 let counters = FakeTcpCounters::default();
5373 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
5374 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), 5);
5375 let mut state = State::Established(Established {
5377 snd: Send {
5378 nxt: ISS_1 + 1,
5379 max: ISS_1 + 1,
5380 una: ISS_1 + 1,
5381 wnd: WindowSize::DEFAULT,
5382 wnd_max: WindowSize::DEFAULT,
5383 buffer: send_buffer.clone(),
5384 wl1: ISS_2,
5385 wl2: ISS_1,
5386 rtt_sampler: RttSampler::default(),
5387 rtt_estimator: Estimator::default(),
5388 timer: None,
5389 congestion_control: CongestionControl::cubic_with_mss(
5390 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
5391 ),
5392 wnd_scale: WindowScale::default(),
5393 }
5394 .into(),
5395 rcv: Recv {
5396 buffer: RecvBufferState::Open {
5397 buffer: RingBuffer::new(BUFFER_SIZE),
5398 assembler: Assembler::new(ISS_2 + 1),
5399 },
5400 timer: None,
5401 remaining_quickacks: 0,
5402 last_segment_at: None,
5403 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
5404 wnd_scale: WindowScale::default(),
5405 last_window_update: (ISS_2 + 1, WindowSize::new(BUFFER_SIZE).unwrap()),
5406 sack_permitted: SACK_PERMITTED,
5407 }
5408 .into(),
5409 });
5410 let last_wnd = WindowSize::new(BUFFER_SIZE - 1).unwrap();
5411 let last_wnd_scale = WindowScale::default();
5412 assert_eq!(
5414 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5415 Segment::fin(ISS_2 + 1, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX)),
5416 clock.now(),
5417 &counters.refs(),
5418 ),
5419 (
5420 Some(Segment::ack(
5421 ISS_1 + 1,
5422 ISS_2 + 2,
5423 UnscaledWindowSize::from_usize(BUFFER_SIZE - 1)
5424 )),
5425 None
5426 )
5427 );
5428 assert_eq!(
5430 state.close(
5431 &counters.refs(),
5432 CloseReason::Shutdown,
5433 &SocketOptions::default_for_state_tests()
5434 ),
5435 Ok(NewlyClosed::No)
5436 );
5437 assert_eq!(
5438 state,
5439 State::LastAck(LastAck {
5440 snd: Send {
5441 nxt: ISS_1 + 1,
5442 max: ISS_1 + 1,
5443 una: ISS_1 + 1,
5444 wnd: WindowSize::DEFAULT,
5445 wnd_max: WindowSize::DEFAULT,
5446 buffer: send_buffer,
5447 wl1: ISS_2 + 1,
5448 wl2: ISS_1 + 1,
5449 rtt_sampler: RttSampler::default(),
5450 rtt_estimator: Estimator::default(),
5451 timer: None,
5452 congestion_control: CongestionControl::cubic_with_mss(
5453 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE
5454 ),
5455 wnd_scale: WindowScale::default(),
5456 },
5457 closed_rcv: RecvParams { ack: ISS_2 + 2, wnd: last_wnd, wnd_scale: last_wnd_scale }
5458 })
5459 );
5460 assert_eq!(
5462 state.poll_send_with_default_options(2, clock.now(), &counters.refs()),
5463 Some(Segment::data(
5464 ISS_1 + 1,
5465 ISS_2 + 2,
5466 last_wnd >> WindowScale::default(),
5467 FragmentedPayload::new_contiguous(&TEST_BYTES[..2]),
5468 ))
5469 );
5470 assert_eq!(
5472 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5473 Some(Segment::piggybacked_fin(
5474 ISS_1 + 3,
5475 ISS_2 + 2,
5476 last_wnd >> WindowScale::default(),
5477 FragmentedPayload::new_contiguous(&TEST_BYTES[2..]),
5478 ))
5479 );
5480 clock.sleep(RTT);
5482 assert_eq!(
5483 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5484 Segment::ack(
5485 ISS_2 + 2,
5486 ISS_1 + 1 + TEST_BYTES.len(),
5487 UnscaledWindowSize::from(u16::MAX)
5488 ),
5489 clock.now(),
5490 &counters.refs(),
5491 ),
5492 (None, None)
5493 );
5494 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
5495 clock.sleep(Rto::DEFAULT.get());
5496 assert_eq!(
5498 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5499 Some(Segment::fin(
5500 ISS_1 + 1 + TEST_BYTES.len(),
5501 ISS_2 + 2,
5502 last_wnd >> WindowScale::default()
5503 ))
5504 );
5505
5506 assert_eq!(
5508 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5509 Segment::ack(
5510 ISS_2 + 2,
5511 ISS_1 + 1 + TEST_BYTES.len() + 1,
5512 UnscaledWindowSize::from(u16::MAX),
5513 ),
5514 clock.now(),
5515 &counters.refs(),
5516 ),
5517 (None, None)
5518 );
5519 assert_eq!(state, State::Closed(Closed { reason: None }));
5521 CounterExpectations {
5522 retransmits: 1,
5523 slow_start_retransmits: 1,
5524 timeouts: 1,
5525 established_closed: 1,
5526 ..Default::default()
5527 }
5528 .assert_counters(&counters);
5529 }
5530
5531 #[test]
5532 fn syn_rcvd_active_close() {
5533 let counters = FakeTcpCounters::default();
5534 let mut state: State<_, RingBuffer, NullBuffer, ()> = State::SynRcvd(SynRcvd {
5535 iss: ISS_1,
5536 irs: ISS_2,
5537 timestamp: None,
5538 retrans_timer: RetransTimer {
5539 at: FakeInstant::default(),
5540 rto: Rto::MIN,
5541 user_timeout_until: None,
5542 remaining_retries: Some(DEFAULT_MAX_RETRIES),
5543 },
5544 simultaneous_open: Some(()),
5545 buffer_sizes: Default::default(),
5546 smss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
5547 rcv_wnd_scale: WindowScale::default(),
5548 snd_wnd_scale: Some(WindowScale::default()),
5549 sack_permitted: SACK_PERMITTED,
5550 });
5551 assert_eq!(
5552 state.close(
5553 &counters.refs(),
5554 CloseReason::Shutdown,
5555 &SocketOptions::default_for_state_tests()
5556 ),
5557 Ok(NewlyClosed::No)
5558 );
5559 assert_matches!(state, State::FinWait1(_));
5560 assert_eq!(
5561 state.poll_send_with_default_options(
5562 u32::MAX,
5563 FakeInstant::default(),
5564 &counters.refs()
5565 ),
5566 Some(Segment::fin(ISS_1 + 1, ISS_2 + 1, UnscaledWindowSize::from(u16::MAX)))
5567 );
5568 }
5569
5570 #[test]
5571 fn established_active_close() {
5572 let mut clock = FakeInstantCtx::default();
5573 let counters = FakeTcpCounters::default();
5574 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
5575 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), 5);
5576 let mut state = State::Established(Established {
5578 snd: Send {
5579 nxt: ISS_1 + 1,
5580 max: ISS_1 + 1,
5581 una: ISS_1 + 1,
5582 wnd: WindowSize::DEFAULT,
5583 wnd_max: WindowSize::DEFAULT,
5584 buffer: send_buffer.clone(),
5585 wl1: ISS_2,
5586 wl2: ISS_1,
5587 rtt_sampler: RttSampler::default(),
5588 rtt_estimator: Estimator::default(),
5589 timer: None,
5590 congestion_control: CongestionControl::cubic_with_mss(Mss(
5591 NonZeroU16::new(5).unwrap()
5592 )),
5593 wnd_scale: WindowScale::default(),
5594 }
5595 .into(),
5596 rcv: Recv {
5597 buffer: RecvBufferState::Open {
5598 buffer: RingBuffer::new(BUFFER_SIZE),
5599 assembler: Assembler::new(ISS_2 + 1),
5600 },
5601 timer: None,
5602 remaining_quickacks: 0,
5603 last_segment_at: None,
5604 mss: Mss(NonZeroU16::new(5).unwrap()),
5605 wnd_scale: WindowScale::default(),
5606 last_window_update: (ISS_2 + 1, WindowSize::new(BUFFER_SIZE).unwrap()),
5607 sack_permitted: SACK_PERMITTED,
5608 }
5609 .into(),
5610 });
5611 assert_eq!(
5612 state.close(
5613 &counters.refs(),
5614 CloseReason::Shutdown,
5615 &SocketOptions::default_for_state_tests()
5616 ),
5617 Ok(NewlyClosed::No)
5618 );
5619 assert_matches!(state, State::FinWait1(_));
5620 assert_eq!(
5621 state.close(
5622 &counters.refs(),
5623 CloseReason::Shutdown,
5624 &SocketOptions::default_for_state_tests()
5625 ),
5626 Err(CloseError::Closing)
5627 );
5628
5629 assert_eq!(
5631 state.poll_send_with_default_options(2, clock.now(), &counters.refs()),
5632 Some(Segment::data(
5633 ISS_1 + 1,
5634 ISS_2 + 1,
5635 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5636 FragmentedPayload::new_contiguous(&TEST_BYTES[..2])
5637 ))
5638 );
5639
5640 assert_eq!(
5642 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5643 Some(Segment::piggybacked_fin(
5644 ISS_1 + 3,
5645 ISS_2 + 1,
5646 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5647 FragmentedPayload::new_contiguous(&TEST_BYTES[2..])
5648 ))
5649 );
5650
5651 assert_eq!(
5653 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5654 Segment::data(
5655 ISS_2 + 1,
5656 ISS_1 + 1 + 1,
5657 UnscaledWindowSize::from(u16::MAX),
5658 TEST_BYTES
5659 ),
5660 clock.now(),
5661 &counters.refs(),
5662 ),
5663 (
5664 Some(Segment::ack(
5665 ISS_1 + TEST_BYTES.len() + 2,
5666 ISS_2 + TEST_BYTES.len() + 1,
5667 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len()),
5668 )),
5669 None
5670 )
5671 );
5672
5673 assert_eq!(
5674 state.read_with(|avail| {
5675 let got = avail.concat();
5676 assert_eq!(got, TEST_BYTES);
5677 got.len()
5678 }),
5679 TEST_BYTES.len()
5680 );
5681
5682 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
5684
5685 clock.sleep(Rto::DEFAULT.get());
5687 assert_eq!(
5688 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5689 Some(Segment::piggybacked_fin(
5690 ISS_1 + 2,
5691 ISS_2 + TEST_BYTES.len() + 1,
5692 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5693 FragmentedPayload::new_contiguous(&TEST_BYTES[1..]),
5694 ))
5695 );
5696
5697 assert_eq!(
5699 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5700 Segment::ack(
5701 ISS_2 + TEST_BYTES.len() + 1,
5702 ISS_1 + TEST_BYTES.len() + 2,
5703 UnscaledWindowSize::from(u16::MAX)
5704 ),
5705 clock.now(),
5706 &counters.refs(),
5707 ),
5708 (None, None)
5709 );
5710 assert_matches!(state, State::FinWait2(_));
5711
5712 assert_eq!(
5714 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5715 Segment::data(
5716 ISS_2 + 1 + TEST_BYTES.len(),
5717 ISS_1 + TEST_BYTES.len() + 2,
5718 UnscaledWindowSize::from(u16::MAX),
5719 TEST_BYTES
5720 ),
5721 clock.now(),
5722 &counters.refs(),
5723 ),
5724 (
5725 Some(Segment::ack(
5726 ISS_1 + TEST_BYTES.len() + 2,
5727 ISS_2 + 2 * TEST_BYTES.len() + 1,
5728 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len()),
5729 )),
5730 None
5731 )
5732 );
5733
5734 assert_eq!(
5735 state.read_with(|avail| {
5736 let got = avail.concat();
5737 assert_eq!(got, TEST_BYTES);
5738 got.len()
5739 }),
5740 TEST_BYTES.len()
5741 );
5742
5743 assert_eq!(
5745 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5746 Segment::fin(
5747 ISS_2 + 2 * TEST_BYTES.len() + 1,
5748 ISS_1 + TEST_BYTES.len() + 2,
5749 UnscaledWindowSize::from(u16::MAX)
5750 ),
5751 clock.now(),
5752 &counters.refs(),
5753 ),
5754 (
5755 Some(Segment::ack(
5756 ISS_1 + TEST_BYTES.len() + 2,
5757 ISS_2 + 2 * TEST_BYTES.len() + 2,
5758 UnscaledWindowSize::from_usize(BUFFER_SIZE - 1),
5759 )),
5760 None
5761 )
5762 );
5763
5764 assert_matches!(state, State::TimeWait(_));
5765
5766 const SMALLEST_DURATION: Duration = Duration::from_secs(1);
5767 assert_eq!(state.poll_send_at(), Some(clock.now() + MSL * 2));
5768 clock.sleep(MSL * 2 - SMALLEST_DURATION);
5769 assert_eq!(
5771 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5772 None
5773 );
5774 assert_matches!(state, State::TimeWait(_));
5775 clock.sleep(SMALLEST_DURATION);
5776 assert_eq!(
5778 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5779 None
5780 );
5781 assert_eq!(state, State::Closed(Closed { reason: None }));
5782 CounterExpectations {
5783 retransmits: 1,
5784 slow_start_retransmits: 1,
5785 timeouts: 1,
5786 established_closed: 1,
5787 ..Default::default()
5788 }
5789 .assert_counters(&counters);
5790 }
5791
5792 #[test]
5793 fn fin_wait_1_fin_ack_to_time_wait() {
5794 let counters = FakeTcpCounters::default();
5795 let mut state = State::FinWait1(FinWait1 {
5798 snd: Send {
5799 nxt: ISS_1 + 2,
5800 max: ISS_1 + 2,
5801 una: ISS_1 + 1,
5802 wnd: WindowSize::DEFAULT,
5803 wnd_max: WindowSize::DEFAULT,
5804 buffer: NullBuffer,
5805 wl1: ISS_2,
5806 wl2: ISS_1,
5807 rtt_sampler: RttSampler::default(),
5808 rtt_estimator: Estimator::default(),
5809 timer: None,
5810 congestion_control: CongestionControl::cubic_with_mss(
5811 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
5812 ),
5813 wnd_scale: WindowScale::default(),
5814 }
5815 .into(),
5816 rcv: Recv {
5817 buffer: RecvBufferState::Open {
5818 buffer: RingBuffer::new(BUFFER_SIZE),
5819 assembler: Assembler::new(ISS_2 + 1),
5820 },
5821 timer: None,
5822 remaining_quickacks: 0,
5823 last_segment_at: None,
5824 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
5825 wnd_scale: WindowScale::default(),
5826 last_window_update: (ISS_2 + 1, WindowSize::new(BUFFER_SIZE).unwrap()),
5827 sack_permitted: SACK_PERMITTED,
5828 }
5829 .into(),
5830 });
5831 assert_eq!(
5832 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5833 Segment::fin(ISS_2 + 1, ISS_1 + 2, UnscaledWindowSize::from(u16::MAX)),
5834 FakeInstant::default(),
5835 &counters.refs(),
5836 ),
5837 (
5838 Some(Segment::ack(
5839 ISS_1 + 2,
5840 ISS_2 + 2,
5841 UnscaledWindowSize::from_usize(BUFFER_SIZE - 1)
5842 )),
5843 None
5844 ),
5845 );
5846 assert_matches!(state, State::TimeWait(_));
5847 }
5848
5849 #[test]
5850 fn simultaneous_close() {
5851 let mut clock = FakeInstantCtx::default();
5852 let counters = FakeTcpCounters::default();
5853 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
5854 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), 5);
5855 let mut state = State::Established(Established {
5857 snd: Send {
5858 nxt: ISS_1 + 1,
5859 max: ISS_1 + 1,
5860 una: ISS_1 + 1,
5861 wnd: WindowSize::DEFAULT,
5862 wnd_max: WindowSize::DEFAULT,
5863 buffer: send_buffer.clone(),
5864 wl1: ISS_2,
5865 wl2: ISS_1,
5866 rtt_sampler: RttSampler::default(),
5867 rtt_estimator: Estimator::default(),
5868 timer: None,
5869 congestion_control: CongestionControl::cubic_with_mss(
5870 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
5871 ),
5872 wnd_scale: WindowScale::default(),
5873 }
5874 .into(),
5875 rcv: Recv {
5876 buffer: RecvBufferState::Open {
5877 buffer: RingBuffer::new(BUFFER_SIZE),
5878 assembler: Assembler::new(ISS_1 + 1),
5879 },
5880 timer: None,
5881 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
5882 wnd_scale: WindowScale::default(),
5883 last_window_update: (ISS_1 + 1, WindowSize::new(BUFFER_SIZE).unwrap()),
5884 remaining_quickacks: 0,
5885 last_segment_at: None,
5886 sack_permitted: SACK_PERMITTED,
5887 }
5888 .into(),
5889 });
5890 assert_eq!(
5891 state.close(
5892 &counters.refs(),
5893 CloseReason::Shutdown,
5894 &SocketOptions::default_for_state_tests()
5895 ),
5896 Ok(NewlyClosed::No)
5897 );
5898 assert_matches!(state, State::FinWait1(_));
5899 assert_eq!(
5900 state.close(
5901 &counters.refs(),
5902 CloseReason::Shutdown,
5903 &SocketOptions::default_for_state_tests()
5904 ),
5905 Err(CloseError::Closing)
5906 );
5907
5908 let fin = state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs());
5909 assert_eq!(
5910 fin,
5911 Some(Segment::piggybacked_fin(
5912 ISS_1 + 1,
5913 ISS_1 + 1,
5914 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5915 FragmentedPayload::new_contiguous(TEST_BYTES),
5916 ))
5917 );
5918 assert_eq!(
5919 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5920 Segment::piggybacked_fin(
5921 ISS_1 + 1,
5922 ISS_1 + 1,
5923 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5924 TEST_BYTES,
5925 ),
5926 clock.now(),
5927 &counters.refs(),
5928 ),
5929 (
5930 Some(Segment::ack(
5931 ISS_1 + TEST_BYTES.len() + 2,
5932 ISS_1 + TEST_BYTES.len() + 2,
5933 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len() - 1),
5934 )),
5935 None
5936 )
5937 );
5938
5939 assert_matches!(state, State::Closing(_));
5942 assert_eq!(
5943 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5944 Segment::ack(
5945 ISS_1 + TEST_BYTES.len() + 2,
5946 ISS_1 + TEST_BYTES.len() + 2,
5947 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len() - 1),
5948 ),
5949 clock.now(),
5950 &counters.refs(),
5951 ),
5952 (None, None)
5953 );
5954
5955 assert_matches!(state, State::TimeWait(_));
5958
5959 const SMALLEST_DURATION: Duration = Duration::from_secs(1);
5960 assert_eq!(state.poll_send_at(), Some(clock.now() + MSL * 2));
5961 clock.sleep(MSL * 2 - SMALLEST_DURATION);
5962 assert_eq!(
5964 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5965 None
5966 );
5967 assert_matches!(state, State::TimeWait(_));
5968 clock.sleep(SMALLEST_DURATION);
5969 assert_eq!(
5971 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
5972 None
5973 );
5974 assert_eq!(state, State::Closed(Closed { reason: None }));
5975 CounterExpectations { established_closed: 1, ..Default::default() }
5976 .assert_counters(&counters);
5977 }
5978
5979 #[test]
5980 fn time_wait_restarts_timer() {
5981 let mut clock = FakeInstantCtx::default();
5982 let counters = FakeTcpCounters::default();
5983 let mut time_wait = State::<_, NullBuffer, NullBuffer, ()>::TimeWait(TimeWait {
5984 last_seq: ISS_1 + 2,
5985 closed_rcv: RecvParams {
5986 ack: ISS_2 + 2,
5987 wnd: WindowSize::DEFAULT,
5988 wnd_scale: WindowScale::default(),
5989 },
5990 expiry: new_time_wait_expiry(clock.now()),
5991 });
5992
5993 assert_eq!(time_wait.poll_send_at(), Some(clock.now() + MSL * 2));
5994 clock.sleep(Duration::from_secs(1));
5995 assert_eq!(
5996 time_wait.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5997 Segment::fin(ISS_2 + 2, ISS_1 + 2, UnscaledWindowSize::from(u16::MAX)),
5998 clock.now(),
5999 &counters.refs(),
6000 ),
6001 (Some(Segment::ack(ISS_1 + 2, ISS_2 + 2, UnscaledWindowSize::from(u16::MAX))), None),
6002 );
6003 assert_eq!(time_wait.poll_send_at(), Some(clock.now() + MSL * 2));
6004 }
6005
6006 #[test_case(
6007 State::Established(Established {
6008 snd: Send {
6009 nxt: ISS_1,
6010 max: ISS_1,
6011 una: ISS_1,
6012 wnd: WindowSize::DEFAULT,
6013 wnd_max: WindowSize::DEFAULT,
6014 buffer: NullBuffer,
6015 wl1: ISS_2,
6016 wl2: ISS_1,
6017 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
6018 rtt_sampler: RttSampler::default(),
6019 timer: None,
6020 congestion_control: CongestionControl::cubic_with_mss(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
6021 wnd_scale: WindowScale::default(),
6022 }.into(),
6023 rcv: Recv {
6024 buffer: RecvBufferState::Open {
6025 buffer: RingBuffer::default(),
6026 assembler: Assembler::new(ISS_2 + 5),
6027 },
6028 timer: None,
6029 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6030 wnd_scale: WindowScale::default(),
6031 last_window_update: (ISS_2 + 5, WindowSize::DEFAULT),
6032 remaining_quickacks: 0,
6033 last_segment_at: None,
6034 sack_permitted: SACK_PERMITTED,
6035 }.into(),
6036 }),
6037 Segment::data(ISS_2, ISS_1, UnscaledWindowSize::from(u16::MAX), TEST_BYTES) =>
6038 Some(Segment::ack(ISS_1, ISS_2 + 5, UnscaledWindowSize::from(u16::MAX))); "retransmit data"
6039 )]
6040 #[test_case(
6041 State::SynRcvd(SynRcvd {
6042 iss: ISS_1,
6043 irs: ISS_2,
6044 timestamp: None,
6045 retrans_timer: RetransTimer {
6046 at: FakeInstant::default(),
6047 rto: Rto::MIN,
6048 user_timeout_until: None,
6049 remaining_retries: Some(DEFAULT_MAX_RETRIES),
6050 },
6051 simultaneous_open: None,
6052 buffer_sizes: BufferSizes::default(),
6053 smss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6054 rcv_wnd_scale: WindowScale::default(),
6055 snd_wnd_scale: Some(WindowScale::default()),
6056 sack_permitted: SACK_PERMITTED,
6057 }),
6058 Segment::syn_ack(ISS_2, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX),
6059 HandshakeOptions { window_scale: Some(WindowScale::default()), ..Default::default() }.into()) =>
6060 Some(Segment::ack(ISS_1 + 1, ISS_2 + 1, UnscaledWindowSize::from(u16::MAX))); "retransmit syn_ack"
6061 )]
6062 fn ack_to_retransmitted_segment(
6064 mut state: State<FakeInstant, RingBuffer, NullBuffer, ()>,
6065 seg: Segment<&[u8]>,
6066 ) -> Option<Segment<()>> {
6067 let counters = FakeTcpCounters::default();
6068 let (reply, _): (_, Option<()>) = state
6069 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
6070 seg,
6071 FakeInstant::default(),
6072 &counters.refs(),
6073 );
6074 reply
6075 }
6076
6077 #[test]
6078 fn fast_retransmit() {
6079 let mut clock = FakeInstantCtx::default();
6080 let counters = FakeTcpCounters::default();
6081 let mut send_buffer = RingBuffer::default();
6082 for b in b'A'..=b'D' {
6083 assert_eq!(
6084 send_buffer.enqueue_data(&[b; DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE_USIZE]),
6085 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE_USIZE
6086 );
6087 }
6088 let mut state: State<_, _, _, ()> = State::Established(Established {
6089 snd: Send {
6090 nxt: ISS_1,
6091 max: ISS_1,
6092 una: ISS_1,
6093 wnd: WindowSize::DEFAULT,
6094 wnd_max: WindowSize::DEFAULT,
6095 buffer: send_buffer,
6096 wl1: ISS_2,
6097 wl2: ISS_1,
6098 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
6099 rtt_sampler: RttSampler::default(),
6100 timer: None,
6101 congestion_control: CongestionControl::cubic_with_mss(
6102 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6103 ),
6104 wnd_scale: WindowScale::default(),
6105 }
6106 .into(),
6107 rcv: Recv {
6108 buffer: RecvBufferState::Open {
6109 buffer: RingBuffer::default(),
6110 assembler: Assembler::new(ISS_2),
6111 },
6112 timer: None,
6113 remaining_quickacks: 0,
6114 last_segment_at: None,
6115 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6116 wnd_scale: WindowScale::default(),
6117 last_window_update: (ISS_2, WindowSize::DEFAULT),
6118 sack_permitted: SACK_PERMITTED,
6119 }
6120 .into(),
6121 });
6122
6123 assert_eq!(
6124 state.poll_send_with_default_options(
6125 u32::from(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
6126 clock.now(),
6127 &counters.refs(),
6128 ),
6129 Some(Segment::data(
6130 ISS_1,
6131 ISS_2,
6132 UnscaledWindowSize::from(u16::MAX),
6133 FragmentedPayload::new_contiguous(&[b'A'; DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE_USIZE])
6134 ))
6135 );
6136
6137 let mut dup_ack = |expected_byte: u8, counters: &TcpCountersRefs<'_>| {
6138 clock.sleep(Duration::from_millis(10));
6139 assert_eq!(
6140 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6141 Segment::ack(ISS_2, ISS_1, UnscaledWindowSize::from(u16::MAX)),
6142 clock.now(),
6143 counters,
6144 ),
6145 (None, None)
6146 );
6147
6148 assert_eq!(
6149 state.poll_send_with_default_options(
6150 u32::from(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
6151 clock.now(),
6152 counters,
6153 ),
6154 Some(Segment::data(
6155 ISS_1
6156 + u32::from(expected_byte - b'A')
6157 * u32::from(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
6158 ISS_2,
6159 UnscaledWindowSize::from(u16::MAX),
6160 FragmentedPayload::new_contiguous(
6161 &[expected_byte; DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE_USIZE]
6162 )
6163 ))
6164 );
6165 };
6166
6167 CounterExpectations::default().assert_counters(&counters);
6170 dup_ack(b'B', &counters.refs());
6171 CounterExpectations { fast_recovery: 1, ..Default::default() }.assert_counters(&counters);
6172 dup_ack(b'C', &counters.refs());
6173 CounterExpectations { fast_recovery: 1, ..Default::default() }.assert_counters(&counters);
6174 dup_ack(b'A', &counters.refs());
6177 CounterExpectations {
6178 retransmits: 1,
6179 fast_recovery: 1,
6180 fast_retransmits: 1,
6181 ..Default::default()
6182 }
6183 .assert_counters(&counters);
6184 dup_ack(b'D', &counters.refs());
6186 CounterExpectations {
6187 retransmits: 1,
6188 fast_recovery: 1,
6189 fast_retransmits: 1,
6190 ..Default::default()
6191 }
6192 .assert_counters(&counters);
6193
6194 clock.sleep(Duration::from_millis(10));
6196 assert_eq!(
6197 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6198 Segment::ack(
6199 ISS_2,
6200 ISS_1 + u32::from(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
6201 UnscaledWindowSize::from(u16::MAX)
6202 ),
6203 clock.now(),
6204 &counters.refs(),
6205 ),
6206 (None, None)
6207 );
6208 let established = assert_matches!(state, State::Established(established) => established);
6209 assert_eq!(
6210 u32::from(established.snd.congestion_control.cwnd()),
6211 2 * u32::from(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE)
6212 );
6213 }
6214
6215 #[test]
6216 fn keep_alive() {
6217 let mut clock = FakeInstantCtx::default();
6218 let counters = FakeTcpCounters::default();
6219 let mut state: State<_, _, _, ()> = State::Established(Established {
6220 snd: Send {
6221 nxt: ISS_1,
6222 max: ISS_1,
6223 una: ISS_1,
6224 wnd: WindowSize::DEFAULT,
6225 wnd_max: WindowSize::DEFAULT,
6226 buffer: RingBuffer::default(),
6227 wl1: ISS_2,
6228 wl2: ISS_1,
6229 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
6230 rtt_sampler: RttSampler::default(),
6231 timer: None,
6232 congestion_control: CongestionControl::cubic_with_mss(
6233 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6234 ),
6235 wnd_scale: WindowScale::default(),
6236 }
6237 .into(),
6238 rcv: Recv {
6239 buffer: RecvBufferState::Open {
6240 buffer: RingBuffer::default(),
6241 assembler: Assembler::new(ISS_2),
6242 },
6243 timer: None,
6244 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6245 wnd_scale: WindowScale::default(),
6246 last_window_update: (ISS_2, WindowSize::DEFAULT),
6247 remaining_quickacks: 0,
6248 last_segment_at: None,
6249 sack_permitted: SACK_PERMITTED,
6250 }
6251 .into(),
6252 });
6253
6254 let socket_options = {
6255 let mut socket_options = SocketOptions::default_for_state_tests();
6256 socket_options.keep_alive.enabled = true;
6257 socket_options
6258 };
6259 let socket_options = &socket_options;
6260 let keep_alive = &socket_options.keep_alive;
6261
6262 assert_eq!(
6264 state.poll_send(
6265 &FakeStateMachineDebugId,
6266 &counters.refs(),
6267 u32::from(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
6268 clock.now(),
6269 socket_options,
6270 ),
6271 Err(NewlyClosed::No),
6272 );
6273 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(keep_alive.idle.into())));
6276
6277 clock.sleep(Duration::from_secs(60 * 60));
6279 assert_eq!(
6280 state.on_segment::<&[u8], ClientlessBufferProvider>(
6281 &FakeStateMachineDebugId,
6282 &counters.refs(),
6283 Segment::ack(ISS_2, ISS_1, UnscaledWindowSize::from(u16::MAX)),
6284 clock.now(),
6285 socket_options,
6286 false, ),
6288 (None, None, DataAcked::No, NewlyClosed::No)
6289 );
6290 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(keep_alive.idle.into())),);
6292 clock.sleep(keep_alive.idle.into());
6293
6294 for _ in 0..keep_alive.count.get() {
6297 assert_eq!(
6298 state.poll_send(
6299 &FakeStateMachineDebugId,
6300 &counters.refs(),
6301 u32::from(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
6302 clock.now(),
6303 socket_options,
6304 ),
6305 Ok(Segment::ack(ISS_1 - 1, ISS_2, UnscaledWindowSize::from(u16::MAX)))
6306 );
6307 clock.sleep(keep_alive.interval.into());
6308 assert_matches!(state, State::Established(_));
6309 }
6310
6311 assert_eq!(
6314 state.poll_send(
6315 &FakeStateMachineDebugId,
6316 &counters.refs(),
6317 u32::from(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
6318 clock.now(),
6319 socket_options,
6320 ),
6321 Err(NewlyClosed::Yes),
6322 );
6323 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
6324 CounterExpectations {
6325 established_closed: 1,
6326 established_timedout: 1,
6327 ..Default::default()
6328 }
6329 .assert_counters(&counters);
6330 }
6331
6332 #[derive(Debug)]
6334 struct ReservingBuffer<B> {
6335 buffer: B,
6336 reserved_bytes: usize,
6337 }
6338
6339 impl<B: Buffer> Buffer for ReservingBuffer<B> {
6340 fn capacity_range() -> (usize, usize) {
6341 B::capacity_range()
6342 }
6343
6344 fn limits(&self) -> BufferLimits {
6345 self.buffer.limits()
6346 }
6347
6348 fn target_capacity(&self) -> usize {
6349 self.buffer.target_capacity()
6350 }
6351
6352 fn request_capacity(&mut self, size: usize) {
6353 self.buffer.request_capacity(size)
6354 }
6355 }
6356
6357 impl<B: SendBuffer> SendBuffer for ReservingBuffer<B> {
6358 type Payload<'a> = B::Payload<'a>;
6359
6360 fn mark_read(&mut self, count: usize) {
6361 self.buffer.mark_read(count)
6362 }
6363
6364 fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
6365 where
6366 F: FnOnce(B::Payload<'a>) -> R,
6367 {
6368 let Self { buffer, reserved_bytes } = self;
6369 buffer.peek_with(offset, |payload| {
6370 let len = payload.len();
6371 let new_len = len.saturating_sub(*reserved_bytes);
6372 f(payload.slice(0..new_len.try_into().unwrap_or(u32::MAX)))
6373 })
6374 }
6375 }
6376
6377 #[test_case(true, 0)]
6378 #[test_case(false, 0)]
6379 #[test_case(true, 1)]
6380 #[test_case(false, 1)]
6381 fn poll_send_len(has_fin: bool, reserved_bytes: usize) {
6382 const VALUE: u8 = 0xaa;
6383
6384 fn with_poll_send_result<const HAS_FIN: bool>(
6385 f: impl FnOnce(Segment<FragmentedPayload<'_, 2>>),
6386 reserved_bytes: usize,
6387 ) {
6388 const DATA_LEN: usize = 40;
6389 let buffer = ReservingBuffer {
6390 buffer: RingBuffer::with_data(DATA_LEN, &vec![VALUE; DATA_LEN]),
6391 reserved_bytes,
6392 };
6393 assert_eq!(buffer.limits().len, DATA_LEN);
6394
6395 let mut snd = Send::<FakeInstant, _, HAS_FIN> {
6396 nxt: ISS_1,
6397 max: ISS_1,
6398 una: ISS_1,
6399 wnd: WindowSize::DEFAULT,
6400 wnd_max: WindowSize::DEFAULT,
6401 buffer,
6402 wl1: ISS_2,
6403 wl2: ISS_1,
6404 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
6405 rtt_sampler: RttSampler::default(),
6406 timer: None,
6407 congestion_control: CongestionControl::cubic_with_mss(
6408 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6409 ),
6410 wnd_scale: WindowScale::default(),
6411 };
6412
6413 let counters = FakeTcpCounters::default();
6414
6415 f(snd
6416 .poll_send(
6417 &FakeStateMachineDebugId,
6418 &counters.refs(),
6419 &RecvParams {
6420 ack: ISS_1,
6421 wnd: WindowSize::DEFAULT,
6422 wnd_scale: WindowScale::ZERO,
6423 },
6424 u32::from(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
6425 FakeInstant::default(),
6426 &SocketOptions::default_for_state_tests(),
6427 )
6428 .expect("has data"))
6429 }
6430
6431 let f = |segment: Segment<FragmentedPayload<'_, 2>>| {
6432 let segment_len = segment.len();
6433 let Segment { header: _, data } = segment;
6434 let data_len = data.len();
6435
6436 if has_fin && reserved_bytes == 0 {
6437 assert_eq!(
6438 segment_len,
6439 u32::try_from(data_len + 1).unwrap(),
6440 "FIN not accounted for"
6441 );
6442 } else {
6443 assert_eq!(segment_len, u32::try_from(data_len).unwrap());
6444 }
6445
6446 let mut target = vec![0; data_len];
6447 data.partial_copy(0, target.as_mut_slice());
6448 assert_eq!(target, vec![VALUE; data_len]);
6449 };
6450 match has_fin {
6451 true => with_poll_send_result::<true>(f, reserved_bytes),
6452 false => with_poll_send_result::<false>(f, reserved_bytes),
6453 }
6454 }
6455
6456 #[test]
6457 fn zero_window_probe() {
6458 let mut clock = FakeInstantCtx::default();
6459 let counters = FakeTcpCounters::default();
6460 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
6461 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), 5);
6462 let mut state = State::Established(Established {
6464 snd: Send {
6465 nxt: ISS_1 + 1,
6466 max: ISS_1 + 1,
6467 una: ISS_1 + 1,
6468 wnd: WindowSize::ZERO,
6469 wnd_max: WindowSize::ZERO,
6470 buffer: send_buffer.clone(),
6471 wl1: ISS_2,
6472 wl2: ISS_1,
6473 rtt_sampler: RttSampler::default(),
6474 rtt_estimator: Estimator::default(),
6475 timer: None,
6476 congestion_control: CongestionControl::cubic_with_mss(
6477 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6478 ),
6479 wnd_scale: WindowScale::default(),
6480 }
6481 .into(),
6482 rcv: Recv {
6483 buffer: RecvBufferState::Open {
6484 buffer: RingBuffer::new(BUFFER_SIZE),
6485 assembler: Assembler::new(ISS_2 + 1),
6486 },
6487 timer: None,
6488 remaining_quickacks: 0,
6489 last_segment_at: None,
6490 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6491 wnd_scale: WindowScale::default(),
6492 last_window_update: (ISS_2 + 1, WindowSize::new(BUFFER_SIZE).unwrap()),
6493 sack_permitted: SACK_PERMITTED,
6494 }
6495 .into(),
6496 });
6497 assert_eq!(
6498 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
6499 None
6500 );
6501 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(Rto::DEFAULT.get())));
6502
6503 clock.sleep(Rto::DEFAULT.get());
6505 assert_eq!(
6506 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
6507 Some(Segment::data(
6508 ISS_1 + 1,
6509 ISS_2 + 1,
6510 UnscaledWindowSize::from_usize(BUFFER_SIZE),
6511 FragmentedPayload::new_contiguous(&TEST_BYTES[0..1])
6512 ))
6513 );
6514
6515 assert_eq!(
6517 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6518 Segment::ack(ISS_2 + 1, ISS_1 + 1, UnscaledWindowSize::from(0)),
6519 clock.now(),
6520 &counters.refs(),
6521 ),
6522 (None, None)
6523 );
6524 assert_eq!(
6526 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
6527 None
6528 );
6529 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(Rto::DEFAULT.get() * 2)));
6530
6531 clock.sleep(Rto::DEFAULT.get());
6533 assert_eq!(
6534 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
6535 None
6536 );
6537
6538 clock.sleep(Rto::DEFAULT.get());
6540 assert_eq!(
6541 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
6542 Some(Segment::data(
6543 ISS_1 + 1,
6544 ISS_2 + 1,
6545 UnscaledWindowSize::from_usize(BUFFER_SIZE),
6546 FragmentedPayload::new_contiguous(&TEST_BYTES[0..1])
6547 ))
6548 );
6549
6550 assert_eq!(
6552 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6553 Segment::ack(ISS_2 + 1, ISS_1 + 2, UnscaledWindowSize::from(u16::MAX)),
6554 clock.now(),
6555 &counters.refs(),
6556 ),
6557 (None, None)
6558 );
6559 assert_eq!(state.poll_send_at(), None);
6560 assert_eq!(
6561 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
6562 Some(Segment::data(
6563 ISS_1 + 2,
6564 ISS_2 + 1,
6565 UnscaledWindowSize::from_usize(BUFFER_SIZE),
6566 FragmentedPayload::new_contiguous(&TEST_BYTES[1..])
6567 ))
6568 );
6569 }
6570
6571 #[test]
6572 fn nagle() {
6573 let clock = FakeInstantCtx::default();
6574 let counters = FakeTcpCounters::default();
6575 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
6576 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), 5);
6577 let mut state: State<_, _, _, ()> = State::Established(Established {
6579 snd: Send {
6580 nxt: ISS_1 + 1,
6581 max: ISS_1 + 1,
6582 una: ISS_1 + 1,
6583 wnd: WindowSize::DEFAULT,
6584 wnd_max: WindowSize::DEFAULT,
6585 buffer: send_buffer.clone(),
6586 wl1: ISS_2,
6587 wl2: ISS_1,
6588 rtt_sampler: RttSampler::default(),
6589 rtt_estimator: Estimator::default(),
6590 timer: None,
6591 congestion_control: CongestionControl::cubic_with_mss(
6592 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6593 ),
6594 wnd_scale: WindowScale::default(),
6595 }
6596 .into(),
6597 rcv: Recv {
6598 buffer: RecvBufferState::Open {
6599 buffer: RingBuffer::new(BUFFER_SIZE),
6600 assembler: Assembler::new(ISS_2 + 1),
6601 },
6602 timer: None,
6603 remaining_quickacks: 0,
6604 last_segment_at: None,
6605 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6606 wnd_scale: WindowScale::default(),
6607 last_window_update: (ISS_2 + 1, WindowSize::new(BUFFER_SIZE).unwrap()),
6608 sack_permitted: SACK_PERMITTED,
6609 }
6610 .into(),
6611 });
6612 let mut socket_options =
6613 SocketOptions { nagle_enabled: true, ..SocketOptions::default_for_state_tests() };
6614 assert_eq!(
6615 state.poll_send(
6616 &FakeStateMachineDebugId,
6617 &counters.refs(),
6618 3,
6619 clock.now(),
6620 &socket_options
6621 ),
6622 Ok(Segment::data(
6623 ISS_1 + 1,
6624 ISS_2 + 1,
6625 UnscaledWindowSize::from_usize(BUFFER_SIZE),
6626 FragmentedPayload::new_contiguous(&TEST_BYTES[0..3])
6627 ))
6628 );
6629 assert_eq!(
6630 state.poll_send(
6631 &FakeStateMachineDebugId,
6632 &counters.refs(),
6633 3,
6634 clock.now(),
6635 &socket_options
6636 ),
6637 Err(NewlyClosed::No)
6638 );
6639 socket_options.nagle_enabled = false;
6640 assert_eq!(
6641 state.poll_send(
6642 &FakeStateMachineDebugId,
6643 &counters.refs(),
6644 3,
6645 clock.now(),
6646 &socket_options
6647 ),
6648 Ok(Segment::data(
6649 ISS_1 + 4,
6650 ISS_2 + 1,
6651 UnscaledWindowSize::from_usize(BUFFER_SIZE),
6652 FragmentedPayload::new_contiguous(&TEST_BYTES[3..5])
6653 ))
6654 );
6655 }
6656
6657 #[test]
6658 fn mss_option() {
6659 let clock = FakeInstantCtx::default();
6660 let counters = FakeTcpCounters::default();
6661 let (syn_sent, syn) = Closed::<Initial>::connect(
6662 ISS_1,
6663 clock.now(),
6664 (),
6665 Default::default(),
6666 Mss(NonZeroU16::new(1).unwrap()),
6667 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6668 &SocketOptions::default_for_state_tests(),
6669 );
6670 let mut state = State::<_, RingBuffer, RingBuffer, ()>::SynSent(syn_sent);
6671
6672 let (seg, passive_open) = state
6674 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
6675 syn,
6676 clock.now(),
6677 &counters.refs(),
6678 );
6679 let syn_ack = seg.expect("expected SYN-ACK");
6680 assert_eq!(passive_open, None);
6681
6682 assert_eq!(
6684 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
6685 syn_ack,
6686 clock.now(),
6687 &counters.refs(),
6688 ),
6689 (Some(Segment::ack(ISS_1 + 1, ISS_1 + 1, UnscaledWindowSize::from(u16::MAX))), None)
6690 );
6691 match state {
6692 State::Closed(_)
6693 | State::Listen(_)
6694 | State::SynRcvd(_)
6695 | State::SynSent(_)
6696 | State::LastAck(_)
6697 | State::FinWait1(_)
6698 | State::FinWait2(_)
6699 | State::Closing(_)
6700 | State::TimeWait(_) => {
6701 panic!("expected that we have entered established state, but got {:?}", state)
6702 }
6703 State::Established(Established { ref mut snd, rcv: _ })
6704 | State::CloseWait(CloseWait { ref mut snd, closed_rcv: _ }) => {
6705 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
6706 }
6707 }
6708 assert_eq!(
6710 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
6711 Some(Segment::data(
6712 ISS_1 + 1,
6713 ISS_1 + 1,
6714 UnscaledWindowSize::from(u16::MAX),
6715 FragmentedPayload::new_contiguous(&TEST_BYTES[..1]),
6716 ))
6717 );
6718 }
6719
6720 const TEST_USER_TIMEOUT: NonZeroDuration = NonZeroDuration::from_secs(2 * 60).unwrap();
6721
6722 #[test_case(Duration::from_millis(1), false, true; "retrans_max_retries")]
6726 #[test_case(Duration::from_secs(1), false, false; "retrans_no_max_retries")]
6727 #[test_case(Duration::from_millis(1), true, true; "zwp_max_retries")]
6728 #[test_case(Duration::from_secs(1), true, false; "zwp_no_max_retires")]
6729 fn user_timeout(rtt: Duration, zero_window_probe: bool, max_retries: bool) {
6730 let mut clock = FakeInstantCtx::default();
6731 let counters = FakeTcpCounters::default();
6732 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
6733 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), 5);
6734 let mut state: State<_, _, _, ()> = State::Established(Established {
6736 snd: Send {
6737 nxt: ISS_1 + 1,
6738 max: ISS_1 + 1,
6739 una: ISS_1 + 1,
6740 wnd: WindowSize::DEFAULT,
6741 wnd_max: WindowSize::DEFAULT,
6742 buffer: send_buffer.clone(),
6743 wl1: ISS_2 + 1,
6744 wl2: ISS_1 + 1,
6745 rtt_sampler: RttSampler::default(),
6746 rtt_estimator: Estimator::Measured { srtt: rtt, rtt_var: Duration::ZERO },
6747 timer: None,
6748 congestion_control: CongestionControl::cubic_with_mss(
6749 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6750 ),
6751 wnd_scale: WindowScale::default(),
6752 }
6753 .into(),
6754 rcv: Recv {
6755 buffer: RecvBufferState::Open {
6756 buffer: RingBuffer::new(BUFFER_SIZE),
6757 assembler: Assembler::new(ISS_2 + 1),
6758 },
6759 timer: None,
6760 remaining_quickacks: 0,
6761 last_segment_at: None,
6762 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6763 wnd_scale: WindowScale::default(),
6764 last_window_update: (ISS_2 + 1, WindowSize::DEFAULT),
6765 sack_permitted: SACK_PERMITTED,
6766 }
6767 .into(),
6768 });
6769 let mut times = 0;
6770 let start = clock.now();
6771 let socket_options = SocketOptions {
6772 user_timeout: (!max_retries).then_some(TEST_USER_TIMEOUT),
6773 ..SocketOptions::default_for_state_tests()
6774 };
6775 while let Ok(seg) = state.poll_send(
6776 &FakeStateMachineDebugId,
6777 &counters.refs(),
6778 u32::MAX,
6779 clock.now(),
6780 &socket_options,
6781 ) {
6782 if zero_window_probe {
6783 let zero_window_ack = Segment::ack(
6784 seg.header.ack.unwrap(),
6785 seg.header.seq,
6786 UnscaledWindowSize::from(0),
6787 );
6788 assert_matches!(
6789 state.on_segment::<(), ClientlessBufferProvider>(
6790 &FakeStateMachineDebugId,
6791 &counters.refs(),
6792 zero_window_ack,
6793 clock.now(),
6794 &socket_options,
6795 false,
6796 ),
6797 (None, None, DataAcked::No, _newly_closed)
6798 );
6799
6800 assert_matches!(
6805 state.poll_send(
6806 &FakeStateMachineDebugId,
6807 &counters.refs(),
6808 u32::MAX,
6809 clock.now(),
6810 &socket_options,
6811 ),
6812 Err(NewlyClosed::No)
6813 );
6814 let inner_state = assert_matches!(state, State::Established(ref e) => e);
6815 assert_matches!(inner_state.snd.timer, Some(SendTimer::ZeroWindowProbe(_)));
6816 }
6817
6818 let deadline = state.poll_send_at().expect("must have a retransmission timer");
6819 clock.sleep(deadline.checked_duration_since(clock.now()).unwrap());
6820 times += 1;
6821 }
6822 let elapsed = clock.now().checked_duration_since(start).unwrap();
6823 if max_retries {
6824 assert_eq!(times, 1 + DEFAULT_MAX_RETRIES.get());
6825 } else {
6826 assert_eq!(elapsed, TEST_USER_TIMEOUT.get());
6827 assert!(times < DEFAULT_MAX_RETRIES.get());
6828 }
6829 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
6830 CounterExpectations {
6831 established_closed: 1,
6832 established_timedout: 1,
6833 fast_retransmits: if zero_window_probe { 1 } else { 0 },
6834 fast_recovery: if zero_window_probe { 1 } else { 0 },
6835 timeouts: counters.stack_wide.timeouts.get(),
6838 retransmits: counters.stack_wide.retransmits.get(),
6839 slow_start_retransmits: counters.stack_wide.slow_start_retransmits.get(),
6840 ..Default::default()
6841 }
6842 .assert_counters(&counters);
6843 }
6844
6845 #[test]
6846 fn retrans_timer_backoff() {
6847 let mut clock = FakeInstantCtx::default();
6848 let mut timer = RetransTimer::new(
6849 clock.now(),
6850 Rto::DEFAULT,
6851 Some(TEST_USER_TIMEOUT),
6852 DEFAULT_MAX_RETRIES,
6853 );
6854 assert_eq!(timer.at, FakeInstant::from(Rto::DEFAULT.get()));
6855 clock.sleep(TEST_USER_TIMEOUT.get());
6856 timer.backoff(clock.now());
6857 assert_eq!(timer.at, FakeInstant::from(TEST_USER_TIMEOUT.get()));
6858 clock.sleep(Duration::from_secs(1));
6859 timer.backoff(clock.now());
6861 assert_eq!(timer.at, FakeInstant::from(TEST_USER_TIMEOUT.get()));
6863 }
6864
6865 #[test_case(
6866 State::Established(Established {
6867 snd: Send {
6868 nxt: ISS_1 + 1,
6869 max: ISS_1 + 1,
6870 una: ISS_1 + 1,
6871 wnd: WindowSize::DEFAULT,
6872 wnd_max: WindowSize::DEFAULT,
6873 buffer: RingBuffer::new(BUFFER_SIZE),
6874 wl1: ISS_2,
6875 wl2: ISS_1,
6876 rtt_sampler: RttSampler::default(),
6877 rtt_estimator: Estimator::Measured {
6878 srtt: Rto::DEFAULT.get(),
6879 rtt_var: Duration::ZERO,
6880 },
6881 timer: None,
6882 congestion_control: CongestionControl::cubic_with_mss(
6883 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6884 ),
6885 wnd_scale: WindowScale::default(),
6886 }.into(),
6887 rcv: Recv {
6888 buffer: RecvBufferState::Open {
6889 buffer: RingBuffer::new(
6890 TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize,
6891 ),
6892 assembler: Assembler::new(ISS_2 + 1),
6893 },
6894 timer: None,
6895 remaining_quickacks: 0,
6896 last_segment_at: None,
6897 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6898 wnd_scale: WindowScale::default(),
6899 last_window_update: (
6900 ISS_2 + 1,
6901 WindowSize::new(TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize).unwrap()
6902 ),
6903 sack_permitted: SACK_PERMITTED,
6904 }.into(),
6905 }); "established")]
6906 #[test_case(
6907 State::FinWait1(FinWait1 {
6908 snd: Send {
6909 nxt: ISS_1 + 1,
6910 max: ISS_1 + 1,
6911 una: ISS_1 + 1,
6912 wnd: WindowSize::DEFAULT,
6913 wnd_max: WindowSize::DEFAULT,
6914 buffer: RingBuffer::new(BUFFER_SIZE),
6915 wl1: ISS_2,
6916 wl2: ISS_1,
6917 rtt_sampler: RttSampler::default(),
6918 rtt_estimator: Estimator::Measured {
6919 srtt: Rto::DEFAULT.get(),
6920 rtt_var: Duration::ZERO,
6921 },
6922 timer: None,
6923 congestion_control: CongestionControl::cubic_with_mss(
6924 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6925 ),
6926 wnd_scale: WindowScale::default(),
6927 }.into(),
6928 rcv: Recv {
6929 buffer: RecvBufferState::Open {
6930 buffer: RingBuffer::new(
6931 TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize,
6932 ),
6933 assembler: Assembler::new(ISS_2 + 1),
6934 },
6935 timer: None,
6936 remaining_quickacks: 0,
6937 last_segment_at: None,
6938 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6939 wnd_scale: WindowScale::default(),
6940 last_window_update: (
6941 ISS_2 + 1,
6942 WindowSize::new(TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize).unwrap()
6943 ),
6944 sack_permitted: SACK_PERMITTED,
6945 }.into(),
6946 }); "fin_wait_1")]
6947 #[test_case(
6948 State::FinWait2(FinWait2 {
6949 last_seq: ISS_1 + 1,
6950 rcv: Recv {
6951 buffer: RecvBufferState::Open {
6952 buffer: RingBuffer::new(
6953 TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize,
6954 ),
6955 assembler: Assembler::new(ISS_2 + 1),
6956 },
6957 timer: None,
6958 remaining_quickacks: 0,
6959 last_segment_at: None,
6960 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
6961 wnd_scale: WindowScale::default(),
6962 last_window_update: (
6963 ISS_2 + 1,
6964 WindowSize::new(TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize).unwrap()
6965 ),
6966 sack_permitted: SACK_PERMITTED,
6967 },
6968 timeout_at: None,
6969 }); "fin_wait_2")]
6970 fn delayed_ack(mut state: State<FakeInstant, RingBuffer, RingBuffer, ()>) {
6971 let mut clock = FakeInstantCtx::default();
6972 let counters = FakeTcpCounters::default();
6973 let socket_options =
6974 SocketOptions { delayed_ack: true, ..SocketOptions::default_for_state_tests() };
6975 assert_eq!(
6976 state.on_segment::<_, ClientlessBufferProvider>(
6977 &FakeStateMachineDebugId,
6978 &counters.refs(),
6979 Segment::data(
6980 ISS_2 + 1,
6981 ISS_1 + 1,
6982 UnscaledWindowSize::from(u16::MAX),
6983 TEST_BYTES,
6984 ),
6985 clock.now(),
6986 &socket_options,
6987 false, ),
6989 (None, None, DataAcked::No, NewlyClosed::No)
6990 );
6991 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(ACK_DELAY_THRESHOLD)));
6992 clock.sleep(ACK_DELAY_THRESHOLD);
6993 assert_eq!(
6994 state.poll_send(
6995 &FakeStateMachineDebugId,
6996 &counters.refs(),
6997 u32::MAX,
6998 clock.now(),
6999 &socket_options
7000 ),
7001 Ok(Segment::ack(
7002 ISS_1 + 1,
7003 ISS_2 + 1 + TEST_BYTES.len(),
7004 UnscaledWindowSize::from_u32(2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE)),
7005 ))
7006 );
7007 let full_segment_sized_payload =
7008 vec![b'0'; u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize];
7009
7010 let expect_last_window_update = (
7011 ISS_2 + 1 + TEST_BYTES.len(),
7012 WindowSize::from_u32(2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE)).unwrap(),
7013 );
7014 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_last_window_update);
7015 assert_eq!(
7017 state.on_segment::<_, ClientlessBufferProvider>(
7018 &FakeStateMachineDebugId,
7019 &counters.refs(),
7020 Segment::data(
7021 ISS_2 + 1 + TEST_BYTES.len(),
7022 ISS_1 + 1,
7023 UnscaledWindowSize::from(u16::MAX),
7024 &full_segment_sized_payload[..],
7025 ),
7026 clock.now(),
7027 &socket_options,
7028 false, ),
7030 (None, None, DataAcked::No, NewlyClosed::No)
7031 );
7032 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(ACK_DELAY_THRESHOLD)));
7034 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_last_window_update);
7037
7038 assert_eq!(
7041 state.on_segment::<_, ClientlessBufferProvider>(
7042 &FakeStateMachineDebugId,
7043 &counters.refs(),
7044 Segment::data(
7045 ISS_2 + 1 + TEST_BYTES.len() + full_segment_sized_payload.len(),
7046 ISS_1 + 1,
7047 UnscaledWindowSize::from(u16::MAX),
7048 &full_segment_sized_payload[..],
7049 ),
7050 clock.now(),
7051 &socket_options,
7052 false, ),
7054 (
7055 Some(Segment::ack(
7056 ISS_1 + 1,
7057 ISS_2 + 1 + TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE),
7058 UnscaledWindowSize::from(0),
7059 )),
7060 None,
7061 DataAcked::No,
7062 NewlyClosed::No,
7063 )
7064 );
7065 assert_eq!(
7067 state.recv_mut().unwrap().last_window_update,
7068 (
7069 ISS_2 + 1 + TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE),
7070 WindowSize::ZERO,
7071 )
7072 );
7073 assert_eq!(state.poll_send_at(), None);
7074 }
7075
7076 #[test]
7077 fn immediate_ack_if_out_of_order_or_fin() {
7078 let clock = FakeInstantCtx::default();
7079 let counters = FakeTcpCounters::default();
7080 let socket_options =
7081 SocketOptions { delayed_ack: true, ..SocketOptions::default_for_state_tests() };
7082 let mut state: State<_, _, _, ()> = State::Established(Established {
7083 snd: Send {
7084 nxt: ISS_1 + 1,
7085 max: ISS_1 + 1,
7086 una: ISS_1 + 1,
7087 wnd: WindowSize::DEFAULT,
7088 wnd_max: WindowSize::DEFAULT,
7089 buffer: RingBuffer::new(BUFFER_SIZE),
7090 wl1: ISS_2,
7091 wl2: ISS_1,
7092 rtt_sampler: RttSampler::default(),
7093 rtt_estimator: Estimator::Measured {
7094 srtt: Rto::DEFAULT.get(),
7095 rtt_var: Duration::ZERO,
7096 },
7097 timer: None,
7098 congestion_control: CongestionControl::cubic_with_mss(
7099 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
7100 ),
7101 wnd_scale: WindowScale::default(),
7102 }
7103 .into(),
7104 rcv: Recv {
7105 buffer: RecvBufferState::Open {
7106 buffer: RingBuffer::new(TEST_BYTES.len() + 1),
7107 assembler: Assembler::new(ISS_2 + 1),
7108 },
7109 timer: None,
7110 remaining_quickacks: 0,
7111 last_segment_at: None,
7112 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
7113 wnd_scale: WindowScale::default(),
7114 last_window_update: (ISS_2 + 1, WindowSize::new(TEST_BYTES.len() + 1).unwrap()),
7115 sack_permitted: SACK_PERMITTED,
7116 }
7117 .into(),
7118 });
7119 assert_eq!(
7122 state.on_segment::<_, ClientlessBufferProvider>(
7123 &FakeStateMachineDebugId,
7124 &counters.refs(),
7125 Segment::data(
7126 ISS_2 + 2,
7127 ISS_1 + 1,
7128 UnscaledWindowSize::from(u16::MAX),
7129 &TEST_BYTES[1..]
7130 ),
7131 clock.now(),
7132 &socket_options,
7133 false, ),
7135 (
7136 Some(Segment::ack(
7137 ISS_1 + 1,
7138 ISS_2 + 1,
7139 UnscaledWindowSize::from(u16::try_from(TEST_BYTES.len() + 1).unwrap())
7140 )),
7141 None,
7142 DataAcked::No,
7143 NewlyClosed::No,
7144 )
7145 );
7146 assert_eq!(state.poll_send_at(), None);
7147 assert_eq!(
7150 state.on_segment::<_, ClientlessBufferProvider>(
7151 &FakeStateMachineDebugId,
7152 &counters.refs(),
7153 Segment::data(
7154 ISS_2 + 1,
7155 ISS_1 + 1,
7156 UnscaledWindowSize::from(u16::MAX),
7157 &TEST_BYTES[..1]
7158 ),
7159 clock.now(),
7160 &socket_options,
7161 false, ),
7163 (
7164 Some(Segment::ack(
7165 ISS_1 + 1,
7166 ISS_2 + 1 + TEST_BYTES.len(),
7167 UnscaledWindowSize::from(1),
7168 )),
7169 None,
7170 DataAcked::No,
7171 NewlyClosed::No
7172 )
7173 );
7174 assert_eq!(state.poll_send_at(), None);
7175 assert_eq!(
7177 state.on_segment::<(), ClientlessBufferProvider>(
7178 &FakeStateMachineDebugId,
7179 &counters.refs(),
7180 Segment::fin(
7181 ISS_2 + 1 + TEST_BYTES.len(),
7182 ISS_1 + 1,
7183 UnscaledWindowSize::from(u16::MAX),
7184 ),
7185 clock.now(),
7186 &socket_options,
7187 false, ),
7189 (
7190 Some(Segment::ack(
7191 ISS_1 + 1,
7192 ISS_2 + 1 + TEST_BYTES.len() + 1,
7193 UnscaledWindowSize::from(0),
7194 )),
7195 None,
7196 DataAcked::No,
7197 NewlyClosed::No,
7198 )
7199 );
7200 assert_eq!(state.poll_send_at(), None);
7201 }
7202
7203 #[test]
7204 fn fin_wait2_timeout() {
7205 let mut clock = FakeInstantCtx::default();
7206 let counters = FakeTcpCounters::default();
7207 let mut state: State<_, _, NullBuffer, ()> = State::FinWait2(FinWait2 {
7208 last_seq: ISS_1,
7209 rcv: Recv {
7210 buffer: RecvBufferState::Open {
7211 buffer: NullBuffer,
7212 assembler: Assembler::new(ISS_2),
7213 },
7214 timer: None,
7215 remaining_quickacks: 0,
7216 last_segment_at: None,
7217 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
7218 wnd_scale: WindowScale::default(),
7219 last_window_update: (ISS_2, WindowSize::DEFAULT),
7220 sack_permitted: SACK_PERMITTED,
7221 },
7222 timeout_at: None,
7223 });
7224 assert_eq!(
7225 state.close(
7226 &counters.refs(),
7227 CloseReason::Close { now: clock.now() },
7228 &SocketOptions::default_for_state_tests()
7229 ),
7230 Err(CloseError::Closing)
7231 );
7232 assert_eq!(
7233 state.poll_send_at(),
7234 Some(clock.now().panicking_add(DEFAULT_FIN_WAIT2_TIMEOUT))
7235 );
7236 clock.sleep(DEFAULT_FIN_WAIT2_TIMEOUT);
7237 assert_eq!(
7238 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
7239 None
7240 );
7241 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
7242 CounterExpectations {
7243 established_closed: 1,
7244 established_timedout: 1,
7245 ..Default::default()
7246 }
7247 .assert_counters(&counters);
7248 }
7249
7250 #[test_case(RetransTimer {
7251 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(100))),
7252 remaining_retries: None,
7253 at: FakeInstant::from(Duration::from_secs(1)),
7254 rto: Rto::new(Duration::from_secs(1)),
7255 }, FakeInstant::from(Duration::from_secs(1)) => true)]
7256 #[test_case(RetransTimer {
7257 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(100))),
7258 remaining_retries: None,
7259 at: FakeInstant::from(Duration::from_secs(2)),
7260 rto: Rto::new(Duration::from_secs(1)),
7261 }, FakeInstant::from(Duration::from_secs(1)) => false)]
7262 #[test_case(RetransTimer {
7263 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(100))),
7264 remaining_retries: Some(NonZeroU8::new(1).unwrap()),
7265 at: FakeInstant::from(Duration::from_secs(2)),
7266 rto: Rto::new(Duration::from_secs(1)),
7267 }, FakeInstant::from(Duration::from_secs(1)) => false)]
7268 #[test_case(RetransTimer {
7269 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(1))),
7270 remaining_retries: Some(NonZeroU8::new(1).unwrap()),
7271 at: FakeInstant::from(Duration::from_secs(1)),
7272 rto: Rto::new(Duration::from_secs(1)),
7273 }, FakeInstant::from(Duration::from_secs(1)) => true)]
7274 fn send_timed_out(timer: RetransTimer<FakeInstant>, now: FakeInstant) -> bool {
7275 timer.timed_out(now)
7276 }
7277
7278 #[test_case(
7279 State::SynSent(SynSent{
7280 iss: ISS_1,
7281 timestamp: Some(FakeInstant::default()),
7282 retrans_timer: RetransTimer::new(
7283 FakeInstant::default(),
7284 Rto::MIN,
7285 NonZeroDuration::from_secs(60),
7286 DEFAULT_MAX_SYN_RETRIES,
7287 ),
7288 active_open: (),
7289 buffer_sizes: Default::default(),
7290 device_mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
7291 default_mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
7292 rcv_wnd_scale: WindowScale::default(),
7293 })
7294 => DEFAULT_MAX_SYN_RETRIES.get(); "syn_sent")]
7295 #[test_case(
7296 State::SynRcvd(SynRcvd{
7297 iss: ISS_1,
7298 irs: ISS_2,
7299 timestamp: Some(FakeInstant::default()),
7300 retrans_timer: RetransTimer::new(
7301 FakeInstant::default(),
7302 Rto::MIN,
7303 NonZeroDuration::from_secs(60),
7304 DEFAULT_MAX_SYNACK_RETRIES,
7305 ),
7306 simultaneous_open: None,
7307 buffer_sizes: BufferSizes::default(),
7308 smss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
7309 rcv_wnd_scale: WindowScale::default(),
7310 snd_wnd_scale: Some(WindowScale::default()),
7311 sack_permitted: SACK_PERMITTED,
7312 })
7313 => DEFAULT_MAX_SYNACK_RETRIES.get(); "syn_rcvd")]
7314 fn handshake_timeout(mut state: State<FakeInstant, RingBuffer, RingBuffer, ()>) -> u8 {
7315 let mut clock = FakeInstantCtx::default();
7316 let counters = FakeTcpCounters::default();
7317 let mut retransmissions = 0;
7318 clock.sleep_until(state.poll_send_at().expect("must have a retransmission timer"));
7319 while let Some(_seg) =
7320 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs())
7321 {
7322 let deadline = state.poll_send_at().expect("must have a retransmission timer");
7323 clock.sleep_until(deadline);
7324 retransmissions += 1;
7325 }
7326 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
7327 CounterExpectations::default().assert_counters(&counters);
7328 retransmissions
7329 }
7330
7331 #[test_case(
7332 u16::MAX as usize, WindowScale::default(), Some(WindowScale::default())
7333 => (WindowScale::default(), WindowScale::default()))]
7334 #[test_case(
7335 u16::MAX as usize + 1, WindowScale::new(1).unwrap(), Some(WindowScale::default())
7336 => (WindowScale::new(1).unwrap(), WindowScale::default()))]
7337 #[test_case(
7338 u16::MAX as usize + 1, WindowScale::new(1).unwrap(), None
7339 => (WindowScale::default(), WindowScale::default()))]
7340 #[test_case(
7341 u16::MAX as usize, WindowScale::default(), Some(WindowScale::new(1).unwrap())
7342 => (WindowScale::default(), WindowScale::new(1).unwrap()))]
7343 fn window_scale(
7344 buffer_size: usize,
7345 syn_window_scale: WindowScale,
7346 syn_ack_window_scale: Option<WindowScale>,
7347 ) -> (WindowScale, WindowScale) {
7348 let mut clock = FakeInstantCtx::default();
7349 let counters = FakeTcpCounters::default();
7350 let (syn_sent, syn_seg) = Closed::<Initial>::connect(
7351 ISS_1,
7352 clock.now(),
7353 (),
7354 BufferSizes { receive: buffer_size, ..Default::default() },
7355 DEVICE_MAXIMUM_SEGMENT_SIZE,
7356 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
7357 &SocketOptions::default_for_state_tests(),
7358 );
7359 assert_eq!(
7360 syn_seg,
7361 Segment::syn(
7362 ISS_1,
7363 UnscaledWindowSize::from(u16::try_from(buffer_size).unwrap_or(u16::MAX)),
7364 HandshakeOptions {
7365 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
7366 window_scale: Some(syn_window_scale),
7367 sack_permitted: SACK_PERMITTED,
7368 }
7369 .into(),
7370 )
7371 );
7372 let mut active = State::SynSent(syn_sent);
7373 clock.sleep(RTT / 2);
7374 let (seg, passive_open) = active
7375 .on_segment_with_default_options::<(), ClientlessBufferProvider>(
7376 Segment::syn_ack(
7377 ISS_2,
7378 ISS_1 + 1,
7379 UnscaledWindowSize::from(u16::MAX),
7380 HandshakeOptions {
7381 mss: Some(DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE),
7382 window_scale: syn_ack_window_scale,
7383 sack_permitted: SACK_PERMITTED,
7384 }
7385 .into(),
7386 ),
7387 clock.now(),
7388 &counters.refs(),
7389 );
7390 assert_eq!(passive_open, None);
7391 assert_matches!(seg, Some(_));
7392
7393 let established: Established<FakeInstant, RingBuffer, NullBuffer> =
7394 assert_matches!(active, State::Established(established) => established);
7395
7396 assert_eq!(established.snd.wnd, WindowSize::DEFAULT);
7397
7398 (established.rcv.wnd_scale, established.snd.wnd_scale)
7399 }
7400
7401 #[test_case(
7402 u16::MAX as usize,
7403 Segment::syn_ack(
7404 ISS_2 + 1 + u16::MAX as usize,
7405 ISS_1 + 1,
7406 UnscaledWindowSize::from(u16::MAX),
7407 Options::default(),
7408 )
7409 )]
7410 #[test_case(
7411 u16::MAX as usize + 1,
7412 Segment::syn_ack(
7413 ISS_2 + 1 + u16::MAX as usize,
7414 ISS_1 + 1,
7415 UnscaledWindowSize::from(u16::MAX),
7416 Options::default(),
7417 )
7418 )]
7419 #[test_case(
7420 u16::MAX as usize,
7421 Segment::data(
7422 ISS_2 + 1 + u16::MAX as usize,
7423 ISS_1 + 1,
7424 UnscaledWindowSize::from(u16::MAX),
7425 &TEST_BYTES[..],
7426 )
7427 )]
7428 #[test_case(
7429 u16::MAX as usize + 1,
7430 Segment::data(
7431 ISS_2 + 1 + u16::MAX as usize,
7432 ISS_1 + 1,
7433 UnscaledWindowSize::from(u16::MAX),
7434 &TEST_BYTES[..],
7435 )
7436 )]
7437 fn window_scale_otw_seq(receive_buf_size: usize, otw_seg: impl Into<Segment<&'static [u8]>>) {
7438 let counters = FakeTcpCounters::default();
7439 let buffer_sizes = BufferSizes { send: 0, receive: receive_buf_size };
7440 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
7441 let mut syn_rcvd: State<_, RingBuffer, RingBuffer, ()> = State::SynRcvd(SynRcvd {
7442 iss: ISS_1,
7443 irs: ISS_2,
7444 timestamp: None,
7445 retrans_timer: RetransTimer::new(
7446 FakeInstant::default(),
7447 Rto::DEFAULT,
7448 NonZeroDuration::from_secs(10),
7449 DEFAULT_MAX_SYNACK_RETRIES,
7450 ),
7451 simultaneous_open: None,
7452 buffer_sizes: BufferSizes { send: 0, receive: receive_buf_size },
7453 smss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
7454 rcv_wnd_scale,
7455 snd_wnd_scale: WindowScale::new(1),
7456 sack_permitted: SACK_PERMITTED,
7457 });
7458
7459 assert_eq!(
7460 syn_rcvd.on_segment_with_default_options::<_, ClientlessBufferProvider>(
7461 otw_seg.into(),
7462 FakeInstant::default(),
7463 &counters.refs()
7464 ),
7465 (Some(Segment::ack(ISS_1 + 1, ISS_2 + 1, buffer_sizes.rwnd_unscaled())), None),
7466 )
7467 }
7468
7469 #[test]
7470 fn poll_send_reserving_buffer() {
7471 const RESERVED_BYTES: usize = 3;
7472 let mut snd: Send<FakeInstant, _, false> = Send {
7473 nxt: ISS_1 + 1,
7474 max: ISS_1 + 1,
7475 una: ISS_1 + 1,
7476 wnd: WindowSize::DEFAULT,
7477 wnd_max: WindowSize::DEFAULT,
7478 wnd_scale: WindowScale::default(),
7479 wl1: ISS_1,
7480 wl2: ISS_2,
7481 buffer: ReservingBuffer {
7482 buffer: RingBuffer::with_data(TEST_BYTES.len(), TEST_BYTES),
7483 reserved_bytes: RESERVED_BYTES,
7484 },
7485 rtt_sampler: RttSampler::default(),
7486 rtt_estimator: Estimator::default(),
7487 timer: None,
7488 congestion_control: CongestionControl::cubic_with_mss(
7489 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
7490 ),
7491 };
7492
7493 let counters = FakeTcpCounters::default();
7494
7495 assert_eq!(
7496 snd.poll_send(
7497 &FakeStateMachineDebugId,
7498 &counters.refs(),
7499 &RecvParams {
7500 ack: ISS_2 + 1,
7501 wnd: WindowSize::DEFAULT,
7502 wnd_scale: WindowScale::ZERO,
7503 },
7504 u32::MAX,
7505 FakeInstant::default(),
7506 &SocketOptions::default_for_state_tests(),
7507 ),
7508 Some(Segment::data(
7509 ISS_1 + 1,
7510 ISS_2 + 1,
7511 WindowSize::DEFAULT >> WindowScale::default(),
7512 FragmentedPayload::new_contiguous(&TEST_BYTES[..TEST_BYTES.len() - RESERVED_BYTES])
7513 ))
7514 );
7515
7516 assert_eq!(snd.nxt, ISS_1 + 1 + (TEST_BYTES.len() - RESERVED_BYTES));
7517 }
7518
7519 #[test]
7520 fn rcv_silly_window_avoidance() {
7521 const MULTIPLE: usize = 3;
7522 const CAP: usize = TEST_BYTES.len() * MULTIPLE;
7523 let mut rcv: Recv<FakeInstant, RingBuffer> = Recv {
7524 buffer: RecvBufferState::Open {
7525 buffer: RingBuffer::new(CAP),
7526 assembler: Assembler::new(ISS_1),
7527 },
7528 timer: None,
7529 remaining_quickacks: 0,
7530 last_segment_at: None,
7531 mss: Mss(NonZeroU16::new(TEST_BYTES.len() as u16).unwrap()),
7532 wnd_scale: WindowScale::default(),
7533 last_window_update: (ISS_1, WindowSize::new(CAP).unwrap()),
7534 sack_permitted: SACK_PERMITTED,
7535 };
7536
7537 fn get_buffer(rcv: &mut Recv<FakeInstant, RingBuffer>) -> &mut RingBuffer {
7538 assert_matches!(
7539 &mut rcv.buffer,
7540 RecvBufferState::Open {ref mut buffer, .. } => buffer
7541 )
7542 }
7543
7544 assert_eq!(rcv.calculate_window_size().window_size, WindowSize::new(CAP).unwrap());
7546
7547 for _ in 0..MULTIPLE {
7548 assert_eq!(get_buffer(&mut rcv).enqueue_data(TEST_BYTES), TEST_BYTES.len());
7549 }
7550 let assembler = assert_matches!(&mut rcv.buffer,
7551 RecvBufferState::Open { ref mut assembler, .. } => assembler);
7552 assert_eq!(assembler.insert(ISS_1..ISS_1 + CAP), CAP);
7553 assert_eq!(rcv.calculate_window_size().window_size, WindowSize::ZERO);
7555
7556 assert_eq!(get_buffer(&mut rcv).read_with(|_| 1), 1);
7559 assert_eq!(rcv.calculate_window_size().window_size, WindowSize::ZERO);
7560
7561 assert_eq!(get_buffer(&mut rcv).read_with(|_| TEST_BYTES.len()), TEST_BYTES.len());
7564 assert_eq!(
7565 rcv.calculate_window_size().window_size,
7566 WindowSize::new(TEST_BYTES.len() + 1).unwrap()
7567 );
7568 }
7569
7570 #[test]
7571 fn correct_window_scale_during_send() {
7573 let snd_wnd_scale = WindowScale::new(4).unwrap();
7574 let rcv_wnd_scale = WindowScale::new(8).unwrap();
7575 let wnd_size = WindowSize::new(1024).unwrap();
7576
7577 let counters = FakeTcpCounters::default();
7578 let new_snd = || Send {
7581 nxt: ISS_1 + 1,
7582 max: ISS_1 + 1,
7583 una: ISS_1 + 1,
7584 wnd: wnd_size,
7585 wnd_max: WindowSize::DEFAULT,
7586 buffer: RingBuffer::with_data(TEST_BYTES.len(), TEST_BYTES),
7587 wl1: ISS_2 + 1,
7588 wl2: ISS_1 + 1,
7589 rtt_estimator: Estimator::default(),
7590 rtt_sampler: RttSampler::default(),
7591 timer: None,
7592 congestion_control: CongestionControl::cubic_with_mss(
7593 DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
7594 ),
7595 wnd_scale: snd_wnd_scale,
7596 };
7597 let new_rcv = || Recv {
7598 buffer: RecvBufferState::Open {
7599 buffer: RingBuffer::new(wnd_size.into()),
7600 assembler: Assembler::new(ISS_2 + 1),
7601 },
7602 timer: None,
7603 remaining_quickacks: 0,
7604 last_segment_at: None,
7605 mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
7606 wnd_scale: rcv_wnd_scale,
7607 last_window_update: (ISS_2 + 1, WindowSize::ZERO),
7608 sack_permitted: SACK_PERMITTED,
7609 };
7610 for mut state in [
7611 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
7612 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
7613 State::Closing(Closing {
7614 snd: new_snd().queue_fin(),
7615 closed_rcv: RecvParams { ack: ISS_2 + 1, wnd: wnd_size, wnd_scale: rcv_wnd_scale },
7616 }),
7617 State::CloseWait(CloseWait {
7618 snd: new_snd().into(),
7619 closed_rcv: RecvParams { ack: ISS_2 + 1, wnd: wnd_size, wnd_scale: rcv_wnd_scale },
7620 }),
7621 State::LastAck(LastAck {
7622 snd: new_snd().queue_fin(),
7623 closed_rcv: RecvParams { ack: ISS_2 + 1, wnd: wnd_size, wnd_scale: rcv_wnd_scale },
7624 }),
7625 ] {
7626 assert_eq!(
7627 state.poll_send_with_default_options(
7628 u32::try_from(TEST_BYTES.len()).unwrap(),
7629 FakeInstant::default(),
7630 &counters.refs(),
7631 ),
7632 Some(Segment::data(
7633 ISS_1 + 1,
7634 ISS_2 + 1,
7635 UnscaledWindowSize::from(4),
7638 FragmentedPayload::new_contiguous(TEST_BYTES)
7639 ))
7640 );
7641 }
7642 }
7643
7644 #[test_case(true; "prompted window update")]
7645 #[test_case(false; "unprompted window update")]
7646 fn snd_silly_window_avoidance(prompted_window_update: bool) {
7647 const CAP: usize = TEST_BYTES.len() * 2;
7648 let mut snd: Send<FakeInstant, RingBuffer, false> = Send {
7649 nxt: ISS_1 + 1,
7650 max: ISS_1 + 1,
7651 una: ISS_1 + 1,
7652 wnd: WindowSize::new(CAP).unwrap(),
7653 wnd_scale: WindowScale::default(),
7654 wnd_max: WindowSize::DEFAULT,
7655 wl1: ISS_1,
7656 wl2: ISS_2,
7657 buffer: RingBuffer::new(CAP),
7658 rtt_sampler: RttSampler::default(),
7659 rtt_estimator: Estimator::default(),
7660 timer: None,
7661 congestion_control: CongestionControl::cubic_with_mss(Mss(NonZeroU16::new(
7662 TEST_BYTES.len() as u16,
7663 )
7664 .unwrap())),
7665 };
7666
7667 let mut clock = FakeInstantCtx::default();
7668 let counters = FakeTcpCounters::default();
7669
7670 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7672 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7673
7674 assert_eq!(
7676 snd.poll_send(
7677 &FakeStateMachineDebugId,
7678 &counters.refs(),
7679 &RecvParams {
7680 ack: ISS_2 + 1,
7681 wnd: WindowSize::DEFAULT,
7682 wnd_scale: WindowScale::ZERO,
7683 },
7684 u32::MAX,
7685 clock.now(),
7686 &SocketOptions::default_for_state_tests(),
7687 ),
7688 Some(Segment::data(
7689 ISS_1 + 1,
7690 ISS_2 + 1,
7691 UnscaledWindowSize::from(u16::MAX),
7692 FragmentedPayload::new_contiguous(TEST_BYTES),
7693 )),
7694 );
7695
7696 assert_eq!(
7697 snd.process_ack(
7698 &FakeStateMachineDebugId,
7699 &counters.refs(),
7700 ISS_2 + 1,
7701 ISS_1 + 1 + TEST_BYTES.len(),
7702 UnscaledWindowSize::from(0),
7703 &SackBlocks::EMPTY,
7704 true,
7705 &RecvParams {
7706 ack: ISS_2 + 1,
7707 wnd_scale: WindowScale::default(),
7708 wnd: WindowSize::DEFAULT,
7709 },
7710 clock.now(),
7711 &SocketOptions::default(),
7712 ),
7713 (None, DataAcked::Yes)
7714 );
7715
7716 assert_eq!(
7719 snd.poll_send(
7720 &FakeStateMachineDebugId,
7721 &counters.refs(),
7722 &RecvParams {
7723 ack: ISS_2 + 1,
7724 wnd: WindowSize::DEFAULT,
7725 wnd_scale: WindowScale::ZERO,
7726 },
7727 u32::MAX,
7728 clock.now(),
7729 &SocketOptions::default_for_state_tests(),
7730 ),
7731 None
7732 );
7733
7734 assert_eq!(
7735 snd.timer,
7736 Some(SendTimer::ZeroWindowProbe(RetransTimer::new(
7737 clock.now(),
7738 snd.rtt_estimator.rto(),
7739 None,
7740 DEFAULT_MAX_RETRIES,
7741 )))
7742 );
7743
7744 clock.sleep_until(snd.timer.as_ref().unwrap().expiry());
7745
7746 assert_eq!(
7747 snd.poll_send(
7748 &FakeStateMachineDebugId,
7749 &counters.refs(),
7750 &RecvParams {
7751 ack: ISS_2 + 1,
7752 wnd: WindowSize::DEFAULT,
7753 wnd_scale: WindowScale::ZERO,
7754 },
7755 u32::MAX,
7756 clock.now(),
7757 &SocketOptions::default_for_state_tests(),
7758 ),
7759 Some(Segment::data(
7760 ISS_1 + 1 + TEST_BYTES.len(),
7761 ISS_2 + 1,
7762 UnscaledWindowSize::from(u16::MAX),
7763 FragmentedPayload::new_contiguous(&TEST_BYTES[..1]),
7764 ))
7765 );
7766
7767 if prompted_window_update {
7768 assert_eq!(
7771 snd.process_ack(
7772 &FakeStateMachineDebugId,
7773 &counters.refs(),
7774 ISS_2 + 1,
7775 ISS_1 + 1 + TEST_BYTES.len() + 1,
7776 UnscaledWindowSize::from(3),
7777 &SackBlocks::EMPTY,
7778 true,
7779 &RecvParams {
7780 ack: ISS_2 + 1,
7781 wnd_scale: WindowScale::default(),
7782 wnd: WindowSize::DEFAULT,
7783 },
7784 clock.now(),
7785 &SocketOptions::default(),
7786 ),
7787 (None, DataAcked::Yes)
7788 );
7789 } else {
7790 assert_eq!(
7792 snd.process_ack(
7793 &FakeStateMachineDebugId,
7794 &counters.refs(),
7795 ISS_2 + 1,
7796 ISS_1 + 1 + TEST_BYTES.len(),
7797 UnscaledWindowSize::from(0),
7798 &SackBlocks::EMPTY,
7799 true,
7800 &RecvParams {
7801 ack: ISS_2 + 1,
7802 wnd_scale: WindowScale::default(),
7803 wnd: WindowSize::DEFAULT,
7804 },
7805 clock.now(),
7806 &SocketOptions::default(),
7807 ),
7808 (None, DataAcked::No)
7809 );
7810
7811 assert_eq!(
7814 snd.process_ack(
7815 &FakeStateMachineDebugId,
7816 &counters.refs(),
7817 ISS_2 + 1,
7818 ISS_1 + 1 + TEST_BYTES.len(),
7819 UnscaledWindowSize::from(3),
7820 &SackBlocks::EMPTY,
7821 true,
7822 &RecvParams {
7823 ack: ISS_2 + 1,
7824 wnd_scale: WindowScale::default(),
7825 wnd: WindowSize::DEFAULT,
7826 },
7827 clock.now(),
7828 &SocketOptions::default(),
7829 ),
7830 (None, DataAcked::No)
7831 );
7832 }
7833
7834 assert_eq!(
7836 snd.poll_send(
7837 &FakeStateMachineDebugId,
7838 &counters.refs(),
7839 &RecvParams {
7840 ack: ISS_2 + 1,
7841 wnd: WindowSize::DEFAULT,
7842 wnd_scale: WindowScale::ZERO,
7843 },
7844 u32::MAX,
7845 clock.now(),
7846 &SocketOptions::default_for_state_tests(),
7847 ),
7848 None,
7849 );
7850 assert_eq!(
7851 snd.timer,
7852 Some(SendTimer::SWSProbe { at: clock.now().panicking_add(SWS_PROBE_TIMEOUT) })
7853 );
7854 clock.sleep(SWS_PROBE_TIMEOUT);
7855
7856 let seq_index = usize::from(prompted_window_update);
7859 assert_eq!(
7860 snd.poll_send(
7861 &FakeStateMachineDebugId,
7862 &counters.refs(),
7863 &RecvParams {
7864 ack: ISS_2 + 1,
7865 wnd: WindowSize::DEFAULT,
7866 wnd_scale: WindowScale::ZERO,
7867 },
7868 u32::MAX,
7869 clock.now(),
7870 &SocketOptions::default_for_state_tests(),
7871 ),
7872 Some(Segment::data(
7873 ISS_1 + 1 + TEST_BYTES.len() + seq_index,
7874 ISS_2 + 1,
7875 UnscaledWindowSize::from(u16::MAX),
7876 FragmentedPayload::new_contiguous(&TEST_BYTES[seq_index..3 + seq_index]),
7877 ))
7878 );
7879 }
7880
7881 #[test]
7882 fn snd_enter_zwp_on_negative_window_update() {
7883 const CAP: usize = TEST_BYTES.len() * 2;
7884 let mut snd: Send<FakeInstant, RingBuffer, false> = Send {
7885 nxt: ISS_1 + 1,
7886 max: ISS_1 + 1,
7887 una: ISS_1 + 1,
7888 wnd: WindowSize::new(CAP).unwrap(),
7889 wnd_scale: WindowScale::default(),
7890 wnd_max: WindowSize::DEFAULT,
7891 wl1: ISS_1,
7892 wl2: ISS_2,
7893 buffer: RingBuffer::new(CAP),
7894 rtt_sampler: RttSampler::default(),
7895 rtt_estimator: Estimator::default(),
7896 timer: None,
7897 congestion_control: CongestionControl::cubic_with_mss(Mss(NonZeroU16::new(
7898 TEST_BYTES.len() as u16,
7899 )
7900 .unwrap())),
7901 };
7902
7903 let clock = FakeInstantCtx::default();
7904 let counters = FakeTcpCounters::default();
7905
7906 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7908 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7909
7910 assert_eq!(
7912 snd.poll_send(
7913 &FakeStateMachineDebugId,
7914 &counters.refs(),
7915 &RecvParams {
7916 ack: ISS_2 + 1,
7917 wnd: WindowSize::DEFAULT,
7918 wnd_scale: WindowScale::ZERO,
7919 },
7920 u32::MAX,
7921 clock.now(),
7922 &SocketOptions::default_for_state_tests(),
7923 ),
7924 Some(Segment::data(
7925 ISS_1 + 1,
7926 ISS_2 + 1,
7927 UnscaledWindowSize::from(u16::MAX),
7928 FragmentedPayload::new_contiguous(TEST_BYTES),
7929 )),
7930 );
7931
7932 assert_matches!(snd.timer, Some(SendTimer::Retrans(_)));
7935
7936 assert_eq!(
7944 snd.process_ack(
7945 &FakeStateMachineDebugId,
7946 &counters.refs(),
7947 ISS_2 + 1,
7948 ISS_1 + 1 + TEST_BYTES.len(),
7949 UnscaledWindowSize::from(0),
7950 &SackBlocks::EMPTY,
7951 true,
7952 &RecvParams {
7953 ack: ISS_2 + 1,
7954 wnd_scale: WindowScale::default(),
7955 wnd: WindowSize::DEFAULT,
7956 },
7957 clock.now(),
7958 &SocketOptions::default(),
7959 ),
7960 (None, DataAcked::Yes)
7961 );
7962
7963 assert_eq!(
7966 snd.poll_send(
7967 &FakeStateMachineDebugId,
7968 &counters.refs(),
7969 &RecvParams {
7970 ack: ISS_2 + 1,
7971 wnd: WindowSize::DEFAULT,
7972 wnd_scale: WindowScale::ZERO,
7973 },
7974 u32::MAX,
7975 clock.now(),
7976 &SocketOptions::default_for_state_tests(),
7977 ),
7978 None,
7979 );
7980 assert_matches!(snd.timer, Some(SendTimer::ZeroWindowProbe(_)));
7981 }
7982
7983 #[test]
7984 fn ack_uses_snd_max() {
7986 let counters = FakeTcpCounters::default();
7987 let mss = Mss(NonZeroU16::new(u16::try_from(TEST_BYTES.len()).unwrap()).unwrap());
7988
7989 let mut clock = FakeInstantCtx::default();
7990 let mut buffer = RingBuffer::new(BUFFER_SIZE);
7991 assert_eq!(buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7992 assert_eq!(buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7993
7994 let mut state: State<_, _, _, ()> = State::Established(Established {
7996 snd: Send {
7997 nxt: ISS_1 + 1,
7998 max: ISS_1 + 1,
7999 una: ISS_1 + 1,
8000 wnd: WindowSize::DEFAULT,
8001 wnd_max: WindowSize::DEFAULT,
8002 buffer,
8003 wl1: ISS_1,
8004 wl2: ISS_1,
8005 rtt_sampler: RttSampler::default(),
8006 rtt_estimator: Estimator::NoSample,
8007 timer: None,
8008 congestion_control: CongestionControl::cubic_with_mss(mss),
8009 wnd_scale: WindowScale::default(),
8010 }
8011 .into(),
8012 rcv: Recv {
8013 buffer: RecvBufferState::Open {
8014 buffer: RingBuffer::new(BUFFER_SIZE),
8015 assembler: Assembler::new(ISS_1 + 1),
8016 },
8017 timer: None,
8018 mss,
8019 wnd_scale: WindowScale::default(),
8020 remaining_quickacks: 0,
8021 last_segment_at: None,
8022 last_window_update: (ISS_1 + 1, WindowSize::new(BUFFER_SIZE).unwrap()),
8023 sack_permitted: SACK_PERMITTED,
8024 }
8025 .into(),
8026 });
8027
8028 assert_eq!(
8030 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
8031 Some(Segment::data(
8032 ISS_1 + 1,
8033 ISS_1 + 1,
8034 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8035 FragmentedPayload::new_contiguous(TEST_BYTES),
8036 )),
8037 );
8038 assert_eq!(
8039 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
8040 Some(Segment::data(
8041 ISS_1 + 1 + TEST_BYTES.len(),
8042 ISS_1 + 1,
8043 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8044 FragmentedPayload::new_contiguous(TEST_BYTES),
8045 )),
8046 );
8047
8048 clock.sleep(Rto::DEFAULT.get());
8050 assert_eq!(
8051 state.poll_send_with_default_options(u32::MAX, clock.now(), &counters.refs()),
8052 Some(Segment::data(
8053 ISS_1 + 1,
8054 ISS_1 + 1,
8055 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8056 FragmentedPayload::new_contiguous(TEST_BYTES),
8057 )),
8058 );
8059
8060 assert_eq!(
8063 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
8064 Segment::data(
8065 ISS_1 + 1,
8066 ISS_1 + 1,
8067 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8068 TEST_BYTES,
8069 ),
8070 clock.now(),
8071 &counters.refs(),
8072 ),
8073 (
8074 Some(Segment::ack(
8075 ISS_1 + 1 + 2 * TEST_BYTES.len(),
8076 ISS_1 + 1 + TEST_BYTES.len(),
8077 UnscaledWindowSize::from(
8078 u16::try_from(BUFFER_SIZE - TEST_BYTES.len()).unwrap()
8079 ),
8080 )),
8081 None,
8082 )
8083 );
8084 }
8085
8086 #[test_case(
8087 State::Closed(Closed { reason: None }),
8088 State::Closed(Closed { reason: None }) => NewlyClosed::No; "closed to closed")]
8089 #[test_case(
8090 State::SynSent(SynSent {
8091 iss: ISS_1,
8092 timestamp: Some(FakeInstant::default()),
8093 retrans_timer: RetransTimer::new(
8094 FakeInstant::default(),
8095 Rto::DEFAULT,
8096 None,
8097 DEFAULT_MAX_SYN_RETRIES,
8098 ),
8099 active_open: (),
8100 buffer_sizes: BufferSizes::default(),
8101 default_mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
8102 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8103 rcv_wnd_scale: WindowScale::default(),
8104 }),
8105 State::Closed(Closed { reason: None }) => NewlyClosed::Yes; "non-closed to closed")]
8106 #[test_case(
8107 State::SynSent(SynSent {
8108 iss: ISS_1,
8109 timestamp: Some(FakeInstant::default()),
8110 retrans_timer: RetransTimer::new(
8111 FakeInstant::default(),
8112 Rto::DEFAULT,
8113 None,
8114 DEFAULT_MAX_SYN_RETRIES,
8115 ),
8116 active_open: (),
8117 buffer_sizes: BufferSizes::default(),
8118 default_mss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
8119 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8120 rcv_wnd_scale: WindowScale::default(),
8121 },
8122 ),
8123 State::SynRcvd(SynRcvd {
8124 iss: ISS_1,
8125 irs: ISS_2,
8126 timestamp: None,
8127 retrans_timer: RetransTimer::new(
8128 FakeInstant::default(),
8129 Rto::DEFAULT,
8130 NonZeroDuration::from_secs(10),
8131 DEFAULT_MAX_SYNACK_RETRIES,
8132 ),
8133 simultaneous_open: None,
8134 buffer_sizes: BufferSizes { send: 0, receive: 0 },
8135 smss: DEFAULT_IPV4_MAXIMUM_SEGMENT_SIZE,
8136 rcv_wnd_scale: WindowScale::new(0).unwrap(),
8137 snd_wnd_scale: WindowScale::new(0),
8138 sack_permitted: SACK_PERMITTED,
8139 }) => NewlyClosed::No; "non-closed to non-closed")]
8140 fn transition_to_state(
8141 mut old_state: State<FakeInstant, RingBuffer, RingBuffer, ()>,
8142 new_state: State<FakeInstant, RingBuffer, RingBuffer, ()>,
8143 ) -> NewlyClosed {
8144 let counters = FakeTcpCounters::default();
8145 old_state.transition_to_state(&counters.refs(), new_state)
8146 }
8147
8148 #[test_case(true, false; "more than mss dequeued")]
8149 #[test_case(false, false; "less than mss dequeued")]
8150 #[test_case(true, true; "more than mss dequeued and delack")]
8151 #[test_case(false, true; "less than mss dequeued and delack")]
8152 fn poll_receive_data_dequeued_state(dequeue_more_than_mss: bool, delayed_ack: bool) {
8153 const BUFFER_SIZE: usize = 5;
8156 const MSS: Mss = Mss(NonZeroU16::new(5).unwrap());
8157 const TEST_BYTES: &[u8] = "Hello".as_bytes();
8158
8159 let new_snd = || Send {
8160 nxt: ISS_1 + 1,
8161 max: ISS_1 + 1,
8162 una: ISS_1 + 1,
8163 wnd: WindowSize::ZERO,
8164 wnd_max: WindowSize::ZERO,
8165 buffer: NullBuffer,
8166 wl1: ISS_2 + 1,
8167 wl2: ISS_1 + 1,
8168 rtt_estimator: Estimator::default(),
8169 rtt_sampler: RttSampler::default(),
8170 timer: None,
8171 congestion_control: CongestionControl::cubic_with_mss(MSS),
8172 wnd_scale: WindowScale::default(),
8173 };
8174 let new_rcv = || Recv {
8175 buffer: RecvBufferState::Open {
8176 buffer: RingBuffer::new(BUFFER_SIZE),
8177 assembler: Assembler::new(ISS_2 + 1),
8178 },
8179 timer: None,
8180 mss: MSS,
8181 remaining_quickacks: 0,
8182 last_segment_at: None,
8183 wnd_scale: WindowScale::default(),
8184 last_window_update: (ISS_2 + 1, WindowSize::new(BUFFER_SIZE).unwrap()),
8185 sack_permitted: SACK_PERMITTED,
8186 };
8187
8188 let clock = FakeInstantCtx::default();
8189 let counters = FakeTcpCounters::default();
8190 for mut state in [
8191 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
8192 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
8193 State::FinWait2(FinWait2 { last_seq: ISS_1 + 1, rcv: new_rcv(), timeout_at: None }),
8194 ] {
8195 assert_matches!(state.poll_receive_data_dequeued(), None);
8198 let expect_window_update = (ISS_2 + 1, WindowSize::new(BUFFER_SIZE).unwrap());
8199 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_window_update);
8200
8201 let seg = state.on_segment_with_options::<_, ClientlessBufferProvider>(
8205 Segment::data(ISS_2 + 1, ISS_1 + 1, UnscaledWindowSize::from(0), TEST_BYTES),
8206 clock.now(),
8207 &counters.refs(),
8208 &SocketOptions { delayed_ack, ..SocketOptions::default_for_state_tests() },
8209 );
8210
8211 let expect_ack = (!delayed_ack).then_some(Segment::ack(
8212 ISS_1 + 1,
8213 ISS_2 + 1 + TEST_BYTES.len(),
8214 UnscaledWindowSize::from((BUFFER_SIZE - TEST_BYTES.len()) as u16),
8215 ));
8216 assert_eq!(seg, (expect_ack, None));
8217 assert_matches!(state.poll_receive_data_dequeued(), None);
8218
8219 let expect_window_update = if delayed_ack {
8220 expect_window_update
8221 } else {
8222 (ISS_2 + 1 + TEST_BYTES.len(), WindowSize::new(0).unwrap())
8223 };
8224 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_window_update);
8225
8226 if dequeue_more_than_mss {
8227 assert_eq!(
8231 state.read_with(|available| {
8232 assert_eq!(available, &[TEST_BYTES]);
8233 available[0].len()
8234 }),
8235 TEST_BYTES.len()
8236 );
8237 assert_eq!(
8238 state.poll_receive_data_dequeued(),
8239 Some(Segment::ack(
8240 ISS_1 + 1,
8241 ISS_2 + 1 + TEST_BYTES.len(),
8242 UnscaledWindowSize::from(BUFFER_SIZE as u16)
8243 ))
8244 );
8245 assert_eq!(
8246 state.recv_mut().unwrap().last_window_update,
8247 (ISS_2 + 1 + TEST_BYTES.len(), WindowSize::new(BUFFER_SIZE).unwrap())
8248 );
8249 assert!(state.recv_mut().unwrap().timer.is_none());
8251 } else {
8252 let mss: usize = MSS.get().get().into();
8256 assert_eq!(
8257 state.read_with(|available| {
8258 assert_eq!(available, &[TEST_BYTES]);
8259 mss / 2 - 1
8260 }),
8261 mss / 2 - 1
8262 );
8263 assert_eq!(state.poll_receive_data_dequeued(), None,);
8264 assert_eq!(
8265 state.recv_mut().unwrap().last_window_update,
8266 expect_window_update,
8268 );
8269 assert_eq!(state.recv_mut().unwrap().timer.is_some(), delayed_ack);
8270 }
8271 }
8272 }
8273
8274 #[test]
8275 fn poll_receive_data_dequeued_small_window() {
8276 const MSS: Mss = Mss(NonZeroU16::new(65000).unwrap());
8277 const WINDOW: WindowSize = WindowSize::from_u32(500).unwrap();
8278 let mut recv = Recv::<FakeInstant, _> {
8279 buffer: RecvBufferState::Open {
8280 buffer: RingBuffer::new(WINDOW.into()),
8281 assembler: Assembler::new(ISS_2 + 1),
8282 },
8283 timer: None,
8284 mss: MSS,
8285 remaining_quickacks: 0,
8286 last_segment_at: None,
8287 wnd_scale: WindowScale::default(),
8288 last_window_update: (ISS_2 + 1, WindowSize::from_u32(1).unwrap()),
8289 sack_permitted: SACK_PERMITTED,
8290 };
8291 let seg = recv.poll_receive_data_dequeued(ISS_1).expect("generates segment");
8292 assert_eq!(seg.header.ack, Some(recv.nxt()));
8293 assert_eq!(seg.header.wnd << recv.wnd_scale, WINDOW);
8294 }
8295
8296 #[test]
8297 fn quickack_period() {
8298 let mut quickack = default_quickack_counter();
8299 let mut state = State::Established(Established::<FakeInstant, _, _> {
8300 snd: Send {
8301 nxt: ISS_1 + 1,
8302 max: ISS_1 + 1,
8303 una: ISS_1 + 1,
8304 wnd: WindowSize::ZERO,
8305 wnd_max: WindowSize::ZERO,
8306 buffer: NullBuffer,
8307 wl1: ISS_2 + 1,
8308 wl2: ISS_1 + 1,
8309 rtt_estimator: Estimator::default(),
8310 rtt_sampler: RttSampler::default(),
8311 timer: None,
8312 congestion_control: CongestionControl::cubic_with_mss(DEVICE_MAXIMUM_SEGMENT_SIZE),
8313 wnd_scale: WindowScale::default(),
8314 }
8315 .into(),
8316 rcv: Recv {
8317 buffer: RecvBufferState::Open {
8318 buffer: RingBuffer::default(),
8319 assembler: Assembler::new(ISS_2 + 1),
8320 },
8321 timer: None,
8322 mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8323 remaining_quickacks: quickack,
8324 last_segment_at: None,
8325 wnd_scale: WindowScale::default(),
8326 last_window_update: (ISS_2 + 1, WindowSize::DEFAULT),
8327 sack_permitted: SACK_PERMITTED,
8328 }
8329 .into(),
8330 });
8331 let socket_options = SocketOptions { delayed_ack: true, ..Default::default() };
8332 let clock = FakeInstantCtx::default();
8333 let counters = FakeTcpCounters::default();
8334 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8335 while quickack != 0 {
8336 let seq = state.recv_mut().unwrap().nxt();
8337 let (segment, _) = Segment::with_data(
8338 seq,
8339 Some(ISS_1 + 1),
8340 None,
8341 WindowSize::ZERO >> WindowScale::default(),
8342 &data[..],
8343 );
8344 let (seg, passive_open) = state.on_segment_with_options::<_, ClientlessBufferProvider>(
8345 segment,
8346 clock.now(),
8347 &counters.refs(),
8348 &socket_options,
8349 );
8350 let recv = state.recv_mut().unwrap();
8351 assert_matches!(recv.timer, None);
8352
8353 assert_eq!(passive_open, None);
8354 let seg = seg.expect("no segment generated");
8355 assert_eq!(seg.header.ack, Some(seq + u32::try_from(data.len()).unwrap()));
8356 assert_eq!(recv.remaining_quickacks, quickack - 1);
8357 quickack -= 1;
8358 state.buffers_mut().into_receive_buffer().unwrap().reset();
8359 }
8360
8361 let (segment, _) = Segment::with_data(
8363 state.recv_mut().unwrap().nxt(),
8364 Some(ISS_1 + 1),
8365 None,
8366 WindowSize::ZERO >> WindowScale::default(),
8367 &data[..],
8368 );
8369 let (seg, passive_open) = state.on_segment_with_options::<_, ClientlessBufferProvider>(
8370 segment,
8371 clock.now(),
8372 &counters.refs(),
8373 &socket_options,
8374 );
8375 assert_eq!(passive_open, None);
8376 assert_eq!(seg, None);
8377 assert_matches!(state.recv_mut().unwrap().timer, Some(ReceiveTimer::DelayedAck { .. }));
8378 }
8379
8380 #[test]
8381 fn quickack_reset_out_of_window() {
8382 let mut state = State::Established(Established::<FakeInstant, _, _> {
8383 snd: Send {
8384 nxt: ISS_1 + 1,
8385 max: ISS_1 + 1,
8386 una: ISS_1 + 1,
8387 wnd: WindowSize::ZERO,
8388 wnd_max: WindowSize::ZERO,
8389 buffer: NullBuffer,
8390 wl1: ISS_2 + 1,
8391 wl2: ISS_1 + 1,
8392 rtt_estimator: Estimator::default(),
8393 rtt_sampler: RttSampler::default(),
8394 timer: None,
8395 congestion_control: CongestionControl::cubic_with_mss(DEVICE_MAXIMUM_SEGMENT_SIZE),
8396 wnd_scale: WindowScale::default(),
8397 }
8398 .into(),
8399 rcv: Recv {
8400 buffer: RecvBufferState::Open {
8401 buffer: RingBuffer::default(),
8402 assembler: Assembler::new(ISS_2 + 1),
8403 },
8404 timer: None,
8405 mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8406 remaining_quickacks: 0,
8408 last_segment_at: None,
8409 wnd_scale: WindowScale::default(),
8410 last_window_update: (ISS_2 + 1, WindowSize::DEFAULT),
8411 sack_permitted: SACK_PERMITTED,
8412 }
8413 .into(),
8414 });
8415 let clock = FakeInstantCtx::default();
8416 let counters = FakeTcpCounters::default();
8417 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8418
8419 let (segment, _) = Segment::with_data(
8420 state.recv_mut().unwrap().nxt() - i32::try_from(data.len() + 1).unwrap(),
8422 Some(ISS_1 + 1),
8423 None,
8424 WindowSize::ZERO >> WindowScale::default(),
8425 &data[..],
8426 );
8427 let (seg, passive_open) = state
8428 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8429 segment,
8430 clock.now(),
8431 &counters.refs(),
8432 );
8433 assert_eq!(passive_open, None);
8434 let recv = state.recv_mut().unwrap();
8435 let seg = seg.expect("expected segment");
8436 assert_eq!(seg.header.ack, Some(recv.nxt()));
8437 assert_eq!(recv.remaining_quickacks, default_quickack_counter());
8438 }
8439
8440 #[test]
8441 fn quickack_reset_rto() {
8442 let mut clock = FakeInstantCtx::default();
8443 let mut state = State::Established(Established::<FakeInstant, _, _> {
8444 snd: Send {
8445 nxt: ISS_1 + 1,
8446 max: ISS_1 + 1,
8447 una: ISS_1 + 1,
8448 wnd: WindowSize::ZERO,
8449 wnd_max: WindowSize::ZERO,
8450 buffer: NullBuffer,
8451 wl1: ISS_2 + 1,
8452 wl2: ISS_1 + 1,
8453 rtt_estimator: Estimator::default(),
8454 rtt_sampler: RttSampler::default(),
8455 timer: None,
8456 congestion_control: CongestionControl::cubic_with_mss(DEVICE_MAXIMUM_SEGMENT_SIZE),
8457 wnd_scale: WindowScale::default(),
8458 }
8459 .into(),
8460 rcv: Recv {
8461 buffer: RecvBufferState::Open {
8462 buffer: RingBuffer::default(),
8463 assembler: Assembler::new(ISS_2 + 1),
8464 },
8465 timer: None,
8466 mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8467 remaining_quickacks: 0,
8469 last_segment_at: Some(clock.now()),
8470 wnd_scale: WindowScale::default(),
8471 last_window_update: (ISS_2 + 1, WindowSize::DEFAULT),
8472 sack_permitted: SACK_PERMITTED,
8473 }
8474 .into(),
8475 });
8476 let counters = FakeTcpCounters::default();
8477 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8478
8479 let (segment, _) = Segment::with_data(
8480 state.recv_mut().unwrap().nxt(),
8481 Some(ISS_1 + 1),
8482 None,
8483 WindowSize::ZERO >> WindowScale::default(),
8484 &data[..],
8485 );
8486 clock.sleep(Rto::DEFAULT.get());
8487 let (seg, passive_open) = state
8488 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8489 segment,
8490 clock.now(),
8491 &counters.refs(),
8492 );
8493 assert_eq!(passive_open, None);
8494 let recv = state.recv_mut().unwrap();
8495 let seg = seg.expect("expected segment");
8496 assert_eq!(seg.header.ack, Some(recv.nxt()));
8497 assert_eq!(recv.remaining_quickacks, default_quickack_counter() - 1);
8500 assert_eq!(recv.last_segment_at, Some(clock.now()));
8501 }
8502
8503 #[test_case(true; "sack permitted")]
8504 #[test_case(false; "sack not permitted")]
8505 fn receiver_selective_acks(sack_permitted: bool) {
8506 let mut state = State::Established(Established::<FakeInstant, _, _> {
8507 snd: Send {
8508 nxt: ISS_1 + 1,
8509 max: ISS_1 + 1,
8510 una: ISS_1 + 1,
8511 wnd: WindowSize::DEFAULT,
8512 wnd_max: WindowSize::DEFAULT,
8513 buffer: RingBuffer::default(),
8514 wl1: ISS_2 + 1,
8515 wl2: ISS_1 + 1,
8516 rtt_estimator: Estimator::default(),
8517 rtt_sampler: RttSampler::default(),
8518 timer: None,
8519 congestion_control: CongestionControl::cubic_with_mss(DEVICE_MAXIMUM_SEGMENT_SIZE),
8520 wnd_scale: WindowScale::default(),
8521 }
8522 .into(),
8523 rcv: Recv {
8524 buffer: RecvBufferState::Open {
8525 buffer: RingBuffer::default(),
8526 assembler: Assembler::new(ISS_2 + 1),
8527 },
8528 timer: None,
8529 mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8530 remaining_quickacks: 0,
8532 last_segment_at: None,
8533 wnd_scale: WindowScale::default(),
8534 last_window_update: (ISS_2 + 1, WindowSize::DEFAULT),
8535 sack_permitted,
8536 }
8537 .into(),
8538 });
8539 let clock = FakeInstantCtx::default();
8540 let counters = FakeTcpCounters::default();
8541 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8542 let mss = u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE);
8543 let seg_start = ISS_2 + 1 + mss;
8545 let (segment, _) = Segment::with_data(
8546 seg_start,
8547 Some(ISS_1 + 1),
8548 None,
8549 WindowSize::DEFAULT >> WindowScale::default(),
8550 &data[..],
8551 );
8552 let (seg, passive_open) = state
8553 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8554 segment,
8555 clock.now(),
8556 &counters.refs(),
8557 );
8558 assert_eq!(passive_open, None);
8559 let seg = seg.expect("expected segment");
8560 assert_eq!(seg.header.ack, Some(ISS_2 + 1));
8561 let expect = if sack_permitted {
8562 SackBlocks::from_iter([SackBlock::try_new(seg_start, seg_start + mss).unwrap()])
8563 } else {
8564 SackBlocks::default()
8565 };
8566 let sack_blocks = assert_matches!(seg.header.options, Options::Segment(o) => o.sack_blocks);
8567 assert_eq!(sack_blocks, expect);
8568
8569 assert_eq!(
8571 state.buffers_mut().into_send_buffer().unwrap().enqueue_data(&data[..]),
8572 data.len()
8573 );
8574 let seg = state
8575 .poll_send_with_default_options(mss, clock.now(), &counters.refs())
8576 .expect("generates segment");
8577 assert_eq!(seg.header.ack, Some(ISS_2 + 1));
8578
8579 let sack_blocks =
8581 assert_matches!(&seg.header.options, Options::Segment(o) => &o.sack_blocks);
8582 assert_eq!(sack_blocks, &expect);
8583 let expect_len = if sack_permitted {
8586 mss - 12
8588 } else {
8589 mss
8590 };
8591 assert_eq!(seg.len(), expect_len);
8592
8593 let (segment, _) = Segment::with_data(
8596 ISS_2 + 1,
8597 Some(ISS_1 + 1),
8598 None,
8599 WindowSize::DEFAULT >> WindowScale::default(),
8600 &data[..],
8601 );
8602 let (seg, passive_open) = state
8603 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8604 segment,
8605 clock.now(),
8606 &counters.refs(),
8607 );
8608 assert_eq!(passive_open, None);
8609 let seg = seg.expect("expected segment");
8610 assert_eq!(seg.header.ack, Some(ISS_2 + (2 * mss) + 1));
8611 let sack_blocks =
8612 assert_matches!(&seg.header.options, Options::Segment(o) => &o.sack_blocks);
8613 assert_eq!(sack_blocks, &SackBlocks::default());
8614 }
8615
8616 #[derive(Debug)]
8617 enum RttTestScenario {
8618 AckOne,
8619 AckTwo,
8620 Retransmit,
8621 AckPartial,
8622 }
8623
8624 #[test_case(RttTestScenario::AckOne)]
8626 #[test_case(RttTestScenario::AckTwo)]
8627 #[test_case(RttTestScenario::Retransmit)]
8628 #[test_case(RttTestScenario::AckPartial)]
8629 fn rtt(scenario: RttTestScenario) {
8630 let mut state = State::Established(Established::<FakeInstant, _, _> {
8631 snd: Send {
8632 nxt: ISS_1 + 1,
8633 max: ISS_1 + 1,
8634 una: ISS_1 + 1,
8635 wnd: WindowSize::DEFAULT,
8636 wnd_max: WindowSize::DEFAULT,
8637 buffer: RingBuffer::default(),
8638 wl1: ISS_2 + 1,
8639 wl2: ISS_1 + 1,
8640 rtt_estimator: Estimator::default(),
8641 rtt_sampler: RttSampler::default(),
8642 timer: None,
8643 congestion_control: CongestionControl::cubic_with_mss(DEVICE_MAXIMUM_SEGMENT_SIZE),
8644 wnd_scale: WindowScale::default(),
8645 }
8646 .into(),
8647 rcv: Recv {
8648 buffer: RecvBufferState::Open {
8649 buffer: RingBuffer::default(),
8650 assembler: Assembler::new(ISS_2 + 1),
8651 },
8652 timer: None,
8653 mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8654 remaining_quickacks: 0,
8656 last_segment_at: None,
8657 wnd_scale: WindowScale::default(),
8658 last_window_update: (ISS_2 + 1, WindowSize::DEFAULT),
8659 sack_permitted: SACK_PERMITTED,
8660 }
8661 .into(),
8662 });
8663
8664 const CLOCK_STEP: Duration = Duration::from_millis(1);
8665
8666 let data = "Hello World".as_bytes();
8667 let data_len_u32 = data.len().try_into().unwrap();
8668 let mut clock = FakeInstantCtx::default();
8669 let counters = FakeTcpCounters::default();
8670 for _ in 0..3 {
8671 assert_eq!(
8672 state.buffers_mut().into_send_buffer().unwrap().enqueue_data(data),
8673 data.len()
8674 );
8675 }
8676
8677 assert_eq!(state.assert_established().snd.rtt_sampler, RttSampler::NotTracking);
8678 let seg = state
8679 .poll_send_with_default_options(data_len_u32, clock.now(), &counters.refs())
8680 .expect("generate segment");
8681 assert_eq!(seg.header.seq, ISS_1 + 1);
8682 assert_eq!(seg.len(), data_len_u32);
8683 let expect_sampler = RttSampler::Tracking {
8684 range: (ISS_1 + 1)..(ISS_1 + 1 + seg.len()),
8685 timestamp: clock.now(),
8686 };
8687 assert_eq!(state.assert_established().snd.rtt_sampler, expect_sampler);
8688 clock.sleep(CLOCK_STEP);
8690 let seg = state
8691 .poll_send_with_default_options(data_len_u32, clock.now(), &counters.refs())
8692 .expect("generate segment");
8693 assert_eq!(seg.header.seq, ISS_1 + 1 + data.len());
8694 assert_eq!(seg.len(), data_len_u32);
8695 let established = state.assert_established();
8697 assert_eq!(established.snd.rtt_sampler, expect_sampler);
8698
8699 assert_eq!(established.snd.rtt_estimator.srtt(), None);
8701
8702 let (retransmit, ack_number) = match scenario {
8703 RttTestScenario::AckPartial => (false, ISS_1 + 1 + 1),
8704 RttTestScenario::AckOne => (false, ISS_1 + 1 + data.len()),
8705 RttTestScenario::AckTwo => (false, ISS_1 + 1 + data.len() * 2),
8706 RttTestScenario::Retransmit => (true, ISS_1 + 1 + data.len() * 2),
8707 };
8708
8709 if retransmit {
8710 let timeout = state.poll_send_at().expect("timeout should be present");
8712 clock.time = timeout;
8713 let seg = state
8714 .poll_send_with_default_options(data_len_u32, clock.now(), &counters.refs())
8715 .expect("generate segment");
8716 assert_eq!(seg.header.seq, ISS_1 + 1);
8718 assert_eq!(state.assert_established().snd.rtt_sampler, RttSampler::NotTracking);
8720 } else {
8721 clock.sleep(CLOCK_STEP);
8722 }
8723
8724 assert_eq!(
8725 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
8726 Segment::ack(ISS_2 + 1, ack_number, WindowSize::DEFAULT >> WindowScale::default()),
8727 clock.now(),
8728 &counters.refs()
8729 ),
8730 (None, None)
8731 );
8732 let established = state.assert_established();
8733 assert_eq!(established.snd.rtt_sampler, RttSampler::NotTracking);
8735 if retransmit {
8736 assert_eq!(established.snd.rtt_estimator.srtt(), None);
8738 } else {
8739 assert_eq!(established.snd.rtt_estimator.srtt(), Some(CLOCK_STEP * 2));
8742 }
8743
8744 clock.sleep(CLOCK_STEP);
8745 let seg = state
8746 .poll_send_with_default_options(data_len_u32, clock.now(), &counters.refs())
8747 .expect("generate segment");
8748 let seq = seg.header.seq;
8749 assert_eq!(seq, ISS_1 + 1 + data.len() * 2);
8750 let expect_sampler =
8751 RttSampler::Tracking { range: seq..(seq + seg.len()), timestamp: clock.now() };
8752 assert_eq!(state.assert_established().snd.rtt_sampler, expect_sampler);
8753
8754 clock.sleep(CLOCK_STEP);
8758 assert_eq!(
8759 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
8760 Segment::ack(
8761 ISS_2 + 1,
8762 ISS_1 + 1 + data.len() * 2,
8763 WindowSize::DEFAULT >> WindowScale::default()
8764 ),
8765 clock.now(),
8766 &counters.refs()
8767 ),
8768 (None, None)
8769 );
8770 assert_eq!(state.assert_established().snd.rtt_sampler, expect_sampler);
8771 }
8772
8773 #[test]
8774 fn loss_recovery_skips_nagle() {
8775 let mut buffer = RingBuffer::default();
8776 let payload = "Hello World".as_bytes();
8777 assert_eq!(buffer.enqueue_data(payload), payload.len());
8778 let mut state = State::<_, _, _, ()>::Established(Established {
8779 snd: Send {
8780 nxt: ISS_1 + 1,
8781 max: ISS_1 + 1,
8782 una: ISS_1 + 1,
8783 wnd: WindowSize::DEFAULT,
8784 wnd_max: WindowSize::DEFAULT,
8785 buffer,
8786 wl1: ISS_2 + 1,
8787 wl2: ISS_1 + 1,
8788 rtt_estimator: Estimator::default(),
8789 rtt_sampler: RttSampler::default(),
8790 timer: None,
8791 congestion_control: CongestionControl::cubic_with_mss(DEVICE_MAXIMUM_SEGMENT_SIZE),
8792 wnd_scale: WindowScale::default(),
8793 }
8794 .into(),
8795 rcv: Recv {
8796 buffer: RecvBufferState::Open {
8797 buffer: RingBuffer::default(),
8798 assembler: Assembler::new(ISS_2 + 1),
8799 },
8800 timer: None,
8801 mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8802 remaining_quickacks: 0,
8804 last_segment_at: None,
8805 wnd_scale: WindowScale::default(),
8806 last_window_update: (ISS_2 + 1, WindowSize::DEFAULT),
8807 sack_permitted: SACK_PERMITTED,
8808 }
8809 .into(),
8810 });
8811
8812 let socket_options =
8813 SocketOptions { nagle_enabled: true, ..SocketOptions::default_for_state_tests() };
8814 let clock = FakeInstantCtx::default();
8815 let counters = FakeTcpCounters::default();
8816 let seg = state
8817 .poll_send(
8818 &FakeStateMachineDebugId,
8819 &counters.refs(),
8820 u32::MAX,
8821 clock.now(),
8822 &socket_options,
8823 )
8824 .expect("should not close");
8825 assert_eq!(seg.len(), u32::try_from(payload.len()).unwrap());
8826 let ack =
8829 Segment::ack(ISS_2 + 1, seg.header.seq, WindowSize::DEFAULT >> WindowScale::default());
8830
8831 let mut dup_acks = 0;
8832 let seg = loop {
8833 let (seg, passive_open, data_acked, newly_closed) = state
8834 .on_segment::<(), ClientlessBufferProvider>(
8835 &FakeStateMachineDebugId,
8836 &counters.refs(),
8837 ack.clone(),
8838 clock.now(),
8839 &socket_options,
8840 false,
8841 );
8842 assert_eq!(seg, None);
8843 assert_eq!(passive_open, None);
8844 assert_eq!(data_acked, DataAcked::No);
8845 assert_eq!(newly_closed, NewlyClosed::No);
8846 dup_acks += 1;
8847
8848 match state.poll_send(
8849 &FakeStateMachineDebugId,
8850 &counters.refs(),
8851 u32::MAX,
8852 clock.now(),
8853 &socket_options,
8854 ) {
8855 Ok(seg) => break seg,
8856 Err(newly_closed) => {
8857 assert_eq!(newly_closed, NewlyClosed::No);
8858 assert!(
8859 dup_acks < DUP_ACK_THRESHOLD,
8860 "failed to retransmit after {dup_acks} dup acks"
8861 );
8862 }
8863 }
8864 };
8865 assert_eq!(seg.len(), u32::try_from(payload.len()).unwrap());
8866 assert_eq!(seg.header.seq, ack.header.ack.unwrap());
8867 }
8868}