1pub(crate) mod info;
11
12use core::convert::{Infallible, TryFrom as _};
13use core::fmt::Debug;
14use core::num::{NonZeroU8, NonZeroU32, NonZeroUsize, TryFromIntError};
15use core::ops::{Deref, DerefMut};
16use core::time::Duration;
17
18use assert_matches::assert_matches;
19use derivative::Derivative;
20use explicit::ResultExt as _;
21use netstack3_base::{
22 Control, EffectiveMss, HandshakeOptions, IcmpErrorCode, Instant, Milliseconds, Mss,
23 MssSizeLimiters, Options, Payload, PayloadLen as _, ResetOptions, RxTimestampOption,
24 SackBlocks, Segment, SegmentHeader, SegmentOptions, SeqNum, Timestamp, TimestampOption,
25 TxTimestampOption, UnscaledWindowSize, WindowScale, WindowSize,
26};
27use netstack3_trace::{TraceResourceId, trace_instant};
28use packet_formats::utils::NonZeroDuration;
29use replace_with::{replace_with, replace_with_and};
30
31use crate::internal::base::{
32 BufferSizes, BuffersRefMut, ConnectionError, IcmpErrorResult, KeepAlive, SocketOptions,
33};
34use crate::internal::buffer::{
35 Assembler, BufferLimits, IntoBuffers, ReceiveBuffer, SackBlockSizeLimiters, SendBuffer,
36};
37use crate::internal::congestion::{
38 CongestionControl, CongestionControlSendOutcome, LossRecoveryMode, LossRecoverySegment,
39};
40use crate::internal::counters::TcpCountersRefs;
41use crate::internal::rtt::{Estimator, Rto, RttSampler};
42use crate::internal::timestamp::{TimestampOptionNegotiationState, TimestampOptionState};
43
44pub(super) const MSL: Duration = Duration::from_secs(2 * 60);
49
50const DEFAULT_MAX_RETRIES: NonZeroU8 = NonZeroU8::new(15).unwrap();
57
58pub(super) const DEFAULT_MAX_SYN_RETRIES: NonZeroU8 = NonZeroU8::new(6).unwrap();
61const DEFAULT_MAX_SYNACK_RETRIES: NonZeroU8 = NonZeroU8::new(5).unwrap();
62
63const ACK_DELAY_THRESHOLD: Duration = Duration::from_millis(40);
71const SWS_PROBE_TIMEOUT: Duration = Duration::from_millis(100);
78const SWS_BUFFER_FACTOR: u32 = 2;
82
83const SACK_PERMITTED: bool = true;
85
86pub(crate) trait StateMachineDebugId: Debug {
91 fn trace_id(&self) -> TraceResourceId<'_>;
92}
93
94#[derive(Debug)]
107#[cfg_attr(test, derive(PartialEq, Eq))]
108pub struct Closed<Error> {
109 pub(crate) reason: Error,
111}
112
113pub(crate) enum Initial {}
116
117impl Closed<Initial> {
118 pub(crate) fn connect<I: Instant, ActiveOpen>(
124 iss: SeqNum,
125 timestamp_offset: Timestamp<Milliseconds>,
126 now: I,
127 active_open: ActiveOpen,
128 buffer_sizes: BufferSizes,
129 device_mss: Mss,
130 default_mss: Mss,
131 SocketOptions {
132 keep_alive: _,
133 nagle_enabled: _,
134 user_timeout,
135 delayed_ack: _,
136 fin_wait2_timeout: _,
137 max_syn_retries,
138 ip_options: _,
139 }: &SocketOptions,
140 ) -> (SynSent<I, ActiveOpen>, Segment<()>) {
141 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
142 let rwnd = buffer_sizes.rwnd_unscaled();
146 let ts_opt = TimestampOptionNegotiationState::new(now, timestamp_offset);
150 let timestamp = ts_opt.make_option_for_syn(now).map(TxTimestampOption::into);
151 (
152 SynSent {
153 iss,
154 timestamp: Some(now),
155 retrans_timer: RetransTimer::new(
156 now,
157 Rto::DEFAULT,
158 *user_timeout,
159 *max_syn_retries,
160 ),
161 active_open,
162 buffer_sizes,
163 device_mss,
164 default_mss,
165 rcv_wnd_scale,
166 ts_opt,
167 },
168 Segment::syn(
169 iss,
170 rwnd,
171 HandshakeOptions {
172 mss: Some(device_mss),
173 window_scale: Some(rcv_wnd_scale),
174 sack_permitted: SACK_PERMITTED,
175 timestamp,
176 },
177 ),
178 )
179 }
180
181 pub(crate) fn listen(
182 iss: SeqNum,
183 timestamp_offset: Timestamp<Milliseconds>,
184 buffer_sizes: BufferSizes,
185 device_mss: Mss,
186 default_mss: Mss,
187 user_timeout: Option<NonZeroDuration>,
188 ) -> Listen {
189 Listen { iss, timestamp_offset, buffer_sizes, device_mss, default_mss, user_timeout }
190 }
191}
192
193impl<Error> Closed<Error> {
194 pub(crate) fn on_segment(&self, segment: &Segment<impl Payload>) -> Option<Segment<()>> {
198 let segment_len = segment.len();
199 let SegmentHeader { seq: seg_seq, ack: seg_ack, wnd: _, control, options: _, push: _ } =
200 segment.header();
201
202 if *control == Some(Control::RST) {
216 return None;
217 }
218 let timestamp = None;
223 Some(match seg_ack {
224 Some(seg_ack) => Segment::rst(*seg_ack, ResetOptions { timestamp }),
225 None => Segment::rst_ack(
226 SeqNum::from(0),
227 *seg_seq + segment_len,
228 ResetOptions { timestamp },
229 ),
230 })
231 }
232}
233
234#[derive(Debug)]
248#[cfg_attr(test, derive(PartialEq, Eq))]
249pub struct Listen {
250 iss: SeqNum,
251 timestamp_offset: Timestamp<Milliseconds>,
252 buffer_sizes: BufferSizes,
253 device_mss: Mss,
254 default_mss: Mss,
255 user_timeout: Option<NonZeroDuration>,
256}
257
258#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
260enum ListenOnSegmentDisposition<I: Instant> {
261 SendSynAckAndEnterSynRcvd(Segment<()>, SynRcvd<I, Infallible>),
262 SendRst(Segment<()>),
263 Ignore,
264}
265
266impl Listen {
267 fn on_segment<I: Instant>(
268 &self,
269 seg: Segment<impl Payload>,
270 now: I,
271 ) -> ListenOnSegmentDisposition<I> {
272 let (header, _data) = seg.into_parts();
273 let SegmentHeader { seq, ack, wnd: _, control, options, push: _ } = header;
274 let Listen { iss, timestamp_offset, buffer_sizes, device_mss, default_mss, user_timeout } =
275 *self;
276 let smss = options.mss().unwrap_or(default_mss).min(device_mss);
277 if control == Some(Control::RST) {
281 return ListenOnSegmentDisposition::Ignore;
282 }
283 if let Some(ack) = ack {
284 let options = ResetOptions { timestamp: None };
296
297 return ListenOnSegmentDisposition::SendRst(Segment::rst(ack, options));
298 }
299 if control == Some(Control::SYN) {
300 let sack_permitted = options.sack_permitted();
301 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
314 let rwnd = buffer_sizes.rwnd_unscaled();
318 let initial_ack_sent = seq + 1;
322 let ts_opt = TimestampOptionState::negotiate(
323 TimestampOptionNegotiationState::new(now, timestamp_offset),
324 options.timestamp().map(RxTimestampOption::from),
325 initial_ack_sent,
326 );
327 return ListenOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
328 Segment::syn_ack(
329 iss,
330 initial_ack_sent,
331 rwnd,
332 HandshakeOptions {
333 mss: Some(smss),
334 window_scale: options.window_scale().map(|_| rcv_wnd_scale),
339 sack_permitted: SACK_PERMITTED,
340 timestamp: ts_opt.make_option_for_ack(now).map(TxTimestampOption::into),
341 },
342 ),
343 SynRcvd {
344 iss,
345 irs: seq,
346 timestamp: Some(now),
347 retrans_timer: RetransTimer::new(
348 now,
349 Rto::DEFAULT,
350 user_timeout,
351 DEFAULT_MAX_SYNACK_RETRIES,
352 ),
353 simultaneous_open: None,
354 buffer_sizes,
355 smss: EffectiveMss::from_mss(
356 smss,
357 MssSizeLimiters { timestamp_enabled: ts_opt.is_enabled() },
358 ),
359 rcv_wnd_scale,
360 snd_wnd_scale: options.window_scale(),
361 sack_permitted,
362 rcv: RecvParams {
363 ack: initial_ack_sent,
364 ts_opt,
365 wnd_scale: WindowScale::default(),
368 wnd: rwnd << WindowScale::default(),
369 last_ack_recv: None,
370 },
371 },
372 );
373 }
374 ListenOnSegmentDisposition::Ignore
375 }
376}
377
378#[derive(Debug)]
392#[cfg_attr(test, derive(PartialEq, Eq))]
393pub struct SynSent<I, ActiveOpen> {
394 iss: SeqNum,
395 timestamp: Option<I>,
399 retrans_timer: RetransTimer<I>,
400 active_open: ActiveOpen,
401 buffer_sizes: BufferSizes,
402 device_mss: Mss,
403 default_mss: Mss,
404 rcv_wnd_scale: WindowScale,
405 ts_opt: TimestampOptionNegotiationState<I>,
407}
408
409#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
411enum SynSentOnSegmentDisposition<I: Instant, ActiveOpen> {
412 SendAckAndEnterEstablished(Established<I, (), ()>),
413 SendSynAckAndEnterSynRcvd(Segment<()>, SynRcvd<I, ActiveOpen>),
414 SendRst(Segment<()>),
415 EnterClosed(Closed<Option<ConnectionError>>),
416 Ignore,
417}
418
419impl<I: Instant + 'static, ActiveOpen> SynSent<I, ActiveOpen> {
420 fn on_segment(
426 &self,
427 seg: Segment<impl Payload>,
428 now: I,
429 ) -> SynSentOnSegmentDisposition<I, ActiveOpen> {
430 let (header, _data) = seg.into_parts();
431 let SegmentHeader { seq: seg_seq, ack: seg_ack, wnd: seg_wnd, control, options, push: _ } =
432 header;
433 let SynSent {
434 iss,
435 timestamp: syn_sent_ts,
436 retrans_timer: RetransTimer { user_timeout_until, remaining_retries: _, at: _, rto: _ },
437 active_open: _,
438 buffer_sizes,
439 device_mss,
440 default_mss,
441 rcv_wnd_scale,
442 ts_opt,
443 } = self;
444 let has_ack = match seg_ack {
453 Some(ack) => {
454 if ack.before(*iss) || ack.after(*iss + 1) {
457 return if control == Some(Control::RST) {
458 SynSentOnSegmentDisposition::Ignore
459 } else {
460 SynSentOnSegmentDisposition::SendRst(Segment::rst(
463 ack,
464 ResetOptions { timestamp: None },
465 ))
466 };
467 }
468 true
469 }
470 None => false,
471 };
472
473 match control {
474 Some(Control::RST) => {
475 if has_ack {
483 SynSentOnSegmentDisposition::EnterClosed(Closed {
484 reason: Some(ConnectionError::ConnectionRefused),
485 })
486 } else {
487 SynSentOnSegmentDisposition::Ignore
488 }
489 }
490 Some(Control::SYN) => {
491 let smss = options.mss().unwrap_or(*default_mss).min(*device_mss);
492 let sack_permitted = options.sack_permitted();
493 match seg_ack {
498 Some(seg_ack) => {
499 if seg_ack.after(*iss) {
517 let irs = seg_seq;
518 let mut rtt_estimator = Estimator::default();
519 if let Some(syn_sent_ts) = syn_sent_ts {
520 rtt_estimator.sample(now.saturating_duration_since(*syn_sent_ts));
521 }
522 let (rcv_wnd_scale, snd_wnd_scale) = options
523 .window_scale()
524 .map(|snd_wnd_scale| (*rcv_wnd_scale, snd_wnd_scale))
525 .unwrap_or_default();
526 let next = *iss + 1;
527 let initial_ack_sent = irs + 1;
534 let ts_opt = TimestampOptionState::negotiate(
535 ts_opt.clone(),
536 options.timestamp().map(RxTimestampOption::from),
537 initial_ack_sent,
538 );
539 let smss = EffectiveMss::from_mss(
540 smss,
541 MssSizeLimiters { timestamp_enabled: ts_opt.is_enabled() },
542 );
543 let established = Established {
544 snd: Send {
545 nxt: next,
546 max: next,
547 una: seg_ack,
548 wnd: seg_wnd << WindowScale::default(),
550 wl1: seg_seq,
551 wl2: seg_ack,
552 last_push: next,
553 buffer: (),
554 rtt_sampler: RttSampler::default(),
555 rtt_estimator,
556 timer: None,
557 congestion_control: CongestionControl::cubic_with_mss(smss),
558 wnd_scale: snd_wnd_scale,
559 wnd_max: seg_wnd << WindowScale::default(),
560 last_data_sent: None,
561 }
562 .into(),
563 rcv: Recv {
564 buffer: RecvBufferState::Open {
565 buffer: (),
566 assembler: Assembler::new(initial_ack_sent),
567 },
568 remaining_quickacks: quickack_counter(
569 buffer_sizes.rcv_limits(),
570 smss,
571 ),
572 last_segment_at: None,
573 timer: None,
574 mss: smss,
575 wnd_scale: rcv_wnd_scale,
576 last_window_update: (initial_ack_sent, buffer_sizes.rwnd()),
577 sack_permitted,
578 ts_opt,
579 }
580 .into(),
581 };
582 SynSentOnSegmentDisposition::SendAckAndEnterEstablished(established)
583 } else {
584 SynSentOnSegmentDisposition::Ignore
585 }
586 }
587 None => {
588 if user_timeout_until.is_none_or(|t| now < t) {
589 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
597 let rwnd = buffer_sizes.rwnd_unscaled();
602 let initial_ack_sent = seg_seq + 1;
610 let ts_opt = TimestampOptionState::negotiate(
611 ts_opt.clone(),
612 options.timestamp().map(RxTimestampOption::from),
613 initial_ack_sent,
614 );
615 let smss = EffectiveMss::from_mss(
616 smss,
617 MssSizeLimiters { timestamp_enabled: ts_opt.is_enabled() },
618 );
619 SynSentOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
620 Segment::syn_ack(
621 *iss,
622 initial_ack_sent,
623 rwnd,
624 HandshakeOptions {
625 mss: Some(*smss.mss()),
626 window_scale: options.window_scale().map(|_| rcv_wnd_scale),
627 sack_permitted: SACK_PERMITTED,
628 timestamp: ts_opt
629 .make_option_for_ack(now)
630 .map(TxTimestampOption::into),
631 },
632 ),
633 SynRcvd {
634 iss: *iss,
635 irs: seg_seq,
636 timestamp: Some(now),
637 retrans_timer: RetransTimer::new_with_user_deadline(
638 now,
639 Rto::DEFAULT,
640 *user_timeout_until,
641 DEFAULT_MAX_SYNACK_RETRIES,
642 ),
643 simultaneous_open: None,
645 buffer_sizes: *buffer_sizes,
646 smss,
647 rcv_wnd_scale,
648 snd_wnd_scale: options.window_scale(),
649 sack_permitted,
650 rcv: RecvParams {
651 ack: initial_ack_sent,
652 ts_opt,
653 wnd_scale: WindowScale::default(),
656 wnd: rwnd << WindowScale::default(),
657 last_ack_recv: None,
658 },
659 },
660 )
661 } else {
662 SynSentOnSegmentDisposition::EnterClosed(Closed { reason: None })
663 }
664 }
665 }
666 }
667 Some(Control::FIN) | None => SynSentOnSegmentDisposition::Ignore,
671 }
672 }
673}
674
675#[derive(Debug)]
690#[cfg_attr(test, derive(PartialEq, Eq))]
691pub struct SynRcvd<I, ActiveOpen> {
692 iss: SeqNum,
693 irs: SeqNum,
694 timestamp: Option<I>,
698 retrans_timer: RetransTimer<I>,
699 simultaneous_open: Option<ActiveOpen>,
703 buffer_sizes: BufferSizes,
704 smss: EffectiveMss,
708 rcv_wnd_scale: WindowScale,
709 snd_wnd_scale: Option<WindowScale>,
710 sack_permitted: bool,
711 rcv: RecvParams<I>,
720}
721
722impl<I: Instant, R: ReceiveBuffer, S: SendBuffer, ActiveOpen> From<SynRcvd<I, Infallible>>
723 for State<I, R, S, ActiveOpen>
724{
725 fn from(
726 SynRcvd {
727 iss,
728 irs,
729 timestamp,
730 retrans_timer,
731 simultaneous_open,
732 buffer_sizes,
733 smss,
734 rcv_wnd_scale,
735 snd_wnd_scale,
736 sack_permitted,
737 rcv,
738 }: SynRcvd<I, Infallible>,
739 ) -> Self {
740 match simultaneous_open {
741 None => State::SynRcvd(SynRcvd {
742 iss,
743 irs,
744 timestamp,
745 retrans_timer,
746 simultaneous_open: None,
747 buffer_sizes,
748 smss,
749 rcv_wnd_scale,
750 snd_wnd_scale,
751 sack_permitted,
752 rcv,
753 }),
754 }
755 }
756}
757enum FinQueued {}
758
759impl FinQueued {
760 const YES: bool = true;
764 const NO: bool = false;
765}
766
767#[derive(Derivative)]
769#[derivative(Debug)]
770#[cfg_attr(test, derivative(PartialEq, Eq))]
771pub(crate) struct Send<I, S, const FIN_QUEUED: bool> {
772 nxt: SeqNum,
773 pub(crate) max: SeqNum,
774 una: SeqNum,
775 wnd: WindowSize,
776 wnd_scale: WindowScale,
777 wnd_max: WindowSize,
778 wl1: SeqNum,
779 wl2: SeqNum,
780 last_push: SeqNum,
781 rtt_sampler: RttSampler<I>,
782 rtt_estimator: Estimator,
783 timer: Option<SendTimer<I>>,
784 #[derivative(PartialEq = "ignore")]
785 congestion_control: CongestionControl<I>,
786 last_data_sent: Option<I>,
787 buffer: S,
788}
789
790impl<I> Send<I, (), false> {
791 fn with_buffer<S>(self, buffer: S) -> Send<I, S, false> {
792 let Self {
793 nxt,
794 max,
795 una,
796 wnd,
797 wnd_scale,
798 wnd_max,
799 wl1,
800 wl2,
801 last_push,
802 rtt_sampler,
803 rtt_estimator,
804 timer,
805 congestion_control,
806 last_data_sent,
807 buffer: _,
808 } = self;
809 Send {
810 nxt,
811 max,
812 una,
813 wnd,
814 wnd_scale,
815 wnd_max,
816 wl1,
817 wl2,
818 last_push,
819 rtt_sampler,
820 rtt_estimator,
821 timer,
822 congestion_control,
823 last_data_sent,
824 buffer,
825 }
826 }
827}
828
829#[derive(Debug, Clone, Copy)]
830#[cfg_attr(test, derive(PartialEq, Eq))]
831struct RetransTimer<I> {
832 user_timeout_until: Option<I>,
833 remaining_retries: Option<NonZeroU8>,
834 at: I,
835 rto: Rto,
836}
837
838impl<I: Instant> RetransTimer<I> {
839 fn new(
840 now: I,
841 rto: Rto,
842 user_timeout: Option<NonZeroDuration>,
843 max_retries: NonZeroU8,
844 ) -> Self {
845 let user_timeout_until = user_timeout.map(|t| now.saturating_add(t.get()));
846 Self::new_with_user_deadline(now, rto, user_timeout_until, max_retries)
847 }
848
849 fn new_with_user_deadline(
850 now: I,
851 rto: Rto,
852 user_timeout_until: Option<I>,
853 max_retries: NonZeroU8,
854 ) -> Self {
855 let rto_at = now.panicking_add(rto.get());
856 let at = user_timeout_until.map(|i| i.min(rto_at)).unwrap_or(rto_at);
857 Self { at, rto, user_timeout_until, remaining_retries: Some(max_retries) }
858 }
859
860 fn backoff(&mut self, now: I) {
861 let Self { at, rto, user_timeout_until, remaining_retries } = self;
862 *remaining_retries = remaining_retries.and_then(|r| NonZeroU8::new(r.get() - 1));
863 *rto = rto.double();
864 let rto_at = now.panicking_add(rto.get());
865 *at = user_timeout_until.map(|i| i.min(rto_at)).unwrap_or(rto_at);
866 }
867
868 fn timed_out(&self, now: I) -> bool {
869 let RetransTimer { user_timeout_until, remaining_retries, at, rto: _ } = self;
870 (remaining_retries.is_none() && now >= *at) || user_timeout_until.is_some_and(|t| now >= t)
871 }
872}
873
874#[derive(Debug, Clone, Copy)]
876#[cfg_attr(test, derive(PartialEq, Eq))]
877enum SendTimer<I> {
878 Retrans(RetransTimer<I>),
881 KeepAlive(KeepAliveTimer<I>),
884 ZeroWindowProbe(RetransTimer<I>),
892 SWSProbe { at: I },
900}
901
902#[derive(Debug, Clone, Copy)]
903#[cfg_attr(test, derive(PartialEq, Eq))]
904enum ReceiveTimer<I> {
905 DelayedAck { at: I },
906}
907
908#[derive(Debug, Clone, Copy)]
909#[cfg_attr(test, derive(PartialEq, Eq))]
910struct KeepAliveTimer<I> {
911 at: I,
912 already_sent: u8,
913 user_timeout_until: Option<I>,
914}
915
916impl<I: Instant> KeepAliveTimer<I> {
917 fn idle(now: I, keep_alive: &KeepAlive) -> Self {
918 assert!(keep_alive.enabled);
920 let at = now.saturating_add(keep_alive.idle.into());
921 Self { at, already_sent: 0, user_timeout_until: None }
922 }
923
924 fn poll_send(
929 &mut self,
930 now: I,
931 keep_alive: &KeepAlive,
932 user_timeout: &Option<NonZeroDuration>,
933 ) -> bool {
934 assert!(keep_alive.enabled);
936 let Self { at, already_sent, user_timeout_until } = self;
937 if *at > now {
938 return false;
939 }
940
941 if user_timeout_until.is_none() {
944 *user_timeout_until = user_timeout.map(|t| now.saturating_add(t.get()));
945 }
946
947 *already_sent = already_sent.saturating_add(1);
948 let interval = now.saturating_add(keep_alive.interval.into());
949 *at = user_timeout_until.map(|i| i.min(interval)).unwrap_or(interval);
950
951 true
952 }
953
954 fn timed_out(&self, now: I, keep_alive: &KeepAlive) -> bool {
955 assert!(keep_alive.enabled);
957 let Self { at: _, already_sent, user_timeout_until } = self;
958 *already_sent >= keep_alive.count.get() || user_timeout_until.is_some_and(|t| now >= t)
959 }
960}
961
962impl<I: Instant> SendTimer<I> {
963 fn expiry(&self) -> I {
964 match self {
965 SendTimer::Retrans(RetransTimer {
966 at,
967 rto: _,
968 user_timeout_until: _,
969 remaining_retries: _,
970 })
971 | SendTimer::KeepAlive(KeepAliveTimer { at, already_sent: _, user_timeout_until: _ })
972 | SendTimer::ZeroWindowProbe(RetransTimer {
973 at,
974 rto: _,
975 user_timeout_until: _,
976 remaining_retries: _,
977 }) => *at,
978 SendTimer::SWSProbe { at } => *at,
979 }
980 }
981}
982
983impl<I: Instant> ReceiveTimer<I> {
984 fn expiry(&self) -> I {
985 match self {
986 ReceiveTimer::DelayedAck { at } => *at,
987 }
988 }
989}
990
991#[derive(Debug)]
993#[cfg_attr(test, derive(PartialEq, Eq))]
994enum RecvBufferState<R> {
995 Open { buffer: R, assembler: Assembler },
996 Closed { buffer_size: usize, nxt: SeqNum },
997}
998
999impl<R: ReceiveBuffer> RecvBufferState<R> {
1000 fn is_closed(&self) -> bool {
1001 matches!(self, Self::Closed { .. })
1002 }
1003
1004 fn has_out_of_order(&self) -> bool {
1005 match self {
1006 Self::Open { assembler, .. } => assembler.has_out_of_order(),
1007 Self::Closed { .. } => false,
1008 }
1009 }
1010
1011 fn close(&mut self) {
1012 let new_state = match self {
1013 Self::Open { buffer, assembler } => {
1014 Self::Closed { nxt: assembler.nxt(), buffer_size: buffer.limits().capacity }
1015 }
1016 Self::Closed { .. } => return,
1017 };
1018 *self = new_state;
1019 }
1020
1021 fn limits(&self) -> BufferLimits {
1022 match self {
1023 RecvBufferState::Open { buffer, .. } => buffer.limits(),
1024 RecvBufferState::Closed { buffer_size, .. } => {
1025 BufferLimits { capacity: *buffer_size, len: 0 }
1026 }
1027 }
1028 }
1029}
1030
1031fn quickack_counter(rcv_limits: BufferLimits, mss: EffectiveMss) -> usize {
1033 const MIN_QUICKACK: usize = 2;
1035 const MAX_QUICKACK: usize = 32;
1039
1040 let BufferLimits { capacity, len } = rcv_limits;
1041 let window = capacity - len;
1042 (window / (2 * usize::from(mss))).clamp(MIN_QUICKACK, MAX_QUICKACK)
1053}
1054
1055#[derive(Debug)]
1057#[cfg_attr(test, derive(PartialEq, Eq))]
1058pub(crate) struct Recv<I, R> {
1059 timer: Option<ReceiveTimer<I>>,
1060 mss: EffectiveMss,
1061 wnd_scale: WindowScale,
1062 last_window_update: (SeqNum, WindowSize),
1063 remaining_quickacks: usize,
1064 last_segment_at: Option<I>,
1065 sack_permitted: bool,
1068
1069 buffer: RecvBufferState<R>,
1071 ts_opt: TimestampOptionState<I>,
1072}
1073
1074impl<I> Recv<I, ()> {
1075 fn with_buffer<R>(self, buffer: R) -> Recv<I, R> {
1076 let Self {
1077 timer,
1078 mss,
1079 wnd_scale,
1080 last_window_update,
1081 buffer: old_buffer,
1082 remaining_quickacks,
1083 last_segment_at,
1084 sack_permitted,
1085 ts_opt,
1086 } = self;
1087 let nxt = match old_buffer {
1088 RecvBufferState::Open { assembler, .. } => assembler.nxt(),
1089 RecvBufferState::Closed { .. } => unreachable!(),
1090 };
1091 Recv {
1092 timer,
1093 mss,
1094 wnd_scale,
1095 last_window_update,
1096 remaining_quickacks,
1097 last_segment_at,
1098 buffer: RecvBufferState::Open { buffer, assembler: Assembler::new(nxt) },
1099 sack_permitted,
1100 ts_opt,
1101 }
1102 }
1103}
1104
1105impl<I, R> Recv<I, R> {
1106 fn sack_blocks(&self) -> SackBlocks {
1107 if self.sack_permitted {
1108 match &self.buffer {
1109 RecvBufferState::Open { buffer: _, assembler } => {
1110 assembler.sack_blocks(SackBlockSizeLimiters {
1111 timestamp_enabled: self.ts_opt.is_enabled(),
1112 })
1113 }
1114 RecvBufferState::Closed { buffer_size: _, nxt: _ } => SackBlocks::default(),
1115 }
1116 } else {
1117 SackBlocks::default()
1119 }
1120 }
1121}
1122
1123impl<I: Instant, R> Recv<I, R> {
1124 fn timestamp_option_for_ack(&self, now: I) -> Option<TimestampOption> {
1125 self.ts_opt.make_option_for_ack(now).map(TxTimestampOption::into)
1126 }
1127}
1128
1129struct WindowSizeCalculation {
1131 rcv_nxt: SeqNum,
1134 window_size: WindowSize,
1136 threshold: usize,
1142}
1143
1144impl<I: Instant, R: ReceiveBuffer> Recv<I, R> {
1145 fn calculate_window_size(&self) -> WindowSizeCalculation {
1147 let rcv_nxt = self.nxt();
1148 let Self {
1149 buffer,
1150 timer: _,
1151 mss,
1152 wnd_scale: _,
1153 last_window_update: (rcv_wup, last_wnd),
1154 remaining_quickacks: _,
1155 last_segment_at: _,
1156 sack_permitted: _,
1157 ts_opt: _,
1158 } = self;
1159
1160 let BufferLimits { capacity, len } = buffer.limits();
1172
1173 let unused_window = u32::try_from(*rcv_wup + *last_wnd - rcv_nxt).unwrap_or(0);
1179 let unused_window = WindowSize::from_u32(unused_window).unwrap_or(WindowSize::MAX);
1181
1182 let reduction = capacity.saturating_sub(len.saturating_add(usize::from(unused_window)));
1186 let threshold = usize::min(capacity / 2, usize::from(mss.get()));
1187 let window_size = if reduction >= threshold {
1188 WindowSize::new(capacity - len).unwrap_or(WindowSize::MAX)
1190 } else {
1191 unused_window
1194 };
1195 WindowSizeCalculation { rcv_nxt, window_size, threshold }
1196 }
1197
1198 fn poll_receive_data_dequeued(&mut self, snd_max: SeqNum, now: I) -> Option<Segment<()>> {
1201 let WindowSizeCalculation { rcv_nxt, window_size: calculated_window_size, threshold } =
1202 self.calculate_window_size();
1203 let (rcv_wup, last_window_size) = self.last_window_update;
1204
1205 let rcv_diff = rcv_nxt - rcv_wup;
1211 debug_assert!(rcv_diff >= 0, "invalid RCV.NXT change: {rcv_nxt:?} < {rcv_wup:?}");
1212 let last_window_size =
1213 last_window_size.saturating_sub(usize::try_from(rcv_diff).unwrap_or(0));
1214
1215 let effective_window_size = (calculated_window_size >> self.wnd_scale) << self.wnd_scale;
1220 let effective_window_size_usize: usize = effective_window_size.into();
1223 let last_window_size_usize: usize = last_window_size.into();
1224
1225 if last_window_size_usize < threshold && effective_window_size_usize >= threshold {
1231 let ack = self.nxt();
1232 self.last_window_update = (rcv_nxt, calculated_window_size);
1234 self.ts_opt.process_tx_ack(ack);
1235 self.timer = None;
1238 Some(Segment::ack(
1239 snd_max,
1240 ack,
1241 calculated_window_size >> self.wnd_scale,
1242 SegmentOptions {
1243 sack_blocks: self.sack_blocks(),
1244 timestamp: self.timestamp_option_for_ack(now),
1245 },
1246 ))
1247 } else {
1248 None
1249 }
1250 }
1251
1252 pub(crate) fn nxt(&self) -> SeqNum {
1253 match &self.buffer {
1254 RecvBufferState::Open { assembler, .. } => assembler.nxt(),
1255 RecvBufferState::Closed { nxt, .. } => *nxt,
1256 }
1257 }
1258
1259 fn poll_send(&mut self, snd_max: SeqNum, now: I) -> Option<Segment<()>> {
1260 match self.timer {
1261 Some(ReceiveTimer::DelayedAck { at }) => (at <= now).then(|| {
1262 self.timer = None;
1263 self.make_ack(snd_max, now)
1264 }),
1265 None => None,
1266 }
1267 }
1268
1269 fn handle_fin(&self) -> RecvParams<I> {
1271 let WindowSizeCalculation { rcv_nxt, window_size, threshold: _ } =
1272 self.calculate_window_size();
1273 RecvParams {
1274 ack: rcv_nxt + 1,
1275 wnd: window_size.checked_sub(1).unwrap_or(WindowSize::ZERO),
1276 wnd_scale: self.wnd_scale,
1277 ts_opt: self.ts_opt.clone(),
1278 last_ack_recv: self.last_segment_at,
1279 }
1280 }
1281
1282 fn reset_quickacks(&mut self) {
1283 let Self {
1284 timer: _,
1285 mss,
1286 wnd_scale: _,
1287 last_window_update: _,
1288 remaining_quickacks,
1289 buffer,
1290 last_segment_at: _,
1291 sack_permitted: _,
1292 ts_opt: _,
1293 } = self;
1294 let new_remaining = quickack_counter(buffer.limits(), *mss);
1295 *remaining_quickacks = new_remaining.max(*remaining_quickacks);
1297 }
1298}
1299
1300impl<'a, I: Instant, R: ReceiveBuffer> RecvSegmentArgumentsProvider<'a, I> for &'a mut Recv<I, R> {
1301 fn take_rcv_segment_args(
1302 self,
1303 ) -> (SeqNum, UnscaledWindowSize, SackBlocks, &'a TimestampOptionState<I>) {
1304 let WindowSizeCalculation { rcv_nxt, window_size, threshold: _ } =
1305 self.calculate_window_size();
1306 self.last_window_update = (rcv_nxt, window_size);
1308 self.ts_opt.process_tx_ack(rcv_nxt);
1309 (rcv_nxt, window_size >> self.wnd_scale, self.sack_blocks(), &self.ts_opt)
1310 }
1311}
1312
1313#[derive(Debug, Clone)]
1315#[cfg_attr(test, derive(PartialEq, Eq))]
1316pub(super) struct RecvParams<I> {
1317 pub(super) ack: SeqNum,
1318 pub(super) wnd_scale: WindowScale,
1319 pub(super) wnd: WindowSize,
1320 ts_opt: TimestampOptionState<I>,
1321 last_ack_recv: Option<I>,
1322}
1323
1324impl<I: Instant> RecvParams<I> {
1325 fn timestamp_option_for_ack(&self, now: I) -> Option<TimestampOption> {
1326 self.ts_opt.make_option_for_ack(now).map(TxTimestampOption::into)
1327 }
1328
1329 fn timestamp_option_for_non_ack(&self, now: I) -> Option<TimestampOption> {
1330 self.ts_opt.make_option_for_non_ack(now).map(TxTimestampOption::into)
1331 }
1332}
1333
1334impl<'a, I: Instant> RecvSegmentArgumentsProvider<'a, I> for &'a mut RecvParams<I> {
1335 fn take_rcv_segment_args(
1336 self,
1337 ) -> (SeqNum, UnscaledWindowSize, SackBlocks, &'a TimestampOptionState<I>) {
1338 self.ts_opt.process_tx_ack(self.ack);
1340 (self.ack, self.wnd >> self.wnd_scale, SackBlocks::default(), &self.ts_opt)
1341 }
1342}
1343
1344enum CalculatedRecvParams<'a, I, R> {
1346 Recv { backing_state: &'a mut Recv<I, R>, cached_window: WindowSizeCalculation },
1347 RecvParams { backing_state: &'a mut RecvParams<I> },
1348}
1349
1350impl<'a, I, R> CalculatedRecvParams<'a, I, R> {
1351 fn from_params(params: &'a mut RecvParams<I>) -> Self {
1356 Self::RecvParams { backing_state: params }
1357 }
1358
1359 fn nxt(&self) -> SeqNum {
1360 match self {
1361 Self::Recv { backing_state: _, cached_window } => cached_window.rcv_nxt,
1362 Self::RecvParams { backing_state } => backing_state.ack,
1363 }
1364 }
1365
1366 fn wnd(&self) -> WindowSize {
1367 match self {
1368 Self::Recv { backing_state: _, cached_window } => cached_window.window_size,
1369 Self::RecvParams { backing_state } => backing_state.wnd,
1370 }
1371 }
1372
1373 fn ts_opt(&self) -> &TimestampOptionState<I> {
1374 match self {
1375 Self::Recv { backing_state, cached_window: _ } => &backing_state.ts_opt,
1376 Self::RecvParams { backing_state } => &backing_state.ts_opt,
1377 }
1378 }
1379
1380 fn ts_opt_mut(&mut self) -> &mut TimestampOptionState<I> {
1381 match self {
1382 Self::Recv { backing_state, cached_window: _ } => &mut backing_state.ts_opt,
1383 Self::RecvParams { backing_state } => &mut backing_state.ts_opt,
1384 }
1385 }
1386}
1387
1388impl<'a, I: Instant, R: ReceiveBuffer> CalculatedRecvParams<'a, I, R> {
1389 fn reset_quickacks(&mut self) {
1390 match self {
1391 CalculatedRecvParams::Recv { backing_state, cached_window: _ } => {
1392 backing_state.reset_quickacks();
1393 }
1394 CalculatedRecvParams::RecvParams { backing_state: _ } => {}
1395 }
1396 }
1397}
1398
1399impl<'a, I: Instant, R> RecvSegmentArgumentsProvider<'a, I> for CalculatedRecvParams<'a, I, R> {
1400 fn take_rcv_segment_args(
1401 self,
1402 ) -> (SeqNum, UnscaledWindowSize, SackBlocks, &'a TimestampOptionState<I>) {
1403 let (ack, wnd, wnd_scale, sack_blocks, ts_opt) = match self {
1404 Self::Recv {
1405 backing_state,
1406 cached_window: WindowSizeCalculation { rcv_nxt, window_size, threshold: _ },
1407 } => {
1408 backing_state.last_window_update = (rcv_nxt, window_size);
1410 backing_state.ts_opt.process_tx_ack(rcv_nxt);
1411 (
1412 rcv_nxt,
1413 window_size,
1414 backing_state.wnd_scale,
1415 backing_state.sack_blocks(),
1416 &backing_state.ts_opt,
1417 )
1418 }
1419 Self::RecvParams {
1420 backing_state: RecvParams { ack, wnd_scale, wnd, ts_opt, last_ack_recv: _ },
1421 } => {
1422 ts_opt.process_tx_ack(*ack);
1424 (*ack, *wnd, *wnd_scale, SackBlocks::default(), &*ts_opt)
1425 }
1426 };
1427 (ack, wnd >> wnd_scale, sack_blocks, ts_opt)
1428 }
1429}
1430
1431impl<'a, I: Instant, R: ReceiveBuffer> CalculatedRecvParams<'a, I, R> {
1432 fn from_recv(recv: &'a mut Recv<I, R>) -> Self {
1433 let cached_window = recv.calculate_window_size();
1434 Self::Recv { backing_state: recv, cached_window }
1435 }
1436}
1437
1438trait RecvSegmentArgumentsProvider<'a, I: Instant>: Sized {
1439 fn take_rcv_segment_args(
1444 self,
1445 ) -> (SeqNum, UnscaledWindowSize, SackBlocks, &'a TimestampOptionState<I>);
1446
1447 fn make_segment<
1450 P,
1451 F: FnOnce(SeqNum, UnscaledWindowSize, SackBlocks, &TimestampOptionState<I>) -> Segment<P>,
1452 >(
1453 self,
1454 f: F,
1455 ) -> Segment<P> {
1456 let (ack, wnd, sack, ts_opt) = self.take_rcv_segment_args();
1457 f(ack, wnd, sack, ts_opt)
1458 }
1459
1460 fn make_ack<P: Payload>(self, seq: SeqNum, now: I) -> Segment<P> {
1463 let (ack, wnd, sack_blocks, ts_opt) = self.take_rcv_segment_args();
1464 Segment::ack(
1465 seq,
1466 ack,
1467 wnd,
1468 SegmentOptions {
1473 sack_blocks,
1474 timestamp: ts_opt.make_option_for_ack(now).map(TxTimestampOption::into),
1475 },
1476 )
1477 }
1478}
1479
1480#[derive(Debug)]
1495#[cfg_attr(test, derive(PartialEq, Eq))]
1496pub struct Established<I, R, S> {
1497 pub(crate) snd: Takeable<Send<I, S, { FinQueued::NO }>>,
1498 pub(crate) rcv: Takeable<Recv<I, R>>,
1499}
1500
1501#[derive(Debug, Clone, Copy, PartialEq)]
1504pub(crate) enum DataAcked {
1505 Yes,
1506 No,
1507}
1508
1509impl<I: Instant, S: SendBuffer, const FIN_QUEUED: bool> Send<I, S, FIN_QUEUED> {
1510 fn timed_out(&mut self, now: I, keep_alive: &KeepAlive) -> bool {
1512 match self.timer {
1513 Some(SendTimer::KeepAlive(keep_alive_timer)) => {
1514 if keep_alive.enabled {
1515 keep_alive_timer.timed_out(now, keep_alive)
1516 } else {
1517 self.timer = None;
1519 false
1520 }
1521 }
1522 Some(SendTimer::Retrans(timer)) | Some(SendTimer::ZeroWindowProbe(timer)) => {
1523 timer.timed_out(now)
1524 }
1525 Some(SendTimer::SWSProbe { at: _ }) | None => false,
1526 }
1527 }
1528
1529 fn poll_send<'a>(
1535 &mut self,
1536 id: &impl StateMachineDebugId,
1537 counters: &TcpCountersRefs<'_>,
1538 rcv: impl RecvSegmentArgumentsProvider<'a, I>,
1539 now: I,
1540 SocketOptions {
1541 keep_alive,
1542 nagle_enabled,
1543 user_timeout,
1544 delayed_ack: _,
1545 fin_wait2_timeout: _,
1546 max_syn_retries: _,
1547 ip_options: _,
1548 }: &SocketOptions,
1549 ) -> Option<Segment<S::Payload<'_>>> {
1550 let Self {
1551 nxt: snd_nxt,
1552 max: snd_max,
1553 una: snd_una,
1554 wnd: snd_wnd,
1555 buffer,
1556 wl1: _,
1557 wl2: _,
1558 last_push,
1559 rtt_sampler,
1560 rtt_estimator,
1561 timer,
1562 congestion_control,
1563 wnd_scale: _,
1564 wnd_max: snd_wnd_max,
1565 last_data_sent,
1566 } = self;
1567 let BufferLimits { capacity: _, len: readable_bytes } = buffer.limits();
1568 let mss = congestion_control.mss();
1569 let mut zero_window_probe = false;
1570 let mut override_sws = false;
1571
1572 match timer {
1573 Some(SendTimer::Retrans(retrans_timer)) => {
1574 if retrans_timer.at <= now {
1575 congestion_control.on_retransmission_timeout(*snd_nxt);
1590 *snd_nxt = *snd_una;
1591 retrans_timer.backoff(now);
1592 counters.increment(|c| &c.timeouts);
1593 }
1594 }
1595 Some(SendTimer::ZeroWindowProbe(retrans_timer)) => {
1596 debug_assert!(readable_bytes > 0 || FIN_QUEUED);
1597 if retrans_timer.at <= now {
1598 zero_window_probe = true;
1599 *snd_nxt = *snd_una;
1600 retrans_timer.backoff(now);
1604 }
1605 }
1606 Some(SendTimer::KeepAlive(keep_alive_timer)) => {
1607 if keep_alive.enabled && !FIN_QUEUED && readable_bytes == 0 {
1612 if keep_alive_timer.poll_send(now, keep_alive, user_timeout) {
1613 return Some(rcv.make_ack(*snd_max - 1, now));
1616 }
1617 } else {
1618 *timer = None;
1619 }
1620 }
1621 Some(SendTimer::SWSProbe { at }) => {
1622 if *at <= now {
1623 override_sws = true;
1624 *timer = None;
1625 }
1626 }
1627 None => {}
1628 };
1629
1630 if *snd_wnd == WindowSize::ZERO && readable_bytes > 0 {
1633 match timer {
1634 Some(SendTimer::ZeroWindowProbe(_)) => {}
1635 _ => {
1636 *timer = Some(SendTimer::ZeroWindowProbe(RetransTimer::new(
1637 now,
1638 rtt_estimator.rto(),
1639 *user_timeout,
1640 DEFAULT_MAX_RETRIES,
1641 )));
1642
1643 return None;
1652 }
1653 }
1654 }
1655
1656 let CongestionControlSendOutcome {
1661 next_seg,
1662 congestion_limit,
1663 congestion_window,
1664 loss_recovery,
1665 } = congestion_control.poll_send(*snd_una, *snd_nxt, *snd_wnd, readable_bytes)?;
1666
1667 let snd_limit = *snd_una + *snd_wnd;
1671 let unused_window = u32::try_from(snd_limit - next_seg).ok_checked::<TryFromIntError>()?;
1672 let offset =
1673 usize::try_from(next_seg - *snd_una).unwrap_or_else(|TryFromIntError { .. }| {
1674 panic!("next_seg({:?}) should never fall behind snd.una({:?})", next_seg, *snd_una);
1675 });
1676 let available = u32::try_from(readable_bytes + usize::from(FIN_QUEUED) - offset)
1677 .unwrap_or_else(|_| WindowSize::MAX.into());
1678 let can_send = unused_window
1682 .min(congestion_limit)
1683 .min(available)
1684 .min(u32::from(mss))
1685 .max(u32::from(zero_window_probe));
1686
1687 if can_send == 0 {
1688 if available == 0 && offset == 0 && timer.is_none() && keep_alive.enabled {
1689 *timer = Some(SendTimer::KeepAlive(KeepAliveTimer::idle(now, keep_alive)));
1690 }
1691 return None;
1692 }
1693
1694 let has_fin = FIN_QUEUED && can_send == available;
1695 let seg = buffer.peek_with(offset, |readable| {
1696 let bytes_to_send = u32::min(
1697 can_send - u32::from(has_fin),
1698 u32::try_from(readable.len()).unwrap_or(u32::MAX),
1699 );
1700 let has_fin = has_fin && bytes_to_send == can_send - u32::from(has_fin);
1701
1702 let loss_recovery_allow_delay = match loss_recovery {
1710 LossRecoverySegment::Yes { rearm_retransmit: _, mode: _ } => false,
1711 LossRecoverySegment::No => true,
1712 };
1713 if bytes_to_send < u32::from(mss) && !has_fin && loss_recovery_allow_delay {
1714 if bytes_to_send == 0 {
1715 return None;
1716 }
1717 if *nagle_enabled && snd_nxt.after(*snd_una) {
1725 return None;
1726 }
1727 if available > unused_window
1756 && unused_window
1757 < u32::min(u32::from(mss), u32::from(*snd_wnd_max) / SWS_BUFFER_FACTOR)
1758 && !override_sws
1759 && !zero_window_probe
1760 {
1761 if timer.is_none() {
1762 *timer =
1763 Some(SendTimer::SWSProbe { at: now.panicking_add(SWS_PROBE_TIMEOUT) })
1764 }
1765 return None;
1766 }
1767 }
1768
1769 let seg = rcv.make_segment(|ack, wnd, sack_blocks, ts_opt| {
1770 let options = SegmentOptions {
1771 sack_blocks,
1772 timestamp: ts_opt.make_option_for_ack(now).map(TxTimestampOption::into),
1777 };
1778 let bytes_to_send = bytes_to_send.min(u32::from(mss.payload_size(&options).get()));
1780
1781 let no_more_data_to_send = u32::try_from(readable_bytes - offset)
1796 .is_ok_and(|avail| avail == bytes_to_send);
1797
1798 let periodic_push =
1799 next_seg.after_or_eq(*last_push + snd_wnd_max.halved().max(WindowSize::ONE));
1800 let push = no_more_data_to_send || periodic_push;
1801 if bytes_to_send > 0 {
1802 *last_data_sent = Some(now);
1803 }
1804 let (seg, discarded) = Segment::new(
1805 SegmentHeader {
1806 seq: next_seg,
1807 ack: Some(ack),
1808 control: has_fin.then_some(Control::FIN),
1809 wnd,
1810 options: Options::Segment(options),
1811 push,
1812 },
1813 readable.slice(0..bytes_to_send),
1814 );
1815 debug_assert_eq!(discarded, 0);
1816 seg
1817 });
1818 Some(seg)
1819 })?;
1820 trace_instant!("tcp::Send::poll_send/segment",
1821 "id" => id.trace_id(),
1822 "seq" => u32::from(next_seg),
1823 "len" => seg.len(),
1824 "can_send" => can_send,
1825 "snd_wnd" => u32::from(*snd_wnd),
1826 "cwnd" => congestion_window,
1827 "unused_window" => unused_window,
1828 "available" => available,
1829 );
1830 let seq_max = next_seg + seg.len();
1831 rtt_sampler.on_will_send_segment(now, next_seg..seq_max, *snd_max);
1832 congestion_control.on_will_send_segment(seg.len());
1833
1834 if seq_max.after(*snd_nxt) {
1835 *snd_nxt = seq_max;
1836 } else {
1837 match loss_recovery {
1840 LossRecoverySegment::Yes { rearm_retransmit: _, ref mode } => match mode {
1841 LossRecoveryMode::FastRecovery => counters.increment(|c| &c.fast_retransmits),
1842 LossRecoveryMode::SackRecovery => counters.increment(|c| &c.sack_retransmits),
1843 },
1844 LossRecoverySegment::No => (),
1845 }
1846 }
1847 if seq_max.after(*snd_max) {
1848 *snd_max = seq_max;
1849 } else {
1850 counters.increment(|c| &c.retransmits);
1852 if congestion_control.in_slow_start() {
1853 counters.increment(|c| &c.slow_start_retransmits);
1854 }
1855 }
1856
1857 if seg.header().push {
1859 *last_push = seg.header().seq;
1860 }
1861
1862 let update_rto = match timer {
1868 Some(SendTimer::Retrans(_)) | Some(SendTimer::ZeroWindowProbe(_)) => {
1869 match loss_recovery {
1872 LossRecoverySegment::Yes { rearm_retransmit, mode: _ } => rearm_retransmit,
1873 LossRecoverySegment::No => false,
1874 }
1875 }
1876 Some(SendTimer::KeepAlive(_)) | Some(SendTimer::SWSProbe { at: _ }) | None => true,
1877 };
1878 if update_rto {
1879 *timer = Some(SendTimer::Retrans(RetransTimer::new(
1880 now,
1881 rtt_estimator.rto(),
1882 *user_timeout,
1883 DEFAULT_MAX_RETRIES,
1884 )))
1885 }
1886 Some(seg)
1887 }
1888
1889 fn process_ack<'a, R: RecvSegmentArgumentsProvider<'a, I>>(
1892 &mut self,
1893 id: &impl StateMachineDebugId,
1894 counters: &TcpCountersRefs<'_>,
1895 seg_seq: SeqNum,
1896 seg_ack: SeqNum,
1897 seg_wnd: UnscaledWindowSize,
1898 seg_sack_blocks: &SackBlocks,
1899 pure_ack: bool,
1900 rcv: R,
1901 now: I,
1902 SocketOptions {
1903 keep_alive,
1904 nagle_enabled: _,
1905 user_timeout,
1906 delayed_ack: _,
1907 fin_wait2_timeout: _,
1908 max_syn_retries: _,
1909 ip_options: _,
1910 }: &SocketOptions,
1911 ) -> (Option<Segment<()>>, DataAcked) {
1912 let Self {
1913 nxt: snd_nxt,
1914 max: snd_max,
1915 una: snd_una,
1916 wnd: snd_wnd,
1917 wl1: snd_wl1,
1918 wl2: snd_wl2,
1919 last_push: _,
1920 wnd_max,
1921 buffer,
1922 rtt_sampler,
1923 rtt_estimator,
1924 timer,
1925 congestion_control,
1926 wnd_scale,
1927 last_data_sent: _,
1928 } = self;
1929 let seg_wnd = seg_wnd << *wnd_scale;
1930 match timer {
1931 Some(SendTimer::KeepAlive(_)) | None => {
1932 *timer = keep_alive
1933 .enabled
1934 .then(|| SendTimer::KeepAlive(KeepAliveTimer::idle(now, keep_alive)));
1935 }
1936 Some(SendTimer::Retrans(retrans_timer)) => {
1937 if seg_ack == *snd_max {
1945 *timer = None;
1946 } else if seg_ack.before(*snd_max) && seg_ack.after(*snd_una) {
1947 *retrans_timer = RetransTimer::new(
1948 now,
1949 rtt_estimator.rto(),
1950 *user_timeout,
1951 DEFAULT_MAX_RETRIES,
1952 );
1953 }
1954 }
1955 Some(SendTimer::ZeroWindowProbe(_)) | Some(SendTimer::SWSProbe { at: _ }) => {}
1956 }
1957 if seg_ack.after(*snd_max) {
1961 return (Some(rcv.make_ack(*snd_max, now)), DataAcked::No);
1966 }
1967
1968 let bytes_acked = match u32::try_from(seg_ack - *snd_una) {
1969 Ok(acked) => NonZeroU32::new(acked),
1970 Err(TryFromIntError { .. }) => {
1971 return (None, DataAcked::No);
1974 }
1975 };
1976
1977 let is_dup_ack_by_sack =
1978 congestion_control.preprocess_ack(seg_ack, *snd_nxt, seg_sack_blocks);
1979 let (is_dup_ack, data_acked) = if let Some(acked) = bytes_acked {
1980 let BufferLimits { len, capacity: _ } = buffer.limits();
1981 let fin_acked = FIN_QUEUED && seg_ack == *snd_una + len + 1;
1982 buffer.mark_read(
1987 NonZeroUsize::try_from(acked)
1988 .unwrap_or_else(|TryFromIntError { .. }| {
1989 panic!(
1993 "acked({:?}) must be smaller than isize::MAX({:?})",
1994 acked,
1995 isize::MAX
1996 )
1997 })
1998 .get()
1999 - usize::from(fin_acked),
2000 );
2001 *snd_una = seg_ack;
2002 if seg_ack.after(*snd_nxt) {
2006 *snd_nxt = seg_ack;
2007 }
2008 if let Some(rtt) = rtt_sampler.on_ack(now, seg_ack) {
2011 rtt_estimator.sample(rtt);
2012 }
2013
2014 let recovered = congestion_control.on_ack(seg_ack, acked, now, rtt_estimator.srtt());
2017 if recovered {
2018 counters.increment(|c| &c.loss_recovered);
2019 }
2020
2021 let is_dup_ack = is_dup_ack_by_sack.unwrap_or(false);
2025
2026 (is_dup_ack, DataAcked::Yes)
2028 } else {
2029 let is_dup_ack = is_dup_ack_by_sack.unwrap_or_else(|| {
2032 snd_nxt.after(*snd_una) && pure_ack && seg_ack == *snd_una && seg_wnd == *snd_wnd });
2048
2049 (is_dup_ack, DataAcked::No)
2053 };
2054
2055 if is_dup_ack {
2056 counters.increment(|c| &c.dup_acks);
2057 let new_loss_recovery = congestion_control.on_dup_ack(seg_ack, *snd_nxt);
2058 match new_loss_recovery {
2059 Some(LossRecoveryMode::FastRecovery) => counters.increment(|c| &c.fast_recovery),
2060 Some(LossRecoveryMode::SackRecovery) => counters.increment(|c| &c.sack_recovery),
2061 None => (),
2062 }
2063 }
2064
2065 if !snd_una.after(seg_ack)
2072 && (snd_wl1.before(seg_seq) || (seg_seq == *snd_wl1 && !snd_wl2.after(seg_ack)))
2073 {
2074 *snd_wnd = seg_wnd;
2075 *snd_wl1 = seg_seq;
2076 *snd_wl2 = seg_ack;
2077 *wnd_max = seg_wnd.max(*wnd_max);
2078 if seg_wnd != WindowSize::ZERO && matches!(timer, Some(SendTimer::ZeroWindowProbe(_))) {
2079 *timer = None;
2080 *snd_nxt = *snd_una;
2084 }
2085 }
2086
2087 if data_acked == DataAcked::Yes || is_dup_ack {
2089 trace_instant!("tcp::Send::process_ack",
2090 "id" => id.trace_id(),
2091 "seg_ack" => u32::from(seg_ack),
2092 "snd_nxt" => u32::from(*snd_nxt),
2093 "snd_wnd" => u32::from(*snd_wnd),
2094 "rtt_ms" => u32::try_from(
2095 rtt_estimator.srtt().unwrap_or(Duration::ZERO).as_millis()
2098 ).unwrap_or(u32::MAX),
2099 "cwnd" => congestion_control.inspect_cwnd().cwnd(),
2100 "ssthresh" => congestion_control.slow_start_threshold(),
2101 "loss_recovery" => congestion_control.inspect_loss_recovery_mode().is_some(),
2102 "acked" => data_acked == DataAcked::Yes,
2103 );
2104 }
2105
2106 (None, data_acked)
2107 }
2108
2109 fn update_mss(&mut self, mss: Mss, seq: SeqNum) -> ShouldRetransmit {
2110 if mss >= *self.congestion_control.mss().mss() {
2122 return ShouldRetransmit::No;
2123 }
2124
2125 self.nxt = seq;
2145
2146 self.congestion_control.update_mss(mss, self.una, self.nxt);
2149
2150 ShouldRetransmit::Yes
2159 }
2160
2161 #[cfg(test)]
2162 pub(crate) fn congestion_control(&self) -> &CongestionControl<I> {
2163 &self.congestion_control
2164 }
2165}
2166
2167impl<I: Instant, S: SendBuffer> Send<I, S, { FinQueued::NO }> {
2168 fn queue_fin(self) -> Send<I, S, { FinQueued::YES }> {
2169 let Self {
2170 nxt,
2171 max,
2172 una,
2173 wnd,
2174 wl1,
2175 wl2,
2176 last_push,
2177 buffer,
2178 rtt_sampler,
2179 rtt_estimator,
2180 timer,
2181 congestion_control,
2182 wnd_scale,
2183 wnd_max,
2184 last_data_sent,
2185 } = self;
2186 Send {
2187 nxt,
2188 max,
2189 una,
2190 wnd,
2191 wl1,
2192 wl2,
2193 last_push,
2194 buffer,
2195 rtt_sampler,
2196 rtt_estimator,
2197 timer,
2198 congestion_control,
2199 wnd_scale,
2200 wnd_max,
2201 last_data_sent,
2202 }
2203 }
2204}
2205
2206#[derive(Debug)]
2220#[cfg_attr(test, derive(PartialEq, Eq))]
2221pub struct CloseWait<I, S> {
2222 snd: Takeable<Send<I, S, { FinQueued::NO }>>,
2223 closed_rcv: RecvParams<I>,
2224}
2225
2226#[derive(Debug)]
2242#[cfg_attr(test, derive(PartialEq, Eq))]
2243pub struct LastAck<I, S> {
2244 snd: Send<I, S, { FinQueued::YES }>,
2245 closed_rcv: RecvParams<I>,
2246}
2247
2248#[derive(Debug)]
2263#[cfg_attr(test, derive(PartialEq, Eq))]
2264pub struct FinWait1<I, R, S> {
2265 snd: Takeable<Send<I, S, { FinQueued::YES }>>,
2266 rcv: Takeable<Recv<I, R>>,
2267}
2268
2269#[derive(Debug)]
2270#[cfg_attr(test, derive(PartialEq, Eq))]
2271pub struct FinWait2<I, R> {
2285 last_seq: SeqNum,
2286 rcv: Recv<I, R>,
2287 snd_info: info::SendInfo<I>,
2288 timeout_at: Option<I>,
2289}
2290
2291#[derive(Debug)]
2292#[cfg_attr(test, derive(PartialEq, Eq))]
2293pub struct Closing<I, S> {
2307 snd: Send<I, S, { FinQueued::YES }>,
2308 closed_rcv: RecvParams<I>,
2309}
2310
2311#[derive(Debug)]
2326#[cfg_attr(test, derive(PartialEq, Eq))]
2327pub struct TimeWait<I> {
2328 pub(super) last_seq: SeqNum,
2329 pub(super) expiry: I,
2330 pub(super) closed_rcv: RecvParams<I>,
2331 pub(super) snd_info: info::SendInfo<I>,
2332}
2333
2334fn new_time_wait_expiry<I: Instant>(now: I) -> I {
2335 now.panicking_add(MSL * 2)
2336}
2337
2338#[derive(Debug)]
2339#[cfg_attr(test, derive(PartialEq, Eq))]
2340pub enum State<I, R, S, ActiveOpen> {
2341 Closed(Closed<Option<ConnectionError>>),
2342 Listen(Listen),
2343 SynRcvd(SynRcvd<I, ActiveOpen>),
2344 SynSent(SynSent<I, ActiveOpen>),
2345 Established(Established<I, R, S>),
2346 CloseWait(CloseWait<I, S>),
2347 LastAck(LastAck<I, S>),
2348 FinWait1(FinWait1<I, R, S>),
2349 FinWait2(FinWait2<I, R>),
2350 Closing(Closing<I, S>),
2351 TimeWait(TimeWait<I>),
2352}
2353
2354impl<I, R, S, ActiveOpen> core::fmt::Display for State<I, R, S, ActiveOpen> {
2355 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
2356 let name = match self {
2357 State::Closed(_) => "Closed",
2358 State::Listen(_) => "Listen",
2359 State::SynRcvd(_) => "SynRcvd",
2360 State::SynSent(_) => "SynSent",
2361 State::Established(_) => "Established",
2362 State::CloseWait(_) => "CloseWait",
2363 State::LastAck(_) => "LastAck",
2364 State::FinWait1(_) => "FinWait1",
2365 State::FinWait2(_) => "FinWait2",
2366 State::Closing(_) => "Closing",
2367 State::TimeWait(_) => "TimeWait",
2368 };
2369 write!(f, "{name}")
2370 }
2371}
2372
2373#[derive(Debug, PartialEq, Eq)]
2374pub(super) enum CloseError {
2376 Closing,
2378 NoConnection,
2380}
2381
2382pub(crate) trait BufferProvider<R: ReceiveBuffer, S: SendBuffer> {
2385 type PassiveOpen;
2388
2389 type ActiveOpen: IntoBuffers<R, S>;
2392
2393 fn new_passive_open_buffers(buffer_sizes: BufferSizes) -> (R, S, Self::PassiveOpen);
2396}
2397
2398#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2410pub(crate) struct Takeable<T>(Option<T>);
2411
2412impl<T> From<T> for Takeable<T> {
2413 fn from(value: T) -> Self {
2414 Self(Some(value))
2415 }
2416}
2417
2418impl<T> Takeable<T> {
2419 pub(crate) fn get(&self) -> &T {
2420 let Self(i) = self;
2421 i.as_ref().expect("accessed taken takeable")
2422 }
2423
2424 pub(crate) fn get_mut(&mut self) -> &mut T {
2425 let Self(i) = self;
2426 i.as_mut().expect("accessed taken takeable")
2427 }
2428
2429 pub(crate) fn new(v: T) -> Self {
2430 Self(Some(v))
2431 }
2432
2433 pub(crate) fn to_ref(&mut self) -> TakeableRef<'_, T> {
2434 TakeableRef(self)
2435 }
2436
2437 pub(crate) fn from_ref(t: TakeableRef<'_, T>) -> Self {
2438 let TakeableRef(Self(t)) = t;
2439 Self(Some(t.take().expect("accessed taken takeable")))
2440 }
2441
2442 pub(crate) fn into_inner(self) -> T {
2443 let Self(i) = self;
2444 i.expect("accessed taken takeable")
2445 }
2446
2447 pub(crate) fn map<R, F: FnOnce(T) -> R>(self, f: F) -> Takeable<R> {
2448 Takeable(Some(f(self.into_inner())))
2449 }
2450}
2451
2452impl<T> Deref for Takeable<T> {
2453 type Target = T;
2454
2455 fn deref(&self) -> &Self::Target {
2456 self.get()
2457 }
2458}
2459
2460impl<T> DerefMut for Takeable<T> {
2461 fn deref_mut(&mut self) -> &mut Self::Target {
2462 self.get_mut()
2463 }
2464}
2465
2466pub(crate) struct TakeableRef<'a, T>(&'a mut Takeable<T>);
2468
2469impl<'a, T> TakeableRef<'a, T> {
2470 pub(crate) fn take(self) -> T {
2471 let Self(Takeable(t)) = self;
2472 t.take().expect("accessed taken takeable")
2473 }
2474
2475 pub(crate) fn to_takeable(self) -> Takeable<T> {
2476 Takeable::new(self.take())
2477 }
2478}
2479
2480#[must_use = "must check to determine if the socket needs to be removed from the demux state"]
2481#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2482pub(crate) enum NewlyClosed {
2483 No,
2484 Yes,
2485}
2486
2487#[derive(Debug)]
2488pub(crate) enum ShouldRetransmit {
2489 No,
2490 Yes,
2491}
2492
2493impl<I: Instant + 'static, R: ReceiveBuffer, S: SendBuffer, ActiveOpen: Debug>
2494 State<I, R, S, ActiveOpen>
2495{
2496 fn transition_to_state(
2498 &mut self,
2499 counters: &TcpCountersRefs<'_>,
2500 new_state: State<I, R, S, ActiveOpen>,
2501 ) -> NewlyClosed {
2502 log::debug!("transition to state {} => {}", self, new_state);
2503 let newly_closed = if let State::Closed(Closed { reason }) = &new_state {
2504 let (was_established, was_closed) = match self {
2505 State::Closed(_) => (false, true),
2506 State::Listen(_) | State::SynRcvd(_) | State::SynSent(_) => (false, false),
2507 State::Established(_)
2508 | State::CloseWait(_)
2509 | State::LastAck(_)
2510 | State::FinWait1(_)
2511 | State::FinWait2(_)
2512 | State::Closing(_)
2513 | State::TimeWait(_) => (true, false),
2514 };
2515 if was_established {
2516 counters.increment(|c| &c.established_closed);
2517 match reason {
2518 Some(ConnectionError::ConnectionRefused)
2519 | Some(ConnectionError::ConnectionReset) => {
2520 counters.increment(|c| &c.established_resets);
2521 }
2522 Some(ConnectionError::TimedOut) => {
2523 counters.increment(|c| &c.established_timedout);
2524 }
2525 _ => {}
2526 }
2527 }
2528 (!was_closed).then_some(NewlyClosed::Yes).unwrap_or(NewlyClosed::No)
2529 } else {
2530 NewlyClosed::No
2531 };
2532 *self = new_state;
2533 newly_closed
2534 }
2535 pub(crate) fn on_segment<P: Payload, BP: BufferProvider<R, S, ActiveOpen = ActiveOpen>>(
2542 &mut self,
2543 id: &impl StateMachineDebugId,
2544 counters: &TcpCountersRefs<'_>,
2545 incoming: Segment<P>,
2546 now: I,
2547 options @ SocketOptions {
2548 keep_alive: _,
2549 nagle_enabled: _,
2550 user_timeout: _,
2551 delayed_ack,
2552 fin_wait2_timeout,
2553 max_syn_retries: _,
2554 ip_options: _,
2555 }: &SocketOptions,
2556 defunct: bool,
2557 ) -> (Option<Segment<()>>, Option<BP::PassiveOpen>, DataAcked, NewlyClosed)
2558 where
2559 BP::PassiveOpen: Debug,
2560 ActiveOpen: IntoBuffers<R, S>,
2561 {
2562 let mut passive_open = None;
2563 let mut data_acked = DataAcked::No;
2564 let (seg, newly_closed) = (|| {
2565 let (mut rcv, snd_max, rst_on_new_data) = match self {
2566 State::Closed(closed) => return (closed.on_segment(&incoming), NewlyClosed::No),
2567 State::Listen(listen) => {
2568 return (
2569 match listen.on_segment(incoming, now) {
2570 ListenOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
2571 syn_ack,
2572 SynRcvd {
2573 iss,
2574 irs,
2575 timestamp,
2576 retrans_timer,
2577 simultaneous_open,
2578 buffer_sizes,
2579 smss,
2580 rcv_wnd_scale,
2581 snd_wnd_scale,
2582 sack_permitted,
2583 rcv,
2584 },
2585 ) => {
2586 match simultaneous_open {
2587 None => {
2588 assert_eq!(
2589 self.transition_to_state(
2590 counters,
2591 State::SynRcvd(SynRcvd {
2592 iss,
2593 irs,
2594 timestamp,
2595 retrans_timer,
2596 simultaneous_open: None,
2597 buffer_sizes,
2598 smss,
2599 rcv_wnd_scale,
2600 snd_wnd_scale,
2601 sack_permitted,
2602 rcv,
2603 }),
2604 ),
2605 NewlyClosed::No
2606 )
2607 }
2608 }
2609 Some(syn_ack)
2610 }
2611 ListenOnSegmentDisposition::SendRst(rst) => Some(rst),
2612 ListenOnSegmentDisposition::Ignore => None,
2613 },
2614 NewlyClosed::No,
2615 );
2616 }
2617 State::SynSent(synsent) => {
2618 return match synsent.on_segment(incoming, now) {
2619 SynSentOnSegmentDisposition::SendAckAndEnterEstablished(established) => (
2620 replace_with_and(self, |this| {
2621 assert_matches!(this, State::SynSent(SynSent {
2622 active_open,
2623 buffer_sizes,
2624 ..
2625 }) => {
2626 log::debug!("transition to state SynSent => Established");
2627 let Established {snd, rcv} = established;
2628 let (rcv_buffer, snd_buffer) =
2629 active_open.into_buffers(buffer_sizes);
2630 let mut established = Established {
2631 snd: snd.map(|s| s.with_buffer(snd_buffer)),
2632 rcv: rcv.map(|s| s.with_buffer(rcv_buffer)),
2633 };
2634 let ack = Some(
2635 established.rcv.make_ack(established.snd.max, now)
2636 );
2637 (State::Established(established), ack)
2638 })
2639 }),
2640 NewlyClosed::No,
2641 ),
2642 SynSentOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
2643 syn_ack,
2644 mut syn_rcvd,
2645 ) => {
2646 log::debug!("transition to state SynSent => SynRcvd");
2647 replace_with(self, |this| {
2648 assert_matches!(this, State::SynSent(SynSent {
2649 active_open,
2650 ..
2651 }) => {
2652 assert_matches!(syn_rcvd.simultaneous_open.replace(active_open), None);
2653 State::SynRcvd(syn_rcvd)
2654 })
2655 });
2656 (Some(syn_ack), NewlyClosed::No)
2657 }
2658 SynSentOnSegmentDisposition::SendRst(rst) => (Some(rst), NewlyClosed::No),
2659 SynSentOnSegmentDisposition::EnterClosed(closed) => {
2660 assert_eq!(
2661 self.transition_to_state(counters, State::Closed(closed)),
2662 NewlyClosed::Yes,
2663 );
2664 (None, NewlyClosed::Yes)
2665 }
2666 SynSentOnSegmentDisposition::Ignore => (None, NewlyClosed::No),
2667 };
2668 }
2669 State::SynRcvd(SynRcvd {
2670 iss,
2671 irs: _,
2672 timestamp: _,
2673 retrans_timer: _,
2674 simultaneous_open: _,
2675 buffer_sizes: _,
2676 smss: _,
2677 rcv_wnd_scale: _,
2678 snd_wnd_scale: _,
2679 sack_permitted: _,
2680 rcv,
2681 }) => (CalculatedRecvParams::from_params(rcv), *iss + 1, false),
2682 State::Established(Established { rcv, snd }) => {
2683 (CalculatedRecvParams::from_recv(rcv.get_mut()), snd.max, false)
2684 }
2685 State::CloseWait(CloseWait { snd, closed_rcv }) => {
2686 (CalculatedRecvParams::from_params(closed_rcv), snd.max, true)
2687 }
2688 State::LastAck(LastAck { snd, closed_rcv })
2689 | State::Closing(Closing { snd, closed_rcv }) => {
2690 (CalculatedRecvParams::from_params(closed_rcv), snd.max, true)
2691 }
2692 State::FinWait1(FinWait1 { rcv, snd }) => {
2693 let closed = rcv.buffer.is_closed();
2694 (CalculatedRecvParams::from_recv(rcv.get_mut()), snd.max, closed)
2695 }
2696 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _, snd_info: _ }) => {
2697 let closed = rcv.buffer.is_closed();
2698 (CalculatedRecvParams::from_recv(rcv), *last_seq, closed)
2699 }
2700 State::TimeWait(TimeWait { last_seq, expiry: _, closed_rcv, snd_info: _ }) => {
2701 (CalculatedRecvParams::from_params(closed_rcv), *last_seq, true)
2702 }
2703 };
2704
2705 if rst_on_new_data && (incoming.header().seq + incoming.data().len()).after(rcv.nxt()) {
2712 return (
2713 Some(Segment::rst(
2714 snd_max,
2715 ResetOptions {
2716 timestamp: rcv
2717 .ts_opt()
2718 .make_option_for_non_ack(now)
2719 .map(TxTimestampOption::into),
2720 },
2721 )),
2722 self.transition_to_state(
2723 counters,
2724 State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }),
2725 ),
2726 );
2727 }
2728
2729 let is_rst = incoming.header().control == Some(Control::RST);
2752 let pure_ack = incoming.len() == 0;
2754 let needs_ack = !pure_ack;
2755 let segment = match incoming.overlap(rcv.nxt(), rcv.wnd()) {
2756 Some(incoming) => incoming,
2757 None => {
2758 let segment = if is_rst {
2766 None
2767 } else {
2768 rcv.reset_quickacks();
2771 Some(rcv.make_ack(snd_max, now))
2772 };
2773
2774 return (segment, NewlyClosed::No);
2775 }
2776 };
2777 let (
2778 SegmentHeader {
2779 seq: seg_seq,
2780 ack: seg_ack,
2781 wnd: seg_wnd,
2782 control,
2783 options: seg_options,
2784 push: _,
2785 },
2786 data,
2787 ) = segment.into_parts();
2788
2789 rcv.ts_opt_mut().update_recent_timestamp(
2793 seg_seq,
2794 seg_options.timestamp().map(RxTimestampOption::from),
2795 );
2796
2797 if control == Some(Control::RST) {
2805 return (
2806 None,
2807 self.transition_to_state(
2808 counters,
2809 State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }),
2810 ),
2811 );
2812 }
2813 if control == Some(Control::SYN) {
2824 return (
2825 Some(Segment::rst(
2826 snd_max,
2827 ResetOptions {
2828 timestamp: rcv
2829 .ts_opt()
2830 .make_option_for_non_ack(now)
2831 .map(TxTimestampOption::into),
2832 },
2833 )),
2834 self.transition_to_state(
2835 counters,
2836 State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }),
2837 ),
2838 );
2839 }
2840 match seg_ack {
2843 Some(seg_ack) => match self {
2844 State::Closed(_) | State::Listen(_) | State::SynSent(_) => {
2845 unreachable!("encountered an already-handled state: {:?}", self)
2847 }
2848 State::SynRcvd(SynRcvd {
2849 iss,
2850 irs,
2851 timestamp: syn_rcvd_ts,
2852 retrans_timer: _,
2853 simultaneous_open,
2854 buffer_sizes,
2855 smss,
2856 rcv_wnd_scale,
2857 snd_wnd_scale,
2858 sack_permitted,
2859 rcv,
2860 }) => {
2861 let snd_next = *iss + 1;
2874 let rcv_next = *irs + 1;
2875 if seg_ack != snd_next {
2876 return (
2877 Some(Segment::rst(
2878 seg_ack,
2879 ResetOptions {
2880 timestamp: rcv.timestamp_option_for_non_ack(now),
2881 },
2882 )),
2883 NewlyClosed::No,
2884 );
2885 } else {
2886 let mut rtt_estimator = Estimator::default();
2887 if let Some(syn_rcvd_ts) = syn_rcvd_ts {
2888 rtt_estimator.sample(now.saturating_duration_since(*syn_rcvd_ts));
2889 }
2890 let (rcv_buffer, snd_buffer) = match simultaneous_open.take() {
2891 None => {
2892 let (rcv_buffer, snd_buffer, client) =
2893 BP::new_passive_open_buffers(*buffer_sizes);
2894 assert_matches!(passive_open.replace(client), None);
2895 (rcv_buffer, snd_buffer)
2896 }
2897 Some(active_open) => active_open.into_buffers(*buffer_sizes),
2898 };
2899 let (snd_wnd_scale, rcv_wnd_scale) = snd_wnd_scale
2900 .map(|snd_wnd_scale| (snd_wnd_scale, *rcv_wnd_scale))
2901 .unwrap_or_default();
2902 let established = Established {
2903 snd: Send {
2904 nxt: snd_next,
2905 max: snd_next,
2906 una: seg_ack,
2907 wnd: seg_wnd << snd_wnd_scale,
2908 wl1: seg_seq,
2909 wl2: seg_ack,
2910 last_push: snd_next,
2911 buffer: snd_buffer,
2912 rtt_sampler: RttSampler::default(),
2913 rtt_estimator,
2914 timer: None,
2915 congestion_control: CongestionControl::cubic_with_mss(*smss),
2916 wnd_scale: snd_wnd_scale,
2917 wnd_max: seg_wnd << snd_wnd_scale,
2918 last_data_sent: None,
2919 }
2920 .into(),
2921 rcv: Recv {
2922 buffer: RecvBufferState::Open {
2923 buffer: rcv_buffer,
2924 assembler: Assembler::new(rcv_next),
2925 },
2926 timer: None,
2927 mss: *smss,
2928 wnd_scale: rcv_wnd_scale,
2929 last_segment_at: None,
2930 remaining_quickacks: quickack_counter(
2931 buffer_sizes.rcv_limits(),
2932 *smss,
2933 ),
2934 last_window_update: (rcv_next, buffer_sizes.rwnd()),
2935 sack_permitted: *sack_permitted,
2936 ts_opt: rcv.ts_opt.clone(),
2937 }
2938 .into(),
2939 };
2940 assert_eq!(
2941 self.transition_to_state(counters, State::Established(established)),
2942 NewlyClosed::No
2943 );
2944 }
2945 }
2949 State::Established(Established { snd, rcv }) => {
2950 let (ack, segment_acked_data) = snd.process_ack(
2951 id,
2952 counters,
2953 seg_seq,
2954 seg_ack,
2955 seg_wnd,
2956 seg_options.sack_blocks(),
2957 pure_ack,
2958 rcv.get_mut(),
2959 now,
2960 options,
2961 );
2962 data_acked = segment_acked_data;
2963 if let Some(ack) = ack {
2964 return (Some(ack), NewlyClosed::No);
2965 }
2966 }
2967 State::CloseWait(CloseWait { snd, closed_rcv }) => {
2968 let (ack, segment_acked_data) = snd.process_ack(
2969 id,
2970 counters,
2971 seg_seq,
2972 seg_ack,
2973 seg_wnd,
2974 seg_options.sack_blocks(),
2975 pure_ack,
2976 closed_rcv,
2977 now,
2978 options,
2979 );
2980 data_acked = segment_acked_data;
2981 if let Some(ack) = ack {
2982 return (Some(ack), NewlyClosed::No);
2983 }
2984 }
2985 State::LastAck(LastAck { snd, closed_rcv }) => {
2986 let BufferLimits { len, capacity: _ } = snd.buffer.limits();
2987 let fin_seq = snd.una + len + 1;
2988 let (ack, segment_acked_data) = snd.process_ack(
2989 id,
2990 counters,
2991 seg_seq,
2992 seg_ack,
2993 seg_wnd,
2994 seg_options.sack_blocks(),
2995 pure_ack,
2996 closed_rcv,
2997 now,
2998 options,
2999 );
3000 data_acked = segment_acked_data;
3001 if let Some(ack) = ack {
3002 return (Some(ack), NewlyClosed::No);
3003 } else if seg_ack == fin_seq {
3004 return (
3005 None,
3006 self.transition_to_state(
3007 counters,
3008 State::Closed(Closed { reason: None }),
3009 ),
3010 );
3011 }
3012 }
3013 State::FinWait1(FinWait1 { snd, rcv }) => {
3014 let BufferLimits { len, capacity: _ } = snd.buffer.limits();
3015 let fin_seq = snd.una + len + 1;
3016 let (ack, segment_acked_data) = snd.process_ack(
3017 id,
3018 counters,
3019 seg_seq,
3020 seg_ack,
3021 seg_wnd,
3022 seg_options.sack_blocks(),
3023 pure_ack,
3024 rcv.get_mut(),
3025 now,
3026 options,
3027 );
3028 data_acked = segment_acked_data;
3029 if let Some(ack) = ack {
3030 return (Some(ack), NewlyClosed::No);
3031 } else if seg_ack == fin_seq {
3032 let last_seq = snd.nxt;
3038 let finwait2 = FinWait2 {
3039 last_seq,
3040 rcv: rcv.to_ref().take(),
3041 timeout_at: fin_wait2_timeout.and_then(|timeout| {
3045 defunct.then_some(now.saturating_add(timeout))
3046 }),
3047 snd_info: info::SendInfo::from_send(&snd),
3048 };
3049 assert_eq!(
3050 self.transition_to_state(counters, State::FinWait2(finwait2)),
3051 NewlyClosed::No
3052 );
3053 }
3054 }
3055 State::Closing(Closing { snd, closed_rcv }) => {
3056 let BufferLimits { len, capacity: _ } = snd.buffer.limits();
3057 let fin_seq = snd.una + len + 1;
3058 let (ack, segment_acked_data) = {
3059 let closed_rcv: &mut RecvParams<I> = closed_rcv;
3063 snd.process_ack(
3064 id,
3065 counters,
3066 seg_seq,
3067 seg_ack,
3068 seg_wnd,
3069 seg_options.sack_blocks(),
3070 pure_ack,
3071 closed_rcv,
3072 now,
3073 options,
3074 )
3075 };
3076 data_acked = segment_acked_data;
3077 if let Some(ack) = ack {
3078 data_acked = segment_acked_data;
3079 return (Some(ack), NewlyClosed::No);
3080 } else if seg_ack == fin_seq {
3081 let timewait = TimeWait {
3086 last_seq: snd.nxt,
3087 expiry: new_time_wait_expiry(now),
3088 closed_rcv: closed_rcv.clone(),
3089 snd_info: info::SendInfo::from_send(&snd),
3090 };
3091 assert_eq!(
3092 self.transition_to_state(counters, State::TimeWait(timewait)),
3093 NewlyClosed::No
3094 );
3095 }
3096 }
3097 State::FinWait2(_) | State::TimeWait(_) => {}
3098 },
3099 None => return (None, NewlyClosed::No),
3102 }
3103 let maybe_ack_to_text = |rcv: &mut Recv<I, R>, rto: Rto| {
3125 if !needs_ack {
3126 return (None, rcv.nxt());
3127 }
3128
3129 if let Some(last) = rcv.last_segment_at.replace(now) {
3133 if now.saturating_duration_since(last) >= rto.get() {
3134 rcv.reset_quickacks();
3135 }
3136 }
3137
3138 let had_out_of_order = rcv.buffer.has_out_of_order();
3141 if data.len() > 0 {
3142 let offset = usize::try_from(seg_seq - rcv.nxt()).unwrap_or_else(|TryFromIntError {..}| {
3143 panic!("The segment was trimmed to fit the window, thus seg.seq({:?}) must not come before rcv.nxt({:?})", seg_seq, rcv.nxt());
3144 });
3145 match &mut rcv.buffer {
3146 RecvBufferState::Open { buffer, assembler } => {
3147 let nwritten = buffer.write_at(offset, &data);
3148 let readable = assembler.insert(seg_seq..seg_seq + nwritten);
3149 buffer.make_readable(readable, assembler.has_outstanding());
3150 }
3151 RecvBufferState::Closed { nxt, .. } => *nxt = seg_seq + data.len(),
3152 }
3153 }
3154 let immediate_ack = !*delayed_ack
3160 || had_out_of_order
3161 || rcv.buffer.has_out_of_order()
3162 || rcv.remaining_quickacks != 0
3164 || rcv.timer.is_some();
3189
3190 if immediate_ack {
3191 rcv.timer = None;
3192 } else {
3193 rcv.timer = Some(ReceiveTimer::DelayedAck {
3194 at: now.panicking_add(ACK_DELAY_THRESHOLD),
3195 });
3196 }
3197 let segment =
3198 (!matches!(rcv.timer, Some(ReceiveTimer::DelayedAck { .. }))).then(|| {
3199 rcv.remaining_quickacks = rcv.remaining_quickacks.saturating_sub(1);
3200 rcv.make_ack(snd_max, now)
3201 });
3202 (segment, rcv.nxt())
3203 };
3204
3205 let (ack_to_text, rcv_nxt) = match self {
3206 State::Closed(_) | State::Listen(_) | State::SynRcvd(_) | State::SynSent(_) => {
3207 unreachable!("encountered an already-handled state: {:?}", self)
3209 }
3210 State::Established(Established { snd, rcv }) => {
3211 maybe_ack_to_text(rcv.get_mut(), snd.rtt_estimator.rto())
3212 }
3213 State::FinWait1(FinWait1 { snd, rcv }) => {
3214 maybe_ack_to_text(rcv.get_mut(), snd.rtt_estimator.rto())
3215 }
3216 State::FinWait2(FinWait2 { last_seq: _, rcv, timeout_at: _, snd_info: _ }) => {
3217 maybe_ack_to_text(rcv, Rto::DEFAULT)
3218 }
3219 State::CloseWait(CloseWait { closed_rcv, .. })
3220 | State::LastAck(LastAck { closed_rcv, .. })
3221 | State::Closing(Closing { closed_rcv, .. })
3222 | State::TimeWait(TimeWait { closed_rcv, .. }) => {
3223 (None, closed_rcv.ack)
3227 }
3228 };
3229 let ack_to_fin = if control == Some(Control::FIN) && rcv_nxt == seg_seq + data.len() {
3232 match self {
3237 State::Closed(_) | State::Listen(_) | State::SynRcvd(_) | State::SynSent(_) => {
3238 unreachable!("encountered an already-handled state: {:?}", self)
3240 }
3241 State::Established(Established { snd, rcv }) => {
3242 let mut params = rcv.handle_fin();
3245 let segment = params.make_ack(snd_max, now);
3246 let closewait =
3247 CloseWait { snd: snd.to_ref().to_takeable(), closed_rcv: params };
3248 assert_eq!(
3249 self.transition_to_state(counters, State::CloseWait(closewait)),
3250 NewlyClosed::No
3251 );
3252 Some(segment)
3253 }
3254 State::CloseWait(_) | State::LastAck(_) | State::Closing(_) => {
3255 None
3263 }
3264 State::FinWait1(FinWait1 { snd, rcv }) => {
3265 let mut params = rcv.handle_fin();
3266 let segment = params.make_ack(snd_max, now);
3267 let closing = Closing { snd: snd.to_ref().take(), closed_rcv: params };
3268 assert_eq!(
3269 self.transition_to_state(counters, State::Closing(closing)),
3270 NewlyClosed::No
3271 );
3272 Some(segment)
3273 }
3274 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _, snd_info }) => {
3275 let mut params = rcv.handle_fin();
3276 let segment = params.make_ack(snd_max, now);
3277 let timewait = TimeWait {
3278 last_seq: *last_seq,
3279 expiry: new_time_wait_expiry(now),
3280 closed_rcv: params,
3281 snd_info: snd_info.clone(),
3282 };
3283 assert_eq!(
3284 self.transition_to_state(counters, State::TimeWait(timewait)),
3285 NewlyClosed::No,
3286 );
3287 Some(segment)
3288 }
3289 State::TimeWait(TimeWait { last_seq, expiry, closed_rcv, snd_info: _ }) => {
3290 *expiry = new_time_wait_expiry(now);
3295 Some(closed_rcv.make_ack(*last_seq, now))
3296 }
3297 }
3298 } else {
3299 None
3300 };
3301 (ack_to_fin.or(ack_to_text), NewlyClosed::No)
3304 })();
3305 (seg, passive_open, data_acked, newly_closed)
3306 }
3307
3308 pub(crate) fn poll_receive_data_dequeued(&mut self, now: I) -> Option<Segment<()>> {
3312 let (rcv, snd_max) = match self {
3313 State::Closed(_)
3314 | State::Listen(_)
3315 | State::SynRcvd(_)
3316 | State::SynSent(_)
3317 | State::CloseWait(_)
3318 | State::LastAck(_)
3319 | State::Closing(_)
3320 | State::TimeWait(_) => return None,
3321 State::Established(Established { snd, rcv }) => (rcv.get_mut(), snd.max),
3322 State::FinWait1(FinWait1 { snd, rcv }) => (rcv.get_mut(), snd.max),
3323 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _, snd_info: _ }) => {
3324 (rcv, *last_seq)
3325 }
3326 };
3327
3328 rcv.poll_receive_data_dequeued(snd_max, now)
3329 }
3330
3331 pub(crate) fn poll_send(
3339 &mut self,
3340 id: &impl StateMachineDebugId,
3341 counters: &TcpCountersRefs<'_>,
3342 now: I,
3343 socket_options: &SocketOptions,
3344 ) -> Result<Segment<S::Payload<'_>>, NewlyClosed> {
3345 let newly_closed = self.poll_close(counters, now, socket_options);
3346 if matches!(self, State::Closed(_)) {
3347 return Err(newly_closed);
3348 }
3349 fn poll_rcv_then_snd<
3350 'a,
3351 I: Instant,
3352 R: ReceiveBuffer,
3353 S: SendBuffer,
3354 M: StateMachineDebugId,
3355 const FIN_QUEUED: bool,
3356 >(
3357 id: &M,
3358 counters: &TcpCountersRefs<'_>,
3359 snd: &'a mut Send<I, S, FIN_QUEUED>,
3360 rcv: &'a mut Recv<I, R>,
3361 now: I,
3362 socket_options: &SocketOptions,
3363 ) -> Option<Segment<S::Payload<'a>>> {
3364 let seg = rcv
3370 .poll_send(snd.max, now)
3371 .map(|seg| seg.into_empty())
3372 .or_else(|| snd.poll_send(id, counters, &mut *rcv, now, socket_options));
3373 if seg.is_some() && matches!(rcv.timer, Some(ReceiveTimer::DelayedAck { .. })) {
3375 rcv.timer = None;
3376 }
3377 seg
3378 }
3379 let seg = match self {
3380 State::SynSent(SynSent {
3381 iss,
3382 timestamp,
3383 retrans_timer,
3384 active_open: _,
3385 buffer_sizes: _,
3386 device_mss,
3387 default_mss: _,
3388 rcv_wnd_scale,
3389 ts_opt,
3390 }) => (retrans_timer.at <= now).then(|| {
3391 *timestamp = None;
3392 retrans_timer.backoff(now);
3393 Segment::syn(
3394 *iss,
3395 UnscaledWindowSize::from(u16::MAX),
3396 HandshakeOptions {
3397 mss: Some(*device_mss),
3398 window_scale: Some(*rcv_wnd_scale),
3399 sack_permitted: SACK_PERMITTED,
3400 timestamp: ts_opt.make_option_for_syn(now).map(TxTimestampOption::into),
3401 },
3402 )
3403 }),
3404 State::SynRcvd(SynRcvd {
3405 iss,
3406 irs,
3407 timestamp,
3408 retrans_timer,
3409 simultaneous_open: _,
3410 buffer_sizes: _,
3411 smss,
3412 rcv_wnd_scale,
3413 snd_wnd_scale,
3414 sack_permitted: _,
3415 rcv,
3416 }) => (retrans_timer.at <= now).then(|| {
3417 *timestamp = None;
3418 retrans_timer.backoff(now);
3419 Segment::syn_ack(
3420 *iss,
3421 *irs + 1,
3422 UnscaledWindowSize::from(u16::MAX),
3423 HandshakeOptions {
3424 mss: Some(*smss.mss()),
3425 window_scale: snd_wnd_scale.map(|_| *rcv_wnd_scale),
3426 sack_permitted: SACK_PERMITTED,
3427 timestamp: rcv.timestamp_option_for_ack(now),
3432 },
3433 )
3434 }),
3435 State::Established(Established { snd, rcv }) => {
3436 poll_rcv_then_snd(id, counters, snd, rcv, now, socket_options)
3437 }
3438 State::CloseWait(CloseWait { snd, closed_rcv }) => {
3439 snd.poll_send(id, counters, closed_rcv, now, socket_options)
3440 }
3441 State::LastAck(LastAck { snd, closed_rcv })
3442 | State::Closing(Closing { snd, closed_rcv }) => {
3443 snd.poll_send(id, counters, closed_rcv, now, socket_options)
3444 }
3445 State::FinWait1(FinWait1 { snd, rcv }) => {
3446 poll_rcv_then_snd(id, counters, snd, rcv, now, socket_options)
3447 }
3448 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _, snd_info: _ }) => {
3449 rcv.poll_send(*last_seq, now).map(|seg| seg.into_empty())
3450 }
3451 State::Closed(_) | State::Listen(_) | State::TimeWait(_) => None,
3452 };
3453 seg.ok_or(NewlyClosed::No)
3454 }
3455
3456 fn poll_close(
3460 &mut self,
3461 counters: &TcpCountersRefs<'_>,
3462 now: I,
3463 SocketOptions {
3464 keep_alive,
3465 nagle_enabled: _,
3466 user_timeout: _,
3467 delayed_ack: _,
3468 fin_wait2_timeout: _,
3469 max_syn_retries: _,
3470 ip_options: _,
3471 }: &SocketOptions,
3472 ) -> NewlyClosed {
3473 let timed_out = match self {
3474 State::Established(Established { snd, rcv: _ }) => snd.timed_out(now, keep_alive),
3475 State::CloseWait(CloseWait { snd, closed_rcv: _ }) => snd.timed_out(now, keep_alive),
3476 State::LastAck(LastAck { snd, closed_rcv: _ })
3477 | State::Closing(Closing { snd, closed_rcv: _ }) => snd.timed_out(now, keep_alive),
3478 State::FinWait1(FinWait1 { snd, rcv: _ }) => snd.timed_out(now, keep_alive),
3479 State::SynSent(SynSent { retrans_timer, .. })
3480 | State::SynRcvd(SynRcvd { retrans_timer, .. }) => retrans_timer.timed_out(now),
3481
3482 State::Closed(_) | State::Listen(_) | State::TimeWait(_) => false,
3483 State::FinWait2(FinWait2 { last_seq: _, rcv: _, timeout_at, snd_info: _ }) => {
3484 timeout_at.map(|at| now >= at).unwrap_or(false)
3485 }
3486 };
3487 if timed_out {
3488 return self.transition_to_state(
3489 counters,
3490 State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }),
3491 );
3492 } else if let State::TimeWait(tw) = self {
3493 if tw.expiry <= now {
3494 return self.transition_to_state(counters, State::Closed(Closed { reason: None }));
3495 }
3496 }
3497 NewlyClosed::No
3498 }
3499
3500 pub(crate) fn poll_send_at(&self) -> Option<I> {
3519 let combine_expiry = |e1: Option<I>, e2: Option<I>| match (e1, e2) {
3520 (None, None) => None,
3521 (None, Some(e2)) => Some(e2),
3522 (Some(e1), None) => Some(e1),
3523 (Some(e1), Some(e2)) => Some(e1.min(e2)),
3524 };
3525 match self {
3526 State::Established(Established { snd, rcv }) => combine_expiry(
3527 snd.timer.as_ref().map(SendTimer::expiry),
3528 rcv.timer.as_ref().map(ReceiveTimer::expiry),
3529 ),
3530 State::CloseWait(CloseWait { snd, closed_rcv: _ }) => Some(snd.timer?.expiry()),
3531 State::LastAck(LastAck { snd, closed_rcv: _ })
3532 | State::Closing(Closing { snd, closed_rcv: _ }) => Some(snd.timer?.expiry()),
3533 State::FinWait1(FinWait1 { snd, rcv }) => combine_expiry(
3534 snd.timer.as_ref().map(SendTimer::expiry),
3535 rcv.timer.as_ref().map(ReceiveTimer::expiry),
3536 ),
3537 State::FinWait2(FinWait2 { last_seq: _, rcv, timeout_at, snd_info: _ }) => {
3538 combine_expiry(*timeout_at, rcv.timer.as_ref().map(ReceiveTimer::expiry))
3539 }
3540 State::SynRcvd(syn_rcvd) => Some(syn_rcvd.retrans_timer.at),
3541 State::SynSent(syn_sent) => Some(syn_sent.retrans_timer.at),
3542 State::Closed(_) | State::Listen(_) => None,
3543 State::TimeWait(TimeWait { last_seq: _, expiry, closed_rcv: _, snd_info: _ }) => {
3544 Some(*expiry)
3545 }
3546 }
3547 }
3548
3549 pub(super) fn close(
3556 &mut self,
3557 counters: &TcpCountersRefs<'_>,
3558 close_reason: CloseReason<I>,
3559 socket_options: &SocketOptions,
3560 ) -> Result<NewlyClosed, CloseError>
3561 where
3562 ActiveOpen: IntoBuffers<R, S>,
3563 {
3564 match self {
3565 State::Closed(_) => Err(CloseError::NoConnection),
3566 State::Listen(_) | State::SynSent(_) => {
3567 Ok(self.transition_to_state(counters, State::Closed(Closed { reason: None })))
3568 }
3569 State::SynRcvd(SynRcvd {
3570 iss,
3571 irs,
3572 timestamp: _,
3573 retrans_timer: _,
3574 simultaneous_open,
3575 buffer_sizes,
3576 smss,
3577 rcv_wnd_scale,
3578 snd_wnd_scale,
3579 sack_permitted,
3580 rcv: RecvParams { ack: _, wnd_scale: _, wnd: _, ts_opt, last_ack_recv: _ },
3581 }) => {
3582 let (rcv_buffer, snd_buffer) = simultaneous_open
3602 .take()
3603 .expect(
3604 "a SYN-RCVD state that is in the pending queue \
3605 should call abort instead of close",
3606 )
3607 .into_buffers(*buffer_sizes);
3608 let (snd_wnd_scale, rcv_wnd_scale) = snd_wnd_scale
3612 .map(|snd_wnd_scale| (snd_wnd_scale, *rcv_wnd_scale))
3613 .unwrap_or_default();
3614 let next = *iss + 1;
3615 let finwait1 = FinWait1 {
3616 snd: Send {
3617 nxt: next,
3618 max: next,
3619 una: next,
3620 wnd: WindowSize::DEFAULT,
3621 wl1: *iss,
3622 wl2: *irs,
3623 last_push: next,
3624 buffer: snd_buffer,
3625 rtt_sampler: RttSampler::default(),
3626 rtt_estimator: Estimator::NoSample,
3627 timer: None,
3628 congestion_control: CongestionControl::cubic_with_mss(*smss),
3629 wnd_scale: snd_wnd_scale,
3630 wnd_max: WindowSize::DEFAULT,
3631 last_data_sent: None,
3632 }
3633 .into(),
3634 rcv: Recv {
3635 buffer: RecvBufferState::Open {
3636 buffer: rcv_buffer,
3637 assembler: Assembler::new(*irs + 1),
3638 },
3639 timer: None,
3640 mss: *smss,
3641 remaining_quickacks: quickack_counter(buffer_sizes.rcv_limits(), *smss),
3642 last_segment_at: None,
3643 wnd_scale: rcv_wnd_scale,
3644 last_window_update: (*irs + 1, buffer_sizes.rwnd()),
3645 sack_permitted: *sack_permitted,
3646 ts_opt: ts_opt.clone(),
3647 }
3648 .into(),
3649 };
3650 Ok(self.transition_to_state(counters, State::FinWait1(finwait1)))
3651 }
3652 State::Established(Established { snd, rcv }) => {
3653 let finwait1 = FinWait1 {
3659 snd: snd.to_ref().take().queue_fin().into(),
3660 rcv: rcv.to_ref().to_takeable(),
3661 };
3662 Ok(self.transition_to_state(counters, State::FinWait1(finwait1)))
3663 }
3664 State::CloseWait(CloseWait { snd, closed_rcv }) => {
3665 let lastack = LastAck {
3666 snd: snd.to_ref().take().queue_fin(),
3667 closed_rcv: closed_rcv.clone(),
3668 };
3669 Ok(self.transition_to_state(counters, State::LastAck(lastack)))
3670 }
3671 State::LastAck(_) | State::FinWait1(_) | State::Closing(_) | State::TimeWait(_) => {
3672 Err(CloseError::Closing)
3673 }
3674 State::FinWait2(FinWait2 { last_seq: _, rcv: _, timeout_at, snd_info: _ }) => {
3675 if let (CloseReason::Close { now }, Some(fin_wait2_timeout)) =
3676 (close_reason, socket_options.fin_wait2_timeout)
3677 {
3678 assert_eq!(timeout_at.replace(now.saturating_add(fin_wait2_timeout)), None);
3679 }
3680 Err(CloseError::Closing)
3681 }
3682 }
3683 }
3684
3685 pub(super) fn shutdown_recv(&mut self) -> Result<(), CloseError> {
3686 match self {
3687 State::Closed(_) => Err(CloseError::NoConnection),
3688
3689 State::Listen(_)
3690 | State::SynSent(_)
3691 | State::SynRcvd(_)
3692 | State::CloseWait(_)
3693 | State::LastAck(_)
3694 | State::Closing(_)
3695 | State::TimeWait(_) => Ok(()),
3696
3697 State::Established(Established { rcv, .. }) | State::FinWait1(FinWait1 { rcv, .. }) => {
3699 rcv.buffer.close();
3700 Ok(())
3701 }
3702 State::FinWait2(FinWait2 { rcv, .. }) => {
3703 rcv.buffer.close();
3704 Ok(())
3705 }
3706 }
3707 }
3708
3709 pub(crate) fn abort(
3712 &mut self,
3713 counters: &TcpCountersRefs<'_>,
3714 now: I,
3715 reason: ConnectionError,
3716 ) -> (Option<Segment<()>>, NewlyClosed) {
3717 let reply = match self {
3718 State::Closed(_)
3731 | State::Listen(_)
3732 | State::SynSent(_)
3733 | State::Closing(_)
3734 | State::LastAck(_)
3735 | State::TimeWait(_) => None,
3736 State::SynRcvd(SynRcvd {
3748 iss,
3749 irs,
3750 timestamp: _,
3751 retrans_timer: _,
3752 simultaneous_open: _,
3753 buffer_sizes: _,
3754 smss: _,
3755 rcv_wnd_scale: _,
3756 snd_wnd_scale: _,
3757 sack_permitted: _,
3758 rcv,
3759 }) => {
3760 Some(Segment::rst_ack(
3763 *iss + 1,
3764 *irs + 1,
3765 ResetOptions { timestamp: rcv.timestamp_option_for_ack(now) },
3766 ))
3767 }
3768 State::Established(Established { snd, rcv }) => Some(Segment::rst_ack(
3769 snd.nxt,
3770 rcv.nxt(),
3771 ResetOptions { timestamp: rcv.timestamp_option_for_ack(now) },
3772 )),
3773 State::FinWait1(FinWait1 { snd, rcv }) => Some(Segment::rst_ack(
3774 snd.nxt,
3775 rcv.nxt(),
3776 ResetOptions { timestamp: rcv.timestamp_option_for_ack(now) },
3777 )),
3778 State::FinWait2(FinWait2 { rcv, last_seq, timeout_at: _, snd_info: _ }) => {
3779 Some(Segment::rst_ack(
3780 *last_seq,
3781 rcv.nxt(),
3782 ResetOptions { timestamp: rcv.timestamp_option_for_ack(now) },
3783 ))
3784 }
3785 State::CloseWait(CloseWait { snd, closed_rcv }) => Some(Segment::rst_ack(
3786 snd.nxt,
3787 closed_rcv.ack,
3788 ResetOptions { timestamp: closed_rcv.timestamp_option_for_ack(now) },
3789 )),
3790 };
3791 (reply, self.transition_to_state(counters, State::Closed(Closed { reason: Some(reason) })))
3792 }
3793
3794 pub(crate) fn buffers_mut(&mut self) -> BuffersRefMut<'_, R, S> {
3795 match self {
3796 State::TimeWait(_) | State::Closed(_) => BuffersRefMut::NoBuffers,
3797 State::Listen(Listen { buffer_sizes, .. })
3798 | State::SynRcvd(SynRcvd { buffer_sizes, .. })
3799 | State::SynSent(SynSent { buffer_sizes, .. }) => BuffersRefMut::Sizes(buffer_sizes),
3800 State::Established(Established { snd, rcv }) => match &mut rcv.buffer {
3801 RecvBufferState::Open { buffer: recv_buf, .. } => {
3802 BuffersRefMut::Both { send: &mut snd.buffer, recv: recv_buf }
3803 }
3804 RecvBufferState::Closed { .. } => BuffersRefMut::SendOnly(&mut snd.buffer),
3805 },
3806 State::FinWait1(FinWait1 { snd, rcv }) => match &mut rcv.buffer {
3807 RecvBufferState::Open { buffer: recv_buf, .. } => {
3808 BuffersRefMut::Both { send: &mut snd.buffer, recv: recv_buf }
3809 }
3810 RecvBufferState::Closed { .. } => BuffersRefMut::SendOnly(&mut snd.buffer),
3811 },
3812 State::FinWait2(FinWait2::<I, R> { rcv, .. }) => match &mut rcv.buffer {
3813 RecvBufferState::Open { buffer: recv_buf, .. } => BuffersRefMut::RecvOnly(recv_buf),
3814 RecvBufferState::Closed { .. } => BuffersRefMut::NoBuffers,
3815 },
3816 State::Closing(Closing::<I, S> { snd, .. })
3817 | State::LastAck(LastAck::<I, S> { snd, .. }) => {
3818 BuffersRefMut::SendOnly(&mut snd.buffer)
3819 }
3820 State::CloseWait(CloseWait::<I, S> { snd, .. }) => {
3821 BuffersRefMut::SendOnly(&mut snd.buffer)
3822 }
3823 }
3824 }
3825
3826 pub(super) fn on_icmp_error(
3829 &mut self,
3830 counters: &TcpCountersRefs<'_>,
3831 err: IcmpErrorCode,
3832 seq: SeqNum,
3833 ) -> (Option<ConnectionError>, NewlyClosed, ShouldRetransmit) {
3834 let Some(result) = IcmpErrorResult::try_from_icmp_error(err) else {
3835 return (None, NewlyClosed::No, ShouldRetransmit::No);
3836 };
3837 let err = match result {
3838 IcmpErrorResult::ConnectionError(err) => err,
3839 IcmpErrorResult::PmtuUpdate(mms) => {
3840 let mss = Mss::from_mms(mms).unwrap_or(Mss::MIN);
3842 let should_send = self.on_pmtu_update(mss, seq);
3843 return (None, NewlyClosed::No, should_send);
3844 }
3845 };
3846 let connect_error = match self {
3867 State::Closed(_) => None,
3868 State::Listen(listen) => unreachable!(
3869 "ICMP errors should not be delivered on a listener, received code {:?} on {:?}",
3870 err, listen
3871 ),
3872 State::SynRcvd(SynRcvd {
3873 iss,
3874 irs: _,
3875 timestamp: _,
3876 retrans_timer: _,
3877 simultaneous_open: _,
3878 buffer_sizes: _,
3879 smss: _,
3880 rcv_wnd_scale: _,
3881 snd_wnd_scale: _,
3882 sack_permitted: _,
3883 rcv: _,
3884 })
3885 | State::SynSent(SynSent {
3886 iss,
3887 timestamp: _,
3888 retrans_timer: _,
3889 active_open: _,
3890 buffer_sizes: _,
3891 device_mss: _,
3892 default_mss: _,
3893 rcv_wnd_scale: _,
3894 ts_opt: _,
3895 }) => {
3896 if *iss == seq {
3897 return (
3898 None,
3899 self.transition_to_state(
3900 counters,
3901 State::Closed(Closed { reason: Some(err) }),
3902 ),
3903 ShouldRetransmit::No,
3904 );
3905 }
3906 None
3907 }
3908 State::Established(Established { snd, rcv: _ })
3909 | State::CloseWait(CloseWait { snd, closed_rcv: _ }) => {
3910 (!snd.una.after(seq) && seq.before(snd.nxt)).then_some(err)
3911 }
3912 State::LastAck(LastAck { snd, closed_rcv: _ })
3913 | State::Closing(Closing { snd, closed_rcv: _ }) => {
3914 (!snd.una.after(seq) && seq.before(snd.nxt)).then_some(err)
3915 }
3916 State::FinWait1(FinWait1 { snd, rcv: _ }) => {
3917 (!snd.una.after(seq) && seq.before(snd.nxt)).then_some(err)
3918 }
3919 State::FinWait2(_) | State::TimeWait(_) => None,
3922 };
3923 (connect_error, NewlyClosed::No, ShouldRetransmit::No)
3924 }
3925
3926 fn on_pmtu_update(&mut self, mss: Mss, seq: SeqNum) -> ShouldRetransmit {
3927 match self {
3930 State::Listen(listen) => unreachable!(
3931 "PMTU updates should not be delivered to a listener, received {mss:?} on {listen:?}"
3932 ),
3933 State::Closed(_)
3934 | State::SynRcvd(_)
3935 | State::SynSent(_)
3936 | State::FinWait2(_)
3937 | State::TimeWait(_) => {}
3938 State::Established(Established { snd, .. })
3939 | State::CloseWait(CloseWait { snd, .. }) => {
3940 if !snd.una.after(seq) && seq.before(snd.nxt) {
3941 return snd.update_mss(mss, seq);
3942 }
3943 }
3944 State::LastAck(LastAck { snd, .. }) | State::Closing(Closing { snd, .. }) => {
3945 if !snd.una.after(seq) && seq.before(snd.nxt) {
3946 return snd.update_mss(mss, seq);
3947 }
3948 }
3949 State::FinWait1(FinWait1 { snd, .. }) => {
3950 if !snd.una.after(seq) && seq.before(snd.nxt) {
3951 return snd.update_mss(mss, seq);
3952 }
3953 }
3954 }
3955 ShouldRetransmit::No
3956 }
3957}
3958
3959pub(super) enum CloseReason<I: Instant> {
3963 Shutdown,
3964 Close { now: I },
3965}
3966
3967#[cfg(test)]
3968mod test {
3969 use alloc::vec;
3970 use alloc::vec::Vec;
3971 use core::fmt::Debug;
3972 use core::time::Duration;
3973
3974 use assert_matches::assert_matches;
3975 use netstack3_base::sync::ResourceTokenValue;
3976 use netstack3_base::testutil::{FakeInstant, FakeInstantCtx};
3977 use netstack3_base::{
3978 CounterCollection, FragmentedPayload, InstantContext as _, Milliseconds, Options,
3979 SackBlock, Timestamp, TimestampOption, Unitless,
3980 };
3981 use packet::InnerPacketBuilder as _;
3982 use test_case::{test_case, test_matrix};
3983
3984 use super::*;
3985 use crate::internal::base::DEFAULT_FIN_WAIT2_TIMEOUT;
3986 use crate::internal::buffer::Buffer;
3987 use crate::internal::buffer::testutil::{InfiniteSendBuffer, RepeatingSendBuffer, RingBuffer};
3988 use crate::internal::congestion::DUP_ACK_THRESHOLD;
3989 use crate::internal::counters::TcpCountersWithSocketInner;
3990 use crate::internal::counters::testutil::CounterExpectations;
3991 use crate::internal::state::info::SendInfo;
3992 use crate::internal::timestamp::{TS_ECHO_REPLY_FOR_NON_ACKS, TimestampValueState};
3993
3994 const TEST_IRS: SeqNum = SeqNum::new(100);
3995 const TEST_ISS: SeqNum = SeqNum::new(300);
3996
3997 const ISS_1: SeqNum = SeqNum::new(500);
3998 const ISS_2: SeqNum = SeqNum::new(700);
3999
4000 const RTT: Duration = Duration::from_millis(500);
4001
4002 const DEVICE_MAXIMUM_SEGMENT_SIZE: Mss = Mss::new(1400).unwrap();
4003
4004 const TEST_MSS: EffectiveMss =
4005 EffectiveMss::from_mss(Mss::new(256).unwrap(), MssSizeLimiters { timestamp_enabled: true });
4006 const BUFFER_SIZE: usize = (TEST_MSS.get() as usize) * 3;
4008 const TEST_BYTES: &[u8] = &[0xab; TEST_MSS.get() as usize];
4010
4011 const TIMESTAMP_OFFSET: Timestamp<Milliseconds> = Timestamp::new(12345);
4014
4015 const DEFAULT_TIMESTAMP: Timestamp<Unitless> = TIMESTAMP_OFFSET.discard_unit();
4017 const DEFAULT_NON_ACK_TS_OPT: TimestampOption =
4019 TimestampOption::new(DEFAULT_TIMESTAMP, TS_ECHO_REPLY_FOR_NON_ACKS);
4020 const DEFAULT_ACK_TS_OPT: TimestampOption = TimestampOption::new(
4022 DEFAULT_TIMESTAMP,
4025 DEFAULT_TIMESTAMP,
4026 );
4027
4028 const RTT_TIMESTAMP: Timestamp<Unitless> =
4032 Timestamp::new(TIMESTAMP_OFFSET.get() + RTT.as_millis() as u32);
4033 const NON_ACK_TS_OPT_AFTER_RTT: TimestampOption =
4036 TimestampOption::new(RTT_TIMESTAMP, TS_ECHO_REPLY_FOR_NON_ACKS);
4037 const ACK_TS_OPT_AFTER_RTT: TimestampOption =
4040 TimestampOption::new(RTT_TIMESTAMP, DEFAULT_TIMESTAMP);
4041
4042 const fn default_ts_opt_state(last_ack: SeqNum) -> TimestampOptionState<FakeInstant> {
4043 TimestampOptionState::Enabled {
4044 ts_recent: DEFAULT_TIMESTAMP,
4048 last_ack_sent: last_ack,
4049 ts_val: TimestampValueState {
4050 offset: TIMESTAMP_OFFSET,
4051 initialized_at: FakeInstant { offset: Duration::ZERO },
4052 },
4053 }
4054 }
4055
4056 const fn default_ts_opt_negotiation_state() -> TimestampOptionNegotiationState<FakeInstant> {
4057 TimestampOptionNegotiationState::Negotiating(TimestampValueState {
4058 offset: TIMESTAMP_OFFSET,
4059 initialized_at: FakeInstant { offset: Duration::ZERO },
4060 })
4061 }
4062
4063 const fn default_segment_options(
4064 ts_val: Timestamp<Unitless>,
4065 ts_echo_reply: Timestamp<Unitless>,
4066 ) -> SegmentOptions {
4067 SegmentOptions {
4068 sack_blocks: SackBlocks::EMPTY,
4069 timestamp: Some(TimestampOption::new(ts_val, ts_echo_reply)),
4070 }
4071 }
4072
4073 const DEFAULT_SEGMENT_OPTIONS: SegmentOptions =
4074 default_segment_options(DEFAULT_TIMESTAMP, DEFAULT_TIMESTAMP);
4075
4076 fn timestamp_now(clock: &FakeInstantCtx) -> Timestamp<Unitless> {
4077 (TIMESTAMP_OFFSET + clock.now().offset).discard_unit()
4078 }
4079
4080 fn default_quickack_counter() -> usize {
4081 quickack_counter(
4082 BufferLimits { capacity: WindowSize::DEFAULT.into(), len: 0 },
4083 EffectiveMss::from_mss(
4084 DEVICE_MAXIMUM_SEGMENT_SIZE,
4085 MssSizeLimiters { timestamp_enabled: true },
4086 ),
4087 )
4088 }
4089
4090 impl SocketOptions {
4091 fn default_for_state_tests() -> Self {
4092 Self { delayed_ack: false, nagle_enabled: false, ..Default::default() }
4095 }
4096 }
4097
4098 enum ClientlessBufferProvider {}
4101
4102 impl<R: ReceiveBuffer + Default, S: SendBuffer + Default> BufferProvider<R, S>
4103 for ClientlessBufferProvider
4104 {
4105 type PassiveOpen = ();
4106 type ActiveOpen = ();
4107
4108 fn new_passive_open_buffers(_buffer_sizes: BufferSizes) -> (R, S, Self::PassiveOpen) {
4109 (R::default(), S::default(), ())
4110 }
4111 }
4112
4113 impl RingBuffer {
4114 fn with_data<'a>(cap: usize, data: &'a [u8]) -> Self {
4115 let mut buffer = RingBuffer::new(cap);
4116 let nwritten = buffer.write_at(0, &data);
4117 assert_eq!(nwritten, data.len());
4118 buffer.make_readable(nwritten, false);
4119 buffer
4120 }
4121 }
4122
4123 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
4125 struct NullBuffer;
4126
4127 impl Buffer for NullBuffer {
4128 fn limits(&self) -> BufferLimits {
4129 BufferLimits { len: 0, capacity: 0 }
4130 }
4131
4132 fn target_capacity(&self) -> usize {
4133 0
4134 }
4135
4136 fn request_capacity(&mut self, _size: usize) {}
4137 }
4138
4139 impl ReceiveBuffer for NullBuffer {
4140 fn write_at<P: Payload>(&mut self, _offset: usize, _data: &P) -> usize {
4141 0
4142 }
4143
4144 fn make_readable(&mut self, count: usize, has_outstanding: bool) {
4145 assert_eq!(count, 0);
4146 assert_eq!(has_outstanding, false);
4147 }
4148 }
4149
4150 impl SendBuffer for NullBuffer {
4151 type Payload<'a> = &'a [u8];
4152
4153 fn mark_read(&mut self, count: usize) {
4154 assert_eq!(count, 0);
4155 }
4156
4157 fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
4158 where
4159 F: FnOnce(Self::Payload<'a>) -> R,
4160 {
4161 assert_eq!(offset, 0);
4162 f(&[])
4163 }
4164 }
4165
4166 #[derive(Debug, Default)]
4167 struct FakeStateMachineDebugId {
4168 resource_token: ResourceTokenValue,
4169 }
4170
4171 impl StateMachineDebugId for FakeStateMachineDebugId {
4172 fn trace_id(&self) -> TraceResourceId<'_> {
4173 TraceResourceId::new(self.resource_token.token())
4174 }
4175 }
4176
4177 impl<R: ReceiveBuffer, S: SendBuffer> State<FakeInstant, R, S, ()> {
4178 fn poll_send_with_default_options(
4179 &mut self,
4180 now: FakeInstant,
4181 counters: &TcpCountersRefs<'_>,
4182 ) -> Option<Segment<S::Payload<'_>>> {
4183 self.poll_send(
4184 &FakeStateMachineDebugId::default(),
4185 counters,
4186 now,
4187 &SocketOptions::default_for_state_tests(),
4188 )
4189 .ok()
4190 }
4191
4192 fn on_segment_with_default_options<P: Payload, BP: BufferProvider<R, S, ActiveOpen = ()>>(
4193 &mut self,
4194 incoming: Segment<P>,
4195 now: FakeInstant,
4196 counters: &TcpCountersRefs<'_>,
4197 ) -> (Option<Segment<()>>, Option<BP::PassiveOpen>)
4198 where
4199 BP::PassiveOpen: Debug,
4200 R: Default,
4201 S: Default,
4202 {
4203 self.on_segment_with_options::<_, BP>(
4204 incoming,
4205 now,
4206 counters,
4207 &SocketOptions::default_for_state_tests(),
4208 )
4209 }
4210
4211 fn on_segment_with_options<P: Payload, BP: BufferProvider<R, S, ActiveOpen = ()>>(
4212 &mut self,
4213 incoming: Segment<P>,
4214 now: FakeInstant,
4215 counters: &TcpCountersRefs<'_>,
4216 options: &SocketOptions,
4217 ) -> (Option<Segment<()>>, Option<BP::PassiveOpen>)
4218 where
4219 BP::PassiveOpen: Debug,
4220 R: Default,
4221 S: Default,
4222 {
4223 let (segment, passive_open, _data_acked, _newly_closed) = self.on_segment::<P, BP>(
4224 &FakeStateMachineDebugId::default(),
4225 counters,
4226 incoming,
4227 now,
4228 options,
4229 false, );
4231 (segment, passive_open)
4232 }
4233
4234 fn recv_mut(&mut self) -> Option<&mut Recv<FakeInstant, R>> {
4235 match self {
4236 State::Closed(_)
4237 | State::Listen(_)
4238 | State::SynRcvd(_)
4239 | State::SynSent(_)
4240 | State::CloseWait(_)
4241 | State::LastAck(_)
4242 | State::Closing(_)
4243 | State::TimeWait(_) => None,
4244 State::Established(Established { rcv, .. })
4245 | State::FinWait1(FinWait1 { rcv, .. }) => Some(rcv.get_mut()),
4246 State::FinWait2(FinWait2 { rcv, .. }) => Some(rcv),
4247 }
4248 }
4249
4250 #[track_caller]
4251 fn assert_established(&mut self) -> &mut Established<FakeInstant, R, S> {
4252 assert_matches!(self, State::Established(e) => e)
4253 }
4254 }
4255
4256 impl<S: SendBuffer + Debug> State<FakeInstant, RingBuffer, S, ()> {
4257 fn read_with(&mut self, f: impl for<'b> FnOnce(&'b [&'_ [u8]]) -> usize) -> usize {
4258 match self {
4259 State::Closed(_)
4260 | State::Listen(_)
4261 | State::SynRcvd(_)
4262 | State::SynSent(_)
4263 | State::CloseWait(_)
4264 | State::LastAck(_)
4265 | State::Closing(_)
4266 | State::TimeWait(_) => {
4267 panic!("No receive state in {:?}", self);
4268 }
4269 State::Established(Established { snd: _, rcv })
4270 | State::FinWait1(FinWait1 { snd: _, rcv }) => {
4271 assert_matches!(&mut rcv.buffer, RecvBufferState::Open{ buffer, .. } => buffer.read_with(f))
4272 }
4273 State::FinWait2(FinWait2 { last_seq: _, rcv, timeout_at: _, snd_info: _ }) => {
4274 assert_matches!(&mut rcv.buffer, RecvBufferState::Open{ buffer, .. } => buffer.read_with(f))
4275 }
4276 }
4277 }
4278 }
4279
4280 impl State<FakeInstant, RingBuffer, NullBuffer, ()> {
4281 fn new_syn_rcvd(instant: FakeInstant) -> Self {
4282 State::SynRcvd(SynRcvd {
4283 iss: TEST_ISS,
4284 irs: TEST_IRS,
4285 timestamp: Some(instant),
4286 retrans_timer: RetransTimer::new(instant, Rto::DEFAULT, None, DEFAULT_MAX_RETRIES),
4287 simultaneous_open: Some(()),
4288 buffer_sizes: Default::default(),
4289 smss: EffectiveMss::from_mss(
4290 DEVICE_MAXIMUM_SEGMENT_SIZE,
4291 MssSizeLimiters { timestamp_enabled: true },
4292 ),
4293 rcv_wnd_scale: WindowScale::default(),
4294 snd_wnd_scale: Some(WindowScale::default()),
4295 sack_permitted: SACK_PERMITTED,
4296 rcv: RecvParams {
4297 ack: TEST_IRS + 1,
4298 wnd: WindowSize::DEFAULT,
4299 wnd_scale: WindowScale::default(),
4300 ts_opt: default_ts_opt_state(TEST_IRS + 1),
4301 last_ack_recv: None,
4302 },
4303 })
4304 }
4305 }
4306
4307 impl<S, const FIN_QUEUED: bool> Send<FakeInstant, S, FIN_QUEUED> {
4308 fn default_for_test_at(seq: SeqNum, buffer: S) -> Self {
4309 Self {
4310 nxt: seq,
4311 max: seq,
4312 una: seq,
4313 wnd: WindowSize::DEFAULT,
4314 wnd_max: WindowSize::DEFAULT,
4315 buffer,
4316 wl1: TEST_IRS + 1,
4317 wl2: seq,
4318 last_push: seq,
4319 rtt_estimator: Estimator::default(),
4320 rtt_sampler: RttSampler::default(),
4321 timer: None,
4322 congestion_control: CongestionControl::cubic_with_mss(EffectiveMss::from_mss(
4323 DEVICE_MAXIMUM_SEGMENT_SIZE,
4324 MssSizeLimiters { timestamp_enabled: true },
4325 )),
4326 wnd_scale: WindowScale::default(),
4327 last_data_sent: None,
4328 }
4329 }
4330
4331 fn default_for_test(buffer: S) -> Self {
4332 Self::default_for_test_at(TEST_ISS + 1, buffer)
4333 }
4334 }
4335
4336 impl<R: ReceiveBuffer> Recv<FakeInstant, R> {
4337 fn default_for_test_at(seq: SeqNum, buffer: R) -> Self {
4338 let BufferLimits { capacity, len } = buffer.limits();
4339 let avail_buffer = capacity - len;
4340 Self {
4341 buffer: RecvBufferState::Open { buffer, assembler: Assembler::new(seq) },
4342 timer: None,
4343 mss: EffectiveMss::from_mss(
4344 DEVICE_MAXIMUM_SEGMENT_SIZE,
4345 MssSizeLimiters { timestamp_enabled: true },
4346 ),
4347 remaining_quickacks: 0,
4348 last_segment_at: None,
4349 wnd_scale: WindowScale::default(),
4350 last_window_update: (
4351 seq,
4352 WindowSize::from_u32(avail_buffer.try_into().unwrap()).unwrap(),
4353 ),
4354 sack_permitted: SACK_PERMITTED,
4355 ts_opt: default_ts_opt_state(seq),
4356 }
4357 }
4358
4359 fn default_for_test(buffer: R) -> Self {
4360 Self::default_for_test_at(TEST_IRS + 1, buffer)
4361 }
4362 }
4363
4364 #[derive(Default)]
4365 struct FakeTcpCounters {
4366 stack_wide: TcpCountersWithSocketInner,
4367 per_socket: TcpCountersWithSocketInner,
4368 }
4369
4370 impl FakeTcpCounters {
4371 fn refs<'a>(&'a self) -> TcpCountersRefs<'a> {
4372 let Self { stack_wide, per_socket } = self;
4373 TcpCountersRefs { stack_wide, per_socket }
4374 }
4375 }
4376
4377 impl CounterExpectations {
4378 #[track_caller]
4379 fn assert_counters(&self, FakeTcpCounters { stack_wide, per_socket }: &FakeTcpCounters) {
4380 assert_eq!(self, &stack_wide.cast(), "stack-wide counter mismatch");
4381 assert_eq!(self, &per_socket.cast(), "per-socket counter mismatch");
4382 }
4383 }
4384
4385 #[test_case(Segment::rst(TEST_IRS, ResetOptions::default()) => None; "drop RST")]
4386 #[test_case(Segment::rst_ack(TEST_IRS, TEST_ISS, ResetOptions::default()) => None; "drop RST|ACK")]
4387 #[test_case(Segment::syn(TEST_IRS, UnscaledWindowSize::from(0), HandshakeOptions::default()) => Some(Segment::rst_ack(SeqNum::new(0), TEST_IRS + 1, ResetOptions::default())); "reset SYN")]
4388 #[test_case(Segment::syn_ack(TEST_IRS, TEST_ISS, UnscaledWindowSize::from(0), HandshakeOptions::default()) => Some(Segment::rst(TEST_ISS, ResetOptions::default())); "reset SYN|ACK")]
4389 #[test_case(
4390 Segment::with_data(
4391 TEST_IRS,
4392 TEST_ISS,
4393 UnscaledWindowSize::from(0),
4394 SegmentOptions::default(),
4395 &[0, 1, 2][..]
4396 ) => Some(Segment::rst(TEST_ISS, ResetOptions::default())); "reset data segment")]
4397 fn segment_arrives_when_closed(
4398 incoming: impl Into<Segment<&'static [u8]>>,
4399 ) -> Option<Segment<()>> {
4400 let closed = Closed { reason: () };
4401 closed.on_segment(&incoming.into())
4402 }
4403
4404 #[test_case(
4405 Segment::rst_ack(TEST_ISS, TEST_IRS - 1, ResetOptions::default()), RTT
4406 => SynSentOnSegmentDisposition::Ignore; "unacceptable ACK with RST")]
4407 #[test_case(
4408 Segment::ack(
4409 TEST_ISS, TEST_IRS - 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4410 ),
4411 RTT
4412 => SynSentOnSegmentDisposition::SendRst(
4413 Segment::rst(TEST_IRS-1, ResetOptions::default()),
4414 ); "unacceptable ACK without RST")]
4415 #[test_case(
4416 Segment::rst_ack(TEST_ISS, TEST_IRS, ResetOptions::default()), RTT
4417 => SynSentOnSegmentDisposition::EnterClosed(
4418 Closed { reason: Some(ConnectionError::ConnectionRefused) },
4419 ); "acceptable ACK(ISS) with RST")]
4420 #[test_case(
4421 Segment::rst_ack(TEST_ISS, TEST_IRS + 1, ResetOptions::default()), RTT
4422 => SynSentOnSegmentDisposition::EnterClosed(
4423 Closed { reason: Some(ConnectionError::ConnectionRefused) },
4424 ); "acceptable ACK(ISS+1) with RST")]
4425 #[test_case(
4426 Segment::rst(TEST_ISS, ResetOptions::default()), RTT
4427 => SynSentOnSegmentDisposition::Ignore; "RST without ack")]
4428 #[test_case(
4429 Segment::syn(
4430 TEST_ISS,
4431 UnscaledWindowSize::from(u16::MAX),
4432 HandshakeOptions {
4433 window_scale: Some(WindowScale::default()),
4434 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
4435 ..Default::default() }
4436 ), RTT
4437 => SynSentOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
4438 Segment::syn_ack(
4439 TEST_IRS,
4440 TEST_ISS + 1,
4441 UnscaledWindowSize::from(u16::MAX),
4442 HandshakeOptions {
4443 mss: Some(Mss::DEFAULT_IPV4),
4444 window_scale: Some(WindowScale::default()),
4445 sack_permitted: SACK_PERMITTED,
4446 timestamp: Some(ACK_TS_OPT_AFTER_RTT),
4447 ..Default::default()
4448 }),
4449 SynRcvd {
4450 iss: TEST_IRS,
4451 irs: TEST_ISS,
4452 timestamp: Some(FakeInstant::from(RTT)),
4453 retrans_timer: RetransTimer::new(
4454 FakeInstant::from(RTT),
4455 Rto::DEFAULT,
4456 NonZeroDuration::new(TEST_USER_TIMEOUT.get() - RTT),
4457 DEFAULT_MAX_SYNACK_RETRIES
4458 ),
4459 simultaneous_open: None,
4460 buffer_sizes: BufferSizes::default(),
4461 smss: EffectiveMss::from_mss(
4462 Mss::DEFAULT_IPV4, MssSizeLimiters { timestamp_enabled: true }
4463 ),
4464 rcv_wnd_scale: WindowScale::default(),
4465 snd_wnd_scale: Some(WindowScale::default()),
4466 sack_permitted: false,
4467 rcv: RecvParams {
4468 ack: TEST_ISS + 1,
4469 wnd: WindowSize::DEFAULT,
4470 wnd_scale: WindowScale::default(),
4471 ts_opt: default_ts_opt_state(TEST_ISS + 1),
4472 last_ack_recv: None,
4473 }
4474 }
4475 ); "SYN only")]
4476 #[test_case(
4477 Segment::fin(
4478 TEST_ISS, TEST_IRS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4479 ),
4480 RTT
4481 => SynSentOnSegmentDisposition::Ignore; "acceptable ACK with FIN")]
4482 #[test_case(
4483 Segment::ack(
4484 TEST_ISS, TEST_IRS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4485 ),
4486 RTT
4487 => SynSentOnSegmentDisposition::Ignore; "acceptable ACK(ISS+1) with nothing")]
4488 #[test_case(
4489 Segment::ack(
4490 TEST_ISS, TEST_IRS, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4491 ),
4492 RTT
4493 => SynSentOnSegmentDisposition::Ignore; "acceptable ACK(ISS) without RST")]
4494 #[test_case(
4495 Segment::syn(TEST_ISS, UnscaledWindowSize::from(u16::MAX), HandshakeOptions::default()),
4496 TEST_USER_TIMEOUT.get()
4497 => SynSentOnSegmentDisposition::EnterClosed(Closed {
4498 reason: None
4499 }); "syn but timed out")]
4500 fn segment_arrives_when_syn_sent(
4501 incoming: Segment<()>,
4502 delay: Duration,
4503 ) -> SynSentOnSegmentDisposition<FakeInstant, ()> {
4504 let syn_sent = SynSent {
4505 iss: TEST_IRS,
4506 timestamp: Some(FakeInstant::default()),
4507 retrans_timer: RetransTimer::new(
4508 FakeInstant::default(),
4509 Rto::DEFAULT,
4510 Some(TEST_USER_TIMEOUT),
4511 DEFAULT_MAX_RETRIES,
4512 ),
4513 active_open: (),
4514 buffer_sizes: BufferSizes::default(),
4515 default_mss: Mss::DEFAULT_IPV4,
4516 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
4517 rcv_wnd_scale: WindowScale::default(),
4518 ts_opt: default_ts_opt_negotiation_state(),
4519 };
4520 syn_sent.on_segment(incoming, FakeInstant::from(delay))
4521 }
4522
4523 #[test_case(Segment::rst(TEST_ISS, ResetOptions::default()) => ListenOnSegmentDisposition::Ignore; "ignore RST")]
4524 #[test_case(
4525 Segment::ack(
4526 TEST_ISS, TEST_IRS, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4527 ) => ListenOnSegmentDisposition::SendRst(Segment::rst(TEST_IRS, ResetOptions::default()));
4528 "reject ACK")]
4529 #[test_case(Segment::syn(TEST_ISS, UnscaledWindowSize::from(u16::MAX),
4530 HandshakeOptions {
4531 window_scale: Some(WindowScale::default()),
4532 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
4533 ..Default::default()
4534 }) =>
4535 ListenOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
4536 Segment::syn_ack(
4537 TEST_IRS,
4538 TEST_ISS + 1,
4539 UnscaledWindowSize::from(u16::MAX),
4540 HandshakeOptions {
4541 mss: Some(Mss::DEFAULT_IPV4),
4542 window_scale: Some(WindowScale::default()),
4543 timestamp: Some(DEFAULT_ACK_TS_OPT),
4544 sack_permitted: SACK_PERMITTED,
4545 ..Default::default()
4546 }),
4547 SynRcvd {
4548 iss: TEST_IRS,
4549 irs: TEST_ISS,
4550 timestamp: Some(FakeInstant::default()),
4551 retrans_timer: RetransTimer::new(
4552 FakeInstant::default(),
4553 Rto::DEFAULT,
4554 None,
4555 DEFAULT_MAX_SYNACK_RETRIES,
4556 ),
4557 simultaneous_open: None,
4558 buffer_sizes: BufferSizes::default(),
4559 smss: EffectiveMss::from_mss(
4560 Mss::DEFAULT_IPV4, MssSizeLimiters{timestamp_enabled: true}
4561 ),
4562 sack_permitted: false,
4563 rcv_wnd_scale: WindowScale::default(),
4564 snd_wnd_scale: Some(WindowScale::default()),
4565 rcv: RecvParams {
4566 ack: TEST_ISS + 1,
4567 wnd: WindowSize::DEFAULT,
4568 wnd_scale: WindowScale::default(),
4569 ts_opt: default_ts_opt_state(TEST_ISS + 1),
4570 last_ack_recv: None,
4571 }
4572 }); "accept syn")]
4573 fn segment_arrives_when_listen(
4574 incoming: Segment<()>,
4575 ) -> ListenOnSegmentDisposition<FakeInstant> {
4576 let listen = Closed::<Initial>::listen(
4577 TEST_IRS,
4578 TIMESTAMP_OFFSET,
4579 Default::default(),
4580 DEVICE_MAXIMUM_SEGMENT_SIZE,
4581 Mss::DEFAULT_IPV4,
4582 None,
4583 );
4584 listen.on_segment(incoming, FakeInstant::default())
4585 }
4586
4587 #[test_case(
4588 Segment::ack(
4589 TEST_IRS, TEST_ISS, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4590 ),
4591 None
4592 => Some(Segment::ack(
4593 TEST_ISS + 1,
4594 TEST_IRS + 1,
4595 UnscaledWindowSize::from(u16::MAX),
4596 default_segment_options(RTT_TIMESTAMP, DEFAULT_TIMESTAMP),
4597 )) ; "OTW segment")]
4598 #[test_case(
4599 Segment::rst_ack(TEST_IRS, TEST_ISS, ResetOptions::default()),
4600 None
4601 => None; "OTW RST")]
4602 #[test_case(
4603 Segment::rst_ack(TEST_IRS + 1, TEST_ISS, ResetOptions::default()),
4604 Some(State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }))
4605 => None; "acceptable RST")]
4606 #[test_case(
4607 Segment::syn(TEST_IRS + 1, UnscaledWindowSize::from(u16::MAX), HandshakeOptions {
4608 window_scale: Some(WindowScale::default()),
4609 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
4610 ..Default::default()
4611 }),
4612 Some(State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }))
4613 => Some(
4614 Segment::rst(TEST_ISS + 1, ResetOptions { timestamp: Some(NON_ACK_TS_OPT_AFTER_RTT) }),
4615 ); "duplicate syn")]
4616 #[test_case(
4617 Segment::ack(
4618 TEST_IRS + 1, TEST_ISS, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4619 ),
4620 None
4621 => Some(
4622 Segment::rst(TEST_ISS, ResetOptions { timestamp: Some(NON_ACK_TS_OPT_AFTER_RTT) }),
4623 ); "unacceptable ack (ISS)")]
4624 #[test_case(
4625 Segment::ack(
4626 TEST_IRS + 1, TEST_ISS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4627 ),
4628 Some(State::Established(
4629 Established {
4630 snd: Send {
4631 rtt_estimator: Estimator::Measured {
4632 srtt: RTT,
4633 rtt_var: RTT / 2,
4634 },
4635 ..Send::default_for_test(NullBuffer)
4636 }.into(),
4637 rcv: Recv {
4638 remaining_quickacks: quickack_counter(BufferLimits {
4639 capacity: WindowSize::DEFAULT.into(),
4640 len: 0,
4641 }, EffectiveMss::from_mss(
4642 DEVICE_MAXIMUM_SEGMENT_SIZE, MssSizeLimiters { timestamp_enabled: true }
4643 )),
4644 ..Recv::default_for_test(RingBuffer::default())
4645 }.into(),
4646 }
4647 ))
4648 => None; "acceptable ack (ISS + 1)")]
4649 #[test_case(
4650 Segment::ack(
4651 TEST_IRS + 1, TEST_ISS + 2, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4652 ),
4653 None
4654 => Some(
4655 Segment::rst(TEST_ISS + 2, ResetOptions { timestamp: Some(NON_ACK_TS_OPT_AFTER_RTT) })
4656 ); "unacceptable ack (ISS + 2)")]
4657 #[test_case(
4658 Segment::ack(
4659 TEST_IRS + 1, TEST_ISS - 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4660 ),
4661 None
4662 => Some(
4663 Segment::rst(TEST_ISS - 1, ResetOptions { timestamp: Some(NON_ACK_TS_OPT_AFTER_RTT) })
4664 ); "unacceptable ack (ISS - 1)")]
4665 #[test_case(
4666 Segment::new_empty(
4667 SegmentHeader {
4668 seq: TEST_IRS + 1,
4669 wnd: UnscaledWindowSize::from(u16::MAX),
4670 options: DEFAULT_SEGMENT_OPTIONS.into(),
4671 ..Default::default()
4672 }
4673 ),
4674 None
4675 => None; "no ack")]
4676 #[test_case(
4677 Segment::fin(
4678 TEST_IRS + 1, TEST_ISS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4679 ),
4680 Some(State::CloseWait(CloseWait {
4681 snd: Send {
4682 rtt_estimator: Estimator::Measured {
4683 srtt: RTT,
4684 rtt_var: RTT / 2,
4685 },
4686 ..Send::default_for_test(NullBuffer)
4687 }.into(),
4688 closed_rcv: RecvParams {
4689 ack: TEST_IRS + 2,
4690 wnd: WindowSize::from_u32(u32::from(u16::MAX - 1)).unwrap(),
4691 wnd_scale: WindowScale::ZERO,
4692 ts_opt: default_ts_opt_state(TEST_IRS + 2),
4693 last_ack_recv: Some(FakeInstant::from(RTT)),
4694 },
4695 }))
4696 => Some(Segment::ack(
4697 TEST_ISS + 1,
4698 TEST_IRS + 2,
4699 UnscaledWindowSize::from(u16::MAX - 1),
4700 default_segment_options(RTT_TIMESTAMP, DEFAULT_TIMESTAMP),
4701 )); "fin")]
4702 fn segment_arrives_when_syn_rcvd(
4703 incoming: Segment<()>,
4704 expected: Option<State<FakeInstant, RingBuffer, NullBuffer, ()>>,
4705 ) -> Option<Segment<()>> {
4706 let mut clock = FakeInstantCtx::default();
4707 let counters = FakeTcpCounters::default();
4708 let mut state = State::new_syn_rcvd(clock.now());
4709 clock.sleep(RTT);
4710 let (seg, _passive_open) = state
4711 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4712 incoming,
4713 clock.now(),
4714 &counters.refs(),
4715 );
4716 match expected {
4717 Some(new_state) => assert_eq!(state, new_state),
4718 None => assert_matches!(state, State::SynRcvd(_)),
4719 };
4720 seg
4721 }
4722
4723 #[test]
4724 fn abort_when_syn_rcvd() {
4725 let clock = FakeInstantCtx::default();
4726 let counters = FakeTcpCounters::default();
4727 let mut state = State::new_syn_rcvd(clock.now());
4728 let segment = assert_matches!(
4729 state.abort(&counters.refs(), clock.now(), ConnectionError::ConnectionReset),
4730 (Some(seg), NewlyClosed::Yes) => seg
4731 );
4732 assert_eq!(segment.header().control, Some(Control::RST));
4733 assert_eq!(segment.header().seq, TEST_ISS + 1);
4734 assert_eq!(segment.header().ack, Some(TEST_IRS + 1));
4735 }
4736
4737 #[test_case(
4738 Segment::syn(TEST_IRS + 1, UnscaledWindowSize::from(u16::MAX), HandshakeOptions {
4739 timestamp: Some(DEFAULT_NON_ACK_TS_OPT), ..Default::default()
4740 }),
4741 Some(State::Closed (
4742 Closed { reason: Some(ConnectionError::ConnectionReset) },
4743 ))
4744 => Some(Segment::rst(TEST_ISS + 1, ResetOptions {timestamp: Some(DEFAULT_NON_ACK_TS_OPT)}));
4745 "duplicate syn")]
4746 #[test_case(
4747 Segment::rst(TEST_IRS + 1, ResetOptions::default()),
4748 Some(State::Closed (
4749 Closed { reason: Some(ConnectionError::ConnectionReset) },
4750 ))
4751 => None; "accepatable rst")]
4752 #[test_case(
4753 Segment::ack(
4754 TEST_ISS + 1, TEST_IRS + 2, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4755 ),
4756 None
4757 => Some(Segment::ack(
4758 TEST_ISS + 1, TEST_IRS + 1, UnscaledWindowSize::from(2), DEFAULT_SEGMENT_OPTIONS
4759 )); "unacceptable ack")]
4760 #[test_case(
4761 Segment::ack(
4762 TEST_IRS + 1, TEST_ISS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4763 ),
4764 None
4765 => None; "pure ack")]
4766 #[test_case(
4767 Segment::fin(
4768 TEST_IRS + 1, TEST_ISS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4769 ),
4770 Some(State::CloseWait(CloseWait {
4771 snd: Send::default_for_test(NullBuffer).into(),
4772 closed_rcv: RecvParams {
4773 ack: TEST_IRS + 2,
4774 wnd: WindowSize::new(1).unwrap(),
4775 wnd_scale: WindowScale::ZERO,
4776 ts_opt: default_ts_opt_state(TEST_IRS + 2),
4777 last_ack_recv: Some(FakeInstant::default()),
4778 },
4779 }))
4780 => Some(
4781 Segment::ack(
4782 TEST_ISS + 1, TEST_IRS + 2, UnscaledWindowSize::from(1), DEFAULT_SEGMENT_OPTIONS
4783 )
4784 ); "pure fin")]
4785 #[test_case(
4786 Segment::piggybacked_fin(
4787 TEST_IRS + 1,
4788 TEST_ISS + 1,
4789 UnscaledWindowSize::from(u16::MAX),
4790 DEFAULT_SEGMENT_OPTIONS,
4791 "A".as_bytes()
4792 ),
4793 Some(State::CloseWait(CloseWait {
4794 snd: Send::default_for_test(NullBuffer).into(),
4795 closed_rcv: RecvParams {
4796 ack: TEST_IRS + 3,
4797 wnd: WindowSize::ZERO,
4798 wnd_scale: WindowScale::ZERO,
4799 ts_opt: default_ts_opt_state(TEST_IRS + 3),
4800 last_ack_recv: Some(FakeInstant::default()),
4801 },
4802 }))
4803 => Some(
4804 Segment::ack(
4805 TEST_ISS + 1, TEST_IRS + 3, UnscaledWindowSize::from(0), DEFAULT_SEGMENT_OPTIONS
4806 )); "fin with 1 byte")]
4807 #[test_case(
4808 Segment::piggybacked_fin(
4809 TEST_IRS + 1,
4810 TEST_ISS + 1,
4811 UnscaledWindowSize::from(u16::MAX),
4812 DEFAULT_SEGMENT_OPTIONS,
4813 "AB".as_bytes()
4814 ),
4815 None
4816 => Some(Segment::ack(
4817 TEST_ISS + 1, TEST_IRS + 3, UnscaledWindowSize::from(0), DEFAULT_SEGMENT_OPTIONS
4818 )); "fin with 2 bytes")]
4819 fn segment_arrives_when_established(
4820 incoming: Segment<&[u8]>,
4821 expected: Option<State<FakeInstant, RingBuffer, NullBuffer, ()>>,
4822 ) -> Option<Segment<()>> {
4823 let counters = FakeTcpCounters::default();
4824 let mut state = State::Established(Established {
4825 snd: Send::default_for_test(NullBuffer).into(),
4826 rcv: Recv::default_for_test(RingBuffer::new(2)).into(),
4827 });
4828 let (seg, passive_open) = state
4829 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4830 incoming,
4831 FakeInstant::default(),
4832 &counters.refs(),
4833 );
4834 assert_eq!(passive_open, None);
4835 match expected {
4836 Some(new_state) => assert_eq!(new_state, state),
4837 None => assert_matches!(state, State::Established(_)),
4838 };
4839 seg
4840 }
4841
4842 #[test]
4843 fn common_rcv_data_segment_arrives() {
4844 let counters = FakeTcpCounters::default();
4845 let new_snd = || Send::default_for_test(NullBuffer);
4848 let new_rcv = || Recv::default_for_test(RingBuffer::new(TEST_BYTES.len()));
4849 for mut state in [
4850 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
4851 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
4852 State::FinWait2(FinWait2 {
4853 last_seq: TEST_ISS + 1,
4854 rcv: new_rcv(),
4855 timeout_at: None,
4856 snd_info: SendInfo::default(),
4857 }),
4858 ] {
4859 assert_eq!(
4860 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
4861 Segment::with_data(
4862 TEST_IRS + 1,
4863 TEST_ISS + 1,
4864 UnscaledWindowSize::from(u16::MAX),
4865 DEFAULT_SEGMENT_OPTIONS,
4866 TEST_BYTES
4867 ),
4868 FakeInstant::default(),
4869 &counters.refs(),
4870 ),
4871 (
4872 Some(Segment::ack(
4873 TEST_ISS + 1,
4874 TEST_IRS + 1 + TEST_BYTES.len(),
4875 UnscaledWindowSize::from(0),
4876 DEFAULT_SEGMENT_OPTIONS
4877 )),
4878 None
4879 )
4880 );
4881 assert_eq!(
4882 state.read_with(|bytes| {
4883 assert_eq!(bytes.concat(), TEST_BYTES);
4884 TEST_BYTES.len()
4885 }),
4886 TEST_BYTES.len()
4887 );
4888 }
4889 }
4890
4891 #[test]
4892 fn common_snd_ack_segment_arrives() {
4893 let counters = FakeTcpCounters::default();
4894 let new_snd = || Send {
4897 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
4898 ..Send::default_for_test(RingBuffer::with_data(TEST_BYTES.len(), TEST_BYTES))
4899 };
4900 let new_rcv = || Recv::default_for_test(NullBuffer);
4901 for mut state in [
4902 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
4903 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
4904 State::Closing(Closing {
4905 snd: new_snd().queue_fin(),
4906 closed_rcv: RecvParams {
4907 ack: TEST_IRS + 1,
4908 wnd: WindowSize::ZERO,
4909 wnd_scale: WindowScale::default(),
4910 ts_opt: default_ts_opt_state(TEST_IRS + 1),
4911 last_ack_recv: Some(FakeInstant::default()),
4912 },
4913 }),
4914 State::CloseWait(CloseWait {
4915 snd: new_snd().into(),
4916 closed_rcv: RecvParams {
4917 ack: TEST_IRS + 1,
4918 wnd: WindowSize::ZERO,
4919 wnd_scale: WindowScale::default(),
4920 ts_opt: default_ts_opt_state(TEST_IRS + 1),
4921 last_ack_recv: Some(FakeInstant::default()),
4922 },
4923 }),
4924 State::LastAck(LastAck {
4925 snd: new_snd().queue_fin(),
4926 closed_rcv: RecvParams {
4927 ack: TEST_IRS + 1,
4928 wnd: WindowSize::ZERO,
4929 wnd_scale: WindowScale::default(),
4930 ts_opt: default_ts_opt_state(TEST_IRS + 1),
4931 last_ack_recv: Some(FakeInstant::default()),
4932 },
4933 }),
4934 ] {
4935 assert_eq!(
4936 state.poll_send_with_default_options(FakeInstant::default(), &counters.refs(),),
4937 Some(Segment::new_assert_no_discard(
4938 SegmentHeader {
4939 seq: TEST_ISS + 1,
4940 ack: Some(TEST_IRS + 1),
4941 control: None,
4942 wnd: UnscaledWindowSize::from(0),
4943 push: true,
4944 options: DEFAULT_SEGMENT_OPTIONS.into(),
4945 },
4946 FragmentedPayload::new_contiguous(TEST_BYTES)
4947 ))
4948 );
4949 assert_eq!(
4950 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
4951 Segment::<()>::ack(
4952 TEST_IRS + 1,
4953 TEST_ISS + 1 + TEST_BYTES.len(),
4954 UnscaledWindowSize::from(u16::MAX),
4955 DEFAULT_SEGMENT_OPTIONS
4956 ),
4957 FakeInstant::default(),
4958 &counters.refs(),
4959 ),
4960 (None, None),
4961 );
4962 assert_eq!(state.poll_send_at(), None);
4963 let snd = match state {
4964 State::Closed(_)
4965 | State::Listen(_)
4966 | State::SynRcvd(_)
4967 | State::SynSent(_)
4968 | State::FinWait2(_)
4969 | State::TimeWait(_) => unreachable!("Unexpected state {:?}", state),
4970 State::Established(e) => e.snd.into_inner().queue_fin(),
4971 State::CloseWait(c) => c.snd.into_inner().queue_fin(),
4972 State::LastAck(l) => l.snd,
4973 State::FinWait1(f) => f.snd.into_inner(),
4974 State::Closing(c) => c.snd,
4975 };
4976 assert_eq!(snd.nxt, TEST_ISS + 1 + TEST_BYTES.len());
4977 assert_eq!(snd.max, TEST_ISS + 1 + TEST_BYTES.len());
4978 assert_eq!(snd.una, TEST_ISS + 1 + TEST_BYTES.len());
4979 assert_eq!(snd.buffer.limits().len, 0);
4980 }
4981 }
4982
4983 #[test_case(
4984 Segment::syn(TEST_IRS + 2, UnscaledWindowSize::from(u16::MAX),
4985 HandshakeOptions {timestamp: Some(DEFAULT_NON_ACK_TS_OPT), ..Default::default()}),
4986 Some(State::Closed (
4987 Closed { reason: Some(ConnectionError::ConnectionReset) },
4988 ))
4989 => Some(Segment::rst(TEST_ISS + 1, ResetOptions {timestamp: Some(DEFAULT_NON_ACK_TS_OPT)})); "syn")]
4990 #[test_case(
4991 Segment::rst(TEST_IRS + 2, ResetOptions::default()),
4992 Some(State::Closed (
4993 Closed { reason: Some(ConnectionError::ConnectionReset) },
4994 ))
4995 => None; "rst")]
4996 #[test_case(
4997 Segment::fin(
4998 TEST_IRS + 2, TEST_ISS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4999 ),
5000 None
5001 => None; "ignore fin")]
5002 #[test_case(
5003 Segment::with_data(
5004 TEST_IRS,
5005 TEST_ISS + 1,
5006 UnscaledWindowSize::from(u16::MAX),
5007 DEFAULT_SEGMENT_OPTIONS,
5008 "a".as_bytes()
5009 ),
5010 None => Some(Segment::ack(
5011 TEST_ISS + 1, TEST_IRS + 2, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
5012 ));
5013 "ack old data")]
5014 #[test_case(
5015 Segment::with_data(
5016 TEST_IRS + 2,
5017 TEST_ISS + 1,
5018 UnscaledWindowSize::from(u16::MAX),
5019 DEFAULT_SEGMENT_OPTIONS,
5020 "Hello".as_bytes()
5021 ),
5022 Some(State::Closed (
5023 Closed { reason: Some(ConnectionError::ConnectionReset) },
5024 ))
5025 => Some(Segment::rst(TEST_ISS + 1, ResetOptions {timestamp: Some(DEFAULT_NON_ACK_TS_OPT)}));
5026 "reset on new data")]
5027 fn segment_arrives_when_close_wait(
5028 incoming: Segment<&[u8]>,
5029 expected: Option<State<FakeInstant, RingBuffer, NullBuffer, ()>>,
5030 ) -> Option<Segment<()>> {
5031 let counters = FakeTcpCounters::default();
5032 let mut state = State::CloseWait(CloseWait {
5033 snd: Send::default_for_test(NullBuffer).into(),
5034 closed_rcv: RecvParams {
5035 ack: TEST_IRS + 2,
5036 wnd: WindowSize::DEFAULT,
5037 wnd_scale: WindowScale::ZERO,
5038 ts_opt: default_ts_opt_state(TEST_IRS + 1),
5039 last_ack_recv: None,
5040 },
5041 });
5042 let (seg, _passive_open) = state
5043 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5044 incoming,
5045 FakeInstant::default(),
5046 &counters.refs(),
5047 );
5048 match expected {
5049 Some(new_state) => assert_eq!(new_state, state),
5050 None => assert_matches!(state, State::CloseWait(_)),
5051 };
5052 seg
5053 }
5054
5055 #[test_case(true; "sack")]
5056 #[test_case(false; "no sack")]
5057 fn active_passive_open(sack_permitted: bool) {
5058 let mut clock = FakeInstantCtx::default();
5059 let counters = FakeTcpCounters::default();
5060 let passive_iss = ISS_2;
5061 let active_iss = ISS_1;
5062 let (syn_sent, syn_seg) = Closed::<Initial>::connect(
5063 active_iss,
5064 TIMESTAMP_OFFSET,
5065 clock.now(),
5066 (),
5067 Default::default(),
5068 DEVICE_MAXIMUM_SEGMENT_SIZE,
5069 Mss::DEFAULT_IPV4,
5070 &SocketOptions::default_for_state_tests(),
5071 );
5072 assert_eq!(
5073 syn_seg,
5074 Segment::syn(
5075 active_iss,
5076 UnscaledWindowSize::from(u16::MAX),
5077 HandshakeOptions {
5078 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
5079 window_scale: Some(WindowScale::default()),
5080 sack_permitted: SACK_PERMITTED,
5082 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
5083 },
5084 )
5085 );
5086 assert_eq!(
5087 syn_sent,
5088 SynSent {
5089 iss: active_iss,
5090 timestamp: Some(clock.now()),
5091 retrans_timer: RetransTimer::new(
5092 clock.now(),
5093 Rto::DEFAULT,
5094 None,
5095 DEFAULT_MAX_SYN_RETRIES,
5096 ),
5097 active_open: (),
5098 buffer_sizes: BufferSizes::default(),
5099 default_mss: Mss::DEFAULT_IPV4,
5100 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
5101 rcv_wnd_scale: WindowScale::default(),
5102 ts_opt: default_ts_opt_negotiation_state(),
5103 }
5104 );
5105 let mut active = State::SynSent(syn_sent);
5106 let mut passive = State::Listen(Closed::<Initial>::listen(
5107 passive_iss,
5108 TIMESTAMP_OFFSET,
5109 Default::default(),
5110 DEVICE_MAXIMUM_SEGMENT_SIZE,
5111 Mss::DEFAULT_IPV4,
5112 None,
5113 ));
5114 clock.sleep(RTT / 2);
5115
5116 let initialized_at = clock.now();
5117
5118 let syn_seg = {
5120 let (mut header, data) = syn_seg.into_parts();
5121 let opt = assert_matches!(&mut header.options, Options::Handshake(o) => o);
5122 opt.sack_permitted = sack_permitted;
5123 Segment::new_assert_no_discard(header, data)
5124 };
5125
5126 let (seg, passive_open) = passive
5127 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5128 syn_seg,
5129 clock.now(),
5130 &counters.refs(),
5131 );
5132 let syn_ack = seg.expect("failed to generate a syn-ack segment");
5133 assert_eq!(passive_open, None);
5134 assert_eq!(
5135 syn_ack,
5136 Segment::syn_ack(
5137 passive_iss,
5138 active_iss + 1,
5139 UnscaledWindowSize::from(u16::MAX),
5140 HandshakeOptions {
5141 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
5142 window_scale: Some(WindowScale::default()),
5143 sack_permitted: SACK_PERMITTED,
5145 timestamp: Some(DEFAULT_ACK_TS_OPT),
5146 },
5147 )
5148 );
5149 assert_matches!(passive, State::SynRcvd(ref syn_rcvd) if syn_rcvd == &SynRcvd {
5150 iss: passive_iss,
5151 irs: active_iss,
5152 timestamp: Some(clock.now()),
5153 retrans_timer: RetransTimer::new(
5154 clock.now(),
5155 Rto::DEFAULT,
5156 None,
5157 DEFAULT_MAX_SYNACK_RETRIES,
5158 ),
5159 simultaneous_open: None,
5160 buffer_sizes: Default::default(),
5161 smss: EffectiveMss::from_mss(
5162 DEVICE_MAXIMUM_SEGMENT_SIZE,
5163 MssSizeLimiters {timestamp_enabled: true}
5164 ),
5165 rcv_wnd_scale: WindowScale::default(),
5166 snd_wnd_scale: Some(WindowScale::default()),
5167 sack_permitted,
5168 rcv: RecvParams {
5169 ack: active_iss + 1,
5170 wnd: WindowSize::DEFAULT,
5171 wnd_scale: WindowScale::default(),
5172 ts_opt: TimestampOptionState::Enabled {
5173 ts_recent: DEFAULT_TIMESTAMP,
5174 last_ack_sent: active_iss + 1,
5175 ts_val: TimestampValueState {
5176 offset: TIMESTAMP_OFFSET,
5177 initialized_at,
5178 },
5179 },
5180 last_ack_recv: None,
5181 },
5182 });
5183 clock.sleep(RTT / 2);
5184
5185 let syn_ack = {
5187 let (mut header, data) = syn_ack.into_parts();
5188 let opt = assert_matches!(&mut header.options, Options::Handshake(o) => o);
5189 opt.sack_permitted = sack_permitted;
5190 Segment::new_assert_no_discard(header, data)
5191 };
5192
5193 let (seg, passive_open) = active
5194 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5195 syn_ack,
5196 clock.now(),
5197 &counters.refs(),
5198 );
5199 let ack_seg = seg.expect("failed to generate a ack segment");
5200 assert_eq!(passive_open, None);
5201 let ts_val = timestamp_now(&clock);
5202 assert_eq!(
5203 ack_seg,
5204 Segment::ack(
5205 active_iss + 1,
5206 passive_iss + 1,
5207 UnscaledWindowSize::from(u16::MAX),
5208 default_segment_options(ts_val, DEFAULT_TIMESTAMP),
5209 )
5210 );
5211 let established = assert_matches!(&active, State::Established(e) => e);
5212 assert_eq!(
5213 established,
5214 &Established {
5215 snd: Send {
5216 wl1: passive_iss,
5217 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
5218 ..Send::default_for_test_at(active_iss + 1, RingBuffer::default())
5219 }
5220 .into(),
5221 rcv: Recv {
5222 remaining_quickacks: default_quickack_counter(),
5223 sack_permitted,
5224 ..Recv::default_for_test_at(passive_iss + 1, RingBuffer::default())
5225 }
5226 .into()
5227 }
5228 );
5229 clock.sleep(RTT / 2);
5230 assert_eq!(
5231 passive.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5232 ack_seg,
5233 clock.now(),
5234 &counters.refs(),
5235 ),
5236 (None, Some(())),
5237 );
5238 let established = assert_matches!(&passive, State::Established(e) => e);
5239 assert_eq!(
5240 established,
5241 &Established {
5242 snd: Send {
5243 wl1: active_iss + 1,
5244 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
5245 ..Send::default_for_test_at(passive_iss + 1, RingBuffer::default())
5246 }
5247 .into(),
5248 rcv: Recv {
5249 remaining_quickacks: default_quickack_counter(),
5250 sack_permitted,
5251 ts_opt: TimestampOptionState::Enabled {
5252 ts_recent: ts_val,
5253 last_ack_sent: active_iss + 1,
5254 ts_val: TimestampValueState { offset: TIMESTAMP_OFFSET, initialized_at },
5255 },
5256 ..Recv::default_for_test_at(active_iss + 1, RingBuffer::default())
5257 }
5258 .into()
5259 }
5260 )
5261 }
5262
5263 #[test]
5264 fn simultaneous_open() {
5265 let mut clock = FakeInstantCtx::default();
5266 let counters = FakeTcpCounters::default();
5267 let (syn_sent1, syn1) = Closed::<Initial>::connect(
5268 ISS_1,
5269 TIMESTAMP_OFFSET,
5270 clock.now(),
5271 (),
5272 Default::default(),
5273 DEVICE_MAXIMUM_SEGMENT_SIZE,
5274 Mss::DEFAULT_IPV4,
5275 &SocketOptions::default_for_state_tests(),
5276 );
5277 let (syn_sent2, syn2) = Closed::<Initial>::connect(
5278 ISS_2,
5279 TIMESTAMP_OFFSET,
5280 clock.now(),
5281 (),
5282 Default::default(),
5283 DEVICE_MAXIMUM_SEGMENT_SIZE,
5284 Mss::DEFAULT_IPV4,
5285 &SocketOptions::default_for_state_tests(),
5286 );
5287
5288 let time1 = timestamp_now(&clock);
5289 assert_eq!(
5290 syn1,
5291 Segment::syn(
5292 ISS_1,
5293 UnscaledWindowSize::from(u16::MAX),
5294 HandshakeOptions {
5295 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
5296 window_scale: Some(WindowScale::default()),
5297 sack_permitted: SACK_PERMITTED,
5298 timestamp: Some(TimestampOption::new(time1, TS_ECHO_REPLY_FOR_NON_ACKS)),
5299 },
5300 )
5301 );
5302 assert_eq!(
5303 syn2,
5304 Segment::syn(
5305 ISS_2,
5306 UnscaledWindowSize::from(u16::MAX),
5307 HandshakeOptions {
5308 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
5309 window_scale: Some(WindowScale::default()),
5310 sack_permitted: SACK_PERMITTED,
5311 timestamp: Some(TimestampOption::new(time1, TS_ECHO_REPLY_FOR_NON_ACKS)),
5312 },
5313 )
5314 );
5315
5316 let mut state1 = State::SynSent(syn_sent1);
5317 let mut state2 = State::SynSent(syn_sent2);
5318
5319 clock.sleep(RTT);
5320 let time2 = timestamp_now(&clock);
5321 let (seg, passive_open) = state1
5322 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5323 syn2,
5324 clock.now(),
5325 &counters.refs(),
5326 );
5327 let syn_ack1 = seg.expect("failed to generate syn ack");
5328 assert_eq!(passive_open, None);
5329 let (seg, passive_open) = state2
5330 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5331 syn1,
5332 clock.now(),
5333 &counters.refs(),
5334 );
5335 let syn_ack2 = seg.expect("failed to generate syn ack");
5336 assert_eq!(passive_open, None);
5337
5338 assert_eq!(
5339 syn_ack1,
5340 Segment::syn_ack(
5341 ISS_1,
5342 ISS_2 + 1,
5343 UnscaledWindowSize::from(u16::MAX),
5344 HandshakeOptions {
5345 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
5346 window_scale: Some(WindowScale::default()),
5347 sack_permitted: SACK_PERMITTED,
5348 timestamp: Some(TimestampOption::new(time2, time1)),
5349 },
5350 )
5351 );
5352 assert_eq!(
5353 syn_ack2,
5354 Segment::syn_ack(
5355 ISS_2,
5356 ISS_1 + 1,
5357 UnscaledWindowSize::from(u16::MAX),
5358 HandshakeOptions {
5359 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
5360 window_scale: Some(WindowScale::default()),
5361 sack_permitted: SACK_PERMITTED,
5362 timestamp: Some(TimestampOption::new(time2, time1)),
5363 },
5364 )
5365 );
5366
5367 assert_matches!(state1, State::SynRcvd(ref syn_rcvd) if syn_rcvd == &SynRcvd {
5368 iss: ISS_1,
5369 irs: ISS_2,
5370 timestamp: Some(clock.now()),
5371 retrans_timer: RetransTimer::new(
5372 clock.now(),
5373 Rto::DEFAULT,
5374 None,
5375 DEFAULT_MAX_SYNACK_RETRIES,
5376 ),
5377 simultaneous_open: Some(()),
5378 buffer_sizes: BufferSizes::default(),
5379 smss: EffectiveMss::from_mss(
5380 DEVICE_MAXIMUM_SEGMENT_SIZE,
5381 MssSizeLimiters{timestamp_enabled: true}
5382 ),
5383 rcv_wnd_scale: WindowScale::default(),
5384 snd_wnd_scale: Some(WindowScale::default()),
5385 sack_permitted: SACK_PERMITTED,
5386 rcv: RecvParams {
5387 ack: ISS_2 + 1,
5388 wnd: WindowSize::DEFAULT,
5389 wnd_scale: WindowScale::default(),
5390 ts_opt: default_ts_opt_state(ISS_2 + 1),
5391 last_ack_recv: None,
5392 },
5393 });
5394 assert_matches!(state2, State::SynRcvd(ref syn_rcvd) if syn_rcvd == &SynRcvd {
5395 iss: ISS_2,
5396 irs: ISS_1,
5397 timestamp: Some(clock.now()),
5398 retrans_timer: RetransTimer::new(
5399 clock.now(),
5400 Rto::DEFAULT,
5401 None,
5402 DEFAULT_MAX_SYNACK_RETRIES,
5403 ),
5404 simultaneous_open: Some(()),
5405 buffer_sizes: BufferSizes::default(),
5406 smss: EffectiveMss::from_mss(
5407 DEVICE_MAXIMUM_SEGMENT_SIZE,
5408 MssSizeLimiters{timestamp_enabled: true}
5409 ),
5410 rcv_wnd_scale: WindowScale::default(),
5411 snd_wnd_scale: Some(WindowScale::default()),
5412 sack_permitted: SACK_PERMITTED,
5413 rcv: RecvParams {
5414 ack: ISS_1 + 1,
5415 wnd: WindowSize::DEFAULT,
5416 wnd_scale: WindowScale::default(),
5417 ts_opt: default_ts_opt_state(ISS_1 + 1),
5418 last_ack_recv: None,
5419 },
5420 });
5421
5422 clock.sleep(RTT);
5423 let time3 = timestamp_now(&clock);
5424 assert_eq!(
5425 state1.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5426 syn_ack2,
5427 clock.now(),
5428 &counters.refs(),
5429 ),
5430 (
5431 Some(Segment::ack(
5432 ISS_1 + 1,
5433 ISS_2 + 1,
5434 UnscaledWindowSize::from(u16::MAX),
5435 default_segment_options(time3, time2),
5436 )),
5437 None
5438 )
5439 );
5440 assert_eq!(
5441 state2.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5442 syn_ack1,
5443 clock.now(),
5444 &counters.refs(),
5445 ),
5446 (
5447 Some(Segment::ack(
5448 ISS_2 + 1,
5449 ISS_1 + 1,
5450 UnscaledWindowSize::from(u16::MAX),
5451 default_segment_options(time3, time2),
5452 )),
5453 None
5454 )
5455 );
5456
5457 let established = assert_matches!(state1, State::Established(e) => e);
5458 assert_eq!(
5459 established,
5460 Established {
5461 snd: Send {
5462 wl1: ISS_2 + 1,
5463 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
5464 congestion_control: CongestionControl::cubic_with_mss(EffectiveMss::from_mss(
5465 Mss::DEFAULT_IPV4,
5466 MssSizeLimiters { timestamp_enabled: true },
5467 )),
5468 ..Send::default_for_test_at(ISS_1 + 1, RingBuffer::default())
5469 }
5470 .into(),
5471 rcv: Recv {
5472 remaining_quickacks: default_quickack_counter() - 1,
5473 last_segment_at: Some(clock.now()),
5474 ts_opt: TimestampOptionState::Enabled {
5475 ts_recent: time2,
5476 last_ack_sent: ISS_2 + 1,
5477 ts_val: TimestampValueState {
5478 offset: TIMESTAMP_OFFSET,
5479 initialized_at: FakeInstant::default(),
5480 }
5481 },
5482 ..Recv::default_for_test_at(ISS_2 + 1, RingBuffer::default())
5483 }
5484 .into()
5485 }
5486 );
5487
5488 let established = assert_matches!(state2, State::Established(e) => e);
5489 assert_eq!(
5490 established,
5491 Established {
5492 snd: Send {
5493 wl1: ISS_1 + 1,
5494 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
5495 congestion_control: CongestionControl::cubic_with_mss(EffectiveMss::from_mss(
5496 Mss::DEFAULT_IPV4,
5497 MssSizeLimiters { timestamp_enabled: true },
5498 )),
5499 ..Send::default_for_test_at(ISS_2 + 1, RingBuffer::default())
5500 }
5501 .into(),
5502 rcv: Recv {
5503 remaining_quickacks: default_quickack_counter() - 1,
5504 last_segment_at: Some(clock.now()),
5505 ts_opt: TimestampOptionState::Enabled {
5506 ts_recent: time2,
5507 last_ack_sent: ISS_1 + 1,
5508 ts_val: TimestampValueState {
5509 offset: TIMESTAMP_OFFSET,
5510 initialized_at: FakeInstant::default(),
5511 }
5512 },
5513 ..Recv::default_for_test_at(ISS_1 + 1, RingBuffer::default())
5514 }
5515 .into()
5516 }
5517 );
5518 }
5519
5520 #[test_case(true; "sack permitted")]
5521 #[test_case(false; "sack not permitted")]
5522 fn established_receive(sack_permitted: bool) {
5523 let clock = FakeInstantCtx::default();
5524 let counters = FakeTcpCounters::default();
5525 let mut established = State::Established(Established {
5526 snd: Send {
5527 wnd: WindowSize::ZERO,
5528 wnd_max: WindowSize::ZERO,
5529 buffer: NullBuffer,
5530 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
5531 ..Send::default_for_test(NullBuffer)
5532 }
5533 .into(),
5534 rcv: Recv {
5535 mss: TEST_MSS,
5536 sack_permitted,
5537 ..Recv::default_for_test(RingBuffer::new(BUFFER_SIZE))
5538 }
5539 .into(),
5540 });
5541
5542 assert_eq!(
5544 established.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5545 Segment::with_data(
5546 TEST_IRS + 1,
5547 TEST_ISS + 1,
5548 UnscaledWindowSize::from(0),
5549 DEFAULT_SEGMENT_OPTIONS,
5550 TEST_BYTES,
5551 ),
5552 clock.now(),
5553 &counters.refs(),
5554 ),
5555 (
5556 Some(Segment::ack(
5557 TEST_ISS + 1,
5558 TEST_IRS + 1 + TEST_BYTES.len(),
5559 UnscaledWindowSize::from((BUFFER_SIZE - TEST_BYTES.len()) as u16),
5560 DEFAULT_SEGMENT_OPTIONS
5561 )),
5562 None
5563 ),
5564 );
5565 assert_eq!(
5566 established.read_with(|available| {
5567 assert_eq!(available, &[TEST_BYTES]);
5568 available[0].len()
5569 }),
5570 TEST_BYTES.len()
5571 );
5572
5573 let segment_start = TEST_IRS + 1 + TEST_BYTES.len() * 2;
5575 assert_eq!(
5576 established.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5577 Segment::with_data(
5578 segment_start,
5579 TEST_ISS + 1,
5580 UnscaledWindowSize::from(0),
5581 DEFAULT_SEGMENT_OPTIONS,
5582 TEST_BYTES,
5583 ),
5584 clock.now(),
5585 &counters.refs()
5586 ),
5587 (
5588 Some(Segment::ack(
5589 TEST_ISS + 1,
5590 TEST_IRS + 1 + TEST_BYTES.len(),
5591 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
5592 SegmentOptions {
5593 sack_blocks: if sack_permitted {
5594 [SackBlock::try_new(
5595 segment_start,
5596 segment_start + u32::try_from(TEST_BYTES.len()).unwrap(),
5597 )
5598 .unwrap()]
5599 .into_iter()
5600 .collect()
5601 } else {
5602 SackBlocks::default()
5603 },
5604 timestamp: Some(DEFAULT_ACK_TS_OPT),
5605 },
5606 )),
5607 None
5608 ),
5609 );
5610 assert_eq!(
5611 established.read_with(|available| {
5612 let empty: &[u8] = &[];
5613 assert_eq!(available, &[empty]);
5614 0
5615 }),
5616 0
5617 );
5618
5619 assert_eq!(
5621 established.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5622 Segment::with_data(
5623 TEST_IRS + 1 + TEST_BYTES.len(),
5624 TEST_ISS + 1,
5625 UnscaledWindowSize::from(0),
5626 DEFAULT_SEGMENT_OPTIONS,
5627 TEST_BYTES,
5628 ),
5629 clock.now(),
5630 &counters.refs()
5631 ),
5632 (
5633 Some(Segment::ack(
5634 TEST_ISS + 1,
5635 TEST_IRS + 1 + 3 * TEST_BYTES.len(),
5636 UnscaledWindowSize::from_usize(BUFFER_SIZE - 2 * TEST_BYTES.len()),
5637 DEFAULT_SEGMENT_OPTIONS
5638 )),
5639 None
5640 ),
5641 );
5642 assert_eq!(
5643 established.read_with(|available| {
5644 assert_eq!(available, &[[TEST_BYTES, TEST_BYTES].concat()]);
5645 available[0].len()
5646 }),
5647 TEST_BYTES.len() * 2
5648 );
5649 }
5650
5651 #[test]
5652 fn established_send() {
5653 let clock = FakeInstantCtx::default();
5654 let counters = FakeTcpCounters::default();
5655 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
5656 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
5658 const PARTIAL_LEN: usize = 10;
5659 assert_eq!(send_buffer.enqueue_data(&TEST_BYTES[..PARTIAL_LEN]), PARTIAL_LEN);
5660 let mut established = State::Established(Established {
5661 snd: Send {
5662 una: TEST_ISS,
5663 wl2: TEST_ISS,
5664 wnd: WindowSize::ZERO,
5665 wnd_max: WindowSize::ZERO,
5666 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
5667 ..Send::default_for_test_at(TEST_ISS + 1, send_buffer)
5668 }
5669 .into(),
5670 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
5671 });
5672 assert_eq!(established.poll_send_with_default_options(clock.now(), &counters.refs()), None);
5674 let open_window = |established: &mut State<FakeInstant, RingBuffer, RingBuffer, ()>,
5675 ack: SeqNum,
5676 win: usize,
5677 now: FakeInstant,
5678 counters: &TcpCountersRefs<'_>| {
5679 assert_eq!(
5680 established.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5681 Segment::ack(
5682 TEST_IRS + 1,
5683 ack,
5684 UnscaledWindowSize::from_usize(win),
5685 DEFAULT_SEGMENT_OPTIONS
5686 ),
5687 now,
5688 counters
5689 ),
5690 (None, None),
5691 );
5692 };
5693 open_window(&mut established, TEST_ISS + 1, 1, clock.now(), &counters.refs());
5695 assert_eq!(
5696 established.poll_send_with_default_options(clock.now(), &counters.refs()),
5697 Some(Segment::with_data(
5698 TEST_ISS + 1,
5699 TEST_IRS + 1,
5700 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5701 DEFAULT_SEGMENT_OPTIONS,
5702 FragmentedPayload::new_contiguous(&TEST_BYTES[1..2]),
5703 ))
5704 );
5705
5706 open_window(
5708 &mut established,
5709 TEST_ISS + 2,
5710 TEST_BYTES.len() + PARTIAL_LEN,
5711 clock.now(),
5712 &counters.refs(),
5713 );
5714 assert_eq!(
5715 established.poll_send_with_default_options(clock.now(), &counters.refs()),
5716 Some(Segment::with_data(
5717 TEST_ISS + 2,
5718 TEST_IRS + 1,
5719 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5720 DEFAULT_SEGMENT_OPTIONS,
5721 FragmentedPayload::new_contiguous(TEST_BYTES),
5722 ))
5723 );
5724
5725 assert_eq!(
5726 established.poll_send(
5727 &FakeStateMachineDebugId::default(),
5728 &counters.refs(),
5729 clock.now(),
5730 &SocketOptions { nagle_enabled: false, ..SocketOptions::default_for_state_tests() }
5731 ),
5732 Ok(Segment::new_assert_no_discard(
5733 SegmentHeader {
5734 seq: TEST_ISS + TEST_BYTES.len() + 2,
5735 ack: Some(TEST_IRS + 1),
5736 control: None,
5737 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
5738 push: true,
5739 options: DEFAULT_SEGMENT_OPTIONS.into(),
5740 },
5741 FragmentedPayload::new_contiguous(&TEST_BYTES[..PARTIAL_LEN - 2]),
5742 ))
5743 );
5744
5745 assert_eq!(established.poll_send_with_default_options(clock.now(), &counters.refs()), None);
5747 }
5748
5749 #[test]
5750 fn self_connect_retransmission() {
5751 let mut clock = FakeInstantCtx::default();
5752 let counters = FakeTcpCounters::default();
5753 let (syn_sent, syn) = Closed::<Initial>::connect(
5754 ISS_1,
5755 TIMESTAMP_OFFSET,
5756 clock.now(),
5757 (),
5758 Default::default(),
5759 *TEST_MSS.mss(),
5760 Mss::DEFAULT_IPV4,
5761 &SocketOptions::default_for_state_tests(),
5762 );
5763
5764 let expected_syn = |ts_val| {
5765 Segment::syn(
5766 ISS_1,
5767 UnscaledWindowSize::from(u16::MAX),
5768 HandshakeOptions {
5769 mss: Some(*TEST_MSS.mss()),
5770 window_scale: Some(WindowScale::default()),
5771 sack_permitted: SACK_PERMITTED,
5772 timestamp: Some(TimestampOption::new(ts_val, TS_ECHO_REPLY_FOR_NON_ACKS)),
5773 },
5774 )
5775 };
5776
5777 let time1 = timestamp_now(&clock);
5778 assert_eq!(syn, expected_syn(time1));
5779 let mut state = State::<_, RingBuffer, RingBuffer, ()>::SynSent(syn_sent);
5780
5781 assert_eq!(state.poll_send_at(), Some(FakeInstant::from(Rto::DEFAULT.get())));
5783 clock.sleep(Rto::DEFAULT.get());
5784 let time2 = timestamp_now(&clock);
5785 assert_eq!(
5787 state.poll_send_with_default_options(clock.now(), &counters.refs()),
5788 Some(expected_syn(time2).into_empty())
5789 );
5790
5791 let (seg, passive_open) = state
5793 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5794 syn,
5795 clock.now(),
5796 &counters.refs(),
5797 );
5798 let syn_ack = seg.expect("expected SYN-ACK");
5799
5800 let expected_syn_ack = |ts_val| {
5801 Segment::syn_ack(
5802 ISS_1,
5803 ISS_1 + 1,
5804 UnscaledWindowSize::from(u16::MAX),
5805 HandshakeOptions {
5806 mss: Some(*TEST_MSS.mss()),
5807 window_scale: Some(WindowScale::default()),
5808 sack_permitted: SACK_PERMITTED,
5809 timestamp: Some(TimestampOption::new(ts_val, time1)),
5810 },
5811 )
5812 };
5813
5814 assert_eq!(syn_ack, expected_syn_ack(time2));
5815 assert_eq!(passive_open, None);
5816 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
5818 clock.sleep(Rto::DEFAULT.get());
5819 let time3 = timestamp_now(&clock);
5820 assert_eq!(
5822 state.poll_send_with_default_options(clock.now(), &counters.refs()),
5823 Some(expected_syn_ack(time3).into_empty())
5824 );
5825
5826 assert_eq!(
5828 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5829 syn_ack,
5830 clock.now(),
5831 &counters.refs(),
5832 ),
5833 (
5834 Some(Segment::ack(
5835 ISS_1 + 1,
5836 ISS_1 + 1,
5837 UnscaledWindowSize::from(u16::MAX),
5838 default_segment_options(time3, time2),
5839 )),
5840 None
5841 )
5842 );
5843 match state {
5844 State::Closed(_)
5845 | State::Listen(_)
5846 | State::SynRcvd(_)
5847 | State::SynSent(_)
5848 | State::LastAck(_)
5849 | State::FinWait1(_)
5850 | State::FinWait2(_)
5851 | State::Closing(_)
5852 | State::TimeWait(_) => {
5853 panic!("expected that we have entered established state, but got {:?}", state)
5854 }
5855 State::Established(Established { ref mut snd, rcv: _ })
5856 | State::CloseWait(CloseWait { ref mut snd, closed_rcv: _ }) => {
5857 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
5858 }
5859 }
5860 assert_eq!(state.poll_send_at(), None);
5862 for i in 0..3 {
5864 assert_eq!(
5865 state.poll_send_with_default_options(clock.now(), &counters.refs()),
5866 Some(Segment::new_assert_no_discard(
5867 SegmentHeader {
5868 seq: ISS_1 + 1,
5869 ack: Some(ISS_1 + 1),
5870 control: None,
5871 wnd: UnscaledWindowSize::from(u16::MAX),
5872 push: true,
5873 options: default_segment_options(timestamp_now(&clock), time2).into(),
5874 },
5875 FragmentedPayload::new_contiguous(TEST_BYTES),
5876 ))
5877 );
5878 assert_eq!(state.poll_send_at(), Some(clock.now() + (1 << i) * Rto::DEFAULT.get()));
5879 clock.sleep((1 << i) * Rto::DEFAULT.get());
5880 CounterExpectations {
5881 retransmits: i,
5882 slow_start_retransmits: i,
5883 timeouts: i,
5884 ..Default::default()
5885 }
5886 .assert_counters(&counters);
5887 }
5888 let time4 = timestamp_now(&clock);
5889 assert_eq!(
5891 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5892 Segment::ack(
5893 ISS_1 + 1 + TEST_BYTES.len(),
5894 ISS_1 + 1 + 1,
5895 UnscaledWindowSize::from(u16::MAX),
5896 default_segment_options(time4, time4),
5897 ),
5898 clock.now(),
5899 &counters.refs(),
5900 ),
5901 (None, None),
5902 );
5903 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
5906 clock.sleep(Rto::DEFAULT.get());
5907 let time5 = timestamp_now(&clock);
5908 assert_eq!(
5909 state.poll_send_with_default_options(clock.now(), &counters.refs(),),
5910 Some(Segment::new_assert_no_discard(
5911 SegmentHeader {
5912 seq: ISS_1 + 1 + 1,
5913 ack: Some(ISS_1 + 1),
5914 wnd: UnscaledWindowSize::from(u16::MAX),
5915 push: true,
5916 options: default_segment_options(time5, time2).into(),
5917 ..Default::default()
5918 },
5919 FragmentedPayload::new_contiguous(&TEST_BYTES[1..]),
5920 ))
5921 );
5922
5923 assert_matches!(
5925 state.on_pmtu_update(Mss::MIN, ISS_1 + TEST_BYTES.len()),
5926 ShouldRetransmit::Yes
5927 );
5928 let new_mss = usize::from(EffectiveMss::from_mss(
5929 Mss::MIN,
5930 MssSizeLimiters { timestamp_enabled: true },
5931 ));
5932 clock.sleep(2 * Rto::DEFAULT.get());
5933 let time6 = timestamp_now(&clock);
5934 assert_eq!(
5935 state.poll_send_with_default_options(clock.now(), &counters.refs(),),
5936 Some(Segment::new_assert_no_discard(
5937 SegmentHeader {
5938 seq: ISS_1 + 1 + 1,
5939 ack: Some(ISS_1 + 1),
5940 wnd: UnscaledWindowSize::from(u16::MAX),
5941 push: false,
5942 options: default_segment_options(time6, time2).into(),
5943 ..Default::default()
5944 },
5945 FragmentedPayload::new_contiguous(&TEST_BYTES[1..new_mss + 1]),
5946 ))
5947 );
5948
5949 assert_eq!(
5955 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5956 Segment::ack(
5957 ISS_1 + 1 + TEST_BYTES.len(),
5958 ISS_1 + new_mss + 2,
5959 UnscaledWindowSize::from(u16::MAX),
5960 default_segment_options(time6, time6),
5961 ),
5962 clock.now(),
5963 &counters.refs(),
5964 ),
5965 (None, None)
5966 );
5967
5968 CounterExpectations {
5969 retransmits: 4,
5970 slow_start_retransmits: 4,
5971 timeouts: 4,
5972 ..Default::default()
5973 }
5974 .assert_counters(&counters);
5975
5976 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
5979 assert_eq!(
5980 state.poll_send_with_default_options(clock.now(), &counters.refs()),
5981 Some(Segment::new_assert_no_discard(
5982 SegmentHeader {
5983 seq: ISS_1 + new_mss + 2,
5984 ack: Some(ISS_1 + 1),
5985 wnd: UnscaledWindowSize::from(u16::MAX),
5986 push: true,
5987 options: default_segment_options(time6, time2).into(),
5988 ..Default::default()
5989 },
5990 FragmentedPayload::new_contiguous(&TEST_BYTES[new_mss + 1..]),
5991 ))
5992 );
5993
5994 assert_eq!(
5996 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5997 Segment::ack(
5998 ISS_1 + 1 + TEST_BYTES.len(),
5999 ISS_1 + 1 + TEST_BYTES.len(),
6000 UnscaledWindowSize::from(u16::MAX),
6001 default_segment_options(time6, time6),
6002 ),
6003 clock.now(),
6004 &counters.refs()
6005 ),
6006 (None, None)
6007 );
6008 assert_eq!(state.poll_send_at(), None);
6010 }
6011
6012 #[test]
6013 fn passive_close() {
6014 let mut clock = FakeInstantCtx::default();
6015 let counters = FakeTcpCounters::default();
6016 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
6017 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
6019 const PARTIAL_LEN: usize = 10;
6020 assert_eq!(send_buffer.enqueue_data(&TEST_BYTES[..PARTIAL_LEN]), PARTIAL_LEN);
6021 let mut state = State::Established(Established {
6023 snd: Send {
6024 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
6025 ..Send::default_for_test(send_buffer.clone())
6026 }
6027 .into(),
6028 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
6029 });
6030 let last_wnd = WindowSize::new(BUFFER_SIZE - 1).unwrap();
6031 let last_wnd_scale = WindowScale::default();
6032 assert_eq!(
6034 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6035 Segment::fin(
6036 TEST_IRS + 1,
6037 TEST_ISS + 1,
6038 UnscaledWindowSize::from(u16::MAX),
6039 DEFAULT_SEGMENT_OPTIONS
6040 ),
6041 clock.now(),
6042 &counters.refs(),
6043 ),
6044 (
6045 Some(Segment::ack(
6046 TEST_ISS + 1,
6047 TEST_IRS + 2,
6048 UnscaledWindowSize::from_usize(BUFFER_SIZE - 1),
6049 DEFAULT_SEGMENT_OPTIONS
6050 )),
6051 None
6052 )
6053 );
6054 assert_eq!(
6056 state.close(
6057 &counters.refs(),
6058 CloseReason::Shutdown,
6059 &SocketOptions::default_for_state_tests()
6060 ),
6061 Ok(NewlyClosed::No)
6062 );
6063 assert_eq!(
6064 state,
6065 State::LastAck(LastAck {
6066 snd: Send::default_for_test(send_buffer),
6067 closed_rcv: RecvParams {
6068 ack: TEST_IRS + 2,
6069 wnd: last_wnd,
6070 wnd_scale: last_wnd_scale,
6071 ts_opt: default_ts_opt_state(TEST_IRS + 2),
6072 last_ack_recv: Some(FakeInstant::default()),
6073 },
6074 })
6075 );
6076 assert_eq!(
6078 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6079 Some(Segment::with_data(
6080 TEST_ISS + 1,
6081 TEST_IRS + 2,
6082 last_wnd >> WindowScale::default(),
6083 DEFAULT_SEGMENT_OPTIONS,
6084 FragmentedPayload::new_contiguous(TEST_BYTES),
6085 ))
6086 );
6087 assert_eq!(
6089 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6090 Some(Segment::new_assert_no_discard(
6091 SegmentHeader {
6092 seq: TEST_ISS + TEST_BYTES.len() + 1,
6093 ack: Some(TEST_IRS + 2),
6094 control: Some(Control::FIN),
6095 wnd: last_wnd >> WindowScale::default(),
6096 push: true,
6097 options: DEFAULT_SEGMENT_OPTIONS.into(),
6098 },
6099 FragmentedPayload::new_contiguous(&TEST_BYTES[..PARTIAL_LEN]),
6100 ))
6101 );
6102 clock.sleep(RTT);
6104 assert_eq!(
6105 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6106 Segment::ack(
6107 TEST_IRS + 2,
6108 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 1,
6109 UnscaledWindowSize::from(u16::MAX),
6110 DEFAULT_SEGMENT_OPTIONS
6111 ),
6112 clock.now(),
6113 &counters.refs(),
6114 ),
6115 (None, None)
6116 );
6117 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
6118 clock.sleep(Rto::DEFAULT.get());
6119 assert_eq!(
6121 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6122 Some(Segment::fin(
6123 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 1,
6124 TEST_IRS + 2,
6125 last_wnd >> WindowScale::default(),
6126 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6127 ))
6128 );
6129
6130 assert_eq!(
6132 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6133 Segment::ack(
6134 TEST_IRS + 2,
6135 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 2,
6136 UnscaledWindowSize::from(u16::MAX),
6137 DEFAULT_SEGMENT_OPTIONS
6138 ),
6139 clock.now(),
6140 &counters.refs(),
6141 ),
6142 (None, None)
6143 );
6144 assert_eq!(state, State::Closed(Closed { reason: None }));
6146 CounterExpectations {
6147 retransmits: 1,
6148 slow_start_retransmits: 1,
6149 timeouts: 1,
6150 established_closed: 1,
6151 ..Default::default()
6152 }
6153 .assert_counters(&counters);
6154 }
6155
6156 #[test]
6157 fn syn_rcvd_active_close() {
6158 let counters = FakeTcpCounters::default();
6159 let mut state: State<_, RingBuffer, NullBuffer, ()> = State::SynRcvd(SynRcvd {
6160 iss: TEST_ISS,
6161 irs: TEST_IRS,
6162 timestamp: None,
6163 retrans_timer: RetransTimer {
6164 at: FakeInstant::default(),
6165 rto: Rto::MIN,
6166 user_timeout_until: None,
6167 remaining_retries: Some(DEFAULT_MAX_RETRIES),
6168 },
6169 simultaneous_open: Some(()),
6170 buffer_sizes: Default::default(),
6171 smss: EffectiveMss::from_mss(
6172 Mss::DEFAULT_IPV4,
6173 MssSizeLimiters { timestamp_enabled: true },
6174 ),
6175 rcv_wnd_scale: WindowScale::default(),
6176 snd_wnd_scale: Some(WindowScale::default()),
6177 sack_permitted: SACK_PERMITTED,
6178 rcv: RecvParams {
6179 ack: TEST_IRS + 1,
6180 wnd: WindowSize::DEFAULT,
6181 wnd_scale: WindowScale::default(),
6182 ts_opt: default_ts_opt_state(TEST_IRS + 1),
6183 last_ack_recv: None,
6184 },
6185 });
6186 assert_eq!(
6187 state.close(
6188 &counters.refs(),
6189 CloseReason::Shutdown,
6190 &SocketOptions::default_for_state_tests()
6191 ),
6192 Ok(NewlyClosed::No)
6193 );
6194 assert_matches!(state, State::FinWait1(_));
6195 assert_eq!(
6196 state.poll_send_with_default_options(FakeInstant::default(), &counters.refs()),
6197 Some(Segment::fin(
6198 TEST_ISS + 1,
6199 TEST_IRS + 1,
6200 UnscaledWindowSize::from(u16::MAX),
6201 DEFAULT_SEGMENT_OPTIONS
6202 ))
6203 );
6204 }
6205
6206 #[test]
6207 fn established_active_close() {
6208 let mut clock = FakeInstantCtx::default();
6209 let counters = FakeTcpCounters::default();
6210 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
6211 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
6213 const PARTIAL_LEN: usize = 10;
6214 assert_eq!(send_buffer.enqueue_data(&TEST_BYTES[..PARTIAL_LEN]), PARTIAL_LEN);
6215 let mut state = State::Established(Established {
6217 snd: Send {
6218 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
6219 ..Send::default_for_test(send_buffer.clone())
6220 }
6221 .into(),
6222 rcv: Recv { mss: TEST_MSS, ..Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)) }
6223 .into(),
6224 });
6225 assert_eq!(
6226 state.close(
6227 &counters.refs(),
6228 CloseReason::Shutdown,
6229 &SocketOptions::default_for_state_tests()
6230 ),
6231 Ok(NewlyClosed::No)
6232 );
6233 assert_matches!(state, State::FinWait1(_));
6234 assert_eq!(
6235 state.close(
6236 &counters.refs(),
6237 CloseReason::Shutdown,
6238 &SocketOptions::default_for_state_tests()
6239 ),
6240 Err(CloseError::Closing)
6241 );
6242
6243 assert_eq!(
6245 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6246 Some(Segment::with_data(
6247 TEST_ISS + 1,
6248 TEST_IRS + 1,
6249 UnscaledWindowSize::from_usize(BUFFER_SIZE),
6250 DEFAULT_SEGMENT_OPTIONS,
6251 FragmentedPayload::new_contiguous(TEST_BYTES)
6252 ))
6253 );
6254
6255 assert_eq!(
6257 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6258 Some(Segment::new_assert_no_discard(
6259 SegmentHeader {
6260 seq: TEST_ISS + 1 + TEST_BYTES.len(),
6261 ack: Some(TEST_IRS + 1),
6262 control: Some(Control::FIN),
6263 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
6264 push: true,
6265 options: DEFAULT_SEGMENT_OPTIONS.into(),
6266 },
6267 FragmentedPayload::new_contiguous(&TEST_BYTES[..PARTIAL_LEN])
6268 ))
6269 );
6270
6271 assert_eq!(
6273 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
6274 Segment::with_data(
6275 TEST_IRS + 1,
6276 TEST_ISS + TEST_BYTES.len() + 1,
6277 UnscaledWindowSize::from(u16::MAX),
6278 DEFAULT_SEGMENT_OPTIONS,
6279 TEST_BYTES
6280 ),
6281 clock.now(),
6282 &counters.refs(),
6283 ),
6284 (
6285 Some(Segment::ack(
6286 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 2,
6287 TEST_IRS + TEST_BYTES.len() + 1,
6288 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len()),
6289 DEFAULT_SEGMENT_OPTIONS
6290 )),
6291 None
6292 )
6293 );
6294
6295 assert_eq!(
6296 state.read_with(|avail| {
6297 let got = avail.concat();
6298 assert_eq!(got, TEST_BYTES);
6299 got.len()
6300 }),
6301 TEST_BYTES.len()
6302 );
6303
6304 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
6306
6307 clock.sleep(Rto::DEFAULT.get());
6310 assert_eq!(
6311 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6312 Some(Segment::new_assert_no_discard(
6313 SegmentHeader {
6314 seq: TEST_ISS + TEST_BYTES.len() + 1,
6315 ack: Some(TEST_IRS + TEST_BYTES.len() + 1),
6316 control: Some(Control::FIN),
6317 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
6318 push: true,
6319 options: default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP)
6320 .into(),
6321 },
6322 FragmentedPayload::new_contiguous(&TEST_BYTES[..PARTIAL_LEN]),
6323 ))
6324 );
6325
6326 assert_eq!(
6328 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6329 Segment::ack(
6330 TEST_IRS + TEST_BYTES.len() + 1,
6331 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 2,
6332 UnscaledWindowSize::from(u16::MAX),
6333 DEFAULT_SEGMENT_OPTIONS
6334 ),
6335 clock.now(),
6336 &counters.refs(),
6337 ),
6338 (None, None)
6339 );
6340 assert_matches!(state, State::FinWait2(_));
6341
6342 assert_eq!(
6344 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
6345 Segment::with_data(
6346 TEST_IRS + TEST_BYTES.len() + 1,
6347 TEST_ISS + TEST_BYTES.len() + 2,
6348 UnscaledWindowSize::from(u16::MAX),
6349 DEFAULT_SEGMENT_OPTIONS,
6350 TEST_BYTES
6351 ),
6352 clock.now(),
6353 &counters.refs(),
6354 ),
6355 (
6356 Some(Segment::ack(
6357 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 2,
6358 TEST_IRS + 2 * TEST_BYTES.len() + 1,
6359 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len()),
6360 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6361 )),
6362 None
6363 )
6364 );
6365
6366 assert_eq!(
6367 state.read_with(|avail| {
6368 let got = avail.concat();
6369 assert_eq!(got, TEST_BYTES);
6370 got.len()
6371 }),
6372 TEST_BYTES.len()
6373 );
6374
6375 assert_eq!(
6377 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6378 Segment::fin(
6379 TEST_IRS + 2 * TEST_BYTES.len() + 1,
6380 TEST_ISS + TEST_BYTES.len() + 2,
6381 UnscaledWindowSize::from(u16::MAX),
6382 DEFAULT_SEGMENT_OPTIONS
6383 ),
6384 clock.now(),
6385 &counters.refs(),
6386 ),
6387 (
6388 Some(Segment::ack(
6389 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 2,
6390 TEST_IRS + 2 * TEST_BYTES.len() + 2,
6391 UnscaledWindowSize::from_usize(BUFFER_SIZE - 1),
6392 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6393 )),
6394 None
6395 )
6396 );
6397
6398 assert_matches!(state, State::TimeWait(_));
6399
6400 const SMALLEST_DURATION: Duration = Duration::from_secs(1);
6401 assert_eq!(state.poll_send_at(), Some(clock.now() + MSL * 2));
6402 clock.sleep(MSL * 2 - SMALLEST_DURATION);
6403 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
6405 assert_matches!(state, State::TimeWait(_));
6406 clock.sleep(SMALLEST_DURATION);
6407 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
6409 assert_eq!(state, State::Closed(Closed { reason: None }));
6410 CounterExpectations {
6411 retransmits: 1,
6412 slow_start_retransmits: 1,
6413 timeouts: 1,
6414 established_closed: 1,
6415 ..Default::default()
6416 }
6417 .assert_counters(&counters);
6418 }
6419
6420 #[test]
6421 fn fin_wait_1_fin_ack_to_time_wait() {
6422 let counters = FakeTcpCounters::default();
6423 let mut state = State::FinWait1(FinWait1 {
6426 snd: Send { una: TEST_ISS + 1, ..Send::default_for_test_at(TEST_ISS + 2, NullBuffer) }
6427 .into(),
6428 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
6429 });
6430 assert_eq!(
6431 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6432 Segment::fin(
6433 TEST_IRS + 1,
6434 TEST_ISS + 2,
6435 UnscaledWindowSize::from(u16::MAX),
6436 DEFAULT_SEGMENT_OPTIONS
6437 ),
6438 FakeInstant::default(),
6439 &counters.refs(),
6440 ),
6441 (
6442 Some(Segment::ack(
6443 TEST_ISS + 2,
6444 TEST_IRS + 2,
6445 UnscaledWindowSize::from_usize(BUFFER_SIZE - 1),
6446 DEFAULT_SEGMENT_OPTIONS
6447 )),
6448 None
6449 ),
6450 );
6451 assert_matches!(state, State::TimeWait(_));
6452 }
6453
6454 #[test]
6455 fn simultaneous_close() {
6456 let mut clock = FakeInstantCtx::default();
6457 let counters = FakeTcpCounters::default();
6458 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
6459 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
6460
6461 let iss = ISS_1;
6462 let mut state = State::Established(Established {
6464 snd: Send::default_for_test_at(iss + 1, send_buffer.clone()).into(),
6465 rcv: Recv::default_for_test_at(iss + 1, RingBuffer::new(BUFFER_SIZE)).into(),
6466 });
6467 assert_eq!(
6468 state.close(
6469 &counters.refs(),
6470 CloseReason::Shutdown,
6471 &SocketOptions::default_for_state_tests()
6472 ),
6473 Ok(NewlyClosed::No)
6474 );
6475 assert_matches!(state, State::FinWait1(_));
6476 assert_eq!(
6477 state.close(
6478 &counters.refs(),
6479 CloseReason::Shutdown,
6480 &SocketOptions::default_for_state_tests()
6481 ),
6482 Err(CloseError::Closing)
6483 );
6484
6485 let fin = state.poll_send_with_default_options(clock.now(), &counters.refs());
6486 assert_eq!(
6487 fin,
6488 Some(Segment::new_assert_no_discard(
6489 SegmentHeader {
6490 seq: iss + 1,
6491 ack: Some(iss + 1),
6492 control: Some(Control::FIN),
6493 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
6494 push: true,
6495 options: DEFAULT_SEGMENT_OPTIONS.into(),
6496 },
6497 FragmentedPayload::new_contiguous(TEST_BYTES),
6498 ))
6499 );
6500 assert_eq!(
6501 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
6502 Segment::piggybacked_fin(
6503 iss + 1,
6504 iss + 1,
6505 UnscaledWindowSize::from_usize(BUFFER_SIZE),
6506 DEFAULT_SEGMENT_OPTIONS,
6507 TEST_BYTES,
6508 ),
6509 clock.now(),
6510 &counters.refs(),
6511 ),
6512 (
6513 Some(Segment::ack(
6514 iss + TEST_BYTES.len() + 2,
6515 iss + TEST_BYTES.len() + 2,
6516 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len() - 1),
6517 DEFAULT_SEGMENT_OPTIONS
6518 )),
6519 None
6520 )
6521 );
6522
6523 assert_matches!(state, State::Closing(_));
6526 assert_eq!(
6527 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6528 Segment::ack(
6529 iss + TEST_BYTES.len() + 2,
6530 iss + TEST_BYTES.len() + 2,
6531 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len() - 1),
6532 DEFAULT_SEGMENT_OPTIONS
6533 ),
6534 clock.now(),
6535 &counters.refs(),
6536 ),
6537 (None, None)
6538 );
6539
6540 assert_matches!(state, State::TimeWait(_));
6543
6544 const SMALLEST_DURATION: Duration = Duration::from_secs(1);
6545 assert_eq!(state.poll_send_at(), Some(clock.now() + MSL * 2));
6546 clock.sleep(MSL * 2 - SMALLEST_DURATION);
6547 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
6549 assert_matches!(state, State::TimeWait(_));
6550 clock.sleep(SMALLEST_DURATION);
6551 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
6553 assert_eq!(state, State::Closed(Closed { reason: None }));
6554 CounterExpectations { established_closed: 1, ..Default::default() }
6555 .assert_counters(&counters);
6556 }
6557
6558 #[test]
6559 fn time_wait_restarts_timer() {
6560 let mut clock = FakeInstantCtx::default();
6561 let counters = FakeTcpCounters::default();
6562 let mut time_wait = State::<_, NullBuffer, NullBuffer, ()>::TimeWait(TimeWait {
6563 last_seq: TEST_ISS + 2,
6564 closed_rcv: RecvParams {
6565 ack: TEST_IRS + 2,
6566 wnd: WindowSize::DEFAULT,
6567 wnd_scale: WindowScale::default(),
6568 ts_opt: default_ts_opt_state(TEST_IRS + 1),
6569 last_ack_recv: None,
6570 },
6571 expiry: new_time_wait_expiry(clock.now()),
6572 snd_info: SendInfo::default(),
6573 });
6574
6575 assert_eq!(time_wait.poll_send_at(), Some(clock.now() + MSL * 2));
6576 clock.sleep(Duration::from_secs(1));
6577 assert_eq!(
6578 time_wait.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6579 Segment::fin(
6580 TEST_IRS + 2,
6581 TEST_ISS + 2,
6582 UnscaledWindowSize::from(u16::MAX),
6583 DEFAULT_SEGMENT_OPTIONS
6584 ),
6585 clock.now(),
6586 &counters.refs(),
6587 ),
6588 (
6589 Some(Segment::ack(
6590 TEST_ISS + 2,
6591 TEST_IRS + 2,
6592 UnscaledWindowSize::from(u16::MAX),
6593 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6594 )),
6595 None
6596 ),
6597 );
6598 assert_eq!(time_wait.poll_send_at(), Some(clock.now() + MSL * 2));
6599 }
6600
6601 #[test_case(
6602 State::Established(Established {
6603 snd: Send::default_for_test_at(TEST_ISS, NullBuffer).into(),
6604 rcv: Recv::default_for_test_at(TEST_IRS + u32::from(TEST_MSS), RingBuffer::default()).into(),
6605 }),
6606 Segment::with_data(
6607 TEST_IRS,
6608 TEST_ISS,
6609 UnscaledWindowSize::from(u16::MAX),
6610 DEFAULT_SEGMENT_OPTIONS,
6611 TEST_BYTES
6612 ) => Some(Segment::ack(
6613 TEST_ISS,
6614 TEST_IRS + u32::from(TEST_MSS),
6615 UnscaledWindowSize::from(u16::MAX),
6616 DEFAULT_SEGMENT_OPTIONS
6617 ));
6618 "retransmit data"
6619 )]
6620 #[test_case(
6621 State::SynRcvd(SynRcvd {
6622 iss: TEST_ISS,
6623 irs: TEST_IRS,
6624 timestamp: None,
6625 retrans_timer: RetransTimer {
6626 at: FakeInstant::default(),
6627 rto: Rto::MIN,
6628 user_timeout_until: None,
6629 remaining_retries: Some(DEFAULT_MAX_RETRIES),
6630 },
6631 simultaneous_open: None,
6632 buffer_sizes: BufferSizes::default(),
6633 smss: EffectiveMss::from_mss(
6634 Mss::DEFAULT_IPV4, MssSizeLimiters {timestamp_enabled: true }
6635 ),
6636 rcv_wnd_scale: WindowScale::default(),
6637 snd_wnd_scale: Some(WindowScale::default()),
6638 sack_permitted: SACK_PERMITTED,
6639 rcv: RecvParams {
6640 ack: TEST_IRS + 1,
6641 wnd: WindowSize::DEFAULT,
6642 wnd_scale: WindowScale::default(),
6643 ts_opt: default_ts_opt_state(TEST_IRS+1),
6644 last_ack_recv: None
6645 },
6646 }),
6647 Segment::syn_ack(
6648 TEST_IRS,
6649 TEST_ISS + 1,
6650 UnscaledWindowSize::from(u16::MAX),
6651 HandshakeOptions {
6652 window_scale: Some(WindowScale::default()),
6653 timestamp: Some(DEFAULT_ACK_TS_OPT),
6654 ..Default::default()
6655 }) =>
6656 Some(Segment::ack(
6657 TEST_ISS + 1, TEST_IRS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
6658 )); "retransmit syn_ack"
6659 )]
6660 fn ack_to_retransmitted_segment(
6662 mut state: State<FakeInstant, RingBuffer, NullBuffer, ()>,
6663 seg: Segment<&[u8]>,
6664 ) -> Option<Segment<()>> {
6665 let counters = FakeTcpCounters::default();
6666 let (reply, _): (_, Option<()>) = state
6667 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
6668 seg,
6669 FakeInstant::default(),
6670 &counters.refs(),
6671 );
6672 reply
6673 }
6674
6675 #[test]
6676 fn fast_retransmit() {
6677 let mut clock = FakeInstantCtx::default();
6678 let counters = FakeTcpCounters::default();
6679 let mut send_buffer = RingBuffer::default();
6680 let mss =
6681 EffectiveMss::from_mss(Mss::DEFAULT_IPV4, MssSizeLimiters { timestamp_enabled: true });
6682
6683 let first_payload_byte = b'A';
6684 let last_payload_byte = b'D';
6685
6686 for b in first_payload_byte..=last_payload_byte {
6687 assert_eq!(send_buffer.enqueue_data(&vec![b; usize::from(mss)]), usize::from(mss));
6688 }
6689 let mut state: State<_, _, _, ()> = State::Established(Established {
6690 snd: Send {
6691 congestion_control: CongestionControl::cubic_with_mss(EffectiveMss::from_mss(
6692 Mss::DEFAULT_IPV4,
6693 MssSizeLimiters { timestamp_enabled: true },
6694 )),
6695 ..Send::default_for_test_at(TEST_ISS, send_buffer.clone())
6696 }
6697 .into(),
6698 rcv: Recv::default_for_test_at(TEST_IRS, RingBuffer::default()).into(),
6699 });
6700
6701 assert_eq!(
6702 state.poll_send_with_default_options(clock.now(), &counters.refs(),),
6703 Some(Segment::with_data(
6704 TEST_ISS,
6705 TEST_IRS,
6706 UnscaledWindowSize::from(u16::MAX),
6707 DEFAULT_SEGMENT_OPTIONS,
6708 FragmentedPayload::new_contiguous(&vec![b'A'; usize::from(mss)])
6709 ))
6710 );
6711
6712 let mut dup_ack = |expected_byte: u8, counters: &TcpCountersRefs<'_>| {
6713 clock.sleep(Duration::from_millis(10));
6714 assert_eq!(
6715 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6716 Segment::ack(
6717 TEST_IRS,
6718 TEST_ISS,
6719 UnscaledWindowSize::from(u16::MAX),
6720 DEFAULT_SEGMENT_OPTIONS
6721 ),
6722 clock.now(),
6723 counters,
6724 ),
6725 (None, None)
6726 );
6727
6728 assert_eq!(
6729 state.poll_send_with_default_options(clock.now(), counters,),
6730 Some(Segment::new_assert_no_discard(
6731 SegmentHeader {
6732 seq: TEST_ISS
6733 + u32::from(expected_byte - first_payload_byte) * u32::from(mss),
6734 ack: Some(TEST_IRS),
6735 control: None,
6736 wnd: UnscaledWindowSize::from(u16::MAX),
6737 push: expected_byte == last_payload_byte,
6738 options: default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP)
6739 .into(),
6740 },
6741 FragmentedPayload::new_contiguous(&vec![expected_byte; usize::from(mss)])
6742 ))
6743 );
6744 };
6745
6746 CounterExpectations::default().assert_counters(&counters);
6749 dup_ack(b'B', &counters.refs());
6750 CounterExpectations { fast_recovery: 0, dup_acks: 1, ..Default::default() }
6751 .assert_counters(&counters);
6752 dup_ack(b'C', &counters.refs());
6753 CounterExpectations { fast_recovery: 0, dup_acks: 2, ..Default::default() }
6754 .assert_counters(&counters);
6755 dup_ack(b'A', &counters.refs());
6758 CounterExpectations {
6759 retransmits: 1,
6760 fast_recovery: 1,
6761 fast_retransmits: 1,
6762 dup_acks: 3,
6763 ..Default::default()
6764 }
6765 .assert_counters(&counters);
6766 dup_ack(b'D', &counters.refs());
6768 CounterExpectations {
6769 retransmits: 1,
6770 fast_recovery: 1,
6771 fast_retransmits: 1,
6772 dup_acks: 4,
6773 ..Default::default()
6774 }
6775 .assert_counters(&counters);
6776
6777 clock.sleep(Duration::from_millis(10));
6779 assert_eq!(
6780 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6781 Segment::ack(
6782 TEST_IRS,
6783 TEST_ISS + u32::from(Mss::DEFAULT_IPV4),
6784 UnscaledWindowSize::from(u16::MAX),
6785 DEFAULT_SEGMENT_OPTIONS
6786 ),
6787 clock.now(),
6788 &counters.refs(),
6789 ),
6790 (None, None)
6791 );
6792 let established = assert_matches!(state, State::Established(established) => established);
6793 assert_eq!(established.snd.congestion_control.inspect_cwnd().cwnd(), 2 * u32::from(mss));
6794 assert_eq!(established.snd.congestion_control.inspect_loss_recovery_mode(), None);
6795 CounterExpectations {
6796 retransmits: 1,
6797 fast_recovery: 1,
6798 fast_retransmits: 1,
6799 dup_acks: 4,
6800 loss_recovered: 1,
6801 ..Default::default()
6802 }
6803 .assert_counters(&counters);
6804 }
6805
6806 #[test_case(true; "user timeout")]
6807 #[test_case(false; "no user timeout")]
6808 fn keep_alive(with_user_timeout: bool) {
6809 let mut clock = FakeInstantCtx::default();
6810 let counters = FakeTcpCounters::default();
6811 let mut state: State<_, _, _, ()> = State::Established(Established {
6812 snd: Send::default_for_test_at(TEST_ISS, RingBuffer::default()).into(),
6813 rcv: Recv::default_for_test_at(TEST_IRS, RingBuffer::default()).into(),
6814 });
6815
6816 let keep_alive = KeepAlive { enabled: true, ..Default::default() };
6817 let num_probes_user_timeout = 3;
6818 let user_timeout_duration = keep_alive
6820 .interval
6821 .saturating_mul(NonZeroU32::new(num_probes_user_timeout - 1).unwrap())
6822 + NonZeroDuration::new(keep_alive.interval.get() / 2).unwrap();
6823 let socket_options = SocketOptions {
6824 keep_alive,
6825 user_timeout: with_user_timeout.then_some(user_timeout_duration),
6826 ..SocketOptions::default_for_state_tests()
6827 };
6828 let socket_options = &socket_options;
6829 let keep_alive = &socket_options.keep_alive;
6830
6831 assert_eq!(
6833 state.poll_send(
6834 &FakeStateMachineDebugId::default(),
6835 &counters.refs(),
6836 clock.now(),
6837 socket_options,
6838 ),
6839 Err(NewlyClosed::No),
6840 );
6841 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(keep_alive.idle.into())));
6844
6845 clock.sleep(keep_alive.idle.get() / 2);
6847 assert_eq!(
6848 state.on_segment::<&[u8], ClientlessBufferProvider>(
6849 &FakeStateMachineDebugId::default(),
6850 &counters.refs(),
6851 Segment::ack(
6852 TEST_IRS,
6853 TEST_ISS,
6854 UnscaledWindowSize::from(u16::MAX),
6855 DEFAULT_SEGMENT_OPTIONS
6856 ),
6857 clock.now(),
6858 socket_options,
6859 false, ),
6861 (None, None, DataAcked::No, NewlyClosed::No)
6862 );
6863 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(keep_alive.idle.into())),);
6865 clock.sleep(keep_alive.idle.into());
6866
6867 let (expect_probes, max_deadline) = if with_user_timeout {
6870 assert!(num_probes_user_timeout < keep_alive.count.get().into());
6872 (num_probes_user_timeout, clock.time + user_timeout_duration.get())
6873 } else {
6874 (u32::from(keep_alive.count.get()), FakeInstant::LATEST)
6875 };
6876 for _ in 0..expect_probes {
6877 assert_eq!(
6878 state.poll_send(
6879 &FakeStateMachineDebugId::default(),
6880 &counters.refs(),
6881 clock.now(),
6882 socket_options,
6883 ),
6884 Ok(Segment::ack(
6885 TEST_ISS - 1,
6886 TEST_IRS,
6887 UnscaledWindowSize::from(u16::MAX),
6888 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6889 ))
6890 );
6891 assert_matches!(state, State::Established(_));
6892 let next = state.poll_send_at().expect("timer must be set");
6893 assert_eq!(next, (clock.time + keep_alive.interval.get()).min(max_deadline));
6894 clock.sleep_until(next);
6895 }
6896
6897 assert_eq!(
6900 state.poll_send(
6901 &FakeStateMachineDebugId::default(),
6902 &counters.refs(),
6903 clock.now(),
6904 socket_options,
6905 ),
6906 Err(NewlyClosed::Yes),
6907 );
6908 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
6909 CounterExpectations {
6910 established_closed: 1,
6911 established_timedout: 1,
6912 ..Default::default()
6913 }
6914 .assert_counters(&counters);
6915 }
6916
6917 #[derive(Debug)]
6919 struct ReservingBuffer<B> {
6920 buffer: B,
6921 reserved_bytes: usize,
6922 }
6923
6924 impl<B: Buffer> Buffer for ReservingBuffer<B> {
6925 fn limits(&self) -> BufferLimits {
6926 self.buffer.limits()
6927 }
6928
6929 fn target_capacity(&self) -> usize {
6930 self.buffer.target_capacity()
6931 }
6932
6933 fn request_capacity(&mut self, size: usize) {
6934 self.buffer.request_capacity(size)
6935 }
6936 }
6937
6938 impl<B: SendBuffer> SendBuffer for ReservingBuffer<B> {
6939 type Payload<'a> = B::Payload<'a>;
6940
6941 fn mark_read(&mut self, count: usize) {
6942 self.buffer.mark_read(count)
6943 }
6944
6945 fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
6946 where
6947 F: FnOnce(B::Payload<'a>) -> R,
6948 {
6949 let Self { buffer, reserved_bytes } = self;
6950 buffer.peek_with(offset, |payload| {
6951 let len = payload.len();
6952 let new_len = len.saturating_sub(*reserved_bytes);
6953 f(payload.slice(0..new_len.try_into().unwrap_or(u32::MAX)))
6954 })
6955 }
6956 }
6957
6958 #[test_case(true, 0)]
6959 #[test_case(false, 0)]
6960 #[test_case(true, 1)]
6961 #[test_case(false, 1)]
6962 fn poll_send_len(has_fin: bool, reserved_bytes: usize) {
6963 const VALUE: u8 = 0xaa;
6964
6965 fn with_poll_send_result<const HAS_FIN: bool>(
6966 f: impl FnOnce(Segment<FragmentedPayload<'_, 2>>),
6967 reserved_bytes: usize,
6968 ) {
6969 const DATA_LEN: usize = 40;
6970 let buffer = ReservingBuffer {
6971 buffer: RingBuffer::with_data(DATA_LEN, &vec![VALUE; DATA_LEN]),
6972 reserved_bytes,
6973 };
6974 assert_eq!(buffer.limits().len, DATA_LEN);
6975
6976 let mut snd = Send::<FakeInstant, _, HAS_FIN>::default_for_test_at(TEST_ISS, buffer);
6977 let counters = FakeTcpCounters::default();
6978
6979 f(snd
6980 .poll_send(
6981 &FakeStateMachineDebugId::default(),
6982 &counters.refs(),
6983 &mut RecvParams {
6984 ack: TEST_ISS,
6985 wnd: WindowSize::DEFAULT,
6986 wnd_scale: WindowScale::ZERO,
6987 ts_opt: default_ts_opt_state(TEST_IRS + 1),
6988 last_ack_recv: None,
6989 },
6990 FakeInstant::default(),
6991 &SocketOptions::default_for_state_tests(),
6992 )
6993 .expect("has data"))
6994 }
6995
6996 let f = |segment: Segment<FragmentedPayload<'_, 2>>| {
6997 let segment_len = segment.len();
6998 let (SegmentHeader { .. }, data) = segment.into_parts();
6999 let data_len = data.len();
7000
7001 if has_fin && reserved_bytes == 0 {
7002 assert_eq!(
7003 segment_len,
7004 u32::try_from(data_len + 1).unwrap(),
7005 "FIN not accounted for"
7006 );
7007 } else {
7008 assert_eq!(segment_len, u32::try_from(data_len).unwrap());
7009 }
7010
7011 let mut target = vec![0; data_len];
7012 data.partial_copy(0, target.as_mut_slice());
7013 assert_eq!(target, vec![VALUE; data_len]);
7014 };
7015 match has_fin {
7016 true => with_poll_send_result::<true>(f, reserved_bytes),
7017 false => with_poll_send_result::<false>(f, reserved_bytes),
7018 }
7019 }
7020
7021 #[test]
7022 fn zero_window_probe() {
7023 let mut clock = FakeInstantCtx::default();
7024 let counters = FakeTcpCounters::default();
7025 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
7026 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7027 let mut state = State::Established(Established {
7029 snd: Send {
7030 wnd: WindowSize::ZERO,
7031 wnd_max: WindowSize::ZERO,
7032 ..Send::default_for_test(send_buffer.clone())
7033 }
7034 .into(),
7035 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
7036 });
7037 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
7038 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(Rto::DEFAULT.get())));
7039
7040 clock.sleep(Rto::DEFAULT.get());
7042 assert_eq!(
7043 state.poll_send_with_default_options(clock.now(), &counters.refs()),
7044 Some(Segment::with_data(
7045 TEST_ISS + 1,
7046 TEST_IRS + 1,
7047 UnscaledWindowSize::from_usize(BUFFER_SIZE),
7048 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
7049 FragmentedPayload::new_contiguous(&TEST_BYTES[0..1])
7050 ))
7051 );
7052
7053 assert_eq!(
7055 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
7056 Segment::ack(
7057 TEST_IRS + 1,
7058 TEST_ISS + 1,
7059 UnscaledWindowSize::from(0),
7060 DEFAULT_SEGMENT_OPTIONS
7061 ),
7062 clock.now(),
7063 &counters.refs(),
7064 ),
7065 (None, None)
7066 );
7067 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
7069 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(Rto::DEFAULT.get() * 2)));
7070
7071 clock.sleep(Rto::DEFAULT.get());
7073 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
7074
7075 clock.sleep(Rto::DEFAULT.get());
7077 assert_eq!(
7078 state.poll_send_with_default_options(clock.now(), &counters.refs()),
7079 Some(Segment::with_data(
7080 TEST_ISS + 1,
7081 TEST_IRS + 1,
7082 UnscaledWindowSize::from_usize(BUFFER_SIZE),
7083 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
7084 FragmentedPayload::new_contiguous(&TEST_BYTES[0..1])
7085 ))
7086 );
7087
7088 assert_eq!(
7090 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
7091 Segment::ack(
7092 TEST_IRS + 1,
7093 TEST_ISS + 2,
7094 UnscaledWindowSize::from(u16::MAX),
7095 DEFAULT_SEGMENT_OPTIONS
7096 ),
7097 clock.now(),
7098 &counters.refs(),
7099 ),
7100 (None, None)
7101 );
7102 assert_eq!(state.poll_send_at(), None);
7103 assert_eq!(
7104 state.poll_send_with_default_options(clock.now(), &counters.refs()),
7105 Some(Segment::new_assert_no_discard(
7106 SegmentHeader {
7107 seq: TEST_ISS + 2,
7108 ack: Some(TEST_IRS + 1),
7109 control: None,
7110 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
7111 push: true,
7112 options: default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP)
7113 .into(),
7114 },
7115 FragmentedPayload::new_contiguous(&TEST_BYTES[1..])
7116 ))
7117 );
7118 }
7119
7120 #[test]
7121 fn nagle() {
7122 let clock = FakeInstantCtx::default();
7123 let counters = FakeTcpCounters::default();
7124 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
7125 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7127 const PARTIAL_LEN: usize = 10;
7128 assert_eq!(send_buffer.enqueue_data(&TEST_BYTES[..PARTIAL_LEN]), PARTIAL_LEN);
7129 let mut state: State<_, _, _, ()> = State::Established(Established {
7131 snd: Send {
7132 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
7133 ..Send::default_for_test(send_buffer.clone())
7134 }
7135 .into(),
7136 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
7137 });
7138 let mut socket_options =
7139 SocketOptions { nagle_enabled: true, ..SocketOptions::default_for_state_tests() };
7140
7141 assert_eq!(
7143 state.poll_send(
7144 &FakeStateMachineDebugId::default(),
7145 &counters.refs(),
7146 clock.now(),
7147 &socket_options
7148 ),
7149 Ok(Segment::with_data(
7150 TEST_ISS + 1,
7151 TEST_IRS + 1,
7152 UnscaledWindowSize::from_usize(BUFFER_SIZE),
7153 DEFAULT_SEGMENT_OPTIONS,
7154 FragmentedPayload::new_contiguous(TEST_BYTES)
7155 ))
7156 );
7157 assert_eq!(
7159 state.poll_send(
7160 &FakeStateMachineDebugId::default(),
7161 &counters.refs(),
7162 clock.now(),
7163 &socket_options
7164 ),
7165 Err(NewlyClosed::No)
7166 );
7167 socket_options.nagle_enabled = false;
7168 assert_eq!(
7169 state.poll_send(
7170 &FakeStateMachineDebugId::default(),
7171 &counters.refs(),
7172 clock.now(),
7173 &socket_options
7174 ),
7175 Ok(Segment::new_assert_no_discard(
7176 SegmentHeader {
7177 seq: TEST_ISS + TEST_BYTES.len() + 1,
7178 ack: Some(TEST_IRS + 1),
7179 control: None,
7180 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
7181 push: true,
7182 options: DEFAULT_SEGMENT_OPTIONS.into(),
7183 },
7184 FragmentedPayload::new_contiguous(&TEST_BYTES[..PARTIAL_LEN])
7185 ))
7186 );
7187 }
7188
7189 #[test]
7190 fn mss_option() {
7191 let mss = Mss::MIN;
7193 assert!(usize::from(mss) < TEST_BYTES.len());
7194
7195 let clock = FakeInstantCtx::default();
7196 let counters = FakeTcpCounters::default();
7197 let (syn_sent, syn) = Closed::<Initial>::connect(
7198 TEST_ISS,
7199 TIMESTAMP_OFFSET,
7200 clock.now(),
7201 (),
7202 Default::default(),
7203 mss,
7204 Mss::DEFAULT_IPV4,
7205 &SocketOptions::default_for_state_tests(),
7206 );
7207 let mut state = State::<_, RingBuffer, RingBuffer, ()>::SynSent(syn_sent);
7208
7209 let (seg, passive_open) = state
7211 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
7212 syn,
7213 clock.now(),
7214 &counters.refs(),
7215 );
7216 let syn_ack = seg.expect("expected SYN-ACK");
7217 assert_eq!(passive_open, None);
7218
7219 assert_eq!(
7221 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
7222 syn_ack,
7223 clock.now(),
7224 &counters.refs(),
7225 ),
7226 (
7227 Some(Segment::ack(
7228 TEST_ISS + 1,
7229 TEST_ISS + 1,
7230 UnscaledWindowSize::from(u16::MAX),
7231 DEFAULT_SEGMENT_OPTIONS
7232 )),
7233 None
7234 )
7235 );
7236 match state {
7237 State::Closed(_)
7238 | State::Listen(_)
7239 | State::SynRcvd(_)
7240 | State::SynSent(_)
7241 | State::LastAck(_)
7242 | State::FinWait1(_)
7243 | State::FinWait2(_)
7244 | State::Closing(_)
7245 | State::TimeWait(_) => {
7246 panic!("expected that we have entered established state, but got {:?}", state)
7247 }
7248 State::Established(Established { ref mut snd, rcv: _ })
7249 | State::CloseWait(CloseWait { ref mut snd, closed_rcv: _ }) => {
7250 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7251 }
7252 }
7253 let effective_mss =
7255 EffectiveMss::from_mss(mss, MssSizeLimiters { timestamp_enabled: true });
7256 assert_eq!(
7257 state.poll_send_with_default_options(clock.now(), &counters.refs()),
7258 Some(Segment::with_data(
7259 TEST_ISS + 1,
7260 TEST_ISS + 1,
7261 UnscaledWindowSize::from(u16::MAX),
7262 DEFAULT_SEGMENT_OPTIONS,
7263 FragmentedPayload::new_contiguous(&TEST_BYTES[..usize::from(effective_mss)]),
7264 ))
7265 );
7266 }
7267
7268 const TEST_USER_TIMEOUT: NonZeroDuration = NonZeroDuration::from_secs(2 * 60).unwrap();
7269
7270 #[test_case(Duration::from_millis(1), false, true; "retrans_max_retries")]
7274 #[test_case(Duration::from_secs(1), false, false; "retrans_no_max_retries")]
7275 #[test_case(Duration::from_millis(1), true, true; "zwp_max_retries")]
7276 #[test_case(Duration::from_secs(1), true, false; "zwp_no_max_retires")]
7277 fn user_timeout(rtt: Duration, zero_window_probe: bool, max_retries: bool) {
7278 let mut clock = FakeInstantCtx::default();
7279 let counters = FakeTcpCounters::default();
7280 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
7281 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7282 let mut state: State<_, _, _, ()> = State::Established(Established {
7284 snd: Send {
7285 rtt_estimator: Estimator::Measured { srtt: rtt, rtt_var: Duration::ZERO },
7286 ..Send::default_for_test(send_buffer.clone())
7287 }
7288 .into(),
7289 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
7290 });
7291 let mut times = 0;
7292 let start = clock.now();
7293 let socket_options = SocketOptions {
7294 user_timeout: (!max_retries).then_some(TEST_USER_TIMEOUT),
7295 ..SocketOptions::default_for_state_tests()
7296 };
7297 while let Ok(seg) = state.poll_send(
7298 &FakeStateMachineDebugId::default(),
7299 &counters.refs(),
7300 clock.now(),
7301 &socket_options,
7302 ) {
7303 if zero_window_probe {
7304 let zero_window_ack = Segment::ack(
7305 seg.header().ack.unwrap(),
7306 seg.header().seq,
7307 UnscaledWindowSize::from(0),
7308 DEFAULT_SEGMENT_OPTIONS,
7309 );
7310 assert_matches!(
7311 state.on_segment::<(), ClientlessBufferProvider>(
7312 &FakeStateMachineDebugId::default(),
7313 &counters.refs(),
7314 zero_window_ack,
7315 clock.now(),
7316 &socket_options,
7317 false,
7318 ),
7319 (None, None, DataAcked::No, _newly_closed)
7320 );
7321
7322 assert_matches!(
7327 state.poll_send(
7328 &FakeStateMachineDebugId::default(),
7329 &counters.refs(),
7330 clock.now(),
7331 &socket_options,
7332 ),
7333 Err(NewlyClosed::No)
7334 );
7335 let inner_state = assert_matches!(state, State::Established(ref e) => e);
7336 assert_matches!(inner_state.snd.timer, Some(SendTimer::ZeroWindowProbe(_)));
7337 }
7338
7339 let deadline = state.poll_send_at().expect("must have a retransmission timer");
7340 clock.sleep(deadline.checked_duration_since(clock.now()).unwrap());
7341 times += 1;
7342 }
7343 let elapsed = clock.now().checked_duration_since(start).unwrap();
7344 if max_retries {
7345 assert_eq!(times, 1 + DEFAULT_MAX_RETRIES.get());
7346 } else {
7347 assert_eq!(elapsed, TEST_USER_TIMEOUT.get());
7348 assert!(times < DEFAULT_MAX_RETRIES.get());
7349 }
7350 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
7351 CounterExpectations {
7352 established_closed: 1,
7353 established_timedout: 1,
7354 fast_recovery: if zero_window_probe { 1 } else { 0 },
7355 timeouts: counters.stack_wide.timeouts.get(),
7358 retransmits: counters.stack_wide.retransmits.get(),
7359 slow_start_retransmits: counters.stack_wide.slow_start_retransmits.get(),
7360 dup_acks: counters.stack_wide.dup_acks.get(),
7361 ..Default::default()
7362 }
7363 .assert_counters(&counters);
7364 }
7365
7366 #[test]
7367 fn retrans_timer_backoff() {
7368 let mut clock = FakeInstantCtx::default();
7369 let mut timer = RetransTimer::new(
7370 clock.now(),
7371 Rto::DEFAULT,
7372 Some(TEST_USER_TIMEOUT),
7373 DEFAULT_MAX_RETRIES,
7374 );
7375 assert_eq!(timer.at, FakeInstant::from(Rto::DEFAULT.get()));
7376 clock.sleep(TEST_USER_TIMEOUT.get());
7377 timer.backoff(clock.now());
7378 assert_eq!(timer.at, FakeInstant::from(TEST_USER_TIMEOUT.get()));
7379 clock.sleep(Duration::from_secs(1));
7380 timer.backoff(clock.now());
7382 assert_eq!(timer.at, FakeInstant::from(TEST_USER_TIMEOUT.get()));
7384 }
7385
7386 #[test_case(
7387 State::Established(Established {
7388 snd: Send {
7389 rtt_estimator: Estimator::Measured {
7390 srtt: Rto::DEFAULT.get(),
7391 rtt_var: Duration::ZERO,
7392 },
7393 ..Send::default_for_test(RingBuffer::new(BUFFER_SIZE))
7394 }.into(),
7395 rcv: Recv::default_for_test(RingBuffer::new(
7396 TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize,
7397 )).into(),
7398 }); "established")]
7399 #[test_case(
7400 State::FinWait1(FinWait1 {
7401 snd: Send {
7402 rtt_estimator: Estimator::Measured {
7403 srtt: Rto::DEFAULT.get(),
7404 rtt_var: Duration::ZERO,
7405 },
7406 ..Send::default_for_test(RingBuffer::new(BUFFER_SIZE))
7407 }.into(),
7408 rcv: Recv::default_for_test(RingBuffer::new(
7409 TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize,
7410 )).into(),
7411 }); "fin_wait_1")]
7412 #[test_case(
7413 State::FinWait2(FinWait2 {
7414 last_seq: TEST_ISS + 1,
7415 rcv: Recv::default_for_test(RingBuffer::new(
7416 TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize,
7417 )),
7418 timeout_at: None,
7419 snd_info: SendInfo::default(),
7420 }); "fin_wait_2")]
7421 fn delayed_ack(mut state: State<FakeInstant, RingBuffer, RingBuffer, ()>) {
7422 let mut clock = FakeInstantCtx::default();
7423 let counters = FakeTcpCounters::default();
7424 let socket_options =
7425 SocketOptions { delayed_ack: true, ..SocketOptions::default_for_state_tests() };
7426 assert_eq!(
7427 state.on_segment::<_, ClientlessBufferProvider>(
7428 &FakeStateMachineDebugId::default(),
7429 &counters.refs(),
7430 Segment::with_data(
7431 TEST_IRS + 1,
7432 TEST_ISS + 1,
7433 UnscaledWindowSize::from(u16::MAX),
7434 DEFAULT_SEGMENT_OPTIONS,
7435 TEST_BYTES,
7436 ),
7437 clock.now(),
7438 &socket_options,
7439 false, ),
7441 (None, None, DataAcked::No, NewlyClosed::No)
7442 );
7443 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(ACK_DELAY_THRESHOLD)));
7444 clock.sleep(ACK_DELAY_THRESHOLD);
7445 assert_eq!(
7446 state.poll_send(
7447 &FakeStateMachineDebugId::default(),
7448 &counters.refs(),
7449 clock.now(),
7450 &socket_options
7451 ),
7452 Ok(Segment::ack(
7453 TEST_ISS + 1,
7454 TEST_IRS + 1 + TEST_BYTES.len(),
7455 UnscaledWindowSize::from_u32(2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE)),
7456 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
7457 ))
7458 );
7459 let full_segment_sized_payload =
7460 vec![b'0'; u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize];
7461
7462 let expect_last_window_update = (
7463 TEST_IRS + 1 + TEST_BYTES.len(),
7464 WindowSize::from_u32(2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE)).unwrap(),
7465 );
7466 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_last_window_update);
7467 assert_eq!(
7469 state.on_segment::<_, ClientlessBufferProvider>(
7470 &FakeStateMachineDebugId::default(),
7471 &counters.refs(),
7472 Segment::with_data(
7473 TEST_IRS + 1 + TEST_BYTES.len(),
7474 TEST_ISS + 1,
7475 UnscaledWindowSize::from(u16::MAX),
7476 DEFAULT_SEGMENT_OPTIONS,
7477 &full_segment_sized_payload[..],
7478 ),
7479 clock.now(),
7480 &socket_options,
7481 false, ),
7483 (None, None, DataAcked::No, NewlyClosed::No)
7484 );
7485 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(ACK_DELAY_THRESHOLD)));
7487 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_last_window_update);
7490
7491 assert_eq!(
7494 state.on_segment::<_, ClientlessBufferProvider>(
7495 &FakeStateMachineDebugId::default(),
7496 &counters.refs(),
7497 Segment::with_data(
7498 TEST_IRS + 1 + TEST_BYTES.len() + full_segment_sized_payload.len(),
7499 TEST_ISS + 1,
7500 UnscaledWindowSize::from(u16::MAX),
7501 DEFAULT_SEGMENT_OPTIONS,
7502 &full_segment_sized_payload[..],
7503 ),
7504 clock.now(),
7505 &socket_options,
7506 false, ),
7508 (
7509 Some(Segment::ack(
7510 TEST_ISS + 1,
7511 TEST_IRS + 1 + TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE),
7512 UnscaledWindowSize::from(0),
7513 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
7514 )),
7515 None,
7516 DataAcked::No,
7517 NewlyClosed::No,
7518 )
7519 );
7520 assert_eq!(
7522 state.recv_mut().unwrap().last_window_update,
7523 (
7524 TEST_IRS + 1 + TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE),
7525 WindowSize::ZERO,
7526 )
7527 );
7528 assert_eq!(state.poll_send_at(), None);
7529 }
7530
7531 #[test_case(true; "sack permitted")]
7532 #[test_case(false; "sack not permitted")]
7533 fn immediate_ack_if_out_of_order_or_fin(sack_permitted: bool) {
7534 let clock = FakeInstantCtx::default();
7535 let counters = FakeTcpCounters::default();
7536 let socket_options =
7537 SocketOptions { delayed_ack: true, ..SocketOptions::default_for_state_tests() };
7538 let mut state: State<_, _, _, ()> = State::Established(Established {
7539 snd: Send::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
7540 rcv: Recv {
7541 sack_permitted,
7542 ..Recv::default_for_test(RingBuffer::new(TEST_BYTES.len() + 1))
7543 }
7544 .into(),
7545 });
7546 let segment_start = TEST_IRS + 2;
7549 assert_eq!(
7550 state.on_segment::<_, ClientlessBufferProvider>(
7551 &FakeStateMachineDebugId::default(),
7552 &counters.refs(),
7553 Segment::with_data(
7554 segment_start,
7555 TEST_ISS + 1,
7556 UnscaledWindowSize::from(u16::MAX),
7557 DEFAULT_SEGMENT_OPTIONS,
7558 &TEST_BYTES[1..]
7559 ),
7560 clock.now(),
7561 &socket_options,
7562 false, ),
7564 (
7565 Some(Segment::ack(
7566 TEST_ISS + 1,
7567 TEST_IRS + 1,
7568 UnscaledWindowSize::from(u16::try_from(TEST_BYTES.len() + 1).unwrap()),
7569 SegmentOptions {
7570 sack_blocks: if sack_permitted {
7571 [SackBlock::try_new(
7572 segment_start,
7573 segment_start + u32::try_from(TEST_BYTES.len()).unwrap() - 1,
7574 )
7575 .unwrap()]
7576 .into_iter()
7577 .collect()
7578 } else {
7579 SackBlocks::default()
7580 },
7581 timestamp: Some(DEFAULT_ACK_TS_OPT),
7582 },
7583 )),
7584 None,
7585 DataAcked::No,
7586 NewlyClosed::No,
7587 )
7588 );
7589 assert_eq!(state.poll_send_at(), None);
7590 assert_eq!(
7593 state.on_segment::<_, ClientlessBufferProvider>(
7594 &FakeStateMachineDebugId::default(),
7595 &counters.refs(),
7596 Segment::with_data(
7597 TEST_IRS + 1,
7598 TEST_ISS + 1,
7599 UnscaledWindowSize::from(u16::MAX),
7600 DEFAULT_SEGMENT_OPTIONS,
7601 &TEST_BYTES[..1]
7602 ),
7603 clock.now(),
7604 &socket_options,
7605 false, ),
7607 (
7608 Some(Segment::ack(
7609 TEST_ISS + 1,
7610 TEST_IRS + 1 + TEST_BYTES.len(),
7611 UnscaledWindowSize::from(1),
7612 DEFAULT_SEGMENT_OPTIONS
7613 )),
7614 None,
7615 DataAcked::No,
7616 NewlyClosed::No
7617 )
7618 );
7619 assert_eq!(state.poll_send_at(), None);
7620 assert_eq!(
7622 state.on_segment::<(), ClientlessBufferProvider>(
7623 &FakeStateMachineDebugId::default(),
7624 &counters.refs(),
7625 Segment::fin(
7626 TEST_IRS + 1 + TEST_BYTES.len(),
7627 TEST_ISS + 1,
7628 UnscaledWindowSize::from(u16::MAX),
7629 DEFAULT_SEGMENT_OPTIONS
7630 ),
7631 clock.now(),
7632 &socket_options,
7633 false, ),
7635 (
7636 Some(Segment::ack(
7637 TEST_ISS + 1,
7638 TEST_IRS + 1 + TEST_BYTES.len() + 1,
7639 UnscaledWindowSize::from(0),
7640 DEFAULT_SEGMENT_OPTIONS
7641 )),
7642 None,
7643 DataAcked::No,
7644 NewlyClosed::No,
7645 )
7646 );
7647 assert_eq!(state.poll_send_at(), None);
7648 }
7649
7650 #[test]
7651 fn fin_wait2_timeout() {
7652 let mut clock = FakeInstantCtx::default();
7653 let counters = FakeTcpCounters::default();
7654 let mut state: State<_, _, NullBuffer, ()> = State::FinWait2(FinWait2 {
7655 last_seq: TEST_ISS,
7656 rcv: Recv::default_for_test_at(TEST_IRS, NullBuffer),
7657 timeout_at: None,
7658 snd_info: SendInfo::default(),
7659 });
7660 assert_eq!(
7661 state.close(
7662 &counters.refs(),
7663 CloseReason::Close { now: clock.now() },
7664 &SocketOptions::default_for_state_tests()
7665 ),
7666 Err(CloseError::Closing)
7667 );
7668 assert_eq!(
7669 state.poll_send_at(),
7670 Some(clock.now().panicking_add(DEFAULT_FIN_WAIT2_TIMEOUT))
7671 );
7672 clock.sleep(DEFAULT_FIN_WAIT2_TIMEOUT);
7673 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
7674 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
7675 CounterExpectations {
7676 established_closed: 1,
7677 established_timedout: 1,
7678 ..Default::default()
7679 }
7680 .assert_counters(&counters);
7681 }
7682
7683 #[test_case(RetransTimer {
7684 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(100))),
7685 remaining_retries: None,
7686 at: FakeInstant::from(Duration::from_secs(1)),
7687 rto: Rto::new(Duration::from_secs(1)),
7688 }, FakeInstant::from(Duration::from_secs(1)) => true)]
7689 #[test_case(RetransTimer {
7690 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(100))),
7691 remaining_retries: None,
7692 at: FakeInstant::from(Duration::from_secs(2)),
7693 rto: Rto::new(Duration::from_secs(1)),
7694 }, FakeInstant::from(Duration::from_secs(1)) => false)]
7695 #[test_case(RetransTimer {
7696 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(100))),
7697 remaining_retries: Some(NonZeroU8::new(1).unwrap()),
7698 at: FakeInstant::from(Duration::from_secs(2)),
7699 rto: Rto::new(Duration::from_secs(1)),
7700 }, FakeInstant::from(Duration::from_secs(1)) => false)]
7701 #[test_case(RetransTimer {
7702 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(1))),
7703 remaining_retries: Some(NonZeroU8::new(1).unwrap()),
7704 at: FakeInstant::from(Duration::from_secs(1)),
7705 rto: Rto::new(Duration::from_secs(1)),
7706 }, FakeInstant::from(Duration::from_secs(1)) => true)]
7707 fn send_timed_out(timer: RetransTimer<FakeInstant>, now: FakeInstant) -> bool {
7708 timer.timed_out(now)
7709 }
7710
7711 #[test_case(
7712 State::SynSent(SynSent{
7713 iss: TEST_ISS,
7714 timestamp: Some(FakeInstant::default()),
7715 retrans_timer: RetransTimer::new(
7716 FakeInstant::default(),
7717 Rto::MIN,
7718 NonZeroDuration::from_secs(60),
7719 DEFAULT_MAX_SYN_RETRIES,
7720 ),
7721 active_open: (),
7722 buffer_sizes: Default::default(),
7723 device_mss: Mss::DEFAULT_IPV4,
7724 default_mss: Mss::DEFAULT_IPV4,
7725 rcv_wnd_scale: WindowScale::default(),
7726 ts_opt: default_ts_opt_negotiation_state(),
7727 })
7728 => DEFAULT_MAX_SYN_RETRIES.get(); "syn_sent")]
7729 #[test_case(
7730 State::SynRcvd(SynRcvd{
7731 iss: TEST_ISS,
7732 irs: TEST_IRS,
7733 timestamp: Some(FakeInstant::default()),
7734 retrans_timer: RetransTimer::new(
7735 FakeInstant::default(),
7736 Rto::MIN,
7737 NonZeroDuration::from_secs(60),
7738 DEFAULT_MAX_SYNACK_RETRIES,
7739 ),
7740 simultaneous_open: None,
7741 buffer_sizes: BufferSizes::default(),
7742 smss: EffectiveMss::from_mss(
7743 Mss::DEFAULT_IPV4, MssSizeLimiters { timestamp_enabled: true }
7744 ),
7745 rcv_wnd_scale: WindowScale::default(),
7746 snd_wnd_scale: Some(WindowScale::default()),
7747 sack_permitted: SACK_PERMITTED,
7748 rcv: RecvParams {
7749 ack: TEST_IRS + 1,
7750 wnd: WindowSize::DEFAULT,
7751 wnd_scale: WindowScale::default(),
7752 ts_opt: default_ts_opt_state(TEST_IRS+1),
7753 last_ack_recv: None,
7754 },
7755 })
7756 => DEFAULT_MAX_SYNACK_RETRIES.get(); "syn_rcvd")]
7757 fn handshake_timeout(mut state: State<FakeInstant, RingBuffer, RingBuffer, ()>) -> u8 {
7758 let mut clock = FakeInstantCtx::default();
7759 let counters = FakeTcpCounters::default();
7760 let mut retransmissions = 0;
7761 clock.sleep_until(state.poll_send_at().expect("must have a retransmission timer"));
7762 while let Some(_seg) = state.poll_send_with_default_options(clock.now(), &counters.refs()) {
7763 let deadline = state.poll_send_at().expect("must have a retransmission timer");
7764 clock.sleep_until(deadline);
7765 retransmissions += 1;
7766 }
7767 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
7768 CounterExpectations::default().assert_counters(&counters);
7769 retransmissions
7770 }
7771
7772 #[test_case(
7773 u16::MAX as usize, WindowScale::default(), Some(WindowScale::default())
7774 => (WindowScale::default(), WindowScale::default()))]
7775 #[test_case(
7776 u16::MAX as usize + 1, WindowScale::new(1).unwrap(), Some(WindowScale::default())
7777 => (WindowScale::new(1).unwrap(), WindowScale::default()))]
7778 #[test_case(
7779 u16::MAX as usize + 1, WindowScale::new(1).unwrap(), None
7780 => (WindowScale::default(), WindowScale::default()))]
7781 #[test_case(
7782 u16::MAX as usize, WindowScale::default(), Some(WindowScale::new(1).unwrap())
7783 => (WindowScale::default(), WindowScale::new(1).unwrap()))]
7784 fn window_scale(
7785 buffer_size: usize,
7786 syn_window_scale: WindowScale,
7787 syn_ack_window_scale: Option<WindowScale>,
7788 ) -> (WindowScale, WindowScale) {
7789 let mut clock = FakeInstantCtx::default();
7790 let counters = FakeTcpCounters::default();
7791 let (syn_sent, syn_seg) = Closed::<Initial>::connect(
7792 TEST_ISS,
7793 TIMESTAMP_OFFSET,
7794 clock.now(),
7795 (),
7796 BufferSizes { receive: buffer_size, ..Default::default() },
7797 DEVICE_MAXIMUM_SEGMENT_SIZE,
7798 Mss::DEFAULT_IPV4,
7799 &SocketOptions::default_for_state_tests(),
7800 );
7801 assert_eq!(
7802 syn_seg,
7803 Segment::syn(
7804 TEST_ISS,
7805 UnscaledWindowSize::from(u16::try_from(buffer_size).unwrap_or(u16::MAX)),
7806 HandshakeOptions {
7807 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
7808 window_scale: Some(syn_window_scale),
7809 sack_permitted: SACK_PERMITTED,
7810 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
7811 },
7812 )
7813 );
7814 let mut active = State::SynSent(syn_sent);
7815 clock.sleep(RTT / 2);
7816 let (seg, passive_open) = active
7817 .on_segment_with_default_options::<(), ClientlessBufferProvider>(
7818 Segment::syn_ack(
7819 TEST_IRS,
7820 TEST_ISS + 1,
7821 UnscaledWindowSize::from(u16::MAX),
7822 HandshakeOptions {
7823 mss: Some(Mss::DEFAULT_IPV4),
7824 window_scale: syn_ack_window_scale,
7825 sack_permitted: SACK_PERMITTED,
7826 timestamp: Some(DEFAULT_ACK_TS_OPT),
7827 },
7828 ),
7829 clock.now(),
7830 &counters.refs(),
7831 );
7832 assert_eq!(passive_open, None);
7833 assert_matches!(seg, Some(_));
7834
7835 let established: Established<FakeInstant, RingBuffer, NullBuffer> =
7836 assert_matches!(active, State::Established(established) => established);
7837
7838 assert_eq!(established.snd.wnd, WindowSize::DEFAULT);
7839
7840 (established.rcv.wnd_scale, established.snd.wnd_scale)
7841 }
7842
7843 #[test_case(
7844 u16::MAX as usize,
7845 Segment::syn_ack(
7846 TEST_IRS + 1 + u16::MAX as usize,
7847 TEST_ISS + 1,
7848 UnscaledWindowSize::from(u16::MAX),
7849 HandshakeOptions{timestamp: Some(DEFAULT_NON_ACK_TS_OPT), .. Default::default()},
7850 )
7851 )]
7852 #[test_case(
7853 u16::MAX as usize + 1,
7854 Segment::syn_ack(
7855 TEST_IRS + 1 + u16::MAX as usize,
7856 TEST_ISS + 1,
7857 UnscaledWindowSize::from(u16::MAX),
7858 HandshakeOptions{timestamp: Some(DEFAULT_NON_ACK_TS_OPT), .. Default::default()},
7859 )
7860 )]
7861 #[test_case(
7862 u16::MAX as usize,
7863 Segment::with_data(
7864 TEST_IRS + 1 + u16::MAX as usize,
7865 TEST_ISS + 1,
7866 UnscaledWindowSize::from(u16::MAX),
7867 DEFAULT_SEGMENT_OPTIONS,
7868 &TEST_BYTES[..],
7869 )
7870 )]
7871 #[test_case(
7872 u16::MAX as usize + 1,
7873 Segment::with_data(
7874 TEST_IRS + 1 + u16::MAX as usize,
7875 TEST_ISS + 1,
7876 UnscaledWindowSize::from(u16::MAX),
7877 DEFAULT_SEGMENT_OPTIONS,
7878 &TEST_BYTES[..],
7879 )
7880 )]
7881 fn window_scale_otw_seq(receive_buf_size: usize, otw_seg: impl Into<Segment<&'static [u8]>>) {
7882 let counters = FakeTcpCounters::default();
7883 let buffer_sizes = BufferSizes { send: 0, receive: receive_buf_size };
7884 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
7885 let rcv = RecvParams {
7886 ack: TEST_IRS + 1,
7887 wnd_scale: WindowScale::default(),
7888 wnd: buffer_sizes.rwnd_unscaled() << WindowScale::default(),
7889 ts_opt: default_ts_opt_state(TEST_IRS + 1),
7890 last_ack_recv: None,
7891 };
7892 let mut syn_rcvd: State<_, RingBuffer, RingBuffer, ()> = State::SynRcvd(SynRcvd {
7893 iss: TEST_ISS,
7894 irs: TEST_IRS,
7895 timestamp: None,
7896 retrans_timer: RetransTimer::new(
7897 FakeInstant::default(),
7898 Rto::DEFAULT,
7899 NonZeroDuration::from_secs(10),
7900 DEFAULT_MAX_SYNACK_RETRIES,
7901 ),
7902 simultaneous_open: None,
7903 buffer_sizes: BufferSizes { send: 0, receive: receive_buf_size },
7904 smss: EffectiveMss::from_mss(
7905 Mss::DEFAULT_IPV4,
7906 MssSizeLimiters { timestamp_enabled: true },
7907 ),
7908 rcv_wnd_scale,
7909 snd_wnd_scale: WindowScale::new(1),
7910 sack_permitted: SACK_PERMITTED,
7911 rcv,
7912 });
7913
7914 assert_eq!(
7915 syn_rcvd.on_segment_with_default_options::<_, ClientlessBufferProvider>(
7916 otw_seg.into(),
7917 FakeInstant::default(),
7918 &counters.refs()
7919 ),
7920 (
7921 Some(Segment::ack(
7922 TEST_ISS + 1,
7923 TEST_IRS + 1,
7924 buffer_sizes.rwnd_unscaled(),
7925 DEFAULT_SEGMENT_OPTIONS
7926 )),
7927 None
7928 ),
7929 )
7930 }
7931
7932 #[test]
7933 fn poll_send_reserving_buffer() {
7934 const RESERVED_BYTES: usize = 3;
7935 let mut snd: Send<FakeInstant, _, false> = Send::default_for_test(ReservingBuffer {
7936 buffer: RingBuffer::with_data(TEST_BYTES.len(), TEST_BYTES),
7937 reserved_bytes: RESERVED_BYTES,
7938 });
7939
7940 let counters = FakeTcpCounters::default();
7941
7942 assert_eq!(
7943 snd.poll_send(
7944 &FakeStateMachineDebugId::default(),
7945 &counters.refs(),
7946 &mut RecvParams {
7947 ack: TEST_IRS + 1,
7948 wnd: WindowSize::DEFAULT,
7949 wnd_scale: WindowScale::ZERO,
7950 ts_opt: default_ts_opt_state(TEST_IRS + 1),
7951 last_ack_recv: None,
7952 },
7953 FakeInstant::default(),
7954 &SocketOptions::default_for_state_tests(),
7955 ),
7956 Some(Segment::with_data(
7957 TEST_ISS + 1,
7958 TEST_IRS + 1,
7959 WindowSize::DEFAULT >> WindowScale::default(),
7960 DEFAULT_SEGMENT_OPTIONS,
7961 FragmentedPayload::new_contiguous(&TEST_BYTES[..TEST_BYTES.len() - RESERVED_BYTES])
7962 ))
7963 );
7964
7965 assert_eq!(snd.nxt, TEST_ISS + 1 + (TEST_BYTES.len() - RESERVED_BYTES));
7966 }
7967
7968 #[test]
7969 fn rcv_silly_window_avoidance() {
7970 const MULTIPLE: usize = 3;
7971 const CAP: usize = TEST_BYTES.len() * MULTIPLE;
7972 let mut rcv: Recv<FakeInstant, RingBuffer> =
7973 Recv { mss: TEST_MSS, ..Recv::default_for_test_at(TEST_IRS, RingBuffer::new(CAP)) };
7974
7975 fn get_buffer(rcv: &mut Recv<FakeInstant, RingBuffer>) -> &mut RingBuffer {
7976 assert_matches!(
7977 &mut rcv.buffer,
7978 RecvBufferState::Open {buffer, .. } => buffer
7979 )
7980 }
7981
7982 assert_eq!(rcv.calculate_window_size().window_size, WindowSize::new(CAP).unwrap());
7984
7985 for _ in 0..MULTIPLE {
7986 assert_eq!(get_buffer(&mut rcv).enqueue_data(TEST_BYTES), TEST_BYTES.len());
7987 }
7988 let assembler = assert_matches!(&mut rcv.buffer,
7989 RecvBufferState::Open { assembler, .. } => assembler);
7990 assert_eq!(assembler.insert(TEST_IRS..TEST_IRS + CAP), CAP);
7991 assert_eq!(rcv.calculate_window_size().window_size, WindowSize::ZERO);
7993
7994 assert_eq!(get_buffer(&mut rcv).read_with(|_| 1), 1);
7997 assert_eq!(rcv.calculate_window_size().window_size, WindowSize::ZERO);
7998
7999 assert_eq!(get_buffer(&mut rcv).read_with(|_| TEST_BYTES.len()), TEST_BYTES.len());
8002 assert_eq!(
8003 rcv.calculate_window_size().window_size,
8004 WindowSize::new(TEST_BYTES.len() + 1).unwrap()
8005 );
8006 }
8007
8008 #[test]
8009 fn correct_window_scale_during_send() {
8011 let snd_wnd_scale = WindowScale::new(4).unwrap();
8012 let rcv_wnd_scale = WindowScale::new(8).unwrap();
8013 let wnd_size = WindowSize::new(1024).unwrap();
8014
8015 let counters = FakeTcpCounters::default();
8016 let new_snd = || Send {
8019 wnd: wnd_size,
8020 wnd_scale: snd_wnd_scale,
8021 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
8022 ..Send::default_for_test(RingBuffer::with_data(TEST_BYTES.len(), TEST_BYTES))
8023 };
8024 let new_rcv = || Recv {
8025 wnd_scale: rcv_wnd_scale,
8026 ..Recv::default_for_test(RingBuffer::new(wnd_size.into()))
8027 };
8028 for mut state in [
8029 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
8030 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
8031 State::Closing(Closing {
8032 snd: new_snd().queue_fin(),
8033 closed_rcv: RecvParams {
8034 ack: TEST_IRS + 1,
8035 wnd: wnd_size,
8036 wnd_scale: rcv_wnd_scale,
8037 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8038 last_ack_recv: Some(FakeInstant::default()),
8039 },
8040 }),
8041 State::CloseWait(CloseWait {
8042 snd: new_snd().into(),
8043 closed_rcv: RecvParams {
8044 ack: TEST_IRS + 1,
8045 wnd: wnd_size,
8046 wnd_scale: rcv_wnd_scale,
8047 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8048 last_ack_recv: Some(FakeInstant::default()),
8049 },
8050 }),
8051 State::LastAck(LastAck {
8052 snd: new_snd().queue_fin(),
8053 closed_rcv: RecvParams {
8054 ack: TEST_IRS + 1,
8055 wnd: wnd_size,
8056 wnd_scale: rcv_wnd_scale,
8057 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8058 last_ack_recv: Some(FakeInstant::default()),
8059 },
8060 }),
8061 ] {
8062 assert_eq!(
8063 state.poll_send_with_default_options(FakeInstant::default(), &counters.refs(),),
8064 Some(Segment::new_assert_no_discard(
8065 SegmentHeader {
8066 seq: TEST_ISS + 1,
8067 ack: Some(TEST_IRS + 1),
8068 control: None,
8069 wnd: UnscaledWindowSize::from(4),
8072 push: true,
8073 options: DEFAULT_SEGMENT_OPTIONS.into(),
8074 },
8075 FragmentedPayload::new_contiguous(TEST_BYTES)
8076 ))
8077 );
8078 }
8079 }
8080
8081 #[test_case(true; "prompted window update")]
8082 #[test_case(false; "unprompted window update")]
8083 fn snd_silly_window_avoidance(prompted_window_update: bool) {
8084 const CAP: usize = TEST_BYTES.len() * 2;
8085 let mut snd: Send<FakeInstant, RingBuffer, false> = Send {
8086 wl1: TEST_IRS,
8087 wl2: TEST_ISS,
8088 wnd: WindowSize::new(CAP).unwrap(),
8089 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
8090 ..Send::default_for_test(RingBuffer::new(CAP))
8091 };
8092
8093 let mut clock = FakeInstantCtx::default();
8094 let counters = FakeTcpCounters::default();
8095
8096 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
8098 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
8099
8100 assert_eq!(
8102 snd.poll_send(
8103 &FakeStateMachineDebugId::default(),
8104 &counters.refs(),
8105 &mut RecvParams {
8106 ack: TEST_IRS + 1,
8107 wnd: WindowSize::DEFAULT,
8108 wnd_scale: WindowScale::ZERO,
8109 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8110 last_ack_recv: None,
8111 },
8112 clock.now(),
8113 &SocketOptions::default_for_state_tests(),
8114 ),
8115 Some(Segment::with_data(
8116 TEST_ISS + 1,
8117 TEST_IRS + 1,
8118 UnscaledWindowSize::from(u16::MAX),
8119 DEFAULT_SEGMENT_OPTIONS,
8120 FragmentedPayload::new_contiguous(TEST_BYTES),
8121 )),
8122 );
8123
8124 assert_eq!(
8125 snd.process_ack(
8126 &FakeStateMachineDebugId::default(),
8127 &counters.refs(),
8128 TEST_IRS + 1,
8129 TEST_ISS + 1 + TEST_BYTES.len(),
8130 UnscaledWindowSize::from(0),
8131 &SackBlocks::EMPTY,
8132 true,
8133 &mut RecvParams {
8134 ack: TEST_IRS + 1,
8135 wnd_scale: WindowScale::default(),
8136 wnd: WindowSize::DEFAULT,
8137 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8138 last_ack_recv: None,
8139 },
8140 clock.now(),
8141 &SocketOptions::default(),
8142 ),
8143 (None, DataAcked::Yes)
8144 );
8145
8146 assert_eq!(
8149 snd.poll_send(
8150 &FakeStateMachineDebugId::default(),
8151 &counters.refs(),
8152 &mut RecvParams {
8153 ack: TEST_IRS + 1,
8154 wnd: WindowSize::DEFAULT,
8155 wnd_scale: WindowScale::ZERO,
8156 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8157 last_ack_recv: None,
8158 },
8159 clock.now(),
8160 &SocketOptions::default_for_state_tests(),
8161 ),
8162 None
8163 );
8164
8165 assert_eq!(
8166 snd.timer,
8167 Some(SendTimer::ZeroWindowProbe(RetransTimer::new(
8168 clock.now(),
8169 snd.rtt_estimator.rto(),
8170 None,
8171 DEFAULT_MAX_RETRIES,
8172 )))
8173 );
8174
8175 clock.sleep_until(snd.timer.as_ref().unwrap().expiry());
8176
8177 assert_eq!(
8178 snd.poll_send(
8179 &FakeStateMachineDebugId::default(),
8180 &counters.refs(),
8181 &mut RecvParams {
8182 ack: TEST_IRS + 1,
8183 wnd: WindowSize::DEFAULT,
8184 wnd_scale: WindowScale::ZERO,
8185 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8186 last_ack_recv: None,
8187 },
8188 clock.now(),
8189 &SocketOptions::default_for_state_tests(),
8190 ),
8191 Some(Segment::with_data(
8192 TEST_ISS + 1 + TEST_BYTES.len(),
8193 TEST_IRS + 1,
8194 UnscaledWindowSize::from(u16::MAX),
8195 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
8196 FragmentedPayload::new_contiguous(&TEST_BYTES[..1]),
8197 ))
8198 );
8199
8200 if prompted_window_update {
8201 assert_eq!(
8204 snd.process_ack(
8205 &FakeStateMachineDebugId::default(),
8206 &counters.refs(),
8207 TEST_IRS + 1,
8208 TEST_ISS + 1 + TEST_BYTES.len() + 1,
8209 UnscaledWindowSize::from(3),
8210 &SackBlocks::EMPTY,
8211 true,
8212 &mut RecvParams {
8213 ack: TEST_IRS + 1,
8214 wnd_scale: WindowScale::default(),
8215 wnd: WindowSize::DEFAULT,
8216 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8217 last_ack_recv: None,
8218 },
8219 clock.now(),
8220 &SocketOptions::default(),
8221 ),
8222 (None, DataAcked::Yes)
8223 );
8224 } else {
8225 assert_eq!(
8227 snd.process_ack(
8228 &FakeStateMachineDebugId::default(),
8229 &counters.refs(),
8230 TEST_IRS + 1,
8231 TEST_ISS + 1 + TEST_BYTES.len(),
8232 UnscaledWindowSize::from(0),
8233 &SackBlocks::EMPTY,
8234 true,
8235 &mut RecvParams {
8236 ack: TEST_IRS + 1,
8237 wnd_scale: WindowScale::default(),
8238 wnd: WindowSize::DEFAULT,
8239 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8240 last_ack_recv: None,
8241 },
8242 clock.now(),
8243 &SocketOptions::default(),
8244 ),
8245 (None, DataAcked::No)
8246 );
8247
8248 assert_eq!(
8251 snd.process_ack(
8252 &FakeStateMachineDebugId::default(),
8253 &counters.refs(),
8254 TEST_IRS + 1,
8255 TEST_ISS + 1 + TEST_BYTES.len(),
8256 UnscaledWindowSize::from(3),
8257 &SackBlocks::EMPTY,
8258 true,
8259 &mut RecvParams {
8260 ack: TEST_IRS + 1,
8261 wnd_scale: WindowScale::default(),
8262 wnd: WindowSize::DEFAULT,
8263 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8264 last_ack_recv: None,
8265 },
8266 clock.now(),
8267 &SocketOptions::default(),
8268 ),
8269 (None, DataAcked::No)
8270 );
8271 }
8272
8273 assert_eq!(
8275 snd.poll_send(
8276 &FakeStateMachineDebugId::default(),
8277 &counters.refs(),
8278 &mut RecvParams {
8279 ack: TEST_IRS + 1,
8280 wnd: WindowSize::DEFAULT,
8281 wnd_scale: WindowScale::ZERO,
8282 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8283 last_ack_recv: None,
8284 },
8285 clock.now(),
8286 &SocketOptions::default_for_state_tests(),
8287 ),
8288 None,
8289 );
8290 assert_eq!(
8291 snd.timer,
8292 Some(SendTimer::SWSProbe { at: clock.now().panicking_add(SWS_PROBE_TIMEOUT) })
8293 );
8294 clock.sleep(SWS_PROBE_TIMEOUT);
8295
8296 let seq_index = usize::from(prompted_window_update);
8299 assert_eq!(
8300 snd.poll_send(
8301 &FakeStateMachineDebugId::default(),
8302 &counters.refs(),
8303 &mut RecvParams {
8304 ack: TEST_IRS + 1,
8305 wnd: WindowSize::DEFAULT,
8306 wnd_scale: WindowScale::ZERO,
8307 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8308 last_ack_recv: None,
8309 },
8310 clock.now(),
8311 &SocketOptions::default_for_state_tests(),
8312 ),
8313 Some(Segment::with_data(
8314 TEST_ISS + 1 + TEST_BYTES.len() + seq_index,
8315 TEST_IRS + 1,
8316 UnscaledWindowSize::from(u16::MAX),
8317 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
8318 FragmentedPayload::new_contiguous(&TEST_BYTES[seq_index..3 + seq_index]),
8319 ))
8320 );
8321 }
8322
8323 #[test]
8324 fn snd_enter_zwp_on_negative_window_update() {
8325 const CAP: usize = TEST_BYTES.len() * 2;
8326 let mut snd: Send<FakeInstant, RingBuffer, false> = Send {
8327 wnd: WindowSize::new(CAP).unwrap(),
8328 wl1: TEST_IRS,
8329 wl2: TEST_ISS,
8330 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
8331 ..Send::default_for_test(RingBuffer::new(CAP))
8332 };
8333
8334 let clock = FakeInstantCtx::default();
8335 let counters = FakeTcpCounters::default();
8336
8337 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
8339 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
8340
8341 assert_eq!(
8343 snd.poll_send(
8344 &FakeStateMachineDebugId::default(),
8345 &counters.refs(),
8346 &mut RecvParams {
8347 ack: TEST_IRS + 1,
8348 wnd: WindowSize::DEFAULT,
8349 wnd_scale: WindowScale::ZERO,
8350 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8351 last_ack_recv: None,
8352 },
8353 clock.now(),
8354 &SocketOptions::default_for_state_tests(),
8355 ),
8356 Some(Segment::with_data(
8357 TEST_ISS + 1,
8358 TEST_IRS + 1,
8359 UnscaledWindowSize::from(u16::MAX),
8360 DEFAULT_SEGMENT_OPTIONS,
8361 FragmentedPayload::new_contiguous(TEST_BYTES),
8362 )),
8363 );
8364
8365 assert_matches!(snd.timer, Some(SendTimer::Retrans(_)));
8368
8369 assert_eq!(
8377 snd.process_ack(
8378 &FakeStateMachineDebugId::default(),
8379 &counters.refs(),
8380 TEST_IRS + 1,
8381 TEST_ISS + 1 + TEST_BYTES.len(),
8382 UnscaledWindowSize::from(0),
8383 &SackBlocks::EMPTY,
8384 true,
8385 &mut RecvParams {
8386 ack: TEST_IRS + 1,
8387 wnd_scale: WindowScale::default(),
8388 wnd: WindowSize::DEFAULT,
8389 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8390 last_ack_recv: None,
8391 },
8392 clock.now(),
8393 &SocketOptions::default(),
8394 ),
8395 (None, DataAcked::Yes)
8396 );
8397
8398 assert_eq!(
8401 snd.poll_send(
8402 &FakeStateMachineDebugId::default(),
8403 &counters.refs(),
8404 &mut RecvParams {
8405 ack: TEST_IRS + 1,
8406 wnd: WindowSize::DEFAULT,
8407 wnd_scale: WindowScale::ZERO,
8408 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8409 last_ack_recv: None,
8410 },
8411 clock.now(),
8412 &SocketOptions::default_for_state_tests(),
8413 ),
8414 None,
8415 );
8416 assert_matches!(snd.timer, Some(SendTimer::ZeroWindowProbe(_)));
8417 }
8418
8419 #[test]
8420 fn ack_uses_snd_max() {
8422 let counters = FakeTcpCounters::default();
8423 let mut clock = FakeInstantCtx::default();
8424 let mut buffer = RingBuffer::new(BUFFER_SIZE);
8425 assert_eq!(buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
8426 assert_eq!(buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
8427
8428 let iss = ISS_1 + 1;
8430 let mut state: State<_, _, _, ()> = State::Established(Established {
8431 snd: Send {
8432 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
8433 ..Send::default_for_test_at(iss, buffer)
8434 }
8435 .into(),
8436 rcv: Recv {
8437 mss: TEST_MSS,
8438 ..Recv::default_for_test_at(iss, RingBuffer::new(BUFFER_SIZE))
8439 }
8440 .into(),
8441 });
8442
8443 assert_eq!(
8445 state.poll_send_with_default_options(clock.now(), &counters.refs()),
8446 Some(Segment::with_data(
8447 iss,
8448 iss,
8449 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8450 DEFAULT_SEGMENT_OPTIONS,
8451 FragmentedPayload::new_contiguous(TEST_BYTES),
8452 )),
8453 );
8454 assert_eq!(
8455 state.poll_send_with_default_options(clock.now(), &counters.refs()),
8456 Some(Segment::new_assert_no_discard(
8457 SegmentHeader {
8458 seq: iss + TEST_BYTES.len(),
8459 ack: Some(iss),
8460 control: None,
8461 wnd: UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8462 push: true,
8463 options: DEFAULT_SEGMENT_OPTIONS.into(),
8464 },
8465 FragmentedPayload::new_contiguous(TEST_BYTES),
8466 )),
8467 );
8468
8469 clock.sleep(Rto::DEFAULT.get());
8471 assert_eq!(
8472 state.poll_send_with_default_options(clock.now(), &counters.refs()),
8473 Some(Segment::with_data(
8474 iss,
8475 iss,
8476 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8477 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
8478 FragmentedPayload::new_contiguous(TEST_BYTES),
8479 )),
8480 );
8481
8482 assert_eq!(
8485 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
8486 Segment::with_data(
8487 iss,
8488 iss,
8489 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8490 DEFAULT_SEGMENT_OPTIONS,
8491 TEST_BYTES,
8492 ),
8493 clock.now(),
8494 &counters.refs(),
8495 ),
8496 (
8497 Some(Segment::ack(
8498 iss + 2 * TEST_BYTES.len(),
8499 iss + TEST_BYTES.len(),
8500 UnscaledWindowSize::from(
8501 u16::try_from(BUFFER_SIZE - TEST_BYTES.len()).unwrap()
8502 ),
8503 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
8504 )),
8505 None,
8506 )
8507 );
8508 }
8509
8510 #[test_case(
8511 State::Closed(Closed { reason: None }),
8512 State::Closed(Closed { reason: None }) => NewlyClosed::No; "closed to closed")]
8513 #[test_case(
8514 State::SynSent(SynSent {
8515 iss: TEST_ISS,
8516 timestamp: Some(FakeInstant::default()),
8517 retrans_timer: RetransTimer::new(
8518 FakeInstant::default(),
8519 Rto::DEFAULT,
8520 None,
8521 DEFAULT_MAX_SYN_RETRIES,
8522 ),
8523 active_open: (),
8524 buffer_sizes: BufferSizes::default(),
8525 default_mss: Mss::DEFAULT_IPV4,
8526 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8527 rcv_wnd_scale: WindowScale::default(),
8528 ts_opt: default_ts_opt_negotiation_state(),
8529 }),
8530 State::Closed(Closed { reason: None }) => NewlyClosed::Yes; "non-closed to closed")]
8531 #[test_case(
8532 State::SynSent(SynSent {
8533 iss: TEST_ISS,
8534 timestamp: Some(FakeInstant::default()),
8535 retrans_timer: RetransTimer::new(
8536 FakeInstant::default(),
8537 Rto::DEFAULT,
8538 None,
8539 DEFAULT_MAX_SYN_RETRIES,
8540 ),
8541 active_open: (),
8542 buffer_sizes: BufferSizes::default(),
8543 default_mss: Mss::DEFAULT_IPV4,
8544 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8545 rcv_wnd_scale: WindowScale::default(),
8546 ts_opt: default_ts_opt_negotiation_state(),
8547 },
8548 ),
8549 State::SynRcvd(SynRcvd {
8550 iss: TEST_ISS,
8551 irs: TEST_IRS,
8552 timestamp: None,
8553 retrans_timer: RetransTimer::new(
8554 FakeInstant::default(),
8555 Rto::DEFAULT,
8556 NonZeroDuration::from_secs(10),
8557 DEFAULT_MAX_SYNACK_RETRIES,
8558 ),
8559 simultaneous_open: None,
8560 buffer_sizes: BufferSizes { send: 0, receive: 0 },
8561 smss: EffectiveMss::from_mss(
8562 Mss::DEFAULT_IPV4, MssSizeLimiters{timestamp_enabled: true}
8563 ),
8564 rcv_wnd_scale: WindowScale::new(0).unwrap(),
8565 snd_wnd_scale: WindowScale::new(0),
8566 sack_permitted: SACK_PERMITTED,
8567 rcv: RecvParams{
8568 ack: TEST_IRS + 1,
8569 wnd: WindowSize::DEFAULT,
8570 wnd_scale: WindowScale::default(),
8571 ts_opt: default_ts_opt_state(TEST_IRS+1),
8572 last_ack_recv: None,
8573 }
8574 }) => NewlyClosed::No; "non-closed to non-closed")]
8575 fn transition_to_state(
8576 mut old_state: State<FakeInstant, RingBuffer, RingBuffer, ()>,
8577 new_state: State<FakeInstant, RingBuffer, RingBuffer, ()>,
8578 ) -> NewlyClosed {
8579 let counters = FakeTcpCounters::default();
8580 old_state.transition_to_state(&counters.refs(), new_state)
8581 }
8582
8583 #[test_case(true, false, false; "more than mss dequeued")]
8584 #[test_case(false, false, false; "less than mss dequeued")]
8585 #[test_case(true, true, false; "more than mss dequeued and delack")]
8586 #[test_case(false, true, false; "less than mss dequeued and delack")]
8587 #[test_case(true, false, true; "more than mss dequeued with sack")]
8588 fn poll_receive_data_dequeued_state(
8589 dequeue_more_than_mss: bool,
8590 delayed_ack: bool,
8591 sack: bool,
8592 ) {
8593 const BUFFER_SIZE: usize = TEST_BYTES.len();
8596
8597 let new_snd = || Send {
8598 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
8599 ..Send::default_for_test(NullBuffer)
8600 };
8601 let new_rcv =
8602 || Recv { mss: TEST_MSS, ..Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)) };
8603
8604 let clock = FakeInstantCtx::default();
8605 let counters = FakeTcpCounters::default();
8606 for mut state in [
8607 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
8608 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
8609 State::FinWait2(FinWait2 {
8610 last_seq: TEST_ISS + 1,
8611 rcv: new_rcv(),
8612 timeout_at: None,
8613 snd_info: SendInfo::default(),
8614 }),
8615 ] {
8616 assert_matches!(state.poll_receive_data_dequeued(clock.now()), None);
8619 let expect_window_update = (TEST_IRS + 1, WindowSize::new(BUFFER_SIZE).unwrap());
8620 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_window_update);
8621
8622 let seg = state.on_segment_with_options::<_, ClientlessBufferProvider>(
8626 Segment::with_data(
8627 TEST_IRS + 1,
8628 TEST_ISS + 1,
8629 UnscaledWindowSize::from(0),
8630 DEFAULT_SEGMENT_OPTIONS,
8631 TEST_BYTES,
8632 ),
8633 clock.now(),
8634 &counters.refs(),
8635 &SocketOptions { delayed_ack, ..SocketOptions::default_for_state_tests() },
8636 );
8637
8638 let expect_ack = (!delayed_ack).then_some(Segment::ack(
8639 TEST_ISS + 1,
8640 TEST_IRS + 1 + TEST_BYTES.len(),
8641 UnscaledWindowSize::from((BUFFER_SIZE - TEST_BYTES.len()) as u16),
8642 DEFAULT_SEGMENT_OPTIONS,
8643 ));
8644 assert_eq!(seg, (expect_ack, None));
8645 assert_matches!(state.poll_receive_data_dequeued(clock.now()), None);
8646
8647 let expect_window_update = if delayed_ack {
8648 expect_window_update
8649 } else {
8650 (TEST_IRS + 1 + TEST_BYTES.len(), WindowSize::new(0).unwrap())
8651 };
8652 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_window_update);
8653
8654 if dequeue_more_than_mss {
8655 assert_eq!(
8659 state.read_with(|available| {
8660 assert_eq!(available, &[TEST_BYTES]);
8661 available[0].len()
8662 }),
8663 TEST_BYTES.len()
8664 );
8665
8666 let expected_sack_blocks = if sack {
8670 let assembler = assert_matches!(
8671 &mut state.recv_mut().unwrap().buffer,
8672 RecvBufferState::Open { buffer: _, assembler } => assembler
8673 );
8674 let gap_start = TEST_IRS + u32::from(TEST_MSS) + 2;
8675 assert_eq!(assembler.insert(gap_start..gap_start + 1), 0);
8678 let expected_sack_blocks =
8679 assembler.sack_blocks(SackBlockSizeLimiters { timestamp_enabled: true });
8680 assert!(!expected_sack_blocks.is_empty());
8681 expected_sack_blocks
8682 } else {
8683 SackBlocks::EMPTY
8684 };
8685
8686 assert_eq!(
8687 state.poll_receive_data_dequeued(clock.now()),
8688 Some(Segment::ack(
8689 TEST_ISS + 1,
8690 TEST_IRS + 1 + TEST_BYTES.len(),
8691 UnscaledWindowSize::from(BUFFER_SIZE as u16),
8692 SegmentOptions {
8693 sack_blocks: expected_sack_blocks,
8694 timestamp: Some(DEFAULT_ACK_TS_OPT),
8695 },
8696 ))
8697 );
8698 assert_eq!(
8699 state.recv_mut().unwrap().last_window_update,
8700 (TEST_IRS + 1 + TEST_BYTES.len(), WindowSize::new(BUFFER_SIZE).unwrap())
8701 );
8702 assert!(state.recv_mut().unwrap().timer.is_none());
8704 } else {
8705 assert_eq!(
8709 state.read_with(|available| {
8710 assert_eq!(available, &[TEST_BYTES]);
8711 TEST_BYTES.len() / 2 - 1
8712 }),
8713 TEST_BYTES.len() / 2 - 1
8714 );
8715 assert_eq!(state.poll_receive_data_dequeued(clock.now()), None,);
8716 assert_eq!(
8717 state.recv_mut().unwrap().last_window_update,
8718 expect_window_update,
8720 );
8721 assert_eq!(state.recv_mut().unwrap().timer.is_some(), delayed_ack);
8722 }
8723 }
8724 }
8725
8726 #[test]
8727 fn poll_receive_data_dequeued_small_window() {
8728 const MSS: Mss = Mss::new(65000).unwrap();
8729 const WINDOW: WindowSize = WindowSize::from_u32(500).unwrap();
8730 let mut recv = Recv::<FakeInstant, _> {
8731 mss: EffectiveMss::from_mss(MSS, MssSizeLimiters { timestamp_enabled: true }),
8732 last_window_update: (TEST_IRS + 1, WindowSize::from_u32(1).unwrap()),
8733 ..Recv::default_for_test(RingBuffer::new(WINDOW.into()))
8734 };
8735 let seg = recv
8736 .poll_receive_data_dequeued(TEST_ISS, FakeInstant::default())
8737 .expect("generates segment");
8738 assert_eq!(seg.header().ack, Some(recv.nxt()));
8739 assert_eq!(seg.header().wnd << recv.wnd_scale, WINDOW);
8740 }
8741
8742 #[test]
8743 fn quickack_period() {
8744 let mut quickack = default_quickack_counter();
8745 let mut state = State::Established(Established::<FakeInstant, _, _> {
8746 snd: Send::default_for_test(NullBuffer).into(),
8747 rcv: Recv {
8748 remaining_quickacks: quickack,
8749 ..Recv::default_for_test(RingBuffer::default())
8750 }
8751 .into(),
8752 });
8753 let socket_options = SocketOptions { delayed_ack: true, ..Default::default() };
8754 let clock = FakeInstantCtx::default();
8755 let counters = FakeTcpCounters::default();
8756 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8757 while quickack != 0 {
8758 let seq = state.recv_mut().unwrap().nxt();
8759 let segment = Segment::new_assert_no_discard(
8760 SegmentHeader {
8761 seq,
8762 ack: Some(TEST_ISS + 1),
8763 options: DEFAULT_SEGMENT_OPTIONS.into(),
8764 ..Default::default()
8765 },
8766 &data[..],
8767 );
8768 let (seg, passive_open) = state.on_segment_with_options::<_, ClientlessBufferProvider>(
8769 segment,
8770 clock.now(),
8771 &counters.refs(),
8772 &socket_options,
8773 );
8774 let recv = state.recv_mut().unwrap();
8775 assert_matches!(recv.timer, None);
8776
8777 assert_eq!(passive_open, None);
8778 let seg = seg.expect("no segment generated");
8779 assert_eq!(seg.header().ack, Some(seq + u32::try_from(data.len()).unwrap()));
8780 assert_eq!(recv.remaining_quickacks, quickack - 1);
8781 quickack -= 1;
8782 state.buffers_mut().into_receive_buffer().unwrap().reset();
8783 }
8784
8785 let segment = Segment::new_assert_no_discard(
8787 SegmentHeader {
8788 seq: state.recv_mut().unwrap().nxt(),
8789 ack: Some(TEST_ISS + 1),
8790 options: DEFAULT_SEGMENT_OPTIONS.into(),
8791 ..Default::default()
8792 },
8793 &data[..],
8794 );
8795 let (seg, passive_open) = state.on_segment_with_options::<_, ClientlessBufferProvider>(
8796 segment,
8797 clock.now(),
8798 &counters.refs(),
8799 &socket_options,
8800 );
8801 assert_eq!(passive_open, None);
8802 assert_eq!(seg, None);
8803 assert_matches!(state.recv_mut().unwrap().timer, Some(ReceiveTimer::DelayedAck { .. }));
8804 }
8805
8806 #[test]
8807 fn quickack_reset_out_of_window() {
8808 let mut state = State::Established(Established::<FakeInstant, _, _> {
8809 snd: Send::default_for_test(NullBuffer).into(),
8810 rcv: Recv::default_for_test(RingBuffer::default()).into(),
8811 });
8812 let clock = FakeInstantCtx::default();
8813 let counters = FakeTcpCounters::default();
8814 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8815
8816 let segment = Segment::new_assert_no_discard(
8817 SegmentHeader {
8818 seq: state.recv_mut().unwrap().nxt() - i32::try_from(data.len() + 1).unwrap(),
8820 ack: Some(TEST_ISS + 1),
8821 options: DEFAULT_SEGMENT_OPTIONS.into(),
8822 ..Default::default()
8823 },
8824 &data[..],
8825 );
8826 let (seg, passive_open) = state
8827 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8828 segment,
8829 clock.now(),
8830 &counters.refs(),
8831 );
8832 assert_eq!(passive_open, None);
8833 let recv = state.recv_mut().unwrap();
8834 let seg = seg.expect("expected segment");
8835 assert_eq!(seg.header().ack, Some(recv.nxt()));
8836 assert_eq!(recv.remaining_quickacks, default_quickack_counter());
8837 }
8838
8839 #[test]
8840 fn quickack_reset_rto() {
8841 let mut clock = FakeInstantCtx::default();
8842 let mut state = State::Established(Established::<FakeInstant, _, _> {
8843 snd: Send::default_for_test(NullBuffer).into(),
8844 rcv: Recv {
8845 last_segment_at: Some(clock.now()),
8846 ..Recv::default_for_test(RingBuffer::default())
8847 }
8848 .into(),
8849 });
8850 let counters = FakeTcpCounters::default();
8851 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8852
8853 let segment = Segment::new_assert_no_discard(
8854 SegmentHeader {
8855 seq: state.recv_mut().unwrap().nxt(),
8856 ack: Some(TEST_ISS + 1),
8857 options: DEFAULT_SEGMENT_OPTIONS.into(),
8858 ..Default::default()
8859 },
8860 &data[..],
8861 );
8862 clock.sleep(Rto::DEFAULT.get());
8863 let (seg, passive_open) = state
8864 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8865 segment,
8866 clock.now(),
8867 &counters.refs(),
8868 );
8869 assert_eq!(passive_open, None);
8870 let recv = state.recv_mut().unwrap();
8871 let seg = seg.expect("expected segment");
8872 assert_eq!(seg.header().ack, Some(recv.nxt()));
8873 assert_eq!(recv.remaining_quickacks, default_quickack_counter() - 1);
8876 assert_eq!(recv.last_segment_at, Some(clock.now()));
8877 }
8878
8879 #[test_case(true; "sack permitted")]
8880 #[test_case(false; "sack not permitted")]
8881 fn receiver_selective_acks(sack_permitted: bool) {
8882 let mut state = State::Established(Established::<FakeInstant, _, _> {
8883 snd: Send::default_for_test(RingBuffer::default()).into(),
8884 rcv: Recv { sack_permitted, ..Recv::default_for_test(RingBuffer::default()) }.into(),
8885 });
8886 let clock = FakeInstantCtx::default();
8887 let counters = FakeTcpCounters::default();
8888 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8889 let mss = u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE);
8890 let seg_start = TEST_IRS + 1 + mss;
8892 let segment = Segment::new_assert_no_discard(
8893 SegmentHeader {
8894 seq: seg_start,
8895 ack: Some(TEST_ISS + 1),
8896 wnd: WindowSize::DEFAULT >> WindowScale::default(),
8897 options: DEFAULT_SEGMENT_OPTIONS.into(),
8898 ..Default::default()
8899 },
8900 &data[..],
8901 );
8902 let (seg, passive_open) = state
8903 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8904 segment,
8905 clock.now(),
8906 &counters.refs(),
8907 );
8908 assert_eq!(passive_open, None);
8909 let seg = seg.expect("expected segment");
8910 assert_eq!(seg.header().ack, Some(TEST_IRS + 1));
8911 let expect = if sack_permitted {
8912 SackBlocks::from_iter([SackBlock::try_new(seg_start, seg_start + mss).unwrap()])
8913 } else {
8914 SackBlocks::default()
8915 };
8916 let sack_blocks =
8917 assert_matches!(&seg.header().options, Options::Segment(o) => &o.sack_blocks);
8918 assert_eq!(sack_blocks, &expect);
8919
8920 assert_eq!(
8922 state.buffers_mut().into_send_buffer().unwrap().enqueue_data(&data[..]),
8923 data.len()
8924 );
8925 let seg = state
8926 .poll_send_with_default_options(clock.now(), &counters.refs())
8927 .expect("generates segment");
8928 assert_eq!(seg.header().ack, Some(TEST_IRS + 1));
8929
8930 let sack_blocks =
8932 assert_matches!(&seg.header().options, Options::Segment(o) => &o.sack_blocks);
8933 assert_eq!(sack_blocks, &expect);
8934 let expect_len = mss - u32::try_from(seg.header().options.builder().bytes_len()).unwrap();
8937 assert_eq!(seg.len(), expect_len);
8938
8939 let segment = Segment::new_assert_no_discard(
8942 SegmentHeader {
8943 seq: TEST_IRS + 1,
8944 ack: Some(TEST_ISS + 1),
8945 options: DEFAULT_SEGMENT_OPTIONS.into(),
8946 ..Default::default()
8947 },
8948 &data[..],
8949 );
8950 let (seg, passive_open) = state
8951 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8952 segment,
8953 clock.now(),
8954 &counters.refs(),
8955 );
8956 assert_eq!(passive_open, None);
8957 let seg = seg.expect("expected segment");
8958 assert_eq!(seg.header().ack, Some(TEST_IRS + (2 * mss) + 1));
8959 let sack_blocks =
8960 assert_matches!(&seg.header().options, Options::Segment(o) => &o.sack_blocks);
8961 assert_eq!(sack_blocks, &SackBlocks::default());
8962 }
8963
8964 #[derive(Debug)]
8965 enum RttTestScenario {
8966 AckOne,
8967 AckTwo,
8968 Retransmit,
8969 AckPartial,
8970 }
8971
8972 #[test_case(RttTestScenario::AckOne)]
8974 #[test_case(RttTestScenario::AckTwo)]
8975 #[test_case(RttTestScenario::Retransmit)]
8976 #[test_case(RttTestScenario::AckPartial)]
8977 fn rtt(scenario: RttTestScenario) {
8978 let mut state = State::Established(Established::<FakeInstant, _, _> {
8979 snd: Send {
8980 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
8981 ..Send::default_for_test(RingBuffer::default())
8982 }
8983 .into(),
8984 rcv: Recv::default_for_test(RingBuffer::default()).into(),
8985 });
8986
8987 const CLOCK_STEP: Duration = Duration::from_millis(1);
8988
8989 let mut clock = FakeInstantCtx::default();
8990 let counters = FakeTcpCounters::default();
8991 for _ in 0..3 {
8992 assert_eq!(
8993 state.buffers_mut().into_send_buffer().unwrap().enqueue_data(TEST_BYTES),
8994 TEST_BYTES.len()
8995 );
8996 }
8997
8998 assert_eq!(state.assert_established().snd.rtt_sampler, RttSampler::NotTracking);
8999 let seg = state
9000 .poll_send_with_default_options(clock.now(), &counters.refs())
9001 .expect("generate segment");
9002 assert_eq!(seg.header().seq, TEST_ISS + 1);
9003 assert_eq!(seg.len(), u32::try_from(TEST_BYTES.len()).unwrap());
9004 let expect_sampler = RttSampler::Tracking {
9005 range: (TEST_ISS + 1)..(TEST_ISS + 1 + seg.len()),
9006 timestamp: clock.now(),
9007 };
9008 assert_eq!(state.assert_established().snd.rtt_sampler, expect_sampler);
9009 clock.sleep(CLOCK_STEP);
9011 let seg = state
9012 .poll_send_with_default_options(clock.now(), &counters.refs())
9013 .expect("generate segment");
9014 assert_eq!(seg.header().seq, TEST_ISS + 1 + TEST_BYTES.len());
9015 assert_eq!(seg.len(), u32::try_from(TEST_BYTES.len()).unwrap());
9016 let established = state.assert_established();
9018 assert_eq!(established.snd.rtt_sampler, expect_sampler);
9019
9020 assert_eq!(established.snd.rtt_estimator.srtt(), None);
9022
9023 let (retransmit, ack_number) = match scenario {
9024 RttTestScenario::AckPartial => (false, TEST_ISS + 1 + 1),
9025 RttTestScenario::AckOne => (false, TEST_ISS + 1 + TEST_BYTES.len()),
9026 RttTestScenario::AckTwo => (false, TEST_ISS + 1 + TEST_BYTES.len() * 2),
9027 RttTestScenario::Retransmit => (true, TEST_ISS + 1 + TEST_BYTES.len() * 2),
9028 };
9029
9030 if retransmit {
9031 let timeout = state.poll_send_at().expect("timeout should be present");
9033 clock.time = timeout;
9034 let seg = state
9035 .poll_send_with_default_options(clock.now(), &counters.refs())
9036 .expect("generate segment");
9037 assert_eq!(seg.header().seq, TEST_ISS + 1);
9039 assert_eq!(state.assert_established().snd.rtt_sampler, RttSampler::NotTracking);
9041 } else {
9042 clock.sleep(CLOCK_STEP);
9043 }
9044
9045 assert_eq!(
9046 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
9047 Segment::ack(
9048 TEST_IRS + 1,
9049 ack_number,
9050 WindowSize::DEFAULT >> WindowScale::default(),
9051 DEFAULT_SEGMENT_OPTIONS
9052 ),
9053 clock.now(),
9054 &counters.refs()
9055 ),
9056 (None, None)
9057 );
9058 let established = state.assert_established();
9059 assert_eq!(established.snd.rtt_sampler, RttSampler::NotTracking);
9061 if retransmit {
9062 assert_eq!(established.snd.rtt_estimator.srtt(), None);
9064 } else {
9065 assert_eq!(established.snd.rtt_estimator.srtt(), Some(CLOCK_STEP * 2));
9068 }
9069
9070 clock.sleep(CLOCK_STEP);
9071 let seg = state
9072 .poll_send_with_default_options(clock.now(), &counters.refs())
9073 .expect("generate segment");
9074 let seq = seg.header().seq;
9075 assert_eq!(seq, TEST_ISS + 1 + TEST_BYTES.len() * 2);
9076 let expect_sampler =
9077 RttSampler::Tracking { range: seq..(seq + seg.len()), timestamp: clock.now() };
9078 assert_eq!(state.assert_established().snd.rtt_sampler, expect_sampler);
9079
9080 clock.sleep(CLOCK_STEP);
9084 assert_eq!(
9085 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
9086 Segment::ack(
9087 TEST_IRS + 1,
9088 TEST_ISS + 1 + TEST_BYTES.len() * 2,
9089 WindowSize::DEFAULT >> WindowScale::default(),
9090 DEFAULT_SEGMENT_OPTIONS
9091 ),
9092 clock.now(),
9093 &counters.refs()
9094 ),
9095 (None, None)
9096 );
9097 assert_eq!(state.assert_established().snd.rtt_sampler, expect_sampler);
9098 }
9099
9100 #[test]
9101 fn loss_recovery_skips_nagle() {
9102 let mut buffer = RingBuffer::default();
9103 let payload = "Hello World".as_bytes();
9104 assert_eq!(buffer.enqueue_data(payload), payload.len());
9105 let mut state = State::<_, _, _, ()>::Established(Established {
9106 snd: Send::default_for_test(buffer).into(),
9107 rcv: Recv::default_for_test(RingBuffer::default()).into(),
9108 });
9109
9110 let socket_options =
9111 SocketOptions { nagle_enabled: true, ..SocketOptions::default_for_state_tests() };
9112 let clock = FakeInstantCtx::default();
9113 let counters = FakeTcpCounters::default();
9114 let seg = state
9115 .poll_send(
9116 &FakeStateMachineDebugId::default(),
9117 &counters.refs(),
9118 clock.now(),
9119 &socket_options,
9120 )
9121 .expect("should not close");
9122 assert_eq!(seg.len(), u32::try_from(payload.len()).unwrap());
9123 let ack = Segment::ack(
9126 TEST_IRS + 1,
9127 seg.header().seq,
9128 WindowSize::DEFAULT >> WindowScale::default(),
9129 DEFAULT_SEGMENT_OPTIONS,
9130 );
9131
9132 let mut dup_acks = 0;
9133 let seg = loop {
9134 let (seg, passive_open, data_acked, newly_closed) = state
9135 .on_segment::<(), ClientlessBufferProvider>(
9136 &FakeStateMachineDebugId::default(),
9137 &counters.refs(),
9138 ack.clone(),
9139 clock.now(),
9140 &socket_options,
9141 false,
9142 );
9143 assert_eq!(seg, None);
9144 assert_eq!(passive_open, None);
9145 assert_eq!(data_acked, DataAcked::No);
9146 assert_eq!(newly_closed, NewlyClosed::No);
9147 dup_acks += 1;
9148
9149 match state.poll_send(
9150 &FakeStateMachineDebugId::default(),
9151 &counters.refs(),
9152 clock.now(),
9153 &socket_options,
9154 ) {
9155 Ok(seg) => break seg,
9156 Err(newly_closed) => {
9157 assert_eq!(newly_closed, NewlyClosed::No);
9158 assert!(
9159 dup_acks < DUP_ACK_THRESHOLD,
9160 "failed to retransmit after {dup_acks} dup acks"
9161 );
9162 }
9163 }
9164 };
9165 assert_eq!(seg.len(), u32::try_from(payload.len()).unwrap());
9166 assert_eq!(seg.header().seq, ack.header().ack.unwrap());
9167 }
9168
9169 #[test]
9170 fn sack_recovery_rearms_rto() {
9171 let mss = EffectiveMss::from_mss(
9172 DEVICE_MAXIMUM_SEGMENT_SIZE,
9173 MssSizeLimiters { timestamp_enabled: true },
9174 );
9175 let una = TEST_ISS + 1;
9176 let nxt = una + (u32::from(DUP_ACK_THRESHOLD) + 1) * u32::from(mss);
9177
9178 let mut congestion_control = CongestionControl::cubic_with_mss(mss);
9179 congestion_control.inflate_cwnd(20 * u32::from(mss));
9181 let mut state = State::<_, _, _, ()>::Established(Established {
9182 snd: Send {
9183 nxt,
9184 max: nxt,
9185 una,
9186 wl1: TEST_IRS + 1,
9187 wl2: una,
9188 congestion_control,
9189 ..Send::default_for_test(InfiniteSendBuffer::default())
9190 }
9191 .into(),
9192 rcv: Recv::default_for_test(RingBuffer::default()).into(),
9193 });
9194
9195 let socket_options = SocketOptions::default_for_state_tests();
9196 const RTT: Duration = Duration::from_millis(1);
9197 let mut clock = FakeInstantCtx::default();
9198 let counters = FakeTcpCounters::default();
9199 let seg = state
9201 .poll_send(
9202 &FakeStateMachineDebugId::default(),
9203 &counters.refs(),
9204 clock.now(),
9205 &socket_options,
9206 )
9207 .expect("should not close");
9208 assert_eq!(seg.len(), u32::from(mss));
9209 let start_rto = assert_matches!(
9210 state.assert_established().snd.timer,
9211 Some(SendTimer::Retrans(RetransTimer{at, ..})) => at
9212 );
9213 clock.sleep(RTT);
9214
9215 let ack = Segment::ack(
9217 TEST_IRS + 1,
9218 una,
9219 WindowSize::DEFAULT >> WindowScale::default(),
9220 SegmentOptions {
9221 sack_blocks: [SackBlock::try_new(
9222 nxt - u32::from(DUP_ACK_THRESHOLD) * u32::from(mss),
9223 nxt,
9224 )
9225 .unwrap()]
9226 .into_iter()
9227 .collect(),
9228 timestamp: Some(DEFAULT_ACK_TS_OPT),
9229 },
9230 );
9231 let (seg, passive_open, data_acked, newly_closed) = state
9232 .on_segment::<(), ClientlessBufferProvider>(
9233 &FakeStateMachineDebugId::default(),
9234 &counters.refs(),
9235 ack,
9236 clock.now(),
9237 &socket_options,
9238 false,
9239 );
9240 assert_eq!(seg, None);
9241 assert_eq!(passive_open, None);
9242 assert_eq!(data_acked, DataAcked::No);
9243 assert_eq!(newly_closed, NewlyClosed::No);
9244 assert_eq!(
9245 state.assert_established().snd.congestion_control.inspect_loss_recovery_mode(),
9246 Some(LossRecoveryMode::SackRecovery)
9247 );
9248
9249 let seg = state
9250 .poll_send(
9251 &FakeStateMachineDebugId::default(),
9252 &counters.refs(),
9253 clock.now(),
9254 &socket_options,
9255 )
9256 .expect("should not close");
9257 assert_eq!(seg.len(), u32::from(mss));
9258 assert_eq!(seg.header().seq, una);
9260 let new_rto = assert_matches!(
9262 state.assert_established().snd.timer,
9263 Some(SendTimer::Retrans(RetransTimer { at, .. })) => at
9264 );
9265 assert!(new_rto > start_rto, "{new_rto:?} > {start_rto:?}");
9266
9267 CounterExpectations {
9268 retransmits: 1,
9269 sack_recovery: 1,
9270 sack_retransmits: 1,
9271 dup_acks: 1,
9272 ..Default::default()
9273 }
9274 .assert_counters(&counters);
9275 }
9276
9277 enum SackPermitted {
9280 Yes,
9281 No,
9282 }
9283
9284 #[test_matrix(
9299 [1, 2, 3, 5, 20, 50],
9300 [SackPermitted::Yes, SackPermitted::No]
9301 )]
9302 fn congestion_window_limiting(theoretical_window: u32, sack_permitted: SackPermitted) {
9303 netstack3_base::testutil::set_logger_for_test();
9304
9305 let mss = EffectiveMss::from_mss(
9306 DEVICE_MAXIMUM_SEGMENT_SIZE,
9307 MssSizeLimiters { timestamp_enabled: true },
9308 );
9309 let generate_sack = match sack_permitted {
9310 SackPermitted::Yes => true,
9311 SackPermitted::No => false,
9312 };
9313
9314 let theoretical_window = theoretical_window * u32::from(mss);
9317
9318 let snd_wnd = WindowSize::MAX;
9320 let wnd_scale = snd_wnd.scale();
9321 let buffer = InfiniteSendBuffer::default();
9323
9324 let mut state = State::<FakeInstant, _, _, ()>::Established(Established {
9325 snd: Send {
9326 wnd: snd_wnd,
9327 wnd_max: snd_wnd,
9328 wnd_scale,
9329 congestion_control: CongestionControl::cubic_with_mss(mss),
9330 ..Send::default_for_test(buffer)
9331 }
9332 .into(),
9333 rcv: Recv { mss, ..Recv::default_for_test(RingBuffer::default()) }.into(),
9334 });
9335
9336 let socket_options = SocketOptions::default_for_state_tests();
9337 let mut clock = FakeInstantCtx::default();
9338 let counters = FakeTcpCounters::default();
9339
9340 assert!(state.assert_established().snd.congestion_control.in_slow_start());
9341
9342 let poll_until_empty =
9343 |state: &mut State<_, _, _, _>, segments: &mut Vec<(SeqNum, u32)>, now| loop {
9344 match state.poll_send(
9345 &FakeStateMachineDebugId::default(),
9346 &counters.refs(),
9347 now,
9348 &socket_options,
9349 ) {
9350 Ok(seg) => {
9351 assert_eq!(seg.len(), u32::from(mss));
9354 segments.push((seg.header().seq, seg.len()));
9355 }
9356 Err(closed) => {
9357 assert_eq!(closed, NewlyClosed::No);
9358 break;
9359 }
9360 }
9361 };
9362
9363 let mut pending_segments = Vec::new();
9364 let mut pending_acks = Vec::new();
9365 let mut receiver = Assembler::new(TEST_ISS + 1);
9366 let mut total_sent = 0;
9367 let mut total_sent_rounds = 0;
9368
9369 let mut loops = 500;
9371 let mut continue_running = |state: &mut State<_, _, _, _>| {
9372 loops -= 1;
9373 assert!(loops > 0, "test seems to have stalled");
9374
9375 const CONGESTION_EVENTS: u64 = 10;
9378 let event_count =
9379 counters.stack_wide.timeouts.get() + counters.stack_wide.loss_recovered.get();
9380 let congestion_control = &state.assert_established().snd.congestion_control;
9381 event_count <= CONGESTION_EVENTS
9382 || congestion_control.inspect_loss_recovery_mode().is_some() || congestion_control.in_slow_start()
9385 };
9386
9387 while continue_running(&mut state) {
9388 clock.sleep(Duration::from_millis(10));
9393 if pending_acks.is_empty() {
9394 poll_until_empty(&mut state, &mut pending_segments, clock.now());
9395 } else {
9396 for (ack, sack_blocks) in pending_acks.drain(..) {
9397 let seg: Segment<()> = Segment::ack(
9398 TEST_IRS + 1,
9399 ack,
9400 snd_wnd >> wnd_scale,
9401 SegmentOptions { sack_blocks, timestamp: Some(DEFAULT_ACK_TS_OPT) },
9402 );
9403 let (seg, passive_open, data_acked, newly_closed) = state
9404 .on_segment::<_, ClientlessBufferProvider>(
9405 &FakeStateMachineDebugId::default(),
9406 &counters.refs(),
9407 seg,
9408 clock.now(),
9409 &socket_options,
9410 false,
9411 );
9412
9413 assert_eq!(seg, None);
9414 assert_eq!(passive_open, None);
9415 assert_eq!(newly_closed, NewlyClosed::No);
9416 let _: DataAcked = data_acked;
9420
9421 poll_until_empty(&mut state, &mut pending_segments, clock.now());
9422 }
9423 }
9424
9425 let established = state.assert_established();
9426 let congestion_control = &established.snd.congestion_control;
9427 let ssthresh = congestion_control.slow_start_threshold();
9428 let cwnd = congestion_control.inspect_cwnd().cwnd();
9429 let in_slow_start = congestion_control.in_slow_start();
9430 let in_loss_recovery = congestion_control.inspect_loss_recovery_mode().is_some();
9431 let pipe = congestion_control.pipe();
9432 let sent = u32::try_from(pending_segments.len()).unwrap() * u32::from(mss);
9433 let recovery_counters = if generate_sack {
9434 (
9435 counters.stack_wide.sack_retransmits.get(),
9436 counters.stack_wide.sack_recovery.get(),
9437 )
9438 } else {
9439 (
9440 counters.stack_wide.fast_retransmits.get(),
9441 counters.stack_wide.fast_recovery.get(),
9442 )
9443 };
9444
9445 if !in_slow_start {
9446 total_sent += sent;
9447 total_sent_rounds += 1;
9448 }
9449
9450 log::debug!(
9453 "ssthresh={ssthresh}, \
9454 cwnd={cwnd}, \
9455 sent={sent}, \
9456 pipe={pipe}, \
9457 in_slow_start={in_slow_start}, \
9458 in_loss_recovery={in_loss_recovery}, \
9459 total_retransmits={}, \
9460 (retransmits,recovery)={:?}",
9461 counters.stack_wide.retransmits.get(),
9462 recovery_counters,
9463 );
9464
9465 if pending_segments.is_empty() {
9466 assert_matches!(established.snd.timer, Some(SendTimer::Retrans(_)));
9467 clock.sleep_until(state.poll_send_at().expect("must have timeout"));
9469 log::debug!("RTO");
9470 continue;
9471 }
9472
9473 let mut available = theoretical_window;
9474 for (seq, len) in pending_segments.drain(..) {
9475 if available < len {
9477 break;
9478 }
9479 available -= len;
9480 if seq.after_or_eq(receiver.nxt()) {
9482 let _: usize = receiver.insert(seq..(seq + len));
9483 }
9484 let sack_blocks = if generate_sack {
9485 receiver.sack_blocks(SackBlockSizeLimiters { timestamp_enabled: true })
9486 } else {
9487 SackBlocks::default()
9488 };
9489 pending_acks.push((receiver.nxt(), sack_blocks));
9490 }
9491 }
9492
9493 let avg_sent = total_sent / total_sent_rounds;
9496 let tolerance = (theoretical_window / 3).max(u32::from(mss));
9502 let low_range = theoretical_window - tolerance;
9503 let high_range = theoretical_window + tolerance;
9504 assert!(
9505 avg_sent >= low_range && avg_sent <= high_range,
9506 "{low_range} <= {avg_sent} <= {high_range}"
9507 );
9508 }
9509
9510 #[test]
9513 fn out_of_order_ack_with_sack_blocks() {
9514 let send_segments = u32::from(DUP_ACK_THRESHOLD + 2);
9515 let mss = EffectiveMss::from_mss(
9516 DEVICE_MAXIMUM_SEGMENT_SIZE,
9517 MssSizeLimiters { timestamp_enabled: true },
9518 );
9519
9520 let send_bytes = send_segments * u32::from(mss);
9521 let snd_wnd = WindowSize::from_u32(send_bytes).unwrap();
9523 let wnd_scale = snd_wnd.scale();
9524 let mut congestion_control = CongestionControl::cubic_with_mss(mss);
9525 congestion_control.inflate_cwnd(snd_wnd.into());
9526
9527 let start = TEST_ISS + 1;
9528
9529 let mut state = State::<FakeInstant, _, _, ()>::Established(Established {
9530 snd: Send {
9531 congestion_control,
9532 wnd_scale,
9533 wnd: snd_wnd,
9534 wnd_max: snd_wnd,
9535 ..Send::default_for_test_at(
9536 start,
9537 RepeatingSendBuffer::new(usize::try_from(send_bytes).unwrap()),
9538 )
9539 }
9540 .into(),
9541 rcv: Recv::default_for_test(RingBuffer::default()).into(),
9542 });
9543 let socket_options = SocketOptions::default_for_state_tests();
9544 let clock = FakeInstantCtx::default();
9545 let counters = FakeTcpCounters::default();
9546 let sent = core::iter::from_fn(|| {
9547 match state.poll_send(
9548 &FakeStateMachineDebugId::default(),
9549 &counters.refs(),
9550 clock.now(),
9551 &socket_options,
9552 ) {
9553 Ok(seg) => Some(seg.len()),
9554 Err(newly_closed) => {
9555 assert_eq!(newly_closed, NewlyClosed::No);
9556 None
9557 }
9558 }
9559 })
9560 .sum::<u32>();
9561 assert_eq!(sent, send_segments * u32::from(mss));
9562
9563 let end = state.assert_established().snd.nxt;
9565 let seg =
9566 Segment::<()>::ack(TEST_IRS + 1, end, snd_wnd >> wnd_scale, DEFAULT_SEGMENT_OPTIONS);
9567 assert_eq!(
9568 state.on_segment::<_, ClientlessBufferProvider>(
9569 &FakeStateMachineDebugId::default(),
9570 &counters.refs(),
9571 seg,
9572 clock.now(),
9573 &socket_options,
9574 false
9575 ),
9576 (None, None, DataAcked::Yes, NewlyClosed::No)
9577 );
9578 assert_eq!(state.assert_established().snd.congestion_control.pipe(), 0);
9579 assert_matches!(
9580 state.poll_send(
9581 &FakeStateMachineDebugId::default(),
9582 &counters.refs(),
9583 clock.now(),
9584 &socket_options
9585 ),
9586 Err(NewlyClosed::No)
9587 );
9588
9589 let sack_block = SackBlock::try_new(
9592 start + u32::from(mss),
9593 start + u32::from(DUP_ACK_THRESHOLD + 1) * u32::from(mss),
9594 )
9595 .unwrap();
9596 assert!(sack_block.right().before(end));
9597 let seg = Segment::<()>::ack(
9598 TEST_IRS + 1,
9599 start,
9600 snd_wnd >> wnd_scale,
9601 SegmentOptions {
9602 sack_blocks: [sack_block].into_iter().collect(),
9603 timestamp: Some(DEFAULT_ACK_TS_OPT),
9604 },
9605 );
9606 assert_eq!(
9607 state.on_segment::<_, ClientlessBufferProvider>(
9608 &FakeStateMachineDebugId::default(),
9609 &counters.refs(),
9610 seg,
9611 clock.now(),
9612 &socket_options,
9613 false
9614 ),
9615 (None, None, DataAcked::No, NewlyClosed::No)
9616 );
9617 let congestion_control = &state.assert_established().snd.congestion_control;
9620 assert_eq!(congestion_control.pipe(), 0);
9621 assert_eq!(congestion_control.inspect_loss_recovery_mode(), None);
9622 assert_matches!(
9624 state.poll_send(
9625 &FakeStateMachineDebugId::default(),
9626 &counters.refs(),
9627 clock.now(),
9628 &socket_options
9629 ),
9630 Err(NewlyClosed::No)
9631 );
9632 }
9633
9634 #[test]
9635 fn push_segments() {
9636 let send_segments = 16;
9637 let mss = EffectiveMss::from_mss(
9638 DEVICE_MAXIMUM_SEGMENT_SIZE,
9639 MssSizeLimiters { timestamp_enabled: true },
9640 );
9641 let send_bytes = send_segments * usize::from(mss);
9642 let snd_wnd = WindowSize::from_u32(4 * u32::from(mss)).unwrap();
9645 let wnd_scale = snd_wnd.scale();
9646 let mut state = State::<FakeInstant, _, _, ()>::Established(Established {
9647 snd: Send {
9648 congestion_control: CongestionControl::cubic_with_mss(mss),
9649 wnd_scale,
9650 wnd: snd_wnd,
9651 wnd_max: snd_wnd,
9652 ..Send::default_for_test(RepeatingSendBuffer::new(send_bytes))
9653 }
9654 .into(),
9655 rcv: Recv::default_for_test(RingBuffer::default()).into(),
9656 });
9657 let socket_options = SocketOptions::default_for_state_tests();
9658 let clock = FakeInstantCtx::default();
9659 let counters = FakeTcpCounters::default();
9660
9661 for i in 0..send_segments {
9662 let seg = state
9663 .poll_send(
9664 &FakeStateMachineDebugId::default(),
9665 &counters.refs(),
9666 clock.now(),
9667 &socket_options,
9668 )
9669 .expect("produces segment");
9670 let is_last = i == (send_segments - 1);
9671 let is_periodic = i != 0 && i % 2 == 0;
9675 assert!(!(is_last && is_periodic));
9678 assert_eq!(seg.header().push, is_last || is_periodic, "at {i}");
9679 let ack = Segment::ack(
9680 TEST_IRS + 1,
9681 seg.header().seq + seg.len(),
9682 snd_wnd >> wnd_scale,
9683 DEFAULT_SEGMENT_OPTIONS,
9684 );
9685 assert_eq!(
9686 state.on_segment::<(), ClientlessBufferProvider>(
9687 &FakeStateMachineDebugId::default(),
9688 &counters.refs(),
9689 ack,
9690 clock.now(),
9691 &socket_options,
9692 false
9693 ),
9694 (None, None, DataAcked::Yes, NewlyClosed::No)
9695 );
9696 }
9697 }
9698
9699 #[test]
9700 fn connect_with_timestamp_option() {
9701 let mut alice_clock = FakeInstantCtx::default();
9702 let mut bob_clock = FakeInstantCtx::default();
9703 let counters = FakeTcpCounters::default();
9704
9705 const ALICE_OFFSET: Timestamp<Milliseconds> = Timestamp::new(1000);
9708 const BOB_OFFSET: Timestamp<Milliseconds> = Timestamp::new(2000);
9709 let alice_time1 = (ALICE_OFFSET + alice_clock.now().offset).discard_unit();
9710 let bob_time1 = (BOB_OFFSET + bob_clock.now().offset).discard_unit();
9711 assert_ne!(alice_time1, bob_time1);
9712
9713 let (alice_state, syn_seg) = Closed::<Initial>::connect(
9716 ISS_1,
9717 ALICE_OFFSET,
9718 alice_clock.now(),
9719 (),
9720 Default::default(),
9721 *TEST_MSS.mss(),
9722 Mss::DEFAULT_IPV4,
9723 &SocketOptions::default_for_state_tests(),
9724 );
9725 assert_eq!(syn_seg.header().control, Some(Control::SYN));
9726 assert_eq!(syn_seg.header().ack, None);
9727 assert_eq!(
9728 *syn_seg.header().options.timestamp(),
9729 Some(TimestampOption::new(alice_time1, TS_ECHO_REPLY_FOR_NON_ACKS))
9730 );
9731 let mut alice_state = State::<_, RingBuffer, RingBuffer, _>::SynSent(alice_state);
9732
9733 let mut bob_state =
9737 State::<_, RingBuffer, RingBuffer, _>::Listen(Closed::<Initial>::listen(
9738 ISS_2,
9739 BOB_OFFSET,
9740 Default::default(),
9741 DEVICE_MAXIMUM_SEGMENT_SIZE,
9742 Mss::DEFAULT_IPV4,
9743 None,
9744 ));
9745 let syn_ack_seg = assert_matches!(
9746 bob_state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
9747 syn_seg,
9748 bob_clock.now(),
9749 &counters.refs(),
9750 ),
9751 (Some(syn_ack_seg), _) => syn_ack_seg
9752 );
9753 assert_eq!(syn_ack_seg.header().control, Some(Control::SYN));
9754 assert_eq!(syn_ack_seg.header().ack, Some(ISS_1 + 1));
9755 assert_eq!(
9756 *syn_ack_seg.header().options.timestamp(),
9757 Some(TimestampOption::new(bob_time1, alice_time1))
9758 );
9759
9760 let ack_seg = assert_matches!(
9763 alice_state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
9764 syn_ack_seg,
9765 alice_clock.now(),
9766 &counters.refs(),
9767 ),
9768 (Some(ack_seg), _) => ack_seg
9769 );
9770 assert_eq!(ack_seg.header().control, None);
9771 assert_eq!(ack_seg.header().ack, Some(ISS_2 + 1));
9772 assert_eq!(
9773 *ack_seg.header().options.timestamp(),
9774 Some(TimestampOption::new(alice_time1, bob_time1))
9775 );
9776 assert_matches!(
9777 bob_state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
9778 ack_seg,
9779 bob_clock.now(),
9780 &counters.refs(),
9781 ),
9782 (None, _)
9783 );
9784
9785 alice_clock.sleep(RTT);
9790 bob_clock.sleep(2 * RTT);
9791
9792 let alice_time2 = (ALICE_OFFSET + alice_clock.now().offset).discard_unit();
9793 let bob_time2 = (BOB_OFFSET + bob_clock.now().offset).discard_unit();
9794 assert_ne!(alice_time2, bob_time2);
9795
9796 assert_eq!(
9799 alice_state
9800 .buffers_mut()
9801 .into_send_buffer()
9802 .expect("should have a send buffer")
9803 .enqueue_data(TEST_BYTES),
9804 TEST_BYTES.len()
9805 );
9806 let data_seg = alice_state
9807 .poll_send(
9808 &FakeStateMachineDebugId::default(),
9809 &counters.refs(),
9810 alice_clock.now(),
9811 &SocketOptions::default_for_state_tests(),
9812 )
9813 .expect("poll_send should succeed");
9814 assert_eq!(data_seg.header().control, None);
9815 assert_eq!(data_seg.header().ack, Some(ISS_2 + 1));
9816 assert_eq!(
9817 *data_seg.header().options.timestamp(),
9818 Some(TimestampOption::new(alice_time2, bob_time1))
9819 );
9820
9821 let ack_seg = assert_matches!(
9825 bob_state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
9826 data_seg,
9827 bob_clock.now(),
9828 &counters.refs(),
9829 ),
9830 (Some(ack_seg), _) => ack_seg
9831 );
9832 assert_eq!(ack_seg.header().control, None);
9833 assert_eq!(ack_seg.header().ack, Some(ISS_1 + TEST_BYTES.len() + 1));
9834 assert_eq!(
9835 *ack_seg.header().options.timestamp(),
9836 Some(TimestampOption::new(bob_time2, alice_time2))
9837 );
9838 assert_matches!(
9839 alice_state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
9840 ack_seg,
9841 alice_clock.now(),
9842 &counters.refs(),
9843 ),
9844 (None, _)
9845 );
9846 }
9847
9848 #[test]
9849 fn connect_without_timestamp_option() {
9850 let clock = FakeInstantCtx::default();
9851 let counters = FakeTcpCounters::default();
9852 let (state, seg) = Closed::<Initial>::connect(
9853 TEST_ISS,
9854 TIMESTAMP_OFFSET,
9855 clock.now(),
9856 (),
9857 Default::default(),
9858 DEVICE_MAXIMUM_SEGMENT_SIZE,
9859 Mss::DEFAULT_IPV4,
9860 &SocketOptions::default_for_state_tests(),
9861 );
9862 assert_eq!(
9864 seg,
9865 Segment::syn(
9866 TEST_ISS,
9867 UnscaledWindowSize::from(u16::MAX),
9868 HandshakeOptions {
9869 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
9870 window_scale: Some(WindowScale::default()),
9871 sack_permitted: SACK_PERMITTED,
9872 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
9873 },
9874 )
9875 );
9876
9877 let mut state = State::SynSent::<_, RingBuffer, RingBuffer, _>(state);
9878
9879 let (seg, passive_open) = state
9882 .on_segment_with_default_options::<(), ClientlessBufferProvider>(
9883 Segment::syn_ack(
9884 TEST_IRS,
9885 TEST_ISS + 1,
9886 UnscaledWindowSize::from(u16::MAX),
9887 HandshakeOptions {
9888 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
9889 window_scale: Some(WindowScale::default()),
9890 sack_permitted: SACK_PERMITTED,
9891 timestamp: None,
9892 },
9893 ),
9894 clock.now(),
9895 &counters.refs(),
9896 );
9897 assert_eq!(passive_open, None);
9898 assert_eq!(
9899 seg,
9900 Some(Segment::ack(
9901 TEST_ISS + 1,
9902 TEST_IRS + 1,
9903 UnscaledWindowSize::from(u16::MAX),
9904 SegmentOptions { sack_blocks: SackBlocks::EMPTY, timestamp: None }
9905 ))
9906 );
9907
9908 let (wl1, wl2, ts_opt, mss) = assert_matches!(
9910 &state,
9911 State::Established(Established {
9912 snd: Takeable(Some(Send { wl1, wl2, .. })),
9913 rcv: Takeable(Some(Recv { ts_opt, mss, ..})),
9914 }) => (wl1, wl2, ts_opt, mss)
9915 );
9916 assert_eq!(*wl1, TEST_IRS);
9917 assert_eq!(*wl2, TEST_ISS + 1);
9918 assert_eq!(*ts_opt, TimestampOptionState::Disabled);
9919 assert_eq!(
9921 *mss,
9922 EffectiveMss::from_mss(
9923 DEVICE_MAXIMUM_SEGMENT_SIZE,
9924 MssSizeLimiters { timestamp_enabled: false }
9925 )
9926 );
9927 }
9928
9929 #[test]
9930 fn segments_with_missing_timestamp_option() {
9931 let clock = FakeInstantCtx::default();
9932 let counters = FakeTcpCounters::default();
9933 let mut established = State::Established(Established {
9935 snd: Send::default_for_test(NullBuffer).into(),
9936 rcv: Recv {
9937 ts_opt: default_ts_opt_state(TEST_IRS + 1),
9938 ..Recv::default_for_test(RingBuffer::new(BUFFER_SIZE))
9939 }
9940 .into(),
9941 });
9942
9943 let (seg, passive_open) = established
9947 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
9948 Segment::with_data(
9949 TEST_IRS + 1,
9950 TEST_ISS + 1,
9951 UnscaledWindowSize::from(0),
9952 SegmentOptions { sack_blocks: SackBlocks::EMPTY, timestamp: None },
9953 TEST_BYTES,
9954 ),
9955 clock.now(),
9956 &counters.refs(),
9957 );
9958 assert_eq!(passive_open, None);
9959 assert_eq!(
9960 seg,
9961 Some(Segment::ack(
9962 TEST_ISS + 1,
9963 TEST_IRS + 1 + TEST_BYTES.len(),
9964 UnscaledWindowSize::from((BUFFER_SIZE - TEST_BYTES.len()) as u16),
9965 DEFAULT_SEGMENT_OPTIONS,
9966 )),
9967 );
9968 assert_eq!(
9969 established.read_with(|available| {
9970 assert_eq!(available, &[TEST_BYTES]);
9971 available[0].len()
9972 }),
9973 TEST_BYTES.len()
9974 );
9975 }
9976
9977 #[test]
9978 fn last_data_sent_update() {
9979 let get_last_data_sent = |state: &State<_, _, _, _>| {
9980 assert_matches!(state, State::Established(Established {
9981 snd: Takeable(Some(Send { last_data_sent, .. })),
9982 ..
9983 }) => *last_data_sent)
9984 };
9985
9986 let mut clock = FakeInstantCtx::default();
9987 let counters = FakeTcpCounters::default();
9988 let start_time = clock.now();
9989
9990 let mut connection = State::Established(Established {
9991 snd: Send::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
9992 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
9993 });
9994 assert_eq!(get_last_data_sent(&connection), None);
9995
9996 let (_seg, _) = connection.on_segment_with_default_options::<_, ClientlessBufferProvider>(
9998 Segment::<()>::ack(
9999 TEST_ISS + 1,
10000 TEST_IRS + 1,
10001 UnscaledWindowSize::from(1000u16),
10002 DEFAULT_SEGMENT_OPTIONS,
10003 ),
10004 clock.now(),
10005 &counters.refs(),
10006 );
10007 assert_eq!(get_last_data_sent(&connection), None);
10008
10009 assert_eq!(
10011 connection
10012 .buffers_mut()
10013 .into_send_buffer()
10014 .expect("should have a send buffer")
10015 .enqueue_data(TEST_BYTES),
10016 TEST_BYTES.len()
10017 );
10018 let _seg = connection
10019 .poll_send(
10020 &FakeStateMachineDebugId::default(),
10021 &counters.refs(),
10022 clock.now(),
10023 &SocketOptions::default_for_state_tests(),
10024 )
10025 .expect("should send segment");
10026
10027 let first_send_time = get_last_data_sent(&connection);
10028 assert_eq!(first_send_time, Some(start_time));
10029
10030 clock.sleep(Duration::from_secs(1));
10032 let time_after_sleep = clock.now();
10033
10034 assert_eq!(
10035 connection
10036 .buffers_mut()
10037 .into_send_buffer()
10038 .expect("should have a send buffer")
10039 .enqueue_data(TEST_BYTES),
10040 TEST_BYTES.len()
10041 );
10042 let _seg = connection
10043 .poll_send(
10044 &FakeStateMachineDebugId::default(),
10045 &counters.refs(),
10046 clock.now(),
10047 &SocketOptions::default_for_state_tests(),
10048 )
10049 .expect("should send segment");
10050
10051 let second_send_time = get_last_data_sent(&connection);
10052 assert_eq!(second_send_time, Some(time_after_sleep));
10053 }
10054}