1use core::convert::{Infallible, TryFrom as _};
11use core::fmt::Debug;
12use core::num::{NonZeroU8, NonZeroU32, NonZeroUsize, TryFromIntError};
13use core::ops::{Deref, DerefMut};
14use core::time::Duration;
15
16use assert_matches::assert_matches;
17use derivative::Derivative;
18use explicit::ResultExt as _;
19use netstack3_base::{
20 Control, EffectiveMss, HandshakeOptions, IcmpErrorCode, Instant, Milliseconds, Mss,
21 MssSizeLimiters, Options, Payload, PayloadLen as _, ResetOptions, RxTimestampOption,
22 SackBlocks, Segment, SegmentHeader, SegmentOptions, SeqNum, Timestamp, TimestampOption,
23 TxTimestampOption, UnscaledWindowSize, WindowScale, WindowSize,
24};
25use netstack3_trace::{TraceResourceId, trace_instant};
26use packet_formats::utils::NonZeroDuration;
27use replace_with::{replace_with, replace_with_and};
28
29use crate::internal::base::{
30 BufferSizes, BuffersRefMut, ConnectionError, IcmpErrorResult, KeepAlive, SocketOptions,
31};
32use crate::internal::buffer::{
33 Assembler, BufferLimits, IntoBuffers, ReceiveBuffer, SackBlockSizeLimiters, SendBuffer,
34};
35use crate::internal::congestion::{
36 CongestionControl, CongestionControlSendOutcome, LossRecoveryMode, LossRecoverySegment,
37};
38use crate::internal::counters::TcpCountersRefs;
39use crate::internal::rtt::{Estimator, Rto, RttSampler};
40use crate::internal::timestamp::{TimestampOptionNegotiationState, TimestampOptionState};
41
42pub(super) const MSL: Duration = Duration::from_secs(2 * 60);
47
48const DEFAULT_MAX_RETRIES: NonZeroU8 = NonZeroU8::new(15).unwrap();
55
56pub(super) const DEFAULT_MAX_SYN_RETRIES: NonZeroU8 = NonZeroU8::new(6).unwrap();
59const DEFAULT_MAX_SYNACK_RETRIES: NonZeroU8 = NonZeroU8::new(5).unwrap();
60
61const ACK_DELAY_THRESHOLD: Duration = Duration::from_millis(40);
69const SWS_PROBE_TIMEOUT: Duration = Duration::from_millis(100);
76const SWS_BUFFER_FACTOR: u32 = 2;
80
81const SACK_PERMITTED: bool = true;
83
84pub(crate) trait StateMachineDebugId: Debug {
89 fn trace_id(&self) -> TraceResourceId<'_>;
90}
91
92#[derive(Debug)]
105#[cfg_attr(test, derive(PartialEq, Eq))]
106pub struct Closed<Error> {
107 pub(crate) reason: Error,
109}
110
111pub(crate) enum Initial {}
114
115impl Closed<Initial> {
116 pub(crate) fn connect<I: Instant, ActiveOpen>(
122 iss: SeqNum,
123 timestamp_offset: Timestamp<Milliseconds>,
124 now: I,
125 active_open: ActiveOpen,
126 buffer_sizes: BufferSizes,
127 device_mss: Mss,
128 default_mss: Mss,
129 SocketOptions {
130 keep_alive: _,
131 nagle_enabled: _,
132 user_timeout,
133 delayed_ack: _,
134 fin_wait2_timeout: _,
135 max_syn_retries,
136 ip_options: _,
137 }: &SocketOptions,
138 ) -> (SynSent<I, ActiveOpen>, Segment<()>) {
139 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
140 let rwnd = buffer_sizes.rwnd_unscaled();
144 let ts_opt = TimestampOptionNegotiationState::new(now, timestamp_offset);
148 let timestamp = ts_opt.make_option_for_syn(now).map(TxTimestampOption::into);
149 (
150 SynSent {
151 iss,
152 timestamp: Some(now),
153 retrans_timer: RetransTimer::new(
154 now,
155 Rto::DEFAULT,
156 *user_timeout,
157 *max_syn_retries,
158 ),
159 active_open,
160 buffer_sizes,
161 device_mss,
162 default_mss,
163 rcv_wnd_scale,
164 ts_opt,
165 },
166 Segment::syn(
167 iss,
168 rwnd,
169 HandshakeOptions {
170 mss: Some(device_mss),
171 window_scale: Some(rcv_wnd_scale),
172 sack_permitted: SACK_PERMITTED,
173 timestamp,
174 },
175 ),
176 )
177 }
178
179 pub(crate) fn listen(
180 iss: SeqNum,
181 timestamp_offset: Timestamp<Milliseconds>,
182 buffer_sizes: BufferSizes,
183 device_mss: Mss,
184 default_mss: Mss,
185 user_timeout: Option<NonZeroDuration>,
186 ) -> Listen {
187 Listen { iss, timestamp_offset, buffer_sizes, device_mss, default_mss, user_timeout }
188 }
189}
190
191impl<Error> Closed<Error> {
192 pub(crate) fn on_segment(&self, segment: &Segment<impl Payload>) -> Option<Segment<()>> {
196 let segment_len = segment.len();
197 let SegmentHeader { seq: seg_seq, ack: seg_ack, wnd: _, control, options: _, push: _ } =
198 segment.header();
199
200 if *control == Some(Control::RST) {
214 return None;
215 }
216 let timestamp = None;
221 Some(match seg_ack {
222 Some(seg_ack) => Segment::rst(*seg_ack, ResetOptions { timestamp }),
223 None => Segment::rst_ack(
224 SeqNum::from(0),
225 *seg_seq + segment_len,
226 ResetOptions { timestamp },
227 ),
228 })
229 }
230}
231
232#[derive(Debug)]
246#[cfg_attr(test, derive(PartialEq, Eq))]
247pub struct Listen {
248 iss: SeqNum,
249 timestamp_offset: Timestamp<Milliseconds>,
250 buffer_sizes: BufferSizes,
251 device_mss: Mss,
252 default_mss: Mss,
253 user_timeout: Option<NonZeroDuration>,
254}
255
256#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
258enum ListenOnSegmentDisposition<I: Instant> {
259 SendSynAckAndEnterSynRcvd(Segment<()>, SynRcvd<I, Infallible>),
260 SendRst(Segment<()>),
261 Ignore,
262}
263
264impl Listen {
265 fn on_segment<I: Instant>(
266 &self,
267 seg: Segment<impl Payload>,
268 now: I,
269 ) -> ListenOnSegmentDisposition<I> {
270 let (header, _data) = seg.into_parts();
271 let SegmentHeader { seq, ack, wnd: _, control, options, push: _ } = header;
272 let Listen { iss, timestamp_offset, buffer_sizes, device_mss, default_mss, user_timeout } =
273 *self;
274 let smss = options.mss().unwrap_or(default_mss).min(device_mss);
275 if control == Some(Control::RST) {
279 return ListenOnSegmentDisposition::Ignore;
280 }
281 if let Some(ack) = ack {
282 let options = ResetOptions { timestamp: None };
294
295 return ListenOnSegmentDisposition::SendRst(Segment::rst(ack, options));
296 }
297 if control == Some(Control::SYN) {
298 let sack_permitted = options.sack_permitted();
299 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
312 let rwnd = buffer_sizes.rwnd_unscaled();
316 let initial_ack_sent = seq + 1;
320 let ts_opt = TimestampOptionState::negotiate(
321 TimestampOptionNegotiationState::new(now, timestamp_offset),
322 options.timestamp().map(RxTimestampOption::from),
323 initial_ack_sent,
324 );
325 return ListenOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
326 Segment::syn_ack(
327 iss,
328 initial_ack_sent,
329 rwnd,
330 HandshakeOptions {
331 mss: Some(smss),
332 window_scale: options.window_scale().map(|_| rcv_wnd_scale),
337 sack_permitted: SACK_PERMITTED,
338 timestamp: ts_opt.make_option_for_ack(now).map(TxTimestampOption::into),
339 },
340 ),
341 SynRcvd {
342 iss,
343 irs: seq,
344 timestamp: Some(now),
345 retrans_timer: RetransTimer::new(
346 now,
347 Rto::DEFAULT,
348 user_timeout,
349 DEFAULT_MAX_SYNACK_RETRIES,
350 ),
351 simultaneous_open: None,
352 buffer_sizes,
353 smss: EffectiveMss::from_mss(
354 smss,
355 MssSizeLimiters { timestamp_enabled: ts_opt.is_enabled() },
356 ),
357 rcv_wnd_scale,
358 snd_wnd_scale: options.window_scale(),
359 sack_permitted,
360 rcv: RecvParams {
361 ack: initial_ack_sent,
362 ts_opt,
363 wnd_scale: WindowScale::default(),
366 wnd: rwnd << WindowScale::default(),
367 },
368 },
369 );
370 }
371 ListenOnSegmentDisposition::Ignore
372 }
373}
374
375#[derive(Debug)]
389#[cfg_attr(test, derive(PartialEq, Eq))]
390pub struct SynSent<I, ActiveOpen> {
391 iss: SeqNum,
392 timestamp: Option<I>,
396 retrans_timer: RetransTimer<I>,
397 active_open: ActiveOpen,
398 buffer_sizes: BufferSizes,
399 device_mss: Mss,
400 default_mss: Mss,
401 rcv_wnd_scale: WindowScale,
402 ts_opt: TimestampOptionNegotiationState<I>,
404}
405
406#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
408enum SynSentOnSegmentDisposition<I: Instant, ActiveOpen> {
409 SendAckAndEnterEstablished(Established<I, (), ()>),
410 SendSynAckAndEnterSynRcvd(Segment<()>, SynRcvd<I, ActiveOpen>),
411 SendRst(Segment<()>),
412 EnterClosed(Closed<Option<ConnectionError>>),
413 Ignore,
414}
415
416impl<I: Instant + 'static, ActiveOpen> SynSent<I, ActiveOpen> {
417 fn on_segment(
423 &self,
424 seg: Segment<impl Payload>,
425 now: I,
426 ) -> SynSentOnSegmentDisposition<I, ActiveOpen> {
427 let (header, _data) = seg.into_parts();
428 let SegmentHeader { seq: seg_seq, ack: seg_ack, wnd: seg_wnd, control, options, push: _ } =
429 header;
430 let SynSent {
431 iss,
432 timestamp: syn_sent_ts,
433 retrans_timer: RetransTimer { user_timeout_until, remaining_retries: _, at: _, rto: _ },
434 active_open: _,
435 buffer_sizes,
436 device_mss,
437 default_mss,
438 rcv_wnd_scale,
439 ts_opt,
440 } = self;
441 let has_ack = match seg_ack {
450 Some(ack) => {
451 if ack.before(*iss) || ack.after(*iss + 1) {
454 return if control == Some(Control::RST) {
455 SynSentOnSegmentDisposition::Ignore
456 } else {
457 SynSentOnSegmentDisposition::SendRst(Segment::rst(
460 ack,
461 ResetOptions { timestamp: None },
462 ))
463 };
464 }
465 true
466 }
467 None => false,
468 };
469
470 match control {
471 Some(Control::RST) => {
472 if has_ack {
480 SynSentOnSegmentDisposition::EnterClosed(Closed {
481 reason: Some(ConnectionError::ConnectionRefused),
482 })
483 } else {
484 SynSentOnSegmentDisposition::Ignore
485 }
486 }
487 Some(Control::SYN) => {
488 let smss = options.mss().unwrap_or(*default_mss).min(*device_mss);
489 let sack_permitted = options.sack_permitted();
490 match seg_ack {
495 Some(seg_ack) => {
496 if seg_ack.after(*iss) {
514 let irs = seg_seq;
515 let mut rtt_estimator = Estimator::default();
516 if let Some(syn_sent_ts) = syn_sent_ts {
517 rtt_estimator.sample(now.saturating_duration_since(*syn_sent_ts));
518 }
519 let (rcv_wnd_scale, snd_wnd_scale) = options
520 .window_scale()
521 .map(|snd_wnd_scale| (*rcv_wnd_scale, snd_wnd_scale))
522 .unwrap_or_default();
523 let next = *iss + 1;
524 let initial_ack_sent = irs + 1;
531 let ts_opt = TimestampOptionState::negotiate(
532 ts_opt.clone(),
533 options.timestamp().map(RxTimestampOption::from),
534 initial_ack_sent,
535 );
536 let smss = EffectiveMss::from_mss(
537 smss,
538 MssSizeLimiters { timestamp_enabled: ts_opt.is_enabled() },
539 );
540 let established = Established {
541 snd: Send {
542 nxt: next,
543 max: next,
544 una: seg_ack,
545 wnd: seg_wnd << WindowScale::default(),
547 wl1: seg_seq,
548 wl2: seg_ack,
549 last_push: next,
550 buffer: (),
551 rtt_sampler: RttSampler::default(),
552 rtt_estimator,
553 timer: None,
554 congestion_control: CongestionControl::cubic_with_mss(smss),
555 wnd_scale: snd_wnd_scale,
556 wnd_max: seg_wnd << WindowScale::default(),
557 }
558 .into(),
559 rcv: Recv {
560 buffer: RecvBufferState::Open {
561 buffer: (),
562 assembler: Assembler::new(initial_ack_sent),
563 },
564 remaining_quickacks: quickack_counter(
565 buffer_sizes.rcv_limits(),
566 smss,
567 ),
568 last_segment_at: None,
569 timer: None,
570 mss: smss,
571 wnd_scale: rcv_wnd_scale,
572 last_window_update: (initial_ack_sent, buffer_sizes.rwnd()),
573 sack_permitted,
574 ts_opt,
575 }
576 .into(),
577 };
578 SynSentOnSegmentDisposition::SendAckAndEnterEstablished(established)
579 } else {
580 SynSentOnSegmentDisposition::Ignore
581 }
582 }
583 None => {
584 if user_timeout_until.is_none_or(|t| now < t) {
585 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
593 let rwnd = buffer_sizes.rwnd_unscaled();
598 let initial_ack_sent = seg_seq + 1;
606 let ts_opt = TimestampOptionState::negotiate(
607 ts_opt.clone(),
608 options.timestamp().map(RxTimestampOption::from),
609 initial_ack_sent,
610 );
611 let smss = EffectiveMss::from_mss(
612 smss,
613 MssSizeLimiters { timestamp_enabled: ts_opt.is_enabled() },
614 );
615 SynSentOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
616 Segment::syn_ack(
617 *iss,
618 initial_ack_sent,
619 rwnd,
620 HandshakeOptions {
621 mss: Some(*smss.mss()),
622 window_scale: options.window_scale().map(|_| rcv_wnd_scale),
623 sack_permitted: SACK_PERMITTED,
624 timestamp: ts_opt
625 .make_option_for_ack(now)
626 .map(TxTimestampOption::into),
627 },
628 ),
629 SynRcvd {
630 iss: *iss,
631 irs: seg_seq,
632 timestamp: Some(now),
633 retrans_timer: RetransTimer::new_with_user_deadline(
634 now,
635 Rto::DEFAULT,
636 *user_timeout_until,
637 DEFAULT_MAX_SYNACK_RETRIES,
638 ),
639 simultaneous_open: None,
641 buffer_sizes: *buffer_sizes,
642 smss,
643 rcv_wnd_scale,
644 snd_wnd_scale: options.window_scale(),
645 sack_permitted,
646 rcv: RecvParams {
647 ack: initial_ack_sent,
648 ts_opt,
649 wnd_scale: WindowScale::default(),
652 wnd: rwnd << WindowScale::default(),
653 },
654 },
655 )
656 } else {
657 SynSentOnSegmentDisposition::EnterClosed(Closed { reason: None })
658 }
659 }
660 }
661 }
662 Some(Control::FIN) | None => SynSentOnSegmentDisposition::Ignore,
666 }
667 }
668}
669
670#[derive(Debug)]
685#[cfg_attr(test, derive(PartialEq, Eq))]
686pub struct SynRcvd<I, ActiveOpen> {
687 iss: SeqNum,
688 irs: SeqNum,
689 timestamp: Option<I>,
693 retrans_timer: RetransTimer<I>,
694 simultaneous_open: Option<ActiveOpen>,
698 buffer_sizes: BufferSizes,
699 smss: EffectiveMss,
703 rcv_wnd_scale: WindowScale,
704 snd_wnd_scale: Option<WindowScale>,
705 sack_permitted: bool,
706 rcv: RecvParams<I>,
715}
716
717impl<I: Instant, R: ReceiveBuffer, S: SendBuffer, ActiveOpen> From<SynRcvd<I, Infallible>>
718 for State<I, R, S, ActiveOpen>
719{
720 fn from(
721 SynRcvd {
722 iss,
723 irs,
724 timestamp,
725 retrans_timer,
726 simultaneous_open,
727 buffer_sizes,
728 smss,
729 rcv_wnd_scale,
730 snd_wnd_scale,
731 sack_permitted,
732 rcv,
733 }: SynRcvd<I, Infallible>,
734 ) -> Self {
735 match simultaneous_open {
736 None => State::SynRcvd(SynRcvd {
737 iss,
738 irs,
739 timestamp,
740 retrans_timer,
741 simultaneous_open: None,
742 buffer_sizes,
743 smss,
744 rcv_wnd_scale,
745 snd_wnd_scale,
746 sack_permitted,
747 rcv,
748 }),
749 }
750 }
751}
752enum FinQueued {}
753
754impl FinQueued {
755 const YES: bool = true;
759 const NO: bool = false;
760}
761
762#[derive(Derivative)]
764#[derivative(Debug)]
765#[cfg_attr(test, derivative(PartialEq, Eq))]
766pub(crate) struct Send<I, S, const FIN_QUEUED: bool> {
767 nxt: SeqNum,
768 pub(crate) max: SeqNum,
769 una: SeqNum,
770 wnd: WindowSize,
771 wnd_scale: WindowScale,
772 wnd_max: WindowSize,
773 wl1: SeqNum,
774 wl2: SeqNum,
775 last_push: SeqNum,
776 rtt_sampler: RttSampler<I>,
777 rtt_estimator: Estimator,
778 timer: Option<SendTimer<I>>,
779 #[derivative(PartialEq = "ignore")]
780 congestion_control: CongestionControl<I>,
781 buffer: S,
782}
783
784impl<I> Send<I, (), false> {
785 fn with_buffer<S>(self, buffer: S) -> Send<I, S, false> {
786 let Self {
787 nxt,
788 max,
789 una,
790 wnd,
791 wnd_scale,
792 wnd_max,
793 wl1,
794 wl2,
795 last_push,
796 rtt_sampler,
797 rtt_estimator,
798 timer,
799 congestion_control,
800 buffer: _,
801 } = self;
802 Send {
803 nxt,
804 max,
805 una,
806 wnd,
807 wnd_scale,
808 wnd_max,
809 wl1,
810 wl2,
811 last_push,
812 rtt_sampler,
813 rtt_estimator,
814 timer,
815 congestion_control,
816 buffer,
817 }
818 }
819}
820
821#[derive(Debug, Clone, Copy)]
822#[cfg_attr(test, derive(PartialEq, Eq))]
823struct RetransTimer<I> {
824 user_timeout_until: Option<I>,
825 remaining_retries: Option<NonZeroU8>,
826 at: I,
827 rto: Rto,
828}
829
830impl<I: Instant> RetransTimer<I> {
831 fn new(
832 now: I,
833 rto: Rto,
834 user_timeout: Option<NonZeroDuration>,
835 max_retries: NonZeroU8,
836 ) -> Self {
837 let user_timeout_until = user_timeout.map(|t| now.saturating_add(t.get()));
838 Self::new_with_user_deadline(now, rto, user_timeout_until, max_retries)
839 }
840
841 fn new_with_user_deadline(
842 now: I,
843 rto: Rto,
844 user_timeout_until: Option<I>,
845 max_retries: NonZeroU8,
846 ) -> Self {
847 let rto_at = now.panicking_add(rto.get());
848 let at = user_timeout_until.map(|i| i.min(rto_at)).unwrap_or(rto_at);
849 Self { at, rto, user_timeout_until, remaining_retries: Some(max_retries) }
850 }
851
852 fn backoff(&mut self, now: I) {
853 let Self { at, rto, user_timeout_until, remaining_retries } = self;
854 *remaining_retries = remaining_retries.and_then(|r| NonZeroU8::new(r.get() - 1));
855 *rto = rto.double();
856 let rto_at = now.panicking_add(rto.get());
857 *at = user_timeout_until.map(|i| i.min(rto_at)).unwrap_or(rto_at);
858 }
859
860 fn timed_out(&self, now: I) -> bool {
861 let RetransTimer { user_timeout_until, remaining_retries, at, rto: _ } = self;
862 (remaining_retries.is_none() && now >= *at) || user_timeout_until.is_some_and(|t| now >= t)
863 }
864}
865
866#[derive(Debug, Clone, Copy)]
868#[cfg_attr(test, derive(PartialEq, Eq))]
869enum SendTimer<I> {
870 Retrans(RetransTimer<I>),
873 KeepAlive(KeepAliveTimer<I>),
876 ZeroWindowProbe(RetransTimer<I>),
884 SWSProbe { at: I },
892}
893
894#[derive(Debug, Clone, Copy)]
895#[cfg_attr(test, derive(PartialEq, Eq))]
896enum ReceiveTimer<I> {
897 DelayedAck { at: I },
898}
899
900#[derive(Debug, Clone, Copy)]
901#[cfg_attr(test, derive(PartialEq, Eq))]
902struct KeepAliveTimer<I> {
903 at: I,
904 already_sent: u8,
905}
906
907impl<I: Instant> KeepAliveTimer<I> {
908 fn idle(now: I, keep_alive: &KeepAlive) -> Self {
909 let at = now.saturating_add(keep_alive.idle.into());
910 Self { at, already_sent: 0 }
911 }
912}
913
914impl<I: Instant> SendTimer<I> {
915 fn expiry(&self) -> I {
916 match self {
917 SendTimer::Retrans(RetransTimer {
918 at,
919 rto: _,
920 user_timeout_until: _,
921 remaining_retries: _,
922 })
923 | SendTimer::KeepAlive(KeepAliveTimer { at, already_sent: _ })
924 | SendTimer::ZeroWindowProbe(RetransTimer {
925 at,
926 rto: _,
927 user_timeout_until: _,
928 remaining_retries: _,
929 }) => *at,
930 SendTimer::SWSProbe { at } => *at,
931 }
932 }
933}
934
935impl<I: Instant> ReceiveTimer<I> {
936 fn expiry(&self) -> I {
937 match self {
938 ReceiveTimer::DelayedAck { at } => *at,
939 }
940 }
941}
942
943#[derive(Debug)]
945#[cfg_attr(test, derive(PartialEq, Eq))]
946enum RecvBufferState<R> {
947 Open { buffer: R, assembler: Assembler },
948 Closed { buffer_size: usize, nxt: SeqNum },
949}
950
951impl<R: ReceiveBuffer> RecvBufferState<R> {
952 fn is_closed(&self) -> bool {
953 matches!(self, Self::Closed { .. })
954 }
955
956 fn has_out_of_order(&self) -> bool {
957 match self {
958 Self::Open { assembler, .. } => assembler.has_out_of_order(),
959 Self::Closed { .. } => false,
960 }
961 }
962
963 fn close(&mut self) {
964 let new_state = match self {
965 Self::Open { buffer, assembler } => {
966 Self::Closed { nxt: assembler.nxt(), buffer_size: buffer.limits().capacity }
967 }
968 Self::Closed { .. } => return,
969 };
970 *self = new_state;
971 }
972
973 fn limits(&self) -> BufferLimits {
974 match self {
975 RecvBufferState::Open { buffer, .. } => buffer.limits(),
976 RecvBufferState::Closed { buffer_size, .. } => {
977 BufferLimits { capacity: *buffer_size, len: 0 }
978 }
979 }
980 }
981}
982
983fn quickack_counter(rcv_limits: BufferLimits, mss: EffectiveMss) -> usize {
985 const MIN_QUICKACK: usize = 2;
987 const MAX_QUICKACK: usize = 32;
991
992 let BufferLimits { capacity, len } = rcv_limits;
993 let window = capacity - len;
994 (window / (2 * usize::from(mss))).clamp(MIN_QUICKACK, MAX_QUICKACK)
1005}
1006
1007#[derive(Debug)]
1009#[cfg_attr(test, derive(PartialEq, Eq))]
1010pub(crate) struct Recv<I, R> {
1011 timer: Option<ReceiveTimer<I>>,
1012 mss: EffectiveMss,
1013 wnd_scale: WindowScale,
1014 last_window_update: (SeqNum, WindowSize),
1015 remaining_quickacks: usize,
1016 last_segment_at: Option<I>,
1017 sack_permitted: bool,
1020
1021 buffer: RecvBufferState<R>,
1023 ts_opt: TimestampOptionState<I>,
1024}
1025
1026impl<I> Recv<I, ()> {
1027 fn with_buffer<R>(self, buffer: R) -> Recv<I, R> {
1028 let Self {
1029 timer,
1030 mss,
1031 wnd_scale,
1032 last_window_update,
1033 buffer: old_buffer,
1034 remaining_quickacks,
1035 last_segment_at,
1036 sack_permitted,
1037 ts_opt,
1038 } = self;
1039 let nxt = match old_buffer {
1040 RecvBufferState::Open { assembler, .. } => assembler.nxt(),
1041 RecvBufferState::Closed { .. } => unreachable!(),
1042 };
1043 Recv {
1044 timer,
1045 mss,
1046 wnd_scale,
1047 last_window_update,
1048 remaining_quickacks,
1049 last_segment_at,
1050 buffer: RecvBufferState::Open { buffer, assembler: Assembler::new(nxt) },
1051 sack_permitted,
1052 ts_opt,
1053 }
1054 }
1055}
1056
1057impl<I, R> Recv<I, R> {
1058 fn sack_blocks(&self) -> SackBlocks {
1059 if self.sack_permitted {
1060 match &self.buffer {
1061 RecvBufferState::Open { buffer: _, assembler } => {
1062 assembler.sack_blocks(SackBlockSizeLimiters {
1063 timestamp_enabled: self.ts_opt.is_enabled(),
1064 })
1065 }
1066 RecvBufferState::Closed { buffer_size: _, nxt: _ } => SackBlocks::default(),
1067 }
1068 } else {
1069 SackBlocks::default()
1071 }
1072 }
1073}
1074
1075impl<I: Instant, R> Recv<I, R> {
1076 fn timestamp_option_for_ack(&self, now: I) -> Option<TimestampOption> {
1077 self.ts_opt.make_option_for_ack(now).map(TxTimestampOption::into)
1078 }
1079}
1080
1081struct WindowSizeCalculation {
1083 rcv_nxt: SeqNum,
1086 window_size: WindowSize,
1088 threshold: usize,
1094}
1095
1096impl<I: Instant, R: ReceiveBuffer> Recv<I, R> {
1097 fn calculate_window_size(&self) -> WindowSizeCalculation {
1099 let rcv_nxt = self.nxt();
1100 let Self {
1101 buffer,
1102 timer: _,
1103 mss,
1104 wnd_scale: _,
1105 last_window_update: (rcv_wup, last_wnd),
1106 remaining_quickacks: _,
1107 last_segment_at: _,
1108 sack_permitted: _,
1109 ts_opt: _,
1110 } = self;
1111
1112 let BufferLimits { capacity, len } = buffer.limits();
1124
1125 let unused_window = u32::try_from(*rcv_wup + *last_wnd - rcv_nxt).unwrap_or(0);
1131 let unused_window = WindowSize::from_u32(unused_window).unwrap_or(WindowSize::MAX);
1133
1134 let reduction = capacity.saturating_sub(len.saturating_add(usize::from(unused_window)));
1138 let threshold = usize::min(capacity / 2, usize::from(mss.get()));
1139 let window_size = if reduction >= threshold {
1140 WindowSize::new(capacity - len).unwrap_or(WindowSize::MAX)
1142 } else {
1143 unused_window
1146 };
1147 WindowSizeCalculation { rcv_nxt, window_size, threshold }
1148 }
1149
1150 fn poll_receive_data_dequeued(&mut self, snd_max: SeqNum, now: I) -> Option<Segment<()>> {
1153 let WindowSizeCalculation { rcv_nxt, window_size: calculated_window_size, threshold } =
1154 self.calculate_window_size();
1155 let (rcv_wup, last_window_size) = self.last_window_update;
1156
1157 let rcv_diff = rcv_nxt - rcv_wup;
1163 debug_assert!(rcv_diff >= 0, "invalid RCV.NXT change: {rcv_nxt:?} < {rcv_wup:?}");
1164 let last_window_size =
1165 last_window_size.saturating_sub(usize::try_from(rcv_diff).unwrap_or(0));
1166
1167 let effective_window_size = (calculated_window_size >> self.wnd_scale) << self.wnd_scale;
1172 let effective_window_size_usize: usize = effective_window_size.into();
1175 let last_window_size_usize: usize = last_window_size.into();
1176
1177 if last_window_size_usize < threshold && effective_window_size_usize >= threshold {
1183 let ack = self.nxt();
1184 self.last_window_update = (rcv_nxt, calculated_window_size);
1186 self.ts_opt.process_tx_ack(ack);
1187 self.timer = None;
1190 Some(Segment::ack(
1191 snd_max,
1192 ack,
1193 calculated_window_size >> self.wnd_scale,
1194 SegmentOptions {
1195 sack_blocks: self.sack_blocks(),
1196 timestamp: self.timestamp_option_for_ack(now),
1197 },
1198 ))
1199 } else {
1200 None
1201 }
1202 }
1203
1204 pub(crate) fn nxt(&self) -> SeqNum {
1205 match &self.buffer {
1206 RecvBufferState::Open { assembler, .. } => assembler.nxt(),
1207 RecvBufferState::Closed { nxt, .. } => *nxt,
1208 }
1209 }
1210
1211 fn poll_send(&mut self, snd_max: SeqNum, now: I) -> Option<Segment<()>> {
1212 match self.timer {
1213 Some(ReceiveTimer::DelayedAck { at }) => (at <= now).then(|| {
1214 self.timer = None;
1215 self.make_ack(snd_max, now)
1216 }),
1217 None => None,
1218 }
1219 }
1220
1221 fn handle_fin(&self) -> RecvParams<I> {
1223 let WindowSizeCalculation { rcv_nxt, window_size, threshold: _ } =
1224 self.calculate_window_size();
1225 RecvParams {
1226 ack: rcv_nxt + 1,
1227 wnd: window_size.checked_sub(1).unwrap_or(WindowSize::ZERO),
1228 wnd_scale: self.wnd_scale,
1229 ts_opt: self.ts_opt.clone(),
1230 }
1231 }
1232
1233 fn reset_quickacks(&mut self) {
1234 let Self {
1235 timer: _,
1236 mss,
1237 wnd_scale: _,
1238 last_window_update: _,
1239 remaining_quickacks,
1240 buffer,
1241 last_segment_at: _,
1242 sack_permitted: _,
1243 ts_opt: _,
1244 } = self;
1245 let new_remaining = quickack_counter(buffer.limits(), *mss);
1246 *remaining_quickacks = new_remaining.max(*remaining_quickacks);
1248 }
1249}
1250
1251impl<'a, I: Instant, R: ReceiveBuffer> RecvSegmentArgumentsProvider<'a, I> for &'a mut Recv<I, R> {
1252 fn take_rcv_segment_args(
1253 self,
1254 ) -> (SeqNum, UnscaledWindowSize, SackBlocks, &'a TimestampOptionState<I>) {
1255 let WindowSizeCalculation { rcv_nxt, window_size, threshold: _ } =
1256 self.calculate_window_size();
1257 self.last_window_update = (rcv_nxt, window_size);
1259 self.ts_opt.process_tx_ack(rcv_nxt);
1260 (rcv_nxt, window_size >> self.wnd_scale, self.sack_blocks(), &self.ts_opt)
1261 }
1262}
1263
1264#[derive(Debug, Clone)]
1266#[cfg_attr(test, derive(PartialEq, Eq))]
1267pub(super) struct RecvParams<I> {
1268 pub(super) ack: SeqNum,
1269 pub(super) wnd_scale: WindowScale,
1270 pub(super) wnd: WindowSize,
1271 ts_opt: TimestampOptionState<I>,
1272}
1273
1274impl<I: Instant> RecvParams<I> {
1275 fn timestamp_option_for_ack(&self, now: I) -> Option<TimestampOption> {
1276 self.ts_opt.make_option_for_ack(now).map(TxTimestampOption::into)
1277 }
1278
1279 fn timestamp_option_for_non_ack(&self, now: I) -> Option<TimestampOption> {
1280 self.ts_opt.make_option_for_non_ack(now).map(TxTimestampOption::into)
1281 }
1282}
1283
1284impl<'a, I: Instant> RecvSegmentArgumentsProvider<'a, I> for &'a mut RecvParams<I> {
1285 fn take_rcv_segment_args(
1286 self,
1287 ) -> (SeqNum, UnscaledWindowSize, SackBlocks, &'a TimestampOptionState<I>) {
1288 self.ts_opt.process_tx_ack(self.ack);
1290 (self.ack, self.wnd >> self.wnd_scale, SackBlocks::default(), &self.ts_opt)
1291 }
1292}
1293
1294enum CalculatedRecvParams<'a, I, R> {
1296 Recv { backing_state: &'a mut Recv<I, R>, cached_window: WindowSizeCalculation },
1297 RecvParams { backing_state: &'a mut RecvParams<I> },
1298}
1299
1300impl<'a, I, R> CalculatedRecvParams<'a, I, R> {
1301 fn from_params(params: &'a mut RecvParams<I>) -> Self {
1306 Self::RecvParams { backing_state: params }
1307 }
1308
1309 fn nxt(&self) -> SeqNum {
1310 match self {
1311 Self::Recv { backing_state: _, cached_window } => cached_window.rcv_nxt,
1312 Self::RecvParams { backing_state } => backing_state.ack,
1313 }
1314 }
1315
1316 fn wnd(&self) -> WindowSize {
1317 match self {
1318 Self::Recv { backing_state: _, cached_window } => cached_window.window_size,
1319 Self::RecvParams { backing_state } => backing_state.wnd,
1320 }
1321 }
1322
1323 fn ts_opt(&self) -> &TimestampOptionState<I> {
1324 match self {
1325 Self::Recv { backing_state, cached_window: _ } => &backing_state.ts_opt,
1326 Self::RecvParams { backing_state } => &backing_state.ts_opt,
1327 }
1328 }
1329
1330 fn ts_opt_mut(&mut self) -> &mut TimestampOptionState<I> {
1331 match self {
1332 Self::Recv { backing_state, cached_window: _ } => &mut backing_state.ts_opt,
1333 Self::RecvParams { backing_state } => &mut backing_state.ts_opt,
1334 }
1335 }
1336}
1337
1338impl<'a, I: Instant, R: ReceiveBuffer> CalculatedRecvParams<'a, I, R> {
1339 fn reset_quickacks(&mut self) {
1340 match self {
1341 CalculatedRecvParams::Recv { backing_state, cached_window: _ } => {
1342 backing_state.reset_quickacks();
1343 }
1344 CalculatedRecvParams::RecvParams { backing_state: _ } => {}
1345 }
1346 }
1347}
1348
1349impl<'a, I: Instant, R> RecvSegmentArgumentsProvider<'a, I> for CalculatedRecvParams<'a, I, R> {
1350 fn take_rcv_segment_args(
1351 self,
1352 ) -> (SeqNum, UnscaledWindowSize, SackBlocks, &'a TimestampOptionState<I>) {
1353 let (ack, wnd, wnd_scale, sack_blocks, ts_opt) = match self {
1354 Self::Recv {
1355 backing_state,
1356 cached_window: WindowSizeCalculation { rcv_nxt, window_size, threshold: _ },
1357 } => {
1358 backing_state.last_window_update = (rcv_nxt, window_size);
1360 backing_state.ts_opt.process_tx_ack(rcv_nxt);
1361 (
1362 rcv_nxt,
1363 window_size,
1364 backing_state.wnd_scale,
1365 backing_state.sack_blocks(),
1366 &backing_state.ts_opt,
1367 )
1368 }
1369 Self::RecvParams { backing_state: RecvParams { ack, wnd_scale, wnd, ts_opt } } => {
1370 ts_opt.process_tx_ack(*ack);
1372 (*ack, *wnd, *wnd_scale, SackBlocks::default(), &*ts_opt)
1373 }
1374 };
1375 (ack, wnd >> wnd_scale, sack_blocks, ts_opt)
1376 }
1377}
1378
1379impl<'a, I: Instant, R: ReceiveBuffer> CalculatedRecvParams<'a, I, R> {
1380 fn from_recv(recv: &'a mut Recv<I, R>) -> Self {
1381 let cached_window = recv.calculate_window_size();
1382 Self::Recv { backing_state: recv, cached_window }
1383 }
1384}
1385
1386trait RecvSegmentArgumentsProvider<'a, I: Instant>: Sized {
1387 fn take_rcv_segment_args(
1392 self,
1393 ) -> (SeqNum, UnscaledWindowSize, SackBlocks, &'a TimestampOptionState<I>);
1394
1395 fn make_segment<
1398 P,
1399 F: FnOnce(SeqNum, UnscaledWindowSize, SackBlocks, &TimestampOptionState<I>) -> Segment<P>,
1400 >(
1401 self,
1402 f: F,
1403 ) -> Segment<P> {
1404 let (ack, wnd, sack, ts_opt) = self.take_rcv_segment_args();
1405 f(ack, wnd, sack, ts_opt)
1406 }
1407
1408 fn make_ack<P: Payload>(self, seq: SeqNum, now: I) -> Segment<P> {
1411 let (ack, wnd, sack_blocks, ts_opt) = self.take_rcv_segment_args();
1412 Segment::ack(
1413 seq,
1414 ack,
1415 wnd,
1416 SegmentOptions {
1421 sack_blocks,
1422 timestamp: ts_opt.make_option_for_ack(now).map(TxTimestampOption::into),
1423 },
1424 )
1425 }
1426}
1427
1428#[derive(Debug)]
1443#[cfg_attr(test, derive(PartialEq, Eq))]
1444pub struct Established<I, R, S> {
1445 pub(crate) snd: Takeable<Send<I, S, { FinQueued::NO }>>,
1446 pub(crate) rcv: Takeable<Recv<I, R>>,
1447}
1448
1449#[derive(Debug, Clone, Copy, PartialEq)]
1452pub(crate) enum DataAcked {
1453 Yes,
1454 No,
1455}
1456
1457impl<I: Instant, S: SendBuffer, const FIN_QUEUED: bool> Send<I, S, FIN_QUEUED> {
1458 fn timed_out(&self, now: I, keep_alive: &KeepAlive) -> bool {
1460 match self.timer {
1461 Some(SendTimer::KeepAlive(keep_alive_timer)) => {
1462 keep_alive.enabled && keep_alive_timer.already_sent >= keep_alive.count.get()
1463 }
1464 Some(SendTimer::Retrans(timer)) | Some(SendTimer::ZeroWindowProbe(timer)) => {
1465 timer.timed_out(now)
1466 }
1467 Some(SendTimer::SWSProbe { at: _ }) | None => false,
1468 }
1469 }
1470
1471 fn poll_send<'a>(
1477 &mut self,
1478 id: &impl StateMachineDebugId,
1479 counters: &TcpCountersRefs<'_>,
1480 rcv: impl RecvSegmentArgumentsProvider<'a, I>,
1481 now: I,
1482 SocketOptions {
1483 keep_alive,
1484 nagle_enabled,
1485 user_timeout,
1486 delayed_ack: _,
1487 fin_wait2_timeout: _,
1488 max_syn_retries: _,
1489 ip_options: _,
1490 }: &SocketOptions,
1491 ) -> Option<Segment<S::Payload<'_>>> {
1492 let Self {
1493 nxt: snd_nxt,
1494 max: snd_max,
1495 una: snd_una,
1496 wnd: snd_wnd,
1497 buffer,
1498 wl1: _,
1499 wl2: _,
1500 last_push,
1501 rtt_sampler,
1502 rtt_estimator,
1503 timer,
1504 congestion_control,
1505 wnd_scale: _,
1506 wnd_max: snd_wnd_max,
1507 } = self;
1508 let BufferLimits { capacity: _, len: readable_bytes } = buffer.limits();
1509 let mss = congestion_control.mss();
1510 let mut zero_window_probe = false;
1511 let mut override_sws = false;
1512
1513 match timer {
1514 Some(SendTimer::Retrans(retrans_timer)) => {
1515 if retrans_timer.at <= now {
1516 congestion_control.on_retransmission_timeout(*snd_nxt);
1531 *snd_nxt = *snd_una;
1532 retrans_timer.backoff(now);
1533 counters.increment(|c| &c.timeouts);
1534 }
1535 }
1536 Some(SendTimer::ZeroWindowProbe(retrans_timer)) => {
1537 debug_assert!(readable_bytes > 0 || FIN_QUEUED);
1538 if retrans_timer.at <= now {
1539 zero_window_probe = true;
1540 *snd_nxt = *snd_una;
1541 retrans_timer.backoff(now);
1545 }
1546 }
1547 Some(SendTimer::KeepAlive(KeepAliveTimer { at, already_sent })) => {
1548 if keep_alive.enabled && !FIN_QUEUED && readable_bytes == 0 {
1553 if *at <= now {
1554 *at = now.saturating_add(keep_alive.interval.into());
1555 *already_sent = already_sent.saturating_add(1);
1556 return Some(rcv.make_ack(*snd_max - 1, now));
1559 }
1560 } else {
1561 *timer = None;
1562 }
1563 }
1564 Some(SendTimer::SWSProbe { at }) => {
1565 if *at <= now {
1566 override_sws = true;
1567 *timer = None;
1568 }
1569 }
1570 None => {}
1571 };
1572
1573 if *snd_wnd == WindowSize::ZERO && readable_bytes > 0 {
1576 match timer {
1577 Some(SendTimer::ZeroWindowProbe(_)) => {}
1578 _ => {
1579 *timer = Some(SendTimer::ZeroWindowProbe(RetransTimer::new(
1580 now,
1581 rtt_estimator.rto(),
1582 *user_timeout,
1583 DEFAULT_MAX_RETRIES,
1584 )));
1585
1586 return None;
1595 }
1596 }
1597 }
1598
1599 let CongestionControlSendOutcome {
1604 next_seg,
1605 congestion_limit,
1606 congestion_window,
1607 loss_recovery,
1608 } = congestion_control.poll_send(*snd_una, *snd_nxt, *snd_wnd, readable_bytes)?;
1609
1610 let snd_limit = *snd_una + *snd_wnd;
1614 let unused_window = u32::try_from(snd_limit - next_seg).ok_checked::<TryFromIntError>()?;
1615 let offset =
1616 usize::try_from(next_seg - *snd_una).unwrap_or_else(|TryFromIntError { .. }| {
1617 panic!("next_seg({:?}) should never fall behind snd.una({:?})", next_seg, *snd_una);
1618 });
1619 let available = u32::try_from(readable_bytes + usize::from(FIN_QUEUED) - offset)
1620 .unwrap_or_else(|_| WindowSize::MAX.into());
1621 let can_send = unused_window
1625 .min(congestion_limit)
1626 .min(available)
1627 .min(u32::from(mss))
1628 .max(u32::from(zero_window_probe));
1629
1630 if can_send == 0 {
1631 if available == 0 && offset == 0 && timer.is_none() && keep_alive.enabled {
1632 *timer = Some(SendTimer::KeepAlive(KeepAliveTimer::idle(now, keep_alive)));
1633 }
1634 return None;
1635 }
1636
1637 let has_fin = FIN_QUEUED && can_send == available;
1638 let seg = buffer.peek_with(offset, |readable| {
1639 let bytes_to_send = u32::min(
1640 can_send - u32::from(has_fin),
1641 u32::try_from(readable.len()).unwrap_or(u32::MAX),
1642 );
1643 let has_fin = has_fin && bytes_to_send == can_send - u32::from(has_fin);
1644
1645 let loss_recovery_allow_delay = match loss_recovery {
1653 LossRecoverySegment::Yes { rearm_retransmit: _, mode: _ } => false,
1654 LossRecoverySegment::No => true,
1655 };
1656 if bytes_to_send < u32::from(mss) && !has_fin && loss_recovery_allow_delay {
1657 if bytes_to_send == 0 {
1658 return None;
1659 }
1660 if *nagle_enabled && snd_nxt.after(*snd_una) {
1668 return None;
1669 }
1670 if available > unused_window
1699 && unused_window
1700 < u32::min(u32::from(mss), u32::from(*snd_wnd_max) / SWS_BUFFER_FACTOR)
1701 && !override_sws
1702 && !zero_window_probe
1703 {
1704 if timer.is_none() {
1705 *timer =
1706 Some(SendTimer::SWSProbe { at: now.panicking_add(SWS_PROBE_TIMEOUT) })
1707 }
1708 return None;
1709 }
1710 }
1711
1712 let seg = rcv.make_segment(|ack, wnd, sack_blocks, ts_opt| {
1713 let options = SegmentOptions {
1714 sack_blocks,
1715 timestamp: ts_opt.make_option_for_ack(now).map(TxTimestampOption::into),
1720 };
1721 let bytes_to_send = bytes_to_send.min(u32::from(mss.payload_size(&options).get()));
1723
1724 let no_more_data_to_send = u32::try_from(readable_bytes - offset)
1739 .is_ok_and(|avail| avail == bytes_to_send);
1740
1741 let periodic_push =
1742 next_seg.after_or_eq(*last_push + snd_wnd_max.halved().max(WindowSize::ONE));
1743 let push = no_more_data_to_send || periodic_push;
1744 let (seg, discarded) = Segment::new(
1745 SegmentHeader {
1746 seq: next_seg,
1747 ack: Some(ack),
1748 control: has_fin.then_some(Control::FIN),
1749 wnd,
1750 options: Options::Segment(options),
1751 push,
1752 },
1753 readable.slice(0..bytes_to_send),
1754 );
1755 debug_assert_eq!(discarded, 0);
1756 seg
1757 });
1758 Some(seg)
1759 })?;
1760 trace_instant!(c"tcp::Send::poll_send/segment",
1761 "id" => id.trace_id(),
1762 "seq" => u32::from(next_seg),
1763 "len" => seg.len(),
1764 "can_send" => can_send,
1765 "snd_wnd" => u32::from(*snd_wnd),
1766 "cwnd" => congestion_window,
1767 "unused_window" => unused_window,
1768 "available" => available,
1769 );
1770 let seq_max = next_seg + seg.len();
1771 rtt_sampler.on_will_send_segment(now, next_seg..seq_max, *snd_max);
1772 congestion_control.on_will_send_segment(seg.len());
1773
1774 if seq_max.after(*snd_nxt) {
1775 *snd_nxt = seq_max;
1776 } else {
1777 match loss_recovery {
1780 LossRecoverySegment::Yes { rearm_retransmit: _, ref mode } => match mode {
1781 LossRecoveryMode::FastRecovery => counters.increment(|c| &c.fast_retransmits),
1782 LossRecoveryMode::SackRecovery => counters.increment(|c| &c.sack_retransmits),
1783 },
1784 LossRecoverySegment::No => (),
1785 }
1786 }
1787 if seq_max.after(*snd_max) {
1788 *snd_max = seq_max;
1789 } else {
1790 counters.increment(|c| &c.retransmits);
1792 if congestion_control.in_slow_start() {
1793 counters.increment(|c| &c.slow_start_retransmits);
1794 }
1795 }
1796
1797 if seg.header().push {
1799 *last_push = seg.header().seq;
1800 }
1801
1802 let update_rto = match timer {
1808 Some(SendTimer::Retrans(_)) | Some(SendTimer::ZeroWindowProbe(_)) => {
1809 match loss_recovery {
1812 LossRecoverySegment::Yes { rearm_retransmit, mode: _ } => rearm_retransmit,
1813 LossRecoverySegment::No => false,
1814 }
1815 }
1816 Some(SendTimer::KeepAlive(_)) | Some(SendTimer::SWSProbe { at: _ }) | None => true,
1817 };
1818 if update_rto {
1819 *timer = Some(SendTimer::Retrans(RetransTimer::new(
1820 now,
1821 rtt_estimator.rto(),
1822 *user_timeout,
1823 DEFAULT_MAX_RETRIES,
1824 )))
1825 }
1826 Some(seg)
1827 }
1828
1829 fn process_ack<'a, R: RecvSegmentArgumentsProvider<'a, I>>(
1832 &mut self,
1833 id: &impl StateMachineDebugId,
1834 counters: &TcpCountersRefs<'_>,
1835 seg_seq: SeqNum,
1836 seg_ack: SeqNum,
1837 seg_wnd: UnscaledWindowSize,
1838 seg_sack_blocks: &SackBlocks,
1839 pure_ack: bool,
1840 rcv: R,
1841 now: I,
1842 SocketOptions {
1843 keep_alive,
1844 nagle_enabled: _,
1845 user_timeout,
1846 delayed_ack: _,
1847 fin_wait2_timeout: _,
1848 max_syn_retries: _,
1849 ip_options: _,
1850 }: &SocketOptions,
1851 ) -> (Option<Segment<()>>, DataAcked) {
1852 let Self {
1853 nxt: snd_nxt,
1854 max: snd_max,
1855 una: snd_una,
1856 wnd: snd_wnd,
1857 wl1: snd_wl1,
1858 wl2: snd_wl2,
1859 last_push: _,
1860 wnd_max,
1861 buffer,
1862 rtt_sampler,
1863 rtt_estimator,
1864 timer,
1865 congestion_control,
1866 wnd_scale,
1867 } = self;
1868 let seg_wnd = seg_wnd << *wnd_scale;
1869 match timer {
1870 Some(SendTimer::KeepAlive(_)) | None => {
1871 if keep_alive.enabled {
1872 *timer = Some(SendTimer::KeepAlive(KeepAliveTimer::idle(now, keep_alive)));
1873 }
1874 }
1875 Some(SendTimer::Retrans(retrans_timer)) => {
1876 if seg_ack == *snd_max {
1884 *timer = None;
1885 } else if seg_ack.before(*snd_max) && seg_ack.after(*snd_una) {
1886 *retrans_timer = RetransTimer::new(
1887 now,
1888 rtt_estimator.rto(),
1889 *user_timeout,
1890 DEFAULT_MAX_RETRIES,
1891 );
1892 }
1893 }
1894 Some(SendTimer::ZeroWindowProbe(_)) | Some(SendTimer::SWSProbe { at: _ }) => {}
1895 }
1896 if seg_ack.after(*snd_max) {
1900 return (Some(rcv.make_ack(*snd_max, now)), DataAcked::No);
1905 }
1906
1907 let bytes_acked = match u32::try_from(seg_ack - *snd_una) {
1908 Ok(acked) => NonZeroU32::new(acked),
1909 Err(TryFromIntError { .. }) => {
1910 return (None, DataAcked::No);
1913 }
1914 };
1915
1916 let is_dup_ack_by_sack =
1917 congestion_control.preprocess_ack(seg_ack, *snd_nxt, seg_sack_blocks);
1918 let (is_dup_ack, data_acked) = if let Some(acked) = bytes_acked {
1919 let BufferLimits { len, capacity: _ } = buffer.limits();
1920 let fin_acked = FIN_QUEUED && seg_ack == *snd_una + len + 1;
1921 buffer.mark_read(
1926 NonZeroUsize::try_from(acked)
1927 .unwrap_or_else(|TryFromIntError { .. }| {
1928 panic!(
1932 "acked({:?}) must be smaller than isize::MAX({:?})",
1933 acked,
1934 isize::MAX
1935 )
1936 })
1937 .get()
1938 - usize::from(fin_acked),
1939 );
1940 *snd_una = seg_ack;
1941 if seg_ack.after(*snd_nxt) {
1945 *snd_nxt = seg_ack;
1946 }
1947 if let Some(rtt) = rtt_sampler.on_ack(now, seg_ack) {
1950 rtt_estimator.sample(rtt);
1951 }
1952
1953 let recovered = congestion_control.on_ack(seg_ack, acked, now, rtt_estimator.srtt());
1956 if recovered {
1957 counters.increment(|c| &c.loss_recovered);
1958 }
1959
1960 let is_dup_ack = is_dup_ack_by_sack.unwrap_or(false);
1964
1965 (is_dup_ack, DataAcked::Yes)
1967 } else {
1968 let is_dup_ack = is_dup_ack_by_sack.unwrap_or_else(|| {
1971 snd_nxt.after(*snd_una) && pure_ack && seg_ack == *snd_una && seg_wnd == *snd_wnd });
1987
1988 (is_dup_ack, DataAcked::No)
1992 };
1993
1994 if is_dup_ack {
1995 counters.increment(|c| &c.dup_acks);
1996 let new_loss_recovery = congestion_control.on_dup_ack(seg_ack, *snd_nxt);
1997 match new_loss_recovery {
1998 Some(LossRecoveryMode::FastRecovery) => counters.increment(|c| &c.fast_recovery),
1999 Some(LossRecoveryMode::SackRecovery) => counters.increment(|c| &c.sack_recovery),
2000 None => (),
2001 }
2002 }
2003
2004 if !snd_una.after(seg_ack)
2011 && (snd_wl1.before(seg_seq) || (seg_seq == *snd_wl1 && !snd_wl2.after(seg_ack)))
2012 {
2013 *snd_wnd = seg_wnd;
2014 *snd_wl1 = seg_seq;
2015 *snd_wl2 = seg_ack;
2016 *wnd_max = seg_wnd.max(*wnd_max);
2017 if seg_wnd != WindowSize::ZERO && matches!(timer, Some(SendTimer::ZeroWindowProbe(_))) {
2018 *timer = None;
2019 *snd_nxt = *snd_una;
2023 }
2024 }
2025
2026 if data_acked == DataAcked::Yes || is_dup_ack {
2028 trace_instant!(c"tcp::Send::process_ack",
2029 "id" => id.trace_id(),
2030 "seg_ack" => u32::from(seg_ack),
2031 "snd_nxt" => u32::from(*snd_nxt),
2032 "snd_wnd" => u32::from(*snd_wnd),
2033 "rtt_ms" => u32::try_from(
2034 rtt_estimator.srtt().unwrap_or(Duration::ZERO).as_millis()
2037 ).unwrap_or(u32::MAX),
2038 "cwnd" => congestion_control.inspect_cwnd().cwnd(),
2039 "ssthresh" => congestion_control.slow_start_threshold(),
2040 "loss_recovery" => congestion_control.inspect_loss_recovery_mode().is_some(),
2041 "acked" => data_acked == DataAcked::Yes,
2042 );
2043 }
2044
2045 (None, data_acked)
2046 }
2047
2048 fn update_mss(&mut self, mss: Mss, seq: SeqNum) -> ShouldRetransmit {
2049 if mss >= *self.congestion_control.mss().mss() {
2061 return ShouldRetransmit::No;
2062 }
2063
2064 self.nxt = seq;
2084
2085 self.congestion_control.update_mss(mss, self.una, self.nxt);
2088
2089 ShouldRetransmit::Yes
2098 }
2099
2100 #[cfg(test)]
2101 pub(crate) fn congestion_control(&self) -> &CongestionControl<I> {
2102 &self.congestion_control
2103 }
2104}
2105
2106impl<I: Instant, S: SendBuffer> Send<I, S, { FinQueued::NO }> {
2107 fn queue_fin(self) -> Send<I, S, { FinQueued::YES }> {
2108 let Self {
2109 nxt,
2110 max,
2111 una,
2112 wnd,
2113 wl1,
2114 wl2,
2115 last_push,
2116 buffer,
2117 rtt_sampler,
2118 rtt_estimator,
2119 timer,
2120 congestion_control,
2121 wnd_scale,
2122 wnd_max,
2123 } = self;
2124 Send {
2125 nxt,
2126 max,
2127 una,
2128 wnd,
2129 wl1,
2130 wl2,
2131 last_push,
2132 buffer,
2133 rtt_sampler,
2134 rtt_estimator,
2135 timer,
2136 congestion_control,
2137 wnd_scale,
2138 wnd_max,
2139 }
2140 }
2141}
2142
2143#[derive(Debug)]
2157#[cfg_attr(test, derive(PartialEq, Eq))]
2158pub struct CloseWait<I, S> {
2159 snd: Takeable<Send<I, S, { FinQueued::NO }>>,
2160 closed_rcv: RecvParams<I>,
2161}
2162
2163#[derive(Debug)]
2179#[cfg_attr(test, derive(PartialEq, Eq))]
2180pub struct LastAck<I, S> {
2181 snd: Send<I, S, { FinQueued::YES }>,
2182 closed_rcv: RecvParams<I>,
2183}
2184
2185#[derive(Debug)]
2200#[cfg_attr(test, derive(PartialEq, Eq))]
2201pub struct FinWait1<I, R, S> {
2202 snd: Takeable<Send<I, S, { FinQueued::YES }>>,
2203 rcv: Takeable<Recv<I, R>>,
2204}
2205
2206#[derive(Debug)]
2207#[cfg_attr(test, derive(PartialEq, Eq))]
2208pub struct FinWait2<I, R> {
2222 last_seq: SeqNum,
2223 rcv: Recv<I, R>,
2224 timeout_at: Option<I>,
2225}
2226
2227#[derive(Debug)]
2228#[cfg_attr(test, derive(PartialEq, Eq))]
2229pub struct Closing<I, S> {
2243 snd: Send<I, S, { FinQueued::YES }>,
2244 closed_rcv: RecvParams<I>,
2245}
2246
2247#[derive(Debug)]
2262#[cfg_attr(test, derive(PartialEq, Eq))]
2263pub struct TimeWait<I> {
2264 pub(super) last_seq: SeqNum,
2265 pub(super) expiry: I,
2266 pub(super) closed_rcv: RecvParams<I>,
2267}
2268
2269fn new_time_wait_expiry<I: Instant>(now: I) -> I {
2270 now.panicking_add(MSL * 2)
2271}
2272
2273#[derive(Debug)]
2274#[cfg_attr(test, derive(PartialEq, Eq))]
2275pub enum State<I, R, S, ActiveOpen> {
2276 Closed(Closed<Option<ConnectionError>>),
2277 Listen(Listen),
2278 SynRcvd(SynRcvd<I, ActiveOpen>),
2279 SynSent(SynSent<I, ActiveOpen>),
2280 Established(Established<I, R, S>),
2281 CloseWait(CloseWait<I, S>),
2282 LastAck(LastAck<I, S>),
2283 FinWait1(FinWait1<I, R, S>),
2284 FinWait2(FinWait2<I, R>),
2285 Closing(Closing<I, S>),
2286 TimeWait(TimeWait<I>),
2287}
2288
2289impl<I, R, S, ActiveOpen> core::fmt::Display for State<I, R, S, ActiveOpen> {
2290 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
2291 let name = match self {
2292 State::Closed(_) => "Closed",
2293 State::Listen(_) => "Listen",
2294 State::SynRcvd(_) => "SynRcvd",
2295 State::SynSent(_) => "SynSent",
2296 State::Established(_) => "Established",
2297 State::CloseWait(_) => "CloseWait",
2298 State::LastAck(_) => "LastAck",
2299 State::FinWait1(_) => "FinWait1",
2300 State::FinWait2(_) => "FinWait2",
2301 State::Closing(_) => "Closing",
2302 State::TimeWait(_) => "TimeWait",
2303 };
2304 write!(f, "{name}")
2305 }
2306}
2307
2308#[derive(Debug, PartialEq, Eq)]
2309pub(super) enum CloseError {
2311 Closing,
2313 NoConnection,
2315}
2316
2317pub(crate) trait BufferProvider<R: ReceiveBuffer, S: SendBuffer> {
2320 type PassiveOpen;
2323
2324 type ActiveOpen: IntoBuffers<R, S>;
2327
2328 fn new_passive_open_buffers(buffer_sizes: BufferSizes) -> (R, S, Self::PassiveOpen);
2331}
2332
2333#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2345pub(crate) struct Takeable<T>(Option<T>);
2346
2347impl<T> From<T> for Takeable<T> {
2348 fn from(value: T) -> Self {
2349 Self(Some(value))
2350 }
2351}
2352
2353impl<T> Takeable<T> {
2354 pub(crate) fn get(&self) -> &T {
2355 let Self(i) = self;
2356 i.as_ref().expect("accessed taken takeable")
2357 }
2358
2359 pub(crate) fn get_mut(&mut self) -> &mut T {
2360 let Self(i) = self;
2361 i.as_mut().expect("accessed taken takeable")
2362 }
2363
2364 pub(crate) fn new(v: T) -> Self {
2365 Self(Some(v))
2366 }
2367
2368 pub(crate) fn to_ref(&mut self) -> TakeableRef<'_, T> {
2369 TakeableRef(self)
2370 }
2371
2372 pub(crate) fn from_ref(t: TakeableRef<'_, T>) -> Self {
2373 let TakeableRef(Self(t)) = t;
2374 Self(Some(t.take().expect("accessed taken takeable")))
2375 }
2376
2377 pub(crate) fn into_inner(self) -> T {
2378 let Self(i) = self;
2379 i.expect("accessed taken takeable")
2380 }
2381
2382 pub(crate) fn map<R, F: FnOnce(T) -> R>(self, f: F) -> Takeable<R> {
2383 Takeable(Some(f(self.into_inner())))
2384 }
2385}
2386
2387impl<T> Deref for Takeable<T> {
2388 type Target = T;
2389
2390 fn deref(&self) -> &Self::Target {
2391 self.get()
2392 }
2393}
2394
2395impl<T> DerefMut for Takeable<T> {
2396 fn deref_mut(&mut self) -> &mut Self::Target {
2397 self.get_mut()
2398 }
2399}
2400
2401pub(crate) struct TakeableRef<'a, T>(&'a mut Takeable<T>);
2403
2404impl<'a, T> TakeableRef<'a, T> {
2405 pub(crate) fn take(self) -> T {
2406 let Self(Takeable(t)) = self;
2407 t.take().expect("accessed taken takeable")
2408 }
2409
2410 pub(crate) fn to_takeable(self) -> Takeable<T> {
2411 Takeable::new(self.take())
2412 }
2413}
2414
2415#[must_use = "must check to determine if the socket needs to be removed from the demux state"]
2416#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2417pub(crate) enum NewlyClosed {
2418 No,
2419 Yes,
2420}
2421
2422#[derive(Debug)]
2423pub(crate) enum ShouldRetransmit {
2424 No,
2425 Yes,
2426}
2427
2428impl<I: Instant + 'static, R: ReceiveBuffer, S: SendBuffer, ActiveOpen: Debug>
2429 State<I, R, S, ActiveOpen>
2430{
2431 fn transition_to_state(
2433 &mut self,
2434 counters: &TcpCountersRefs<'_>,
2435 new_state: State<I, R, S, ActiveOpen>,
2436 ) -> NewlyClosed {
2437 log::debug!("transition to state {} => {}", self, new_state);
2438 let newly_closed = if let State::Closed(Closed { reason }) = &new_state {
2439 let (was_established, was_closed) = match self {
2440 State::Closed(_) => (false, true),
2441 State::Listen(_) | State::SynRcvd(_) | State::SynSent(_) => (false, false),
2442 State::Established(_)
2443 | State::CloseWait(_)
2444 | State::LastAck(_)
2445 | State::FinWait1(_)
2446 | State::FinWait2(_)
2447 | State::Closing(_)
2448 | State::TimeWait(_) => (true, false),
2449 };
2450 if was_established {
2451 counters.increment(|c| &c.established_closed);
2452 match reason {
2453 Some(ConnectionError::ConnectionRefused)
2454 | Some(ConnectionError::ConnectionReset) => {
2455 counters.increment(|c| &c.established_resets);
2456 }
2457 Some(ConnectionError::TimedOut) => {
2458 counters.increment(|c| &c.established_timedout);
2459 }
2460 _ => {}
2461 }
2462 }
2463 (!was_closed).then_some(NewlyClosed::Yes).unwrap_or(NewlyClosed::No)
2464 } else {
2465 NewlyClosed::No
2466 };
2467 *self = new_state;
2468 newly_closed
2469 }
2470 pub(crate) fn on_segment<P: Payload, BP: BufferProvider<R, S, ActiveOpen = ActiveOpen>>(
2477 &mut self,
2478 id: &impl StateMachineDebugId,
2479 counters: &TcpCountersRefs<'_>,
2480 incoming: Segment<P>,
2481 now: I,
2482 options @ SocketOptions {
2483 keep_alive: _,
2484 nagle_enabled: _,
2485 user_timeout: _,
2486 delayed_ack,
2487 fin_wait2_timeout,
2488 max_syn_retries: _,
2489 ip_options: _,
2490 }: &SocketOptions,
2491 defunct: bool,
2492 ) -> (Option<Segment<()>>, Option<BP::PassiveOpen>, DataAcked, NewlyClosed)
2493 where
2494 BP::PassiveOpen: Debug,
2495 ActiveOpen: IntoBuffers<R, S>,
2496 {
2497 let mut passive_open = None;
2498 let mut data_acked = DataAcked::No;
2499 let (seg, newly_closed) = (|| {
2500 let (mut rcv, snd_max, rst_on_new_data) = match self {
2501 State::Closed(closed) => return (closed.on_segment(&incoming), NewlyClosed::No),
2502 State::Listen(listen) => {
2503 return (
2504 match listen.on_segment(incoming, now) {
2505 ListenOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
2506 syn_ack,
2507 SynRcvd {
2508 iss,
2509 irs,
2510 timestamp,
2511 retrans_timer,
2512 simultaneous_open,
2513 buffer_sizes,
2514 smss,
2515 rcv_wnd_scale,
2516 snd_wnd_scale,
2517 sack_permitted,
2518 rcv,
2519 },
2520 ) => {
2521 match simultaneous_open {
2522 None => {
2523 assert_eq!(
2524 self.transition_to_state(
2525 counters,
2526 State::SynRcvd(SynRcvd {
2527 iss,
2528 irs,
2529 timestamp,
2530 retrans_timer,
2531 simultaneous_open: None,
2532 buffer_sizes,
2533 smss,
2534 rcv_wnd_scale,
2535 snd_wnd_scale,
2536 sack_permitted,
2537 rcv,
2538 }),
2539 ),
2540 NewlyClosed::No
2541 )
2542 }
2543 }
2544 Some(syn_ack)
2545 }
2546 ListenOnSegmentDisposition::SendRst(rst) => Some(rst),
2547 ListenOnSegmentDisposition::Ignore => None,
2548 },
2549 NewlyClosed::No,
2550 );
2551 }
2552 State::SynSent(synsent) => {
2553 return match synsent.on_segment(incoming, now) {
2554 SynSentOnSegmentDisposition::SendAckAndEnterEstablished(established) => (
2555 replace_with_and(self, |this| {
2556 assert_matches!(this, State::SynSent(SynSent {
2557 active_open,
2558 buffer_sizes,
2559 ..
2560 }) => {
2561 log::debug!("transition to state SynSent => Established");
2562 let Established {snd, rcv} = established;
2563 let (rcv_buffer, snd_buffer) =
2564 active_open.into_buffers(buffer_sizes);
2565 let mut established = Established {
2566 snd: snd.map(|s| s.with_buffer(snd_buffer)),
2567 rcv: rcv.map(|s| s.with_buffer(rcv_buffer)),
2568 };
2569 let ack = Some(
2570 established.rcv.make_ack(established.snd.max, now)
2571 );
2572 (State::Established(established), ack)
2573 })
2574 }),
2575 NewlyClosed::No,
2576 ),
2577 SynSentOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
2578 syn_ack,
2579 mut syn_rcvd,
2580 ) => {
2581 log::debug!("transition to state SynSent => SynRcvd");
2582 replace_with(self, |this| {
2583 assert_matches!(this, State::SynSent(SynSent {
2584 active_open,
2585 ..
2586 }) => {
2587 assert_matches!(syn_rcvd.simultaneous_open.replace(active_open), None);
2588 State::SynRcvd(syn_rcvd)
2589 })
2590 });
2591 (Some(syn_ack), NewlyClosed::No)
2592 }
2593 SynSentOnSegmentDisposition::SendRst(rst) => (Some(rst), NewlyClosed::No),
2594 SynSentOnSegmentDisposition::EnterClosed(closed) => {
2595 assert_eq!(
2596 self.transition_to_state(counters, State::Closed(closed)),
2597 NewlyClosed::Yes,
2598 );
2599 (None, NewlyClosed::Yes)
2600 }
2601 SynSentOnSegmentDisposition::Ignore => (None, NewlyClosed::No),
2602 };
2603 }
2604 State::SynRcvd(SynRcvd {
2605 iss,
2606 irs: _,
2607 timestamp: _,
2608 retrans_timer: _,
2609 simultaneous_open: _,
2610 buffer_sizes: _,
2611 smss: _,
2612 rcv_wnd_scale: _,
2613 snd_wnd_scale: _,
2614 sack_permitted: _,
2615 rcv,
2616 }) => (CalculatedRecvParams::from_params(rcv), *iss + 1, false),
2617 State::Established(Established { rcv, snd }) => {
2618 (CalculatedRecvParams::from_recv(rcv.get_mut()), snd.max, false)
2619 }
2620 State::CloseWait(CloseWait { snd, closed_rcv }) => {
2621 (CalculatedRecvParams::from_params(closed_rcv), snd.max, true)
2622 }
2623 State::LastAck(LastAck { snd, closed_rcv })
2624 | State::Closing(Closing { snd, closed_rcv }) => {
2625 (CalculatedRecvParams::from_params(closed_rcv), snd.max, true)
2626 }
2627 State::FinWait1(FinWait1 { rcv, snd }) => {
2628 let closed = rcv.buffer.is_closed();
2629 (CalculatedRecvParams::from_recv(rcv.get_mut()), snd.max, closed)
2630 }
2631 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _ }) => {
2632 let closed = rcv.buffer.is_closed();
2633 (CalculatedRecvParams::from_recv(rcv), *last_seq, closed)
2634 }
2635 State::TimeWait(TimeWait { last_seq, expiry: _, closed_rcv }) => {
2636 (CalculatedRecvParams::from_params(closed_rcv), *last_seq, true)
2637 }
2638 };
2639
2640 if rst_on_new_data && (incoming.header().seq + incoming.data().len()).after(rcv.nxt()) {
2647 return (
2648 Some(Segment::rst(
2649 snd_max,
2650 ResetOptions {
2651 timestamp: rcv
2652 .ts_opt()
2653 .make_option_for_non_ack(now)
2654 .map(TxTimestampOption::into),
2655 },
2656 )),
2657 self.transition_to_state(
2658 counters,
2659 State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }),
2660 ),
2661 );
2662 }
2663
2664 let is_rst = incoming.header().control == Some(Control::RST);
2687 let pure_ack = incoming.len() == 0;
2689 let needs_ack = !pure_ack;
2690 let segment = match incoming.overlap(rcv.nxt(), rcv.wnd()) {
2691 Some(incoming) => incoming,
2692 None => {
2693 let segment = if is_rst {
2701 None
2702 } else {
2703 rcv.reset_quickacks();
2706 Some(rcv.make_ack(snd_max, now))
2707 };
2708
2709 return (segment, NewlyClosed::No);
2710 }
2711 };
2712 let (
2713 SegmentHeader {
2714 seq: seg_seq,
2715 ack: seg_ack,
2716 wnd: seg_wnd,
2717 control,
2718 options: seg_options,
2719 push: _,
2720 },
2721 data,
2722 ) = segment.into_parts();
2723
2724 rcv.ts_opt_mut().update_recent_timestamp(
2728 seg_seq,
2729 seg_options.timestamp().map(RxTimestampOption::from),
2730 );
2731
2732 if control == Some(Control::RST) {
2740 return (
2741 None,
2742 self.transition_to_state(
2743 counters,
2744 State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }),
2745 ),
2746 );
2747 }
2748 if control == Some(Control::SYN) {
2759 return (
2760 Some(Segment::rst(
2761 snd_max,
2762 ResetOptions {
2763 timestamp: rcv
2764 .ts_opt()
2765 .make_option_for_non_ack(now)
2766 .map(TxTimestampOption::into),
2767 },
2768 )),
2769 self.transition_to_state(
2770 counters,
2771 State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }),
2772 ),
2773 );
2774 }
2775 match seg_ack {
2778 Some(seg_ack) => match self {
2779 State::Closed(_) | State::Listen(_) | State::SynSent(_) => {
2780 unreachable!("encountered an already-handled state: {:?}", self)
2782 }
2783 State::SynRcvd(SynRcvd {
2784 iss,
2785 irs,
2786 timestamp: syn_rcvd_ts,
2787 retrans_timer: _,
2788 simultaneous_open,
2789 buffer_sizes,
2790 smss,
2791 rcv_wnd_scale,
2792 snd_wnd_scale,
2793 sack_permitted,
2794 rcv,
2795 }) => {
2796 let snd_next = *iss + 1;
2809 let rcv_next = *irs + 1;
2810 if seg_ack != snd_next {
2811 return (
2812 Some(Segment::rst(
2813 seg_ack,
2814 ResetOptions {
2815 timestamp: rcv.timestamp_option_for_non_ack(now),
2816 },
2817 )),
2818 NewlyClosed::No,
2819 );
2820 } else {
2821 let mut rtt_estimator = Estimator::default();
2822 if let Some(syn_rcvd_ts) = syn_rcvd_ts {
2823 rtt_estimator.sample(now.saturating_duration_since(*syn_rcvd_ts));
2824 }
2825 let (rcv_buffer, snd_buffer) = match simultaneous_open.take() {
2826 None => {
2827 let (rcv_buffer, snd_buffer, client) =
2828 BP::new_passive_open_buffers(*buffer_sizes);
2829 assert_matches!(passive_open.replace(client), None);
2830 (rcv_buffer, snd_buffer)
2831 }
2832 Some(active_open) => active_open.into_buffers(*buffer_sizes),
2833 };
2834 let (snd_wnd_scale, rcv_wnd_scale) = snd_wnd_scale
2835 .map(|snd_wnd_scale| (snd_wnd_scale, *rcv_wnd_scale))
2836 .unwrap_or_default();
2837 let established = Established {
2838 snd: Send {
2839 nxt: snd_next,
2840 max: snd_next,
2841 una: seg_ack,
2842 wnd: seg_wnd << snd_wnd_scale,
2843 wl1: seg_seq,
2844 wl2: seg_ack,
2845 last_push: snd_next,
2846 buffer: snd_buffer,
2847 rtt_sampler: RttSampler::default(),
2848 rtt_estimator,
2849 timer: None,
2850 congestion_control: CongestionControl::cubic_with_mss(*smss),
2851 wnd_scale: snd_wnd_scale,
2852 wnd_max: seg_wnd << snd_wnd_scale,
2853 }
2854 .into(),
2855 rcv: Recv {
2856 buffer: RecvBufferState::Open {
2857 buffer: rcv_buffer,
2858 assembler: Assembler::new(rcv_next),
2859 },
2860 timer: None,
2861 mss: *smss,
2862 wnd_scale: rcv_wnd_scale,
2863 last_segment_at: None,
2864 remaining_quickacks: quickack_counter(
2865 buffer_sizes.rcv_limits(),
2866 *smss,
2867 ),
2868 last_window_update: (rcv_next, buffer_sizes.rwnd()),
2869 sack_permitted: *sack_permitted,
2870 ts_opt: rcv.ts_opt.clone(),
2871 }
2872 .into(),
2873 };
2874 assert_eq!(
2875 self.transition_to_state(counters, State::Established(established)),
2876 NewlyClosed::No
2877 );
2878 }
2879 }
2883 State::Established(Established { snd, rcv }) => {
2884 let (ack, segment_acked_data) = snd.process_ack(
2885 id,
2886 counters,
2887 seg_seq,
2888 seg_ack,
2889 seg_wnd,
2890 seg_options.sack_blocks(),
2891 pure_ack,
2892 rcv.get_mut(),
2893 now,
2894 options,
2895 );
2896 data_acked = segment_acked_data;
2897 if let Some(ack) = ack {
2898 return (Some(ack), NewlyClosed::No);
2899 }
2900 }
2901 State::CloseWait(CloseWait { snd, closed_rcv }) => {
2902 let (ack, segment_acked_data) = snd.process_ack(
2903 id,
2904 counters,
2905 seg_seq,
2906 seg_ack,
2907 seg_wnd,
2908 seg_options.sack_blocks(),
2909 pure_ack,
2910 closed_rcv,
2911 now,
2912 options,
2913 );
2914 data_acked = segment_acked_data;
2915 if let Some(ack) = ack {
2916 return (Some(ack), NewlyClosed::No);
2917 }
2918 }
2919 State::LastAck(LastAck { snd, closed_rcv }) => {
2920 let BufferLimits { len, capacity: _ } = snd.buffer.limits();
2921 let fin_seq = snd.una + len + 1;
2922 let (ack, segment_acked_data) = snd.process_ack(
2923 id,
2924 counters,
2925 seg_seq,
2926 seg_ack,
2927 seg_wnd,
2928 seg_options.sack_blocks(),
2929 pure_ack,
2930 closed_rcv,
2931 now,
2932 options,
2933 );
2934 data_acked = segment_acked_data;
2935 if let Some(ack) = ack {
2936 return (Some(ack), NewlyClosed::No);
2937 } else if seg_ack == fin_seq {
2938 return (
2939 None,
2940 self.transition_to_state(
2941 counters,
2942 State::Closed(Closed { reason: None }),
2943 ),
2944 );
2945 }
2946 }
2947 State::FinWait1(FinWait1 { snd, rcv }) => {
2948 let BufferLimits { len, capacity: _ } = snd.buffer.limits();
2949 let fin_seq = snd.una + len + 1;
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 } else if seg_ack == fin_seq {
2966 let last_seq = snd.nxt;
2972 let finwait2 = FinWait2 {
2973 last_seq,
2974 rcv: rcv.to_ref().take(),
2975 timeout_at: fin_wait2_timeout.and_then(|timeout| {
2979 defunct.then_some(now.saturating_add(timeout))
2980 }),
2981 };
2982 assert_eq!(
2983 self.transition_to_state(counters, State::FinWait2(finwait2)),
2984 NewlyClosed::No
2985 );
2986 }
2987 }
2988 State::Closing(Closing { snd, closed_rcv }) => {
2989 let BufferLimits { len, capacity: _ } = snd.buffer.limits();
2990 let fin_seq = snd.una + len + 1;
2991 let (ack, segment_acked_data) = {
2992 let closed_rcv: &mut RecvParams<I> = closed_rcv;
2996 snd.process_ack(
2997 id,
2998 counters,
2999 seg_seq,
3000 seg_ack,
3001 seg_wnd,
3002 seg_options.sack_blocks(),
3003 pure_ack,
3004 closed_rcv,
3005 now,
3006 options,
3007 )
3008 };
3009 data_acked = segment_acked_data;
3010 if let Some(ack) = ack {
3011 data_acked = segment_acked_data;
3012 return (Some(ack), NewlyClosed::No);
3013 } else if seg_ack == fin_seq {
3014 let timewait = TimeWait {
3019 last_seq: snd.nxt,
3020 expiry: new_time_wait_expiry(now),
3021 closed_rcv: closed_rcv.clone(),
3022 };
3023 assert_eq!(
3024 self.transition_to_state(counters, State::TimeWait(timewait)),
3025 NewlyClosed::No
3026 );
3027 }
3028 }
3029 State::FinWait2(_) | State::TimeWait(_) => {}
3030 },
3031 None => return (None, NewlyClosed::No),
3034 }
3035 let maybe_ack_to_text = |rcv: &mut Recv<I, R>, rto: Rto| {
3057 if !needs_ack {
3058 return (None, rcv.nxt());
3059 }
3060
3061 if let Some(last) = rcv.last_segment_at.replace(now) {
3065 if now.saturating_duration_since(last) >= rto.get() {
3066 rcv.reset_quickacks();
3067 }
3068 }
3069
3070 let had_out_of_order = rcv.buffer.has_out_of_order();
3073 if data.len() > 0 {
3074 let offset = usize::try_from(seg_seq - rcv.nxt()).unwrap_or_else(|TryFromIntError {..}| {
3075 panic!("The segment was trimmed to fit the window, thus seg.seq({:?}) must not come before rcv.nxt({:?})", seg_seq, rcv.nxt());
3076 });
3077 match &mut rcv.buffer {
3078 RecvBufferState::Open { buffer, assembler } => {
3079 let nwritten = buffer.write_at(offset, &data);
3080 let readable = assembler.insert(seg_seq..seg_seq + nwritten);
3081 buffer.make_readable(readable, assembler.has_outstanding());
3082 }
3083 RecvBufferState::Closed { nxt, .. } => *nxt = seg_seq + data.len(),
3084 }
3085 }
3086 let immediate_ack = !*delayed_ack
3092 || had_out_of_order
3093 || rcv.buffer.has_out_of_order()
3094 || rcv.remaining_quickacks != 0
3096 || rcv.timer.is_some();
3121
3122 if immediate_ack {
3123 rcv.timer = None;
3124 } else {
3125 rcv.timer = Some(ReceiveTimer::DelayedAck {
3126 at: now.panicking_add(ACK_DELAY_THRESHOLD),
3127 });
3128 }
3129 let segment =
3130 (!matches!(rcv.timer, Some(ReceiveTimer::DelayedAck { .. }))).then(|| {
3131 rcv.remaining_quickacks = rcv.remaining_quickacks.saturating_sub(1);
3132 rcv.make_ack(snd_max, now)
3133 });
3134 (segment, rcv.nxt())
3135 };
3136
3137 let (ack_to_text, rcv_nxt) = match self {
3138 State::Closed(_) | State::Listen(_) | State::SynRcvd(_) | State::SynSent(_) => {
3139 unreachable!("encountered an already-handled state: {:?}", self)
3141 }
3142 State::Established(Established { snd, rcv }) => {
3143 maybe_ack_to_text(rcv.get_mut(), snd.rtt_estimator.rto())
3144 }
3145 State::FinWait1(FinWait1 { snd, rcv }) => {
3146 maybe_ack_to_text(rcv.get_mut(), snd.rtt_estimator.rto())
3147 }
3148 State::FinWait2(FinWait2 { last_seq: _, rcv, timeout_at: _ }) => {
3149 maybe_ack_to_text(rcv, Rto::DEFAULT)
3150 }
3151 State::CloseWait(CloseWait { closed_rcv, .. })
3152 | State::LastAck(LastAck { closed_rcv, .. })
3153 | State::Closing(Closing { closed_rcv, .. })
3154 | State::TimeWait(TimeWait { closed_rcv, .. }) => {
3155 (None, closed_rcv.ack)
3159 }
3160 };
3161 let ack_to_fin = if control == Some(Control::FIN) && rcv_nxt == seg_seq + data.len() {
3164 match self {
3169 State::Closed(_) | State::Listen(_) | State::SynRcvd(_) | State::SynSent(_) => {
3170 unreachable!("encountered an already-handled state: {:?}", self)
3172 }
3173 State::Established(Established { snd, rcv }) => {
3174 let mut params = rcv.handle_fin();
3177 let segment = params.make_ack(snd_max, now);
3178 let closewait =
3179 CloseWait { snd: snd.to_ref().to_takeable(), closed_rcv: params };
3180 assert_eq!(
3181 self.transition_to_state(counters, State::CloseWait(closewait)),
3182 NewlyClosed::No
3183 );
3184 Some(segment)
3185 }
3186 State::CloseWait(_) | State::LastAck(_) | State::Closing(_) => {
3187 None
3195 }
3196 State::FinWait1(FinWait1 { snd, rcv }) => {
3197 let mut params = rcv.handle_fin();
3198 let segment = params.make_ack(snd_max, now);
3199 let closing = Closing { snd: snd.to_ref().take(), closed_rcv: params };
3200 assert_eq!(
3201 self.transition_to_state(counters, State::Closing(closing)),
3202 NewlyClosed::No
3203 );
3204 Some(segment)
3205 }
3206 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _ }) => {
3207 let mut params = rcv.handle_fin();
3208 let segment = params.make_ack(snd_max, now);
3209 let timewait = TimeWait {
3210 last_seq: *last_seq,
3211 expiry: new_time_wait_expiry(now),
3212 closed_rcv: params,
3213 };
3214 assert_eq!(
3215 self.transition_to_state(counters, State::TimeWait(timewait)),
3216 NewlyClosed::No,
3217 );
3218 Some(segment)
3219 }
3220 State::TimeWait(TimeWait { last_seq, expiry, closed_rcv }) => {
3221 *expiry = new_time_wait_expiry(now);
3226 Some(closed_rcv.make_ack(*last_seq, now))
3227 }
3228 }
3229 } else {
3230 None
3231 };
3232 (ack_to_fin.or(ack_to_text), NewlyClosed::No)
3235 })();
3236 (seg, passive_open, data_acked, newly_closed)
3237 }
3238
3239 pub(crate) fn poll_receive_data_dequeued(&mut self, now: I) -> Option<Segment<()>> {
3243 let (rcv, snd_max) = match self {
3244 State::Closed(_)
3245 | State::Listen(_)
3246 | State::SynRcvd(_)
3247 | State::SynSent(_)
3248 | State::CloseWait(_)
3249 | State::LastAck(_)
3250 | State::Closing(_)
3251 | State::TimeWait(_) => return None,
3252 State::Established(Established { snd, rcv }) => (rcv.get_mut(), snd.max),
3253 State::FinWait1(FinWait1 { snd, rcv }) => (rcv.get_mut(), snd.max),
3254 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _ }) => (rcv, *last_seq),
3255 };
3256
3257 rcv.poll_receive_data_dequeued(snd_max, now)
3258 }
3259
3260 pub(crate) fn poll_send(
3268 &mut self,
3269 id: &impl StateMachineDebugId,
3270 counters: &TcpCountersRefs<'_>,
3271 now: I,
3272 socket_options: &SocketOptions,
3273 ) -> Result<Segment<S::Payload<'_>>, NewlyClosed> {
3274 let newly_closed = self.poll_close(counters, now, socket_options);
3275 if matches!(self, State::Closed(_)) {
3276 return Err(newly_closed);
3277 }
3278 fn poll_rcv_then_snd<
3279 'a,
3280 I: Instant,
3281 R: ReceiveBuffer,
3282 S: SendBuffer,
3283 M: StateMachineDebugId,
3284 const FIN_QUEUED: bool,
3285 >(
3286 id: &M,
3287 counters: &TcpCountersRefs<'_>,
3288 snd: &'a mut Send<I, S, FIN_QUEUED>,
3289 rcv: &'a mut Recv<I, R>,
3290 now: I,
3291 socket_options: &SocketOptions,
3292 ) -> Option<Segment<S::Payload<'a>>> {
3293 let seg = rcv
3299 .poll_send(snd.max, now)
3300 .map(|seg| seg.into_empty())
3301 .or_else(|| snd.poll_send(id, counters, &mut *rcv, now, socket_options));
3302 if seg.is_some() && matches!(rcv.timer, Some(ReceiveTimer::DelayedAck { .. })) {
3304 rcv.timer = None;
3305 }
3306 seg
3307 }
3308 let seg = match self {
3309 State::SynSent(SynSent {
3310 iss,
3311 timestamp,
3312 retrans_timer,
3313 active_open: _,
3314 buffer_sizes: _,
3315 device_mss,
3316 default_mss: _,
3317 rcv_wnd_scale,
3318 ts_opt,
3319 }) => (retrans_timer.at <= now).then(|| {
3320 *timestamp = None;
3321 retrans_timer.backoff(now);
3322 Segment::syn(
3323 *iss,
3324 UnscaledWindowSize::from(u16::MAX),
3325 HandshakeOptions {
3326 mss: Some(*device_mss),
3327 window_scale: Some(*rcv_wnd_scale),
3328 sack_permitted: SACK_PERMITTED,
3329 timestamp: ts_opt.make_option_for_syn(now).map(TxTimestampOption::into),
3330 },
3331 )
3332 }),
3333 State::SynRcvd(SynRcvd {
3334 iss,
3335 irs,
3336 timestamp,
3337 retrans_timer,
3338 simultaneous_open: _,
3339 buffer_sizes: _,
3340 smss,
3341 rcv_wnd_scale,
3342 snd_wnd_scale,
3343 sack_permitted: _,
3344 rcv,
3345 }) => (retrans_timer.at <= now).then(|| {
3346 *timestamp = None;
3347 retrans_timer.backoff(now);
3348 Segment::syn_ack(
3349 *iss,
3350 *irs + 1,
3351 UnscaledWindowSize::from(u16::MAX),
3352 HandshakeOptions {
3353 mss: Some(*smss.mss()),
3354 window_scale: snd_wnd_scale.map(|_| *rcv_wnd_scale),
3355 sack_permitted: SACK_PERMITTED,
3356 timestamp: rcv.timestamp_option_for_ack(now),
3361 },
3362 )
3363 }),
3364 State::Established(Established { snd, rcv }) => {
3365 poll_rcv_then_snd(id, counters, snd, rcv, now, socket_options)
3366 }
3367 State::CloseWait(CloseWait { snd, closed_rcv }) => {
3368 snd.poll_send(id, counters, closed_rcv, now, socket_options)
3369 }
3370 State::LastAck(LastAck { snd, closed_rcv })
3371 | State::Closing(Closing { snd, closed_rcv }) => {
3372 snd.poll_send(id, counters, closed_rcv, now, socket_options)
3373 }
3374 State::FinWait1(FinWait1 { snd, rcv }) => {
3375 poll_rcv_then_snd(id, counters, snd, rcv, now, socket_options)
3376 }
3377 State::FinWait2(FinWait2 { last_seq, rcv, timeout_at: _ }) => {
3378 rcv.poll_send(*last_seq, now).map(|seg| seg.into_empty())
3379 }
3380 State::Closed(_) | State::Listen(_) | State::TimeWait(_) => None,
3381 };
3382 seg.ok_or(NewlyClosed::No)
3383 }
3384
3385 fn poll_close(
3389 &mut self,
3390 counters: &TcpCountersRefs<'_>,
3391 now: I,
3392 SocketOptions {
3393 keep_alive,
3394 nagle_enabled: _,
3395 user_timeout: _,
3396 delayed_ack: _,
3397 fin_wait2_timeout: _,
3398 max_syn_retries: _,
3399 ip_options: _,
3400 }: &SocketOptions,
3401 ) -> NewlyClosed {
3402 let timed_out = match self {
3403 State::Established(Established { snd, rcv: _ }) => snd.timed_out(now, keep_alive),
3404 State::CloseWait(CloseWait { snd, closed_rcv: _ }) => snd.timed_out(now, keep_alive),
3405 State::LastAck(LastAck { snd, closed_rcv: _ })
3406 | State::Closing(Closing { snd, closed_rcv: _ }) => snd.timed_out(now, keep_alive),
3407 State::FinWait1(FinWait1 { snd, rcv: _ }) => snd.timed_out(now, keep_alive),
3408 State::SynSent(SynSent { retrans_timer, .. })
3409 | State::SynRcvd(SynRcvd { retrans_timer, .. }) => retrans_timer.timed_out(now),
3410
3411 State::Closed(_) | State::Listen(_) | State::TimeWait(_) => false,
3412 State::FinWait2(FinWait2 { last_seq: _, rcv: _, timeout_at }) => {
3413 timeout_at.map(|at| now >= at).unwrap_or(false)
3414 }
3415 };
3416 if timed_out {
3417 return self.transition_to_state(
3418 counters,
3419 State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }),
3420 );
3421 } else if let State::TimeWait(tw) = self {
3422 if tw.expiry <= now {
3423 return self.transition_to_state(counters, State::Closed(Closed { reason: None }));
3424 }
3425 }
3426 NewlyClosed::No
3427 }
3428
3429 pub(crate) fn poll_send_at(&self) -> Option<I> {
3448 let combine_expiry = |e1: Option<I>, e2: Option<I>| match (e1, e2) {
3449 (None, None) => None,
3450 (None, Some(e2)) => Some(e2),
3451 (Some(e1), None) => Some(e1),
3452 (Some(e1), Some(e2)) => Some(e1.min(e2)),
3453 };
3454 match self {
3455 State::Established(Established { snd, rcv }) => combine_expiry(
3456 snd.timer.as_ref().map(SendTimer::expiry),
3457 rcv.timer.as_ref().map(ReceiveTimer::expiry),
3458 ),
3459 State::CloseWait(CloseWait { snd, closed_rcv: _ }) => Some(snd.timer?.expiry()),
3460 State::LastAck(LastAck { snd, closed_rcv: _ })
3461 | State::Closing(Closing { snd, closed_rcv: _ }) => Some(snd.timer?.expiry()),
3462 State::FinWait1(FinWait1 { snd, rcv }) => combine_expiry(
3463 snd.timer.as_ref().map(SendTimer::expiry),
3464 rcv.timer.as_ref().map(ReceiveTimer::expiry),
3465 ),
3466 State::FinWait2(FinWait2 { last_seq: _, rcv, timeout_at }) => {
3467 combine_expiry(*timeout_at, rcv.timer.as_ref().map(ReceiveTimer::expiry))
3468 }
3469 State::SynRcvd(syn_rcvd) => Some(syn_rcvd.retrans_timer.at),
3470 State::SynSent(syn_sent) => Some(syn_sent.retrans_timer.at),
3471 State::Closed(_) | State::Listen(_) => None,
3472 State::TimeWait(TimeWait { last_seq: _, expiry, closed_rcv: _ }) => Some(*expiry),
3473 }
3474 }
3475
3476 pub(super) fn close(
3483 &mut self,
3484 counters: &TcpCountersRefs<'_>,
3485 close_reason: CloseReason<I>,
3486 socket_options: &SocketOptions,
3487 ) -> Result<NewlyClosed, CloseError>
3488 where
3489 ActiveOpen: IntoBuffers<R, S>,
3490 {
3491 match self {
3492 State::Closed(_) => Err(CloseError::NoConnection),
3493 State::Listen(_) | State::SynSent(_) => {
3494 Ok(self.transition_to_state(counters, State::Closed(Closed { reason: None })))
3495 }
3496 State::SynRcvd(SynRcvd {
3497 iss,
3498 irs,
3499 timestamp: _,
3500 retrans_timer: _,
3501 simultaneous_open,
3502 buffer_sizes,
3503 smss,
3504 rcv_wnd_scale,
3505 snd_wnd_scale,
3506 sack_permitted,
3507 rcv: RecvParams { ack: _, wnd_scale: _, wnd: _, ts_opt },
3508 }) => {
3509 let (rcv_buffer, snd_buffer) = simultaneous_open
3529 .take()
3530 .expect(
3531 "a SYN-RCVD state that is in the pending queue \
3532 should call abort instead of close",
3533 )
3534 .into_buffers(*buffer_sizes);
3535 let (snd_wnd_scale, rcv_wnd_scale) = snd_wnd_scale
3539 .map(|snd_wnd_scale| (snd_wnd_scale, *rcv_wnd_scale))
3540 .unwrap_or_default();
3541 let next = *iss + 1;
3542 let finwait1 = FinWait1 {
3543 snd: Send {
3544 nxt: next,
3545 max: next,
3546 una: next,
3547 wnd: WindowSize::DEFAULT,
3548 wl1: *iss,
3549 wl2: *irs,
3550 last_push: next,
3551 buffer: snd_buffer,
3552 rtt_sampler: RttSampler::default(),
3553 rtt_estimator: Estimator::NoSample,
3554 timer: None,
3555 congestion_control: CongestionControl::cubic_with_mss(*smss),
3556 wnd_scale: snd_wnd_scale,
3557 wnd_max: WindowSize::DEFAULT,
3558 }
3559 .into(),
3560 rcv: Recv {
3561 buffer: RecvBufferState::Open {
3562 buffer: rcv_buffer,
3563 assembler: Assembler::new(*irs + 1),
3564 },
3565 timer: None,
3566 mss: *smss,
3567 remaining_quickacks: quickack_counter(buffer_sizes.rcv_limits(), *smss),
3568 last_segment_at: None,
3569 wnd_scale: rcv_wnd_scale,
3570 last_window_update: (*irs + 1, buffer_sizes.rwnd()),
3571 sack_permitted: *sack_permitted,
3572 ts_opt: ts_opt.clone(),
3573 }
3574 .into(),
3575 };
3576 Ok(self.transition_to_state(counters, State::FinWait1(finwait1)))
3577 }
3578 State::Established(Established { snd, rcv }) => {
3579 let finwait1 = FinWait1 {
3585 snd: snd.to_ref().take().queue_fin().into(),
3586 rcv: rcv.to_ref().to_takeable(),
3587 };
3588 Ok(self.transition_to_state(counters, State::FinWait1(finwait1)))
3589 }
3590 State::CloseWait(CloseWait { snd, closed_rcv }) => {
3591 let lastack = LastAck {
3592 snd: snd.to_ref().take().queue_fin(),
3593 closed_rcv: closed_rcv.clone(),
3594 };
3595 Ok(self.transition_to_state(counters, State::LastAck(lastack)))
3596 }
3597 State::LastAck(_) | State::FinWait1(_) | State::Closing(_) | State::TimeWait(_) => {
3598 Err(CloseError::Closing)
3599 }
3600 State::FinWait2(FinWait2 { last_seq: _, rcv: _, timeout_at }) => {
3601 if let (CloseReason::Close { now }, Some(fin_wait2_timeout)) =
3602 (close_reason, socket_options.fin_wait2_timeout)
3603 {
3604 assert_eq!(timeout_at.replace(now.saturating_add(fin_wait2_timeout)), None);
3605 }
3606 Err(CloseError::Closing)
3607 }
3608 }
3609 }
3610
3611 pub(super) fn shutdown_recv(&mut self) -> Result<(), CloseError> {
3612 match self {
3613 State::Closed(_) => Err(CloseError::NoConnection),
3614
3615 State::Listen(_)
3616 | State::SynSent(_)
3617 | State::SynRcvd(_)
3618 | State::CloseWait(_)
3619 | State::LastAck(_)
3620 | State::Closing(_)
3621 | State::TimeWait(_) => Ok(()),
3622
3623 State::Established(Established { rcv, .. }) | State::FinWait1(FinWait1 { rcv, .. }) => {
3625 rcv.buffer.close();
3626 Ok(())
3627 }
3628 State::FinWait2(FinWait2 { rcv, .. }) => {
3629 rcv.buffer.close();
3630 Ok(())
3631 }
3632 }
3633 }
3634
3635 pub(crate) fn abort(
3638 &mut self,
3639 counters: &TcpCountersRefs<'_>,
3640 now: I,
3641 reason: ConnectionError,
3642 ) -> (Option<Segment<()>>, NewlyClosed) {
3643 let reply = match self {
3644 State::Closed(_)
3657 | State::Listen(_)
3658 | State::SynSent(_)
3659 | State::Closing(_)
3660 | State::LastAck(_)
3661 | State::TimeWait(_) => None,
3662 State::SynRcvd(SynRcvd {
3674 iss,
3675 irs,
3676 timestamp: _,
3677 retrans_timer: _,
3678 simultaneous_open: _,
3679 buffer_sizes: _,
3680 smss: _,
3681 rcv_wnd_scale: _,
3682 snd_wnd_scale: _,
3683 sack_permitted: _,
3684 rcv,
3685 }) => {
3686 Some(Segment::rst_ack(
3689 *iss + 1,
3690 *irs + 1,
3691 ResetOptions { timestamp: rcv.timestamp_option_for_ack(now) },
3692 ))
3693 }
3694 State::Established(Established { snd, rcv }) => Some(Segment::rst_ack(
3695 snd.nxt,
3696 rcv.nxt(),
3697 ResetOptions { timestamp: rcv.timestamp_option_for_ack(now) },
3698 )),
3699 State::FinWait1(FinWait1 { snd, rcv }) => Some(Segment::rst_ack(
3700 snd.nxt,
3701 rcv.nxt(),
3702 ResetOptions { timestamp: rcv.timestamp_option_for_ack(now) },
3703 )),
3704 State::FinWait2(FinWait2 { rcv, last_seq, timeout_at: _ }) => Some(Segment::rst_ack(
3705 *last_seq,
3706 rcv.nxt(),
3707 ResetOptions { timestamp: rcv.timestamp_option_for_ack(now) },
3708 )),
3709 State::CloseWait(CloseWait { snd, closed_rcv }) => Some(Segment::rst_ack(
3710 snd.nxt,
3711 closed_rcv.ack,
3712 ResetOptions { timestamp: closed_rcv.timestamp_option_for_ack(now) },
3713 )),
3714 };
3715 (reply, self.transition_to_state(counters, State::Closed(Closed { reason: Some(reason) })))
3716 }
3717
3718 pub(crate) fn buffers_mut(&mut self) -> BuffersRefMut<'_, R, S> {
3719 match self {
3720 State::TimeWait(_) | State::Closed(_) => BuffersRefMut::NoBuffers,
3721 State::Listen(Listen { buffer_sizes, .. })
3722 | State::SynRcvd(SynRcvd { buffer_sizes, .. })
3723 | State::SynSent(SynSent { buffer_sizes, .. }) => BuffersRefMut::Sizes(buffer_sizes),
3724 State::Established(Established { snd, rcv }) => match &mut rcv.buffer {
3725 RecvBufferState::Open { buffer: recv_buf, .. } => {
3726 BuffersRefMut::Both { send: &mut snd.buffer, recv: recv_buf }
3727 }
3728 RecvBufferState::Closed { .. } => BuffersRefMut::SendOnly(&mut snd.buffer),
3729 },
3730 State::FinWait1(FinWait1 { snd, rcv }) => match &mut rcv.buffer {
3731 RecvBufferState::Open { buffer: recv_buf, .. } => {
3732 BuffersRefMut::Both { send: &mut snd.buffer, recv: recv_buf }
3733 }
3734 RecvBufferState::Closed { .. } => BuffersRefMut::SendOnly(&mut snd.buffer),
3735 },
3736 State::FinWait2(FinWait2::<I, R> { rcv, .. }) => match &mut rcv.buffer {
3737 RecvBufferState::Open { buffer: recv_buf, .. } => BuffersRefMut::RecvOnly(recv_buf),
3738 RecvBufferState::Closed { .. } => BuffersRefMut::NoBuffers,
3739 },
3740 State::Closing(Closing::<I, S> { snd, .. })
3741 | State::LastAck(LastAck::<I, S> { snd, .. }) => {
3742 BuffersRefMut::SendOnly(&mut snd.buffer)
3743 }
3744 State::CloseWait(CloseWait::<I, S> { snd, .. }) => {
3745 BuffersRefMut::SendOnly(&mut snd.buffer)
3746 }
3747 }
3748 }
3749
3750 pub(super) fn on_icmp_error(
3753 &mut self,
3754 counters: &TcpCountersRefs<'_>,
3755 err: IcmpErrorCode,
3756 seq: SeqNum,
3757 ) -> (Option<ConnectionError>, NewlyClosed, ShouldRetransmit) {
3758 let Some(result) = IcmpErrorResult::try_from_icmp_error(err) else {
3759 return (None, NewlyClosed::No, ShouldRetransmit::No);
3760 };
3761 let err = match result {
3762 IcmpErrorResult::ConnectionError(err) => err,
3763 IcmpErrorResult::PmtuUpdate(mms) => {
3764 let mss = Mss::from_mms(mms).unwrap_or(Mss::MIN);
3766 let should_send = self.on_pmtu_update(mss, seq);
3767 return (None, NewlyClosed::No, should_send);
3768 }
3769 };
3770 let connect_error = match self {
3791 State::Closed(_) => None,
3792 State::Listen(listen) => unreachable!(
3793 "ICMP errors should not be delivered on a listener, received code {:?} on {:?}",
3794 err, listen
3795 ),
3796 State::SynRcvd(SynRcvd {
3797 iss,
3798 irs: _,
3799 timestamp: _,
3800 retrans_timer: _,
3801 simultaneous_open: _,
3802 buffer_sizes: _,
3803 smss: _,
3804 rcv_wnd_scale: _,
3805 snd_wnd_scale: _,
3806 sack_permitted: _,
3807 rcv: _,
3808 })
3809 | State::SynSent(SynSent {
3810 iss,
3811 timestamp: _,
3812 retrans_timer: _,
3813 active_open: _,
3814 buffer_sizes: _,
3815 device_mss: _,
3816 default_mss: _,
3817 rcv_wnd_scale: _,
3818 ts_opt: _,
3819 }) => {
3820 if *iss == seq {
3821 return (
3822 None,
3823 self.transition_to_state(
3824 counters,
3825 State::Closed(Closed { reason: Some(err) }),
3826 ),
3827 ShouldRetransmit::No,
3828 );
3829 }
3830 None
3831 }
3832 State::Established(Established { snd, rcv: _ })
3833 | State::CloseWait(CloseWait { snd, closed_rcv: _ }) => {
3834 (!snd.una.after(seq) && seq.before(snd.nxt)).then_some(err)
3835 }
3836 State::LastAck(LastAck { snd, closed_rcv: _ })
3837 | State::Closing(Closing { snd, closed_rcv: _ }) => {
3838 (!snd.una.after(seq) && seq.before(snd.nxt)).then_some(err)
3839 }
3840 State::FinWait1(FinWait1 { snd, rcv: _ }) => {
3841 (!snd.una.after(seq) && seq.before(snd.nxt)).then_some(err)
3842 }
3843 State::FinWait2(_) | State::TimeWait(_) => None,
3846 };
3847 (connect_error, NewlyClosed::No, ShouldRetransmit::No)
3848 }
3849
3850 fn on_pmtu_update(&mut self, mss: Mss, seq: SeqNum) -> ShouldRetransmit {
3851 match self {
3854 State::Listen(listen) => unreachable!(
3855 "PMTU updates should not be delivered to a listener, received {mss:?} on {listen:?}"
3856 ),
3857 State::Closed(_)
3858 | State::SynRcvd(_)
3859 | State::SynSent(_)
3860 | State::FinWait2(_)
3861 | State::TimeWait(_) => {}
3862 State::Established(Established { snd, .. })
3863 | State::CloseWait(CloseWait { snd, .. }) => {
3864 if !snd.una.after(seq) && seq.before(snd.nxt) {
3865 return snd.update_mss(mss, seq);
3866 }
3867 }
3868 State::LastAck(LastAck { snd, .. }) | State::Closing(Closing { snd, .. }) => {
3869 if !snd.una.after(seq) && seq.before(snd.nxt) {
3870 return snd.update_mss(mss, seq);
3871 }
3872 }
3873 State::FinWait1(FinWait1 { snd, .. }) => {
3874 if !snd.una.after(seq) && seq.before(snd.nxt) {
3875 return snd.update_mss(mss, seq);
3876 }
3877 }
3878 }
3879 ShouldRetransmit::No
3880 }
3881}
3882
3883pub(super) enum CloseReason<I: Instant> {
3887 Shutdown,
3888 Close { now: I },
3889}
3890
3891#[cfg(test)]
3892mod test {
3893 use alloc::vec;
3894 use alloc::vec::Vec;
3895 use core::fmt::Debug;
3896 use core::time::Duration;
3897
3898 use assert_matches::assert_matches;
3899 use netstack3_base::sync::ResourceTokenValue;
3900 use netstack3_base::testutil::{FakeInstant, FakeInstantCtx};
3901 use netstack3_base::{
3902 CounterCollection, FragmentedPayload, InstantContext as _, Milliseconds, Options,
3903 SackBlock, Timestamp, TimestampOption, Unitless,
3904 };
3905 use packet::InnerPacketBuilder as _;
3906 use test_case::{test_case, test_matrix};
3907
3908 use super::*;
3909 use crate::internal::base::DEFAULT_FIN_WAIT2_TIMEOUT;
3910 use crate::internal::buffer::Buffer;
3911 use crate::internal::buffer::testutil::{InfiniteSendBuffer, RepeatingSendBuffer, RingBuffer};
3912 use crate::internal::congestion::DUP_ACK_THRESHOLD;
3913 use crate::internal::counters::TcpCountersWithSocketInner;
3914 use crate::internal::counters::testutil::CounterExpectations;
3915 use crate::internal::timestamp::{TS_ECHO_REPLY_FOR_NON_ACKS, TimestampValueState};
3916
3917 const TEST_IRS: SeqNum = SeqNum::new(100);
3918 const TEST_ISS: SeqNum = SeqNum::new(300);
3919
3920 const ISS_1: SeqNum = SeqNum::new(500);
3921 const ISS_2: SeqNum = SeqNum::new(700);
3922
3923 const RTT: Duration = Duration::from_millis(500);
3924
3925 const DEVICE_MAXIMUM_SEGMENT_SIZE: Mss = Mss::new(1400).unwrap();
3926
3927 const TEST_MSS: EffectiveMss =
3928 EffectiveMss::from_mss(Mss::new(256).unwrap(), MssSizeLimiters { timestamp_enabled: true });
3929 const BUFFER_SIZE: usize = (TEST_MSS.get() as usize) * 3;
3931 const TEST_BYTES: &[u8] = &[0xab; TEST_MSS.get() as usize];
3933
3934 const TIMESTAMP_OFFSET: Timestamp<Milliseconds> = Timestamp::new(12345);
3937
3938 const DEFAULT_TIMESTAMP: Timestamp<Unitless> = TIMESTAMP_OFFSET.discard_unit();
3940 const DEFAULT_NON_ACK_TS_OPT: TimestampOption =
3942 TimestampOption::new(DEFAULT_TIMESTAMP, TS_ECHO_REPLY_FOR_NON_ACKS);
3943 const DEFAULT_ACK_TS_OPT: TimestampOption = TimestampOption::new(
3945 DEFAULT_TIMESTAMP,
3948 DEFAULT_TIMESTAMP,
3949 );
3950
3951 const RTT_TIMESTAMP: Timestamp<Unitless> =
3955 Timestamp::new(TIMESTAMP_OFFSET.get() + RTT.as_millis() as u32);
3956 const NON_ACK_TS_OPT_AFTER_RTT: TimestampOption =
3959 TimestampOption::new(RTT_TIMESTAMP, TS_ECHO_REPLY_FOR_NON_ACKS);
3960 const ACK_TS_OPT_AFTER_RTT: TimestampOption =
3963 TimestampOption::new(RTT_TIMESTAMP, DEFAULT_TIMESTAMP);
3964
3965 const fn default_ts_opt_state(last_ack: SeqNum) -> TimestampOptionState<FakeInstant> {
3966 TimestampOptionState::Enabled {
3967 ts_recent: DEFAULT_TIMESTAMP,
3971 last_ack_sent: last_ack,
3972 ts_val: TimestampValueState {
3973 offset: TIMESTAMP_OFFSET,
3974 initialized_at: FakeInstant { offset: Duration::ZERO },
3975 },
3976 }
3977 }
3978
3979 const fn default_ts_opt_negotiation_state() -> TimestampOptionNegotiationState<FakeInstant> {
3980 TimestampOptionNegotiationState::Negotiating(TimestampValueState {
3981 offset: TIMESTAMP_OFFSET,
3982 initialized_at: FakeInstant { offset: Duration::ZERO },
3983 })
3984 }
3985
3986 const fn default_segment_options(
3987 ts_val: Timestamp<Unitless>,
3988 ts_echo_reply: Timestamp<Unitless>,
3989 ) -> SegmentOptions {
3990 SegmentOptions {
3991 sack_blocks: SackBlocks::EMPTY,
3992 timestamp: Some(TimestampOption::new(ts_val, ts_echo_reply)),
3993 }
3994 }
3995
3996 const DEFAULT_SEGMENT_OPTIONS: SegmentOptions =
3997 default_segment_options(DEFAULT_TIMESTAMP, DEFAULT_TIMESTAMP);
3998
3999 fn timestamp_now(clock: &FakeInstantCtx) -> Timestamp<Unitless> {
4000 (TIMESTAMP_OFFSET + clock.now().offset).discard_unit()
4001 }
4002
4003 fn default_quickack_counter() -> usize {
4004 quickack_counter(
4005 BufferLimits { capacity: WindowSize::DEFAULT.into(), len: 0 },
4006 EffectiveMss::from_mss(
4007 DEVICE_MAXIMUM_SEGMENT_SIZE,
4008 MssSizeLimiters { timestamp_enabled: true },
4009 ),
4010 )
4011 }
4012
4013 impl SocketOptions {
4014 fn default_for_state_tests() -> Self {
4015 Self { delayed_ack: false, nagle_enabled: false, ..Default::default() }
4018 }
4019 }
4020
4021 enum ClientlessBufferProvider {}
4024
4025 impl<R: ReceiveBuffer + Default, S: SendBuffer + Default> BufferProvider<R, S>
4026 for ClientlessBufferProvider
4027 {
4028 type PassiveOpen = ();
4029 type ActiveOpen = ();
4030
4031 fn new_passive_open_buffers(_buffer_sizes: BufferSizes) -> (R, S, Self::PassiveOpen) {
4032 (R::default(), S::default(), ())
4033 }
4034 }
4035
4036 impl RingBuffer {
4037 fn with_data<'a>(cap: usize, data: &'a [u8]) -> Self {
4038 let mut buffer = RingBuffer::new(cap);
4039 let nwritten = buffer.write_at(0, &data);
4040 assert_eq!(nwritten, data.len());
4041 buffer.make_readable(nwritten, false);
4042 buffer
4043 }
4044 }
4045
4046 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
4048 struct NullBuffer;
4049
4050 impl Buffer for NullBuffer {
4051 fn limits(&self) -> BufferLimits {
4052 BufferLimits { len: 0, capacity: 0 }
4053 }
4054
4055 fn target_capacity(&self) -> usize {
4056 0
4057 }
4058
4059 fn request_capacity(&mut self, _size: usize) {}
4060 }
4061
4062 impl ReceiveBuffer for NullBuffer {
4063 fn write_at<P: Payload>(&mut self, _offset: usize, _data: &P) -> usize {
4064 0
4065 }
4066
4067 fn make_readable(&mut self, count: usize, has_outstanding: bool) {
4068 assert_eq!(count, 0);
4069 assert_eq!(has_outstanding, false);
4070 }
4071 }
4072
4073 impl SendBuffer for NullBuffer {
4074 type Payload<'a> = &'a [u8];
4075
4076 fn mark_read(&mut self, count: usize) {
4077 assert_eq!(count, 0);
4078 }
4079
4080 fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
4081 where
4082 F: FnOnce(Self::Payload<'a>) -> R,
4083 {
4084 assert_eq!(offset, 0);
4085 f(&[])
4086 }
4087 }
4088
4089 #[derive(Debug, Default)]
4090 struct FakeStateMachineDebugId {
4091 resource_token: ResourceTokenValue,
4092 }
4093
4094 impl StateMachineDebugId for FakeStateMachineDebugId {
4095 fn trace_id(&self) -> TraceResourceId<'_> {
4096 TraceResourceId::new(self.resource_token.token())
4097 }
4098 }
4099
4100 impl<R: ReceiveBuffer, S: SendBuffer> State<FakeInstant, R, S, ()> {
4101 fn poll_send_with_default_options(
4102 &mut self,
4103 now: FakeInstant,
4104 counters: &TcpCountersRefs<'_>,
4105 ) -> Option<Segment<S::Payload<'_>>> {
4106 self.poll_send(
4107 &FakeStateMachineDebugId::default(),
4108 counters,
4109 now,
4110 &SocketOptions::default_for_state_tests(),
4111 )
4112 .ok()
4113 }
4114
4115 fn on_segment_with_default_options<P: Payload, BP: BufferProvider<R, S, ActiveOpen = ()>>(
4116 &mut self,
4117 incoming: Segment<P>,
4118 now: FakeInstant,
4119 counters: &TcpCountersRefs<'_>,
4120 ) -> (Option<Segment<()>>, Option<BP::PassiveOpen>)
4121 where
4122 BP::PassiveOpen: Debug,
4123 R: Default,
4124 S: Default,
4125 {
4126 self.on_segment_with_options::<_, BP>(
4127 incoming,
4128 now,
4129 counters,
4130 &SocketOptions::default_for_state_tests(),
4131 )
4132 }
4133
4134 fn on_segment_with_options<P: Payload, BP: BufferProvider<R, S, ActiveOpen = ()>>(
4135 &mut self,
4136 incoming: Segment<P>,
4137 now: FakeInstant,
4138 counters: &TcpCountersRefs<'_>,
4139 options: &SocketOptions,
4140 ) -> (Option<Segment<()>>, Option<BP::PassiveOpen>)
4141 where
4142 BP::PassiveOpen: Debug,
4143 R: Default,
4144 S: Default,
4145 {
4146 let (segment, passive_open, _data_acked, _newly_closed) = self.on_segment::<P, BP>(
4147 &FakeStateMachineDebugId::default(),
4148 counters,
4149 incoming,
4150 now,
4151 options,
4152 false, );
4154 (segment, passive_open)
4155 }
4156
4157 fn recv_mut(&mut self) -> Option<&mut Recv<FakeInstant, R>> {
4158 match self {
4159 State::Closed(_)
4160 | State::Listen(_)
4161 | State::SynRcvd(_)
4162 | State::SynSent(_)
4163 | State::CloseWait(_)
4164 | State::LastAck(_)
4165 | State::Closing(_)
4166 | State::TimeWait(_) => None,
4167 State::Established(Established { rcv, .. })
4168 | State::FinWait1(FinWait1 { rcv, .. }) => Some(rcv.get_mut()),
4169 State::FinWait2(FinWait2 { rcv, .. }) => Some(rcv),
4170 }
4171 }
4172
4173 #[track_caller]
4174 fn assert_established(&mut self) -> &mut Established<FakeInstant, R, S> {
4175 assert_matches!(self, State::Established(e) => e)
4176 }
4177 }
4178
4179 impl<S: SendBuffer + Debug> State<FakeInstant, RingBuffer, S, ()> {
4180 fn read_with(&mut self, f: impl for<'b> FnOnce(&'b [&'_ [u8]]) -> usize) -> usize {
4181 match self {
4182 State::Closed(_)
4183 | State::Listen(_)
4184 | State::SynRcvd(_)
4185 | State::SynSent(_)
4186 | State::CloseWait(_)
4187 | State::LastAck(_)
4188 | State::Closing(_)
4189 | State::TimeWait(_) => {
4190 panic!("No receive state in {:?}", self);
4191 }
4192 State::Established(Established { snd: _, rcv })
4193 | State::FinWait1(FinWait1 { snd: _, rcv }) => {
4194 assert_matches!(&mut rcv.buffer, RecvBufferState::Open{ buffer, .. } => buffer.read_with(f))
4195 }
4196 State::FinWait2(FinWait2 { last_seq: _, rcv, timeout_at: _ }) => {
4197 assert_matches!(&mut rcv.buffer, RecvBufferState::Open{ buffer, .. } => buffer.read_with(f))
4198 }
4199 }
4200 }
4201 }
4202
4203 impl State<FakeInstant, RingBuffer, NullBuffer, ()> {
4204 fn new_syn_rcvd(instant: FakeInstant) -> Self {
4205 State::SynRcvd(SynRcvd {
4206 iss: TEST_ISS,
4207 irs: TEST_IRS,
4208 timestamp: Some(instant),
4209 retrans_timer: RetransTimer::new(instant, Rto::DEFAULT, None, DEFAULT_MAX_RETRIES),
4210 simultaneous_open: Some(()),
4211 buffer_sizes: Default::default(),
4212 smss: EffectiveMss::from_mss(
4213 DEVICE_MAXIMUM_SEGMENT_SIZE,
4214 MssSizeLimiters { timestamp_enabled: true },
4215 ),
4216 rcv_wnd_scale: WindowScale::default(),
4217 snd_wnd_scale: Some(WindowScale::default()),
4218 sack_permitted: SACK_PERMITTED,
4219 rcv: RecvParams {
4220 ack: TEST_IRS + 1,
4221 wnd: WindowSize::DEFAULT,
4222 wnd_scale: WindowScale::default(),
4223 ts_opt: default_ts_opt_state(TEST_IRS + 1),
4224 },
4225 })
4226 }
4227 }
4228
4229 impl<S, const FIN_QUEUED: bool> Send<FakeInstant, S, FIN_QUEUED> {
4230 fn default_for_test_at(seq: SeqNum, buffer: S) -> Self {
4231 Self {
4232 nxt: seq,
4233 max: seq,
4234 una: seq,
4235 wnd: WindowSize::DEFAULT,
4236 wnd_max: WindowSize::DEFAULT,
4237 buffer,
4238 wl1: TEST_IRS + 1,
4239 wl2: seq,
4240 last_push: seq,
4241 rtt_estimator: Estimator::default(),
4242 rtt_sampler: RttSampler::default(),
4243 timer: None,
4244 congestion_control: CongestionControl::cubic_with_mss(EffectiveMss::from_mss(
4245 DEVICE_MAXIMUM_SEGMENT_SIZE,
4246 MssSizeLimiters { timestamp_enabled: true },
4247 )),
4248 wnd_scale: WindowScale::default(),
4249 }
4250 }
4251
4252 fn default_for_test(buffer: S) -> Self {
4253 Self::default_for_test_at(TEST_ISS + 1, buffer)
4254 }
4255 }
4256
4257 impl<R: ReceiveBuffer> Recv<FakeInstant, R> {
4258 fn default_for_test_at(seq: SeqNum, buffer: R) -> Self {
4259 let BufferLimits { capacity, len } = buffer.limits();
4260 let avail_buffer = capacity - len;
4261 Self {
4262 buffer: RecvBufferState::Open { buffer, assembler: Assembler::new(seq) },
4263 timer: None,
4264 mss: EffectiveMss::from_mss(
4265 DEVICE_MAXIMUM_SEGMENT_SIZE,
4266 MssSizeLimiters { timestamp_enabled: true },
4267 ),
4268 remaining_quickacks: 0,
4269 last_segment_at: None,
4270 wnd_scale: WindowScale::default(),
4271 last_window_update: (
4272 seq,
4273 WindowSize::from_u32(avail_buffer.try_into().unwrap()).unwrap(),
4274 ),
4275 sack_permitted: SACK_PERMITTED,
4276 ts_opt: default_ts_opt_state(seq),
4277 }
4278 }
4279
4280 fn default_for_test(buffer: R) -> Self {
4281 Self::default_for_test_at(TEST_IRS + 1, buffer)
4282 }
4283 }
4284
4285 #[derive(Default)]
4286 struct FakeTcpCounters {
4287 stack_wide: TcpCountersWithSocketInner,
4288 per_socket: TcpCountersWithSocketInner,
4289 }
4290
4291 impl FakeTcpCounters {
4292 fn refs<'a>(&'a self) -> TcpCountersRefs<'a> {
4293 let Self { stack_wide, per_socket } = self;
4294 TcpCountersRefs { stack_wide, per_socket }
4295 }
4296 }
4297
4298 impl CounterExpectations {
4299 #[track_caller]
4300 fn assert_counters(&self, FakeTcpCounters { stack_wide, per_socket }: &FakeTcpCounters) {
4301 assert_eq!(self, &stack_wide.cast(), "stack-wide counter mismatch");
4302 assert_eq!(self, &per_socket.cast(), "per-socket counter mismatch");
4303 }
4304 }
4305
4306 #[test_case(Segment::rst(TEST_IRS, ResetOptions::default()) => None; "drop RST")]
4307 #[test_case(Segment::rst_ack(TEST_IRS, TEST_ISS, ResetOptions::default()) => None; "drop RST|ACK")]
4308 #[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")]
4309 #[test_case(Segment::syn_ack(TEST_IRS, TEST_ISS, UnscaledWindowSize::from(0), HandshakeOptions::default()) => Some(Segment::rst(TEST_ISS, ResetOptions::default())); "reset SYN|ACK")]
4310 #[test_case(
4311 Segment::with_data(
4312 TEST_IRS,
4313 TEST_ISS,
4314 UnscaledWindowSize::from(0),
4315 SegmentOptions::default(),
4316 &[0, 1, 2][..]
4317 ) => Some(Segment::rst(TEST_ISS, ResetOptions::default())); "reset data segment")]
4318 fn segment_arrives_when_closed(
4319 incoming: impl Into<Segment<&'static [u8]>>,
4320 ) -> Option<Segment<()>> {
4321 let closed = Closed { reason: () };
4322 closed.on_segment(&incoming.into())
4323 }
4324
4325 #[test_case(
4326 Segment::rst_ack(TEST_ISS, TEST_IRS - 1, ResetOptions::default()), RTT
4327 => SynSentOnSegmentDisposition::Ignore; "unacceptable ACK with RST")]
4328 #[test_case(
4329 Segment::ack(
4330 TEST_ISS, TEST_IRS - 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4331 ),
4332 RTT
4333 => SynSentOnSegmentDisposition::SendRst(
4334 Segment::rst(TEST_IRS-1, ResetOptions::default()),
4335 ); "unacceptable ACK without RST")]
4336 #[test_case(
4337 Segment::rst_ack(TEST_ISS, TEST_IRS, ResetOptions::default()), RTT
4338 => SynSentOnSegmentDisposition::EnterClosed(
4339 Closed { reason: Some(ConnectionError::ConnectionRefused) },
4340 ); "acceptable ACK(ISS) with RST")]
4341 #[test_case(
4342 Segment::rst_ack(TEST_ISS, TEST_IRS + 1, ResetOptions::default()), RTT
4343 => SynSentOnSegmentDisposition::EnterClosed(
4344 Closed { reason: Some(ConnectionError::ConnectionRefused) },
4345 ); "acceptable ACK(ISS+1) with RST")]
4346 #[test_case(
4347 Segment::rst(TEST_ISS, ResetOptions::default()), RTT
4348 => SynSentOnSegmentDisposition::Ignore; "RST without ack")]
4349 #[test_case(
4350 Segment::syn(
4351 TEST_ISS,
4352 UnscaledWindowSize::from(u16::MAX),
4353 HandshakeOptions {
4354 window_scale: Some(WindowScale::default()),
4355 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
4356 ..Default::default() }
4357 ), RTT
4358 => SynSentOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
4359 Segment::syn_ack(
4360 TEST_IRS,
4361 TEST_ISS + 1,
4362 UnscaledWindowSize::from(u16::MAX),
4363 HandshakeOptions {
4364 mss: Some(Mss::DEFAULT_IPV4),
4365 window_scale: Some(WindowScale::default()),
4366 sack_permitted: SACK_PERMITTED,
4367 timestamp: Some(ACK_TS_OPT_AFTER_RTT),
4368 ..Default::default()
4369 }),
4370 SynRcvd {
4371 iss: TEST_IRS,
4372 irs: TEST_ISS,
4373 timestamp: Some(FakeInstant::from(RTT)),
4374 retrans_timer: RetransTimer::new(
4375 FakeInstant::from(RTT),
4376 Rto::DEFAULT,
4377 NonZeroDuration::new(TEST_USER_TIMEOUT.get() - RTT),
4378 DEFAULT_MAX_SYNACK_RETRIES
4379 ),
4380 simultaneous_open: None,
4381 buffer_sizes: BufferSizes::default(),
4382 smss: EffectiveMss::from_mss(
4383 Mss::DEFAULT_IPV4, MssSizeLimiters { timestamp_enabled: true }
4384 ),
4385 rcv_wnd_scale: WindowScale::default(),
4386 snd_wnd_scale: Some(WindowScale::default()),
4387 sack_permitted: false,
4388 rcv: RecvParams {
4389 ack: TEST_ISS + 1,
4390 wnd: WindowSize::DEFAULT,
4391 wnd_scale: WindowScale::default(),
4392 ts_opt: default_ts_opt_state(TEST_ISS + 1),
4393 }
4394 }
4395 ); "SYN only")]
4396 #[test_case(
4397 Segment::fin(
4398 TEST_ISS, TEST_IRS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4399 ),
4400 RTT
4401 => SynSentOnSegmentDisposition::Ignore; "acceptable ACK with FIN")]
4402 #[test_case(
4403 Segment::ack(
4404 TEST_ISS, TEST_IRS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4405 ),
4406 RTT
4407 => SynSentOnSegmentDisposition::Ignore; "acceptable ACK(ISS+1) with nothing")]
4408 #[test_case(
4409 Segment::ack(
4410 TEST_ISS, TEST_IRS, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4411 ),
4412 RTT
4413 => SynSentOnSegmentDisposition::Ignore; "acceptable ACK(ISS) without RST")]
4414 #[test_case(
4415 Segment::syn(TEST_ISS, UnscaledWindowSize::from(u16::MAX), HandshakeOptions::default()),
4416 TEST_USER_TIMEOUT.get()
4417 => SynSentOnSegmentDisposition::EnterClosed(Closed {
4418 reason: None
4419 }); "syn but timed out")]
4420 fn segment_arrives_when_syn_sent(
4421 incoming: Segment<()>,
4422 delay: Duration,
4423 ) -> SynSentOnSegmentDisposition<FakeInstant, ()> {
4424 let syn_sent = SynSent {
4425 iss: TEST_IRS,
4426 timestamp: Some(FakeInstant::default()),
4427 retrans_timer: RetransTimer::new(
4428 FakeInstant::default(),
4429 Rto::DEFAULT,
4430 Some(TEST_USER_TIMEOUT),
4431 DEFAULT_MAX_RETRIES,
4432 ),
4433 active_open: (),
4434 buffer_sizes: BufferSizes::default(),
4435 default_mss: Mss::DEFAULT_IPV4,
4436 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
4437 rcv_wnd_scale: WindowScale::default(),
4438 ts_opt: default_ts_opt_negotiation_state(),
4439 };
4440 syn_sent.on_segment(incoming, FakeInstant::from(delay))
4441 }
4442
4443 #[test_case(Segment::rst(TEST_ISS, ResetOptions::default()) => ListenOnSegmentDisposition::Ignore; "ignore RST")]
4444 #[test_case(
4445 Segment::ack(
4446 TEST_ISS, TEST_IRS, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4447 ) => ListenOnSegmentDisposition::SendRst(Segment::rst(TEST_IRS, ResetOptions::default()));
4448 "reject ACK")]
4449 #[test_case(Segment::syn(TEST_ISS, UnscaledWindowSize::from(u16::MAX),
4450 HandshakeOptions {
4451 window_scale: Some(WindowScale::default()),
4452 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
4453 ..Default::default()
4454 }) =>
4455 ListenOnSegmentDisposition::SendSynAckAndEnterSynRcvd(
4456 Segment::syn_ack(
4457 TEST_IRS,
4458 TEST_ISS + 1,
4459 UnscaledWindowSize::from(u16::MAX),
4460 HandshakeOptions {
4461 mss: Some(Mss::DEFAULT_IPV4),
4462 window_scale: Some(WindowScale::default()),
4463 timestamp: Some(DEFAULT_ACK_TS_OPT),
4464 sack_permitted: SACK_PERMITTED,
4465 ..Default::default()
4466 }),
4467 SynRcvd {
4468 iss: TEST_IRS,
4469 irs: TEST_ISS,
4470 timestamp: Some(FakeInstant::default()),
4471 retrans_timer: RetransTimer::new(
4472 FakeInstant::default(),
4473 Rto::DEFAULT,
4474 None,
4475 DEFAULT_MAX_SYNACK_RETRIES,
4476 ),
4477 simultaneous_open: None,
4478 buffer_sizes: BufferSizes::default(),
4479 smss: EffectiveMss::from_mss(
4480 Mss::DEFAULT_IPV4, MssSizeLimiters{timestamp_enabled: true}
4481 ),
4482 sack_permitted: false,
4483 rcv_wnd_scale: WindowScale::default(),
4484 snd_wnd_scale: Some(WindowScale::default()),
4485 rcv: RecvParams {
4486 ack: TEST_ISS + 1,
4487 wnd: WindowSize::DEFAULT,
4488 wnd_scale: WindowScale::default(),
4489 ts_opt: default_ts_opt_state(TEST_ISS + 1),
4490 }
4491 }); "accept syn")]
4492 fn segment_arrives_when_listen(
4493 incoming: Segment<()>,
4494 ) -> ListenOnSegmentDisposition<FakeInstant> {
4495 let listen = Closed::<Initial>::listen(
4496 TEST_IRS,
4497 TIMESTAMP_OFFSET,
4498 Default::default(),
4499 DEVICE_MAXIMUM_SEGMENT_SIZE,
4500 Mss::DEFAULT_IPV4,
4501 None,
4502 );
4503 listen.on_segment(incoming, FakeInstant::default())
4504 }
4505
4506 #[test_case(
4507 Segment::ack(
4508 TEST_IRS, TEST_ISS, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4509 ),
4510 None
4511 => Some(Segment::ack(
4512 TEST_ISS + 1,
4513 TEST_IRS + 1,
4514 UnscaledWindowSize::from(u16::MAX),
4515 default_segment_options(RTT_TIMESTAMP, DEFAULT_TIMESTAMP),
4516 )) ; "OTW segment")]
4517 #[test_case(
4518 Segment::rst_ack(TEST_IRS, TEST_ISS, ResetOptions::default()),
4519 None
4520 => None; "OTW RST")]
4521 #[test_case(
4522 Segment::rst_ack(TEST_IRS + 1, TEST_ISS, ResetOptions::default()),
4523 Some(State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }))
4524 => None; "acceptable RST")]
4525 #[test_case(
4526 Segment::syn(TEST_IRS + 1, UnscaledWindowSize::from(u16::MAX), HandshakeOptions {
4527 window_scale: Some(WindowScale::default()),
4528 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
4529 ..Default::default()
4530 }),
4531 Some(State::Closed(Closed { reason: Some(ConnectionError::ConnectionReset) }))
4532 => Some(
4533 Segment::rst(TEST_ISS + 1, ResetOptions { timestamp: Some(NON_ACK_TS_OPT_AFTER_RTT) }),
4534 ); "duplicate syn")]
4535 #[test_case(
4536 Segment::ack(
4537 TEST_IRS + 1, TEST_ISS, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4538 ),
4539 None
4540 => Some(
4541 Segment::rst(TEST_ISS, ResetOptions { timestamp: Some(NON_ACK_TS_OPT_AFTER_RTT) }),
4542 ); "unacceptable ack (ISS)")]
4543 #[test_case(
4544 Segment::ack(
4545 TEST_IRS + 1, TEST_ISS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4546 ),
4547 Some(State::Established(
4548 Established {
4549 snd: Send {
4550 rtt_estimator: Estimator::Measured {
4551 srtt: RTT,
4552 rtt_var: RTT / 2,
4553 },
4554 ..Send::default_for_test(NullBuffer)
4555 }.into(),
4556 rcv: Recv {
4557 remaining_quickacks: quickack_counter(BufferLimits {
4558 capacity: WindowSize::DEFAULT.into(),
4559 len: 0,
4560 }, EffectiveMss::from_mss(
4561 DEVICE_MAXIMUM_SEGMENT_SIZE, MssSizeLimiters { timestamp_enabled: true }
4562 )),
4563 ..Recv::default_for_test(RingBuffer::default())
4564 }.into(),
4565 }
4566 ))
4567 => None; "acceptable ack (ISS + 1)")]
4568 #[test_case(
4569 Segment::ack(
4570 TEST_IRS + 1, TEST_ISS + 2, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4571 ),
4572 None
4573 => Some(
4574 Segment::rst(TEST_ISS + 2, ResetOptions { timestamp: Some(NON_ACK_TS_OPT_AFTER_RTT) })
4575 ); "unacceptable ack (ISS + 2)")]
4576 #[test_case(
4577 Segment::ack(
4578 TEST_IRS + 1, TEST_ISS - 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4579 ),
4580 None
4581 => Some(
4582 Segment::rst(TEST_ISS - 1, ResetOptions { timestamp: Some(NON_ACK_TS_OPT_AFTER_RTT) })
4583 ); "unacceptable ack (ISS - 1)")]
4584 #[test_case(
4585 Segment::new_empty(
4586 SegmentHeader {
4587 seq: TEST_IRS + 1,
4588 wnd: UnscaledWindowSize::from(u16::MAX),
4589 options: DEFAULT_SEGMENT_OPTIONS.into(),
4590 ..Default::default()
4591 }
4592 ),
4593 None
4594 => None; "no ack")]
4595 #[test_case(
4596 Segment::fin(
4597 TEST_IRS + 1, TEST_ISS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4598 ),
4599 Some(State::CloseWait(CloseWait {
4600 snd: Send {
4601 rtt_estimator: Estimator::Measured {
4602 srtt: RTT,
4603 rtt_var: RTT / 2,
4604 },
4605 ..Send::default_for_test(NullBuffer)
4606 }.into(),
4607 closed_rcv: RecvParams {
4608 ack: TEST_IRS + 2,
4609 wnd: WindowSize::from_u32(u32::from(u16::MAX - 1)).unwrap(),
4610 wnd_scale: WindowScale::ZERO,
4611 ts_opt: default_ts_opt_state(TEST_IRS + 2),
4612 }
4613 }))
4614 => Some(Segment::ack(
4615 TEST_ISS + 1,
4616 TEST_IRS + 2,
4617 UnscaledWindowSize::from(u16::MAX - 1),
4618 default_segment_options(RTT_TIMESTAMP, DEFAULT_TIMESTAMP),
4619 )); "fin")]
4620 fn segment_arrives_when_syn_rcvd(
4621 incoming: Segment<()>,
4622 expected: Option<State<FakeInstant, RingBuffer, NullBuffer, ()>>,
4623 ) -> Option<Segment<()>> {
4624 let mut clock = FakeInstantCtx::default();
4625 let counters = FakeTcpCounters::default();
4626 let mut state = State::new_syn_rcvd(clock.now());
4627 clock.sleep(RTT);
4628 let (seg, _passive_open) = state
4629 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4630 incoming,
4631 clock.now(),
4632 &counters.refs(),
4633 );
4634 match expected {
4635 Some(new_state) => assert_eq!(state, new_state),
4636 None => assert_matches!(state, State::SynRcvd(_)),
4637 };
4638 seg
4639 }
4640
4641 #[test]
4642 fn abort_when_syn_rcvd() {
4643 let clock = FakeInstantCtx::default();
4644 let counters = FakeTcpCounters::default();
4645 let mut state = State::new_syn_rcvd(clock.now());
4646 let segment = assert_matches!(
4647 state.abort(&counters.refs(), clock.now(), ConnectionError::ConnectionReset),
4648 (Some(seg), NewlyClosed::Yes) => seg
4649 );
4650 assert_eq!(segment.header().control, Some(Control::RST));
4651 assert_eq!(segment.header().seq, TEST_ISS + 1);
4652 assert_eq!(segment.header().ack, Some(TEST_IRS + 1));
4653 }
4654
4655 #[test_case(
4656 Segment::syn(TEST_IRS + 1, UnscaledWindowSize::from(u16::MAX), HandshakeOptions {
4657 timestamp: Some(DEFAULT_NON_ACK_TS_OPT), ..Default::default()
4658 }),
4659 Some(State::Closed (
4660 Closed { reason: Some(ConnectionError::ConnectionReset) },
4661 ))
4662 => Some(Segment::rst(TEST_ISS + 1, ResetOptions {timestamp: Some(DEFAULT_NON_ACK_TS_OPT)}));
4663 "duplicate syn")]
4664 #[test_case(
4665 Segment::rst(TEST_IRS + 1, ResetOptions::default()),
4666 Some(State::Closed (
4667 Closed { reason: Some(ConnectionError::ConnectionReset) },
4668 ))
4669 => None; "accepatable rst")]
4670 #[test_case(
4671 Segment::ack(
4672 TEST_ISS + 1, TEST_IRS + 2, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4673 ),
4674 None
4675 => Some(Segment::ack(
4676 TEST_ISS + 1, TEST_IRS + 1, UnscaledWindowSize::from(2), DEFAULT_SEGMENT_OPTIONS
4677 )); "unacceptable ack")]
4678 #[test_case(
4679 Segment::ack(
4680 TEST_IRS + 1, TEST_ISS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4681 ),
4682 None
4683 => None; "pure ack")]
4684 #[test_case(
4685 Segment::fin(
4686 TEST_IRS + 1, TEST_ISS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4687 ),
4688 Some(State::CloseWait(CloseWait {
4689 snd: Send::default_for_test(NullBuffer).into(),
4690 closed_rcv: RecvParams {
4691 ack: TEST_IRS + 2,
4692 wnd: WindowSize::new(1).unwrap(),
4693 wnd_scale: WindowScale::ZERO,
4694 ts_opt: default_ts_opt_state(TEST_IRS + 2),
4695 }
4696 }))
4697 => Some(
4698 Segment::ack(
4699 TEST_ISS + 1, TEST_IRS + 2, UnscaledWindowSize::from(1), DEFAULT_SEGMENT_OPTIONS
4700 )
4701 ); "pure fin")]
4702 #[test_case(
4703 Segment::piggybacked_fin(
4704 TEST_IRS + 1,
4705 TEST_ISS + 1,
4706 UnscaledWindowSize::from(u16::MAX),
4707 DEFAULT_SEGMENT_OPTIONS,
4708 "A".as_bytes()
4709 ),
4710 Some(State::CloseWait(CloseWait {
4711 snd: Send::default_for_test(NullBuffer).into(),
4712 closed_rcv: RecvParams {
4713 ack: TEST_IRS + 3,
4714 wnd: WindowSize::ZERO,
4715 wnd_scale: WindowScale::ZERO,
4716 ts_opt: default_ts_opt_state(TEST_IRS + 3),
4717 }
4718 }))
4719 => Some(
4720 Segment::ack(
4721 TEST_ISS + 1, TEST_IRS + 3, UnscaledWindowSize::from(0), DEFAULT_SEGMENT_OPTIONS
4722 )); "fin with 1 byte")]
4723 #[test_case(
4724 Segment::piggybacked_fin(
4725 TEST_IRS + 1,
4726 TEST_ISS + 1,
4727 UnscaledWindowSize::from(u16::MAX),
4728 DEFAULT_SEGMENT_OPTIONS,
4729 "AB".as_bytes()
4730 ),
4731 None
4732 => Some(Segment::ack(
4733 TEST_ISS + 1, TEST_IRS + 3, UnscaledWindowSize::from(0), DEFAULT_SEGMENT_OPTIONS
4734 )); "fin with 2 bytes")]
4735 fn segment_arrives_when_established(
4736 incoming: Segment<&[u8]>,
4737 expected: Option<State<FakeInstant, RingBuffer, NullBuffer, ()>>,
4738 ) -> Option<Segment<()>> {
4739 let counters = FakeTcpCounters::default();
4740 let mut state = State::Established(Established {
4741 snd: Send::default_for_test(NullBuffer).into(),
4742 rcv: Recv::default_for_test(RingBuffer::new(2)).into(),
4743 });
4744 let (seg, passive_open) = state
4745 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4746 incoming,
4747 FakeInstant::default(),
4748 &counters.refs(),
4749 );
4750 assert_eq!(passive_open, None);
4751 match expected {
4752 Some(new_state) => assert_eq!(new_state, state),
4753 None => assert_matches!(state, State::Established(_)),
4754 };
4755 seg
4756 }
4757
4758 #[test]
4759 fn common_rcv_data_segment_arrives() {
4760 let counters = FakeTcpCounters::default();
4761 let new_snd = || Send::default_for_test(NullBuffer);
4764 let new_rcv = || Recv::default_for_test(RingBuffer::new(TEST_BYTES.len()));
4765 for mut state in [
4766 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
4767 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
4768 State::FinWait2(FinWait2 { last_seq: TEST_ISS + 1, rcv: new_rcv(), timeout_at: None }),
4769 ] {
4770 assert_eq!(
4771 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
4772 Segment::with_data(
4773 TEST_IRS + 1,
4774 TEST_ISS + 1,
4775 UnscaledWindowSize::from(u16::MAX),
4776 DEFAULT_SEGMENT_OPTIONS,
4777 TEST_BYTES
4778 ),
4779 FakeInstant::default(),
4780 &counters.refs(),
4781 ),
4782 (
4783 Some(Segment::ack(
4784 TEST_ISS + 1,
4785 TEST_IRS + 1 + TEST_BYTES.len(),
4786 UnscaledWindowSize::from(0),
4787 DEFAULT_SEGMENT_OPTIONS
4788 )),
4789 None
4790 )
4791 );
4792 assert_eq!(
4793 state.read_with(|bytes| {
4794 assert_eq!(bytes.concat(), TEST_BYTES);
4795 TEST_BYTES.len()
4796 }),
4797 TEST_BYTES.len()
4798 );
4799 }
4800 }
4801
4802 #[test]
4803 fn common_snd_ack_segment_arrives() {
4804 let counters = FakeTcpCounters::default();
4805 let new_snd = || Send {
4808 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
4809 ..Send::default_for_test(RingBuffer::with_data(TEST_BYTES.len(), TEST_BYTES))
4810 };
4811 let new_rcv = || Recv::default_for_test(NullBuffer);
4812 for mut state in [
4813 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
4814 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
4815 State::Closing(Closing {
4816 snd: new_snd().queue_fin(),
4817 closed_rcv: RecvParams {
4818 ack: TEST_IRS + 1,
4819 wnd: WindowSize::ZERO,
4820 wnd_scale: WindowScale::default(),
4821 ts_opt: default_ts_opt_state(TEST_IRS + 1),
4822 },
4823 }),
4824 State::CloseWait(CloseWait {
4825 snd: new_snd().into(),
4826 closed_rcv: RecvParams {
4827 ack: TEST_IRS + 1,
4828 wnd: WindowSize::ZERO,
4829 wnd_scale: WindowScale::default(),
4830 ts_opt: default_ts_opt_state(TEST_IRS + 1),
4831 },
4832 }),
4833 State::LastAck(LastAck {
4834 snd: new_snd().queue_fin(),
4835 closed_rcv: RecvParams {
4836 ack: TEST_IRS + 1,
4837 wnd: WindowSize::ZERO,
4838 wnd_scale: WindowScale::default(),
4839 ts_opt: default_ts_opt_state(TEST_IRS + 1),
4840 },
4841 }),
4842 ] {
4843 assert_eq!(
4844 state.poll_send_with_default_options(FakeInstant::default(), &counters.refs(),),
4845 Some(Segment::new_assert_no_discard(
4846 SegmentHeader {
4847 seq: TEST_ISS + 1,
4848 ack: Some(TEST_IRS + 1),
4849 control: None,
4850 wnd: UnscaledWindowSize::from(0),
4851 push: true,
4852 options: DEFAULT_SEGMENT_OPTIONS.into(),
4853 },
4854 FragmentedPayload::new_contiguous(TEST_BYTES)
4855 ))
4856 );
4857 assert_eq!(
4858 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
4859 Segment::<()>::ack(
4860 TEST_IRS + 1,
4861 TEST_ISS + 1 + TEST_BYTES.len(),
4862 UnscaledWindowSize::from(u16::MAX),
4863 DEFAULT_SEGMENT_OPTIONS
4864 ),
4865 FakeInstant::default(),
4866 &counters.refs(),
4867 ),
4868 (None, None),
4869 );
4870 assert_eq!(state.poll_send_at(), None);
4871 let snd = match state {
4872 State::Closed(_)
4873 | State::Listen(_)
4874 | State::SynRcvd(_)
4875 | State::SynSent(_)
4876 | State::FinWait2(_)
4877 | State::TimeWait(_) => unreachable!("Unexpected state {:?}", state),
4878 State::Established(e) => e.snd.into_inner().queue_fin(),
4879 State::CloseWait(c) => c.snd.into_inner().queue_fin(),
4880 State::LastAck(l) => l.snd,
4881 State::FinWait1(f) => f.snd.into_inner(),
4882 State::Closing(c) => c.snd,
4883 };
4884 assert_eq!(snd.nxt, TEST_ISS + 1 + TEST_BYTES.len());
4885 assert_eq!(snd.max, TEST_ISS + 1 + TEST_BYTES.len());
4886 assert_eq!(snd.una, TEST_ISS + 1 + TEST_BYTES.len());
4887 assert_eq!(snd.buffer.limits().len, 0);
4888 }
4889 }
4890
4891 #[test_case(
4892 Segment::syn(TEST_IRS + 2, UnscaledWindowSize::from(u16::MAX),
4893 HandshakeOptions {timestamp: Some(DEFAULT_NON_ACK_TS_OPT), ..Default::default()}),
4894 Some(State::Closed (
4895 Closed { reason: Some(ConnectionError::ConnectionReset) },
4896 ))
4897 => Some(Segment::rst(TEST_ISS + 1, ResetOptions {timestamp: Some(DEFAULT_NON_ACK_TS_OPT)})); "syn")]
4898 #[test_case(
4899 Segment::rst(TEST_IRS + 2, ResetOptions::default()),
4900 Some(State::Closed (
4901 Closed { reason: Some(ConnectionError::ConnectionReset) },
4902 ))
4903 => None; "rst")]
4904 #[test_case(
4905 Segment::fin(
4906 TEST_IRS + 2, TEST_ISS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4907 ),
4908 None
4909 => None; "ignore fin")]
4910 #[test_case(
4911 Segment::with_data(
4912 TEST_IRS,
4913 TEST_ISS + 1,
4914 UnscaledWindowSize::from(u16::MAX),
4915 DEFAULT_SEGMENT_OPTIONS,
4916 "a".as_bytes()
4917 ),
4918 None => Some(Segment::ack(
4919 TEST_ISS + 1, TEST_IRS + 2, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
4920 ));
4921 "ack old data")]
4922 #[test_case(
4923 Segment::with_data(
4924 TEST_IRS + 2,
4925 TEST_ISS + 1,
4926 UnscaledWindowSize::from(u16::MAX),
4927 DEFAULT_SEGMENT_OPTIONS,
4928 "Hello".as_bytes()
4929 ),
4930 Some(State::Closed (
4931 Closed { reason: Some(ConnectionError::ConnectionReset) },
4932 ))
4933 => Some(Segment::rst(TEST_ISS + 1, ResetOptions {timestamp: Some(DEFAULT_NON_ACK_TS_OPT)}));
4934 "reset on new data")]
4935 fn segment_arrives_when_close_wait(
4936 incoming: Segment<&[u8]>,
4937 expected: Option<State<FakeInstant, RingBuffer, NullBuffer, ()>>,
4938 ) -> Option<Segment<()>> {
4939 let counters = FakeTcpCounters::default();
4940 let mut state = State::CloseWait(CloseWait {
4941 snd: Send::default_for_test(NullBuffer).into(),
4942 closed_rcv: RecvParams {
4943 ack: TEST_IRS + 2,
4944 wnd: WindowSize::DEFAULT,
4945 wnd_scale: WindowScale::ZERO,
4946 ts_opt: default_ts_opt_state(TEST_IRS + 1),
4947 },
4948 });
4949 let (seg, _passive_open) = state
4950 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
4951 incoming,
4952 FakeInstant::default(),
4953 &counters.refs(),
4954 );
4955 match expected {
4956 Some(new_state) => assert_eq!(new_state, state),
4957 None => assert_matches!(state, State::CloseWait(_)),
4958 };
4959 seg
4960 }
4961
4962 #[test_case(true; "sack")]
4963 #[test_case(false; "no sack")]
4964 fn active_passive_open(sack_permitted: bool) {
4965 let mut clock = FakeInstantCtx::default();
4966 let counters = FakeTcpCounters::default();
4967 let passive_iss = ISS_2;
4968 let active_iss = ISS_1;
4969 let (syn_sent, syn_seg) = Closed::<Initial>::connect(
4970 active_iss,
4971 TIMESTAMP_OFFSET,
4972 clock.now(),
4973 (),
4974 Default::default(),
4975 DEVICE_MAXIMUM_SEGMENT_SIZE,
4976 Mss::DEFAULT_IPV4,
4977 &SocketOptions::default_for_state_tests(),
4978 );
4979 assert_eq!(
4980 syn_seg,
4981 Segment::syn(
4982 active_iss,
4983 UnscaledWindowSize::from(u16::MAX),
4984 HandshakeOptions {
4985 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
4986 window_scale: Some(WindowScale::default()),
4987 sack_permitted: SACK_PERMITTED,
4989 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
4990 },
4991 )
4992 );
4993 assert_eq!(
4994 syn_sent,
4995 SynSent {
4996 iss: active_iss,
4997 timestamp: Some(clock.now()),
4998 retrans_timer: RetransTimer::new(
4999 clock.now(),
5000 Rto::DEFAULT,
5001 None,
5002 DEFAULT_MAX_SYN_RETRIES,
5003 ),
5004 active_open: (),
5005 buffer_sizes: BufferSizes::default(),
5006 default_mss: Mss::DEFAULT_IPV4,
5007 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
5008 rcv_wnd_scale: WindowScale::default(),
5009 ts_opt: default_ts_opt_negotiation_state(),
5010 }
5011 );
5012 let mut active = State::SynSent(syn_sent);
5013 let mut passive = State::Listen(Closed::<Initial>::listen(
5014 passive_iss,
5015 TIMESTAMP_OFFSET,
5016 Default::default(),
5017 DEVICE_MAXIMUM_SEGMENT_SIZE,
5018 Mss::DEFAULT_IPV4,
5019 None,
5020 ));
5021 clock.sleep(RTT / 2);
5022
5023 let initialized_at = clock.now();
5024
5025 let syn_seg = {
5027 let (mut header, data) = syn_seg.into_parts();
5028 let opt = assert_matches!(&mut header.options, Options::Handshake(o) => o);
5029 opt.sack_permitted = sack_permitted;
5030 Segment::new_assert_no_discard(header, data)
5031 };
5032
5033 let (seg, passive_open) = passive
5034 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5035 syn_seg,
5036 clock.now(),
5037 &counters.refs(),
5038 );
5039 let syn_ack = seg.expect("failed to generate a syn-ack segment");
5040 assert_eq!(passive_open, None);
5041 assert_eq!(
5042 syn_ack,
5043 Segment::syn_ack(
5044 passive_iss,
5045 active_iss + 1,
5046 UnscaledWindowSize::from(u16::MAX),
5047 HandshakeOptions {
5048 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
5049 window_scale: Some(WindowScale::default()),
5050 sack_permitted: SACK_PERMITTED,
5052 timestamp: Some(DEFAULT_ACK_TS_OPT),
5053 },
5054 )
5055 );
5056 assert_matches!(passive, State::SynRcvd(ref syn_rcvd) if syn_rcvd == &SynRcvd {
5057 iss: passive_iss,
5058 irs: active_iss,
5059 timestamp: Some(clock.now()),
5060 retrans_timer: RetransTimer::new(
5061 clock.now(),
5062 Rto::DEFAULT,
5063 None,
5064 DEFAULT_MAX_SYNACK_RETRIES,
5065 ),
5066 simultaneous_open: None,
5067 buffer_sizes: Default::default(),
5068 smss: EffectiveMss::from_mss(
5069 DEVICE_MAXIMUM_SEGMENT_SIZE,
5070 MssSizeLimiters {timestamp_enabled: true}
5071 ),
5072 rcv_wnd_scale: WindowScale::default(),
5073 snd_wnd_scale: Some(WindowScale::default()),
5074 sack_permitted,
5075 rcv: RecvParams {
5076 ack: active_iss + 1,
5077 wnd: WindowSize::DEFAULT,
5078 wnd_scale: WindowScale::default(),
5079 ts_opt: TimestampOptionState::Enabled {
5080 ts_recent: DEFAULT_TIMESTAMP,
5081 last_ack_sent: active_iss + 1,
5082 ts_val: TimestampValueState {
5083 offset: TIMESTAMP_OFFSET,
5084 initialized_at,
5085 },
5086 },
5087 },
5088 });
5089 clock.sleep(RTT / 2);
5090
5091 let syn_ack = {
5093 let (mut header, data) = syn_ack.into_parts();
5094 let opt = assert_matches!(&mut header.options, Options::Handshake(o) => o);
5095 opt.sack_permitted = sack_permitted;
5096 Segment::new_assert_no_discard(header, data)
5097 };
5098
5099 let (seg, passive_open) = active
5100 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5101 syn_ack,
5102 clock.now(),
5103 &counters.refs(),
5104 );
5105 let ack_seg = seg.expect("failed to generate a ack segment");
5106 assert_eq!(passive_open, None);
5107 let ts_val = timestamp_now(&clock);
5108 assert_eq!(
5109 ack_seg,
5110 Segment::ack(
5111 active_iss + 1,
5112 passive_iss + 1,
5113 UnscaledWindowSize::from(u16::MAX),
5114 default_segment_options(ts_val, DEFAULT_TIMESTAMP),
5115 )
5116 );
5117 let established = assert_matches!(&active, State::Established(e) => e);
5118 assert_eq!(
5119 established,
5120 &Established {
5121 snd: Send {
5122 wl1: passive_iss,
5123 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
5124 ..Send::default_for_test_at(active_iss + 1, RingBuffer::default())
5125 }
5126 .into(),
5127 rcv: Recv {
5128 remaining_quickacks: default_quickack_counter(),
5129 sack_permitted,
5130 ..Recv::default_for_test_at(passive_iss + 1, RingBuffer::default())
5131 }
5132 .into()
5133 }
5134 );
5135 clock.sleep(RTT / 2);
5136 assert_eq!(
5137 passive.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5138 ack_seg,
5139 clock.now(),
5140 &counters.refs(),
5141 ),
5142 (None, Some(())),
5143 );
5144 let established = assert_matches!(&passive, State::Established(e) => e);
5145 assert_eq!(
5146 established,
5147 &Established {
5148 snd: Send {
5149 wl1: active_iss + 1,
5150 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
5151 ..Send::default_for_test_at(passive_iss + 1, RingBuffer::default())
5152 }
5153 .into(),
5154 rcv: Recv {
5155 remaining_quickacks: default_quickack_counter(),
5156 sack_permitted,
5157 ts_opt: TimestampOptionState::Enabled {
5158 ts_recent: ts_val,
5159 last_ack_sent: active_iss + 1,
5160 ts_val: TimestampValueState { offset: TIMESTAMP_OFFSET, initialized_at },
5161 },
5162 ..Recv::default_for_test_at(active_iss + 1, RingBuffer::default())
5163 }
5164 .into()
5165 }
5166 )
5167 }
5168
5169 #[test]
5170 fn simultaneous_open() {
5171 let mut clock = FakeInstantCtx::default();
5172 let counters = FakeTcpCounters::default();
5173 let (syn_sent1, syn1) = Closed::<Initial>::connect(
5174 ISS_1,
5175 TIMESTAMP_OFFSET,
5176 clock.now(),
5177 (),
5178 Default::default(),
5179 DEVICE_MAXIMUM_SEGMENT_SIZE,
5180 Mss::DEFAULT_IPV4,
5181 &SocketOptions::default_for_state_tests(),
5182 );
5183 let (syn_sent2, syn2) = Closed::<Initial>::connect(
5184 ISS_2,
5185 TIMESTAMP_OFFSET,
5186 clock.now(),
5187 (),
5188 Default::default(),
5189 DEVICE_MAXIMUM_SEGMENT_SIZE,
5190 Mss::DEFAULT_IPV4,
5191 &SocketOptions::default_for_state_tests(),
5192 );
5193
5194 let time1 = timestamp_now(&clock);
5195 assert_eq!(
5196 syn1,
5197 Segment::syn(
5198 ISS_1,
5199 UnscaledWindowSize::from(u16::MAX),
5200 HandshakeOptions {
5201 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
5202 window_scale: Some(WindowScale::default()),
5203 sack_permitted: SACK_PERMITTED,
5204 timestamp: Some(TimestampOption::new(time1, TS_ECHO_REPLY_FOR_NON_ACKS)),
5205 },
5206 )
5207 );
5208 assert_eq!(
5209 syn2,
5210 Segment::syn(
5211 ISS_2,
5212 UnscaledWindowSize::from(u16::MAX),
5213 HandshakeOptions {
5214 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
5215 window_scale: Some(WindowScale::default()),
5216 sack_permitted: SACK_PERMITTED,
5217 timestamp: Some(TimestampOption::new(time1, TS_ECHO_REPLY_FOR_NON_ACKS)),
5218 },
5219 )
5220 );
5221
5222 let mut state1 = State::SynSent(syn_sent1);
5223 let mut state2 = State::SynSent(syn_sent2);
5224
5225 clock.sleep(RTT);
5226 let time2 = timestamp_now(&clock);
5227 let (seg, passive_open) = state1
5228 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5229 syn2,
5230 clock.now(),
5231 &counters.refs(),
5232 );
5233 let syn_ack1 = seg.expect("failed to generate syn ack");
5234 assert_eq!(passive_open, None);
5235 let (seg, passive_open) = state2
5236 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5237 syn1,
5238 clock.now(),
5239 &counters.refs(),
5240 );
5241 let syn_ack2 = seg.expect("failed to generate syn ack");
5242 assert_eq!(passive_open, None);
5243
5244 assert_eq!(
5245 syn_ack1,
5246 Segment::syn_ack(
5247 ISS_1,
5248 ISS_2 + 1,
5249 UnscaledWindowSize::from(u16::MAX),
5250 HandshakeOptions {
5251 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
5252 window_scale: Some(WindowScale::default()),
5253 sack_permitted: SACK_PERMITTED,
5254 timestamp: Some(TimestampOption::new(time2, time1)),
5255 },
5256 )
5257 );
5258 assert_eq!(
5259 syn_ack2,
5260 Segment::syn_ack(
5261 ISS_2,
5262 ISS_1 + 1,
5263 UnscaledWindowSize::from(u16::MAX),
5264 HandshakeOptions {
5265 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
5266 window_scale: Some(WindowScale::default()),
5267 sack_permitted: SACK_PERMITTED,
5268 timestamp: Some(TimestampOption::new(time2, time1)),
5269 },
5270 )
5271 );
5272
5273 assert_matches!(state1, State::SynRcvd(ref syn_rcvd) if syn_rcvd == &SynRcvd {
5274 iss: ISS_1,
5275 irs: ISS_2,
5276 timestamp: Some(clock.now()),
5277 retrans_timer: RetransTimer::new(
5278 clock.now(),
5279 Rto::DEFAULT,
5280 None,
5281 DEFAULT_MAX_SYNACK_RETRIES,
5282 ),
5283 simultaneous_open: Some(()),
5284 buffer_sizes: BufferSizes::default(),
5285 smss: EffectiveMss::from_mss(
5286 DEVICE_MAXIMUM_SEGMENT_SIZE,
5287 MssSizeLimiters{timestamp_enabled: true}
5288 ),
5289 rcv_wnd_scale: WindowScale::default(),
5290 snd_wnd_scale: Some(WindowScale::default()),
5291 sack_permitted: SACK_PERMITTED,
5292 rcv: RecvParams {
5293 ack: ISS_2 + 1,
5294 wnd: WindowSize::DEFAULT,
5295 wnd_scale: WindowScale::default(),
5296 ts_opt: default_ts_opt_state(ISS_2 + 1),
5297 },
5298 });
5299 assert_matches!(state2, State::SynRcvd(ref syn_rcvd) if syn_rcvd == &SynRcvd {
5300 iss: ISS_2,
5301 irs: ISS_1,
5302 timestamp: Some(clock.now()),
5303 retrans_timer: RetransTimer::new(
5304 clock.now(),
5305 Rto::DEFAULT,
5306 None,
5307 DEFAULT_MAX_SYNACK_RETRIES,
5308 ),
5309 simultaneous_open: Some(()),
5310 buffer_sizes: BufferSizes::default(),
5311 smss: EffectiveMss::from_mss(
5312 DEVICE_MAXIMUM_SEGMENT_SIZE,
5313 MssSizeLimiters{timestamp_enabled: true}
5314 ),
5315 rcv_wnd_scale: WindowScale::default(),
5316 snd_wnd_scale: Some(WindowScale::default()),
5317 sack_permitted: SACK_PERMITTED,
5318 rcv: RecvParams {
5319 ack: ISS_1 + 1,
5320 wnd: WindowSize::DEFAULT,
5321 wnd_scale: WindowScale::default(),
5322 ts_opt: default_ts_opt_state(ISS_1 + 1),
5323 },
5324 });
5325
5326 clock.sleep(RTT);
5327 let time3 = timestamp_now(&clock);
5328 assert_eq!(
5329 state1.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5330 syn_ack2,
5331 clock.now(),
5332 &counters.refs(),
5333 ),
5334 (
5335 Some(Segment::ack(
5336 ISS_1 + 1,
5337 ISS_2 + 1,
5338 UnscaledWindowSize::from(u16::MAX),
5339 default_segment_options(time3, time2),
5340 )),
5341 None
5342 )
5343 );
5344 assert_eq!(
5345 state2.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5346 syn_ack1,
5347 clock.now(),
5348 &counters.refs(),
5349 ),
5350 (
5351 Some(Segment::ack(
5352 ISS_2 + 1,
5353 ISS_1 + 1,
5354 UnscaledWindowSize::from(u16::MAX),
5355 default_segment_options(time3, time2),
5356 )),
5357 None
5358 )
5359 );
5360
5361 let established = assert_matches!(state1, State::Established(e) => e);
5362 assert_eq!(
5363 established,
5364 Established {
5365 snd: Send {
5366 wl1: ISS_2 + 1,
5367 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
5368 congestion_control: CongestionControl::cubic_with_mss(EffectiveMss::from_mss(
5369 Mss::DEFAULT_IPV4,
5370 MssSizeLimiters { timestamp_enabled: true },
5371 )),
5372 ..Send::default_for_test_at(ISS_1 + 1, RingBuffer::default())
5373 }
5374 .into(),
5375 rcv: Recv {
5376 remaining_quickacks: default_quickack_counter() - 1,
5377 last_segment_at: Some(clock.now()),
5378 ts_opt: TimestampOptionState::Enabled {
5379 ts_recent: time2,
5380 last_ack_sent: ISS_2 + 1,
5381 ts_val: TimestampValueState {
5382 offset: TIMESTAMP_OFFSET,
5383 initialized_at: FakeInstant::default(),
5384 }
5385 },
5386 ..Recv::default_for_test_at(ISS_2 + 1, RingBuffer::default())
5387 }
5388 .into()
5389 }
5390 );
5391
5392 let established = assert_matches!(state2, State::Established(e) => e);
5393 assert_eq!(
5394 established,
5395 Established {
5396 snd: Send {
5397 wl1: ISS_1 + 1,
5398 rtt_estimator: Estimator::Measured { srtt: RTT, rtt_var: RTT / 2 },
5399 congestion_control: CongestionControl::cubic_with_mss(EffectiveMss::from_mss(
5400 Mss::DEFAULT_IPV4,
5401 MssSizeLimiters { timestamp_enabled: true },
5402 )),
5403 ..Send::default_for_test_at(ISS_2 + 1, RingBuffer::default())
5404 }
5405 .into(),
5406 rcv: Recv {
5407 remaining_quickacks: default_quickack_counter() - 1,
5408 last_segment_at: Some(clock.now()),
5409 ts_opt: TimestampOptionState::Enabled {
5410 ts_recent: time2,
5411 last_ack_sent: ISS_1 + 1,
5412 ts_val: TimestampValueState {
5413 offset: TIMESTAMP_OFFSET,
5414 initialized_at: FakeInstant::default(),
5415 }
5416 },
5417 ..Recv::default_for_test_at(ISS_1 + 1, RingBuffer::default())
5418 }
5419 .into()
5420 }
5421 );
5422 }
5423
5424 #[test_case(true; "sack permitted")]
5425 #[test_case(false; "sack not permitted")]
5426 fn established_receive(sack_permitted: bool) {
5427 let clock = FakeInstantCtx::default();
5428 let counters = FakeTcpCounters::default();
5429 let mut established = State::Established(Established {
5430 snd: Send {
5431 wnd: WindowSize::ZERO,
5432 wnd_max: WindowSize::ZERO,
5433 buffer: NullBuffer,
5434 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
5435 ..Send::default_for_test(NullBuffer)
5436 }
5437 .into(),
5438 rcv: Recv {
5439 mss: TEST_MSS,
5440 sack_permitted,
5441 ..Recv::default_for_test(RingBuffer::new(BUFFER_SIZE))
5442 }
5443 .into(),
5444 });
5445
5446 assert_eq!(
5448 established.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5449 Segment::with_data(
5450 TEST_IRS + 1,
5451 TEST_ISS + 1,
5452 UnscaledWindowSize::from(0),
5453 DEFAULT_SEGMENT_OPTIONS,
5454 TEST_BYTES,
5455 ),
5456 clock.now(),
5457 &counters.refs(),
5458 ),
5459 (
5460 Some(Segment::ack(
5461 TEST_ISS + 1,
5462 TEST_IRS + 1 + TEST_BYTES.len(),
5463 UnscaledWindowSize::from((BUFFER_SIZE - TEST_BYTES.len()) as u16),
5464 DEFAULT_SEGMENT_OPTIONS
5465 )),
5466 None
5467 ),
5468 );
5469 assert_eq!(
5470 established.read_with(|available| {
5471 assert_eq!(available, &[TEST_BYTES]);
5472 available[0].len()
5473 }),
5474 TEST_BYTES.len()
5475 );
5476
5477 let segment_start = TEST_IRS + 1 + TEST_BYTES.len() * 2;
5479 assert_eq!(
5480 established.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5481 Segment::with_data(
5482 segment_start,
5483 TEST_ISS + 1,
5484 UnscaledWindowSize::from(0),
5485 DEFAULT_SEGMENT_OPTIONS,
5486 TEST_BYTES,
5487 ),
5488 clock.now(),
5489 &counters.refs()
5490 ),
5491 (
5492 Some(Segment::ack(
5493 TEST_ISS + 1,
5494 TEST_IRS + 1 + TEST_BYTES.len(),
5495 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
5496 SegmentOptions {
5497 sack_blocks: if sack_permitted {
5498 [SackBlock::try_new(
5499 segment_start,
5500 segment_start + u32::try_from(TEST_BYTES.len()).unwrap(),
5501 )
5502 .unwrap()]
5503 .into_iter()
5504 .collect()
5505 } else {
5506 SackBlocks::default()
5507 },
5508 timestamp: Some(DEFAULT_ACK_TS_OPT),
5509 },
5510 )),
5511 None
5512 ),
5513 );
5514 assert_eq!(
5515 established.read_with(|available| {
5516 let empty: &[u8] = &[];
5517 assert_eq!(available, &[empty]);
5518 0
5519 }),
5520 0
5521 );
5522
5523 assert_eq!(
5525 established.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5526 Segment::with_data(
5527 TEST_IRS + 1 + TEST_BYTES.len(),
5528 TEST_ISS + 1,
5529 UnscaledWindowSize::from(0),
5530 DEFAULT_SEGMENT_OPTIONS,
5531 TEST_BYTES,
5532 ),
5533 clock.now(),
5534 &counters.refs()
5535 ),
5536 (
5537 Some(Segment::ack(
5538 TEST_ISS + 1,
5539 TEST_IRS + 1 + 3 * TEST_BYTES.len(),
5540 UnscaledWindowSize::from_usize(BUFFER_SIZE - 2 * TEST_BYTES.len()),
5541 DEFAULT_SEGMENT_OPTIONS
5542 )),
5543 None
5544 ),
5545 );
5546 assert_eq!(
5547 established.read_with(|available| {
5548 assert_eq!(available, &[[TEST_BYTES, TEST_BYTES].concat()]);
5549 available[0].len()
5550 }),
5551 TEST_BYTES.len() * 2
5552 );
5553 }
5554
5555 #[test]
5556 fn established_send() {
5557 let clock = FakeInstantCtx::default();
5558 let counters = FakeTcpCounters::default();
5559 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
5560 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
5562 const PARTIAL_LEN: usize = 10;
5563 assert_eq!(send_buffer.enqueue_data(&TEST_BYTES[..PARTIAL_LEN]), PARTIAL_LEN);
5564 let mut established = State::Established(Established {
5565 snd: Send {
5566 una: TEST_ISS,
5567 wl2: TEST_ISS,
5568 wnd: WindowSize::ZERO,
5569 wnd_max: WindowSize::ZERO,
5570 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
5571 ..Send::default_for_test_at(TEST_ISS + 1, send_buffer)
5572 }
5573 .into(),
5574 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
5575 });
5576 assert_eq!(established.poll_send_with_default_options(clock.now(), &counters.refs()), None);
5578 let open_window = |established: &mut State<FakeInstant, RingBuffer, RingBuffer, ()>,
5579 ack: SeqNum,
5580 win: usize,
5581 now: FakeInstant,
5582 counters: &TcpCountersRefs<'_>| {
5583 assert_eq!(
5584 established.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5585 Segment::ack(
5586 TEST_IRS + 1,
5587 ack,
5588 UnscaledWindowSize::from_usize(win),
5589 DEFAULT_SEGMENT_OPTIONS
5590 ),
5591 now,
5592 counters
5593 ),
5594 (None, None),
5595 );
5596 };
5597 open_window(&mut established, TEST_ISS + 1, 1, clock.now(), &counters.refs());
5599 assert_eq!(
5600 established.poll_send_with_default_options(clock.now(), &counters.refs()),
5601 Some(Segment::with_data(
5602 TEST_ISS + 1,
5603 TEST_IRS + 1,
5604 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5605 DEFAULT_SEGMENT_OPTIONS,
5606 FragmentedPayload::new_contiguous(&TEST_BYTES[1..2]),
5607 ))
5608 );
5609
5610 open_window(
5612 &mut established,
5613 TEST_ISS + 2,
5614 TEST_BYTES.len() + PARTIAL_LEN,
5615 clock.now(),
5616 &counters.refs(),
5617 );
5618 assert_eq!(
5619 established.poll_send_with_default_options(clock.now(), &counters.refs()),
5620 Some(Segment::with_data(
5621 TEST_ISS + 2,
5622 TEST_IRS + 1,
5623 UnscaledWindowSize::from_usize(BUFFER_SIZE),
5624 DEFAULT_SEGMENT_OPTIONS,
5625 FragmentedPayload::new_contiguous(TEST_BYTES),
5626 ))
5627 );
5628
5629 assert_eq!(
5630 established.poll_send(
5631 &FakeStateMachineDebugId::default(),
5632 &counters.refs(),
5633 clock.now(),
5634 &SocketOptions { nagle_enabled: false, ..SocketOptions::default_for_state_tests() }
5635 ),
5636 Ok(Segment::new_assert_no_discard(
5637 SegmentHeader {
5638 seq: TEST_ISS + TEST_BYTES.len() + 2,
5639 ack: Some(TEST_IRS + 1),
5640 control: None,
5641 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
5642 push: true,
5643 options: DEFAULT_SEGMENT_OPTIONS.into(),
5644 },
5645 FragmentedPayload::new_contiguous(&TEST_BYTES[..PARTIAL_LEN - 2]),
5646 ))
5647 );
5648
5649 assert_eq!(established.poll_send_with_default_options(clock.now(), &counters.refs()), None);
5651 }
5652
5653 #[test]
5654 fn self_connect_retransmission() {
5655 let mut clock = FakeInstantCtx::default();
5656 let counters = FakeTcpCounters::default();
5657 let (syn_sent, syn) = Closed::<Initial>::connect(
5658 ISS_1,
5659 TIMESTAMP_OFFSET,
5660 clock.now(),
5661 (),
5662 Default::default(),
5663 *TEST_MSS.mss(),
5664 Mss::DEFAULT_IPV4,
5665 &SocketOptions::default_for_state_tests(),
5666 );
5667
5668 let expected_syn = |ts_val| {
5669 Segment::syn(
5670 ISS_1,
5671 UnscaledWindowSize::from(u16::MAX),
5672 HandshakeOptions {
5673 mss: Some(*TEST_MSS.mss()),
5674 window_scale: Some(WindowScale::default()),
5675 sack_permitted: SACK_PERMITTED,
5676 timestamp: Some(TimestampOption::new(ts_val, TS_ECHO_REPLY_FOR_NON_ACKS)),
5677 },
5678 )
5679 };
5680
5681 let time1 = timestamp_now(&clock);
5682 assert_eq!(syn, expected_syn(time1));
5683 let mut state = State::<_, RingBuffer, RingBuffer, ()>::SynSent(syn_sent);
5684
5685 assert_eq!(state.poll_send_at(), Some(FakeInstant::from(Rto::DEFAULT.get())));
5687 clock.sleep(Rto::DEFAULT.get());
5688 let time2 = timestamp_now(&clock);
5689 assert_eq!(
5691 state.poll_send_with_default_options(clock.now(), &counters.refs()),
5692 Some(expected_syn(time2).into_empty())
5693 );
5694
5695 let (seg, passive_open) = state
5697 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
5698 syn,
5699 clock.now(),
5700 &counters.refs(),
5701 );
5702 let syn_ack = seg.expect("expected SYN-ACK");
5703
5704 let expected_syn_ack = |ts_val| {
5705 Segment::syn_ack(
5706 ISS_1,
5707 ISS_1 + 1,
5708 UnscaledWindowSize::from(u16::MAX),
5709 HandshakeOptions {
5710 mss: Some(*TEST_MSS.mss()),
5711 window_scale: Some(WindowScale::default()),
5712 sack_permitted: SACK_PERMITTED,
5713 timestamp: Some(TimestampOption::new(ts_val, time1)),
5714 },
5715 )
5716 };
5717
5718 assert_eq!(syn_ack, expected_syn_ack(time2));
5719 assert_eq!(passive_open, None);
5720 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
5722 clock.sleep(Rto::DEFAULT.get());
5723 let time3 = timestamp_now(&clock);
5724 assert_eq!(
5726 state.poll_send_with_default_options(clock.now(), &counters.refs()),
5727 Some(expected_syn_ack(time3).into_empty())
5728 );
5729
5730 assert_eq!(
5732 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
5733 syn_ack,
5734 clock.now(),
5735 &counters.refs(),
5736 ),
5737 (
5738 Some(Segment::ack(
5739 ISS_1 + 1,
5740 ISS_1 + 1,
5741 UnscaledWindowSize::from(u16::MAX),
5742 default_segment_options(time3, time2),
5743 )),
5744 None
5745 )
5746 );
5747 match state {
5748 State::Closed(_)
5749 | State::Listen(_)
5750 | State::SynRcvd(_)
5751 | State::SynSent(_)
5752 | State::LastAck(_)
5753 | State::FinWait1(_)
5754 | State::FinWait2(_)
5755 | State::Closing(_)
5756 | State::TimeWait(_) => {
5757 panic!("expected that we have entered established state, but got {:?}", state)
5758 }
5759 State::Established(Established { ref mut snd, rcv: _ })
5760 | State::CloseWait(CloseWait { ref mut snd, closed_rcv: _ }) => {
5761 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
5762 }
5763 }
5764 assert_eq!(state.poll_send_at(), None);
5766 for i in 0..3 {
5768 assert_eq!(
5769 state.poll_send_with_default_options(clock.now(), &counters.refs()),
5770 Some(Segment::new_assert_no_discard(
5771 SegmentHeader {
5772 seq: ISS_1 + 1,
5773 ack: Some(ISS_1 + 1),
5774 control: None,
5775 wnd: UnscaledWindowSize::from(u16::MAX),
5776 push: true,
5777 options: default_segment_options(timestamp_now(&clock), time2).into(),
5778 },
5779 FragmentedPayload::new_contiguous(TEST_BYTES),
5780 ))
5781 );
5782 assert_eq!(state.poll_send_at(), Some(clock.now() + (1 << i) * Rto::DEFAULT.get()));
5783 clock.sleep((1 << i) * Rto::DEFAULT.get());
5784 CounterExpectations {
5785 retransmits: i,
5786 slow_start_retransmits: i,
5787 timeouts: i,
5788 ..Default::default()
5789 }
5790 .assert_counters(&counters);
5791 }
5792 let time4 = timestamp_now(&clock);
5793 assert_eq!(
5795 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5796 Segment::ack(
5797 ISS_1 + 1 + TEST_BYTES.len(),
5798 ISS_1 + 1 + 1,
5799 UnscaledWindowSize::from(u16::MAX),
5800 default_segment_options(time4, time4),
5801 ),
5802 clock.now(),
5803 &counters.refs(),
5804 ),
5805 (None, None),
5806 );
5807 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
5810 clock.sleep(Rto::DEFAULT.get());
5811 let time5 = timestamp_now(&clock);
5812 assert_eq!(
5813 state.poll_send_with_default_options(clock.now(), &counters.refs(),),
5814 Some(Segment::new_assert_no_discard(
5815 SegmentHeader {
5816 seq: ISS_1 + 1 + 1,
5817 ack: Some(ISS_1 + 1),
5818 wnd: UnscaledWindowSize::from(u16::MAX),
5819 push: true,
5820 options: default_segment_options(time5, time2).into(),
5821 ..Default::default()
5822 },
5823 FragmentedPayload::new_contiguous(&TEST_BYTES[1..]),
5824 ))
5825 );
5826
5827 assert_matches!(
5829 state.on_pmtu_update(Mss::MIN, ISS_1 + TEST_BYTES.len()),
5830 ShouldRetransmit::Yes
5831 );
5832 let new_mss = usize::from(EffectiveMss::from_mss(
5833 Mss::MIN,
5834 MssSizeLimiters { timestamp_enabled: true },
5835 ));
5836 clock.sleep(2 * Rto::DEFAULT.get());
5837 let time6 = timestamp_now(&clock);
5838 assert_eq!(
5839 state.poll_send_with_default_options(clock.now(), &counters.refs(),),
5840 Some(Segment::new_assert_no_discard(
5841 SegmentHeader {
5842 seq: ISS_1 + 1 + 1,
5843 ack: Some(ISS_1 + 1),
5844 wnd: UnscaledWindowSize::from(u16::MAX),
5845 push: false,
5846 options: default_segment_options(time6, time2).into(),
5847 ..Default::default()
5848 },
5849 FragmentedPayload::new_contiguous(&TEST_BYTES[1..new_mss + 1]),
5850 ))
5851 );
5852
5853 assert_eq!(
5859 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5860 Segment::ack(
5861 ISS_1 + 1 + TEST_BYTES.len(),
5862 ISS_1 + new_mss + 2,
5863 UnscaledWindowSize::from(u16::MAX),
5864 default_segment_options(time6, time6),
5865 ),
5866 clock.now(),
5867 &counters.refs(),
5868 ),
5869 (None, None)
5870 );
5871
5872 CounterExpectations {
5873 retransmits: 4,
5874 slow_start_retransmits: 4,
5875 timeouts: 4,
5876 ..Default::default()
5877 }
5878 .assert_counters(&counters);
5879
5880 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
5883 assert_eq!(
5884 state.poll_send_with_default_options(clock.now(), &counters.refs()),
5885 Some(Segment::new_assert_no_discard(
5886 SegmentHeader {
5887 seq: ISS_1 + new_mss + 2,
5888 ack: Some(ISS_1 + 1),
5889 wnd: UnscaledWindowSize::from(u16::MAX),
5890 push: true,
5891 options: default_segment_options(time6, time2).into(),
5892 ..Default::default()
5893 },
5894 FragmentedPayload::new_contiguous(&TEST_BYTES[new_mss + 1..]),
5895 ))
5896 );
5897
5898 assert_eq!(
5900 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5901 Segment::ack(
5902 ISS_1 + 1 + TEST_BYTES.len(),
5903 ISS_1 + 1 + TEST_BYTES.len(),
5904 UnscaledWindowSize::from(u16::MAX),
5905 default_segment_options(time6, time6),
5906 ),
5907 clock.now(),
5908 &counters.refs()
5909 ),
5910 (None, None)
5911 );
5912 assert_eq!(state.poll_send_at(), None);
5914 }
5915
5916 #[test]
5917 fn passive_close() {
5918 let mut clock = FakeInstantCtx::default();
5919 let counters = FakeTcpCounters::default();
5920 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
5921 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
5923 const PARTIAL_LEN: usize = 10;
5924 assert_eq!(send_buffer.enqueue_data(&TEST_BYTES[..PARTIAL_LEN]), PARTIAL_LEN);
5925 let mut state = State::Established(Established {
5927 snd: Send {
5928 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
5929 ..Send::default_for_test(send_buffer.clone())
5930 }
5931 .into(),
5932 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
5933 });
5934 let last_wnd = WindowSize::new(BUFFER_SIZE - 1).unwrap();
5935 let last_wnd_scale = WindowScale::default();
5936 assert_eq!(
5938 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
5939 Segment::fin(
5940 TEST_IRS + 1,
5941 TEST_ISS + 1,
5942 UnscaledWindowSize::from(u16::MAX),
5943 DEFAULT_SEGMENT_OPTIONS
5944 ),
5945 clock.now(),
5946 &counters.refs(),
5947 ),
5948 (
5949 Some(Segment::ack(
5950 TEST_ISS + 1,
5951 TEST_IRS + 2,
5952 UnscaledWindowSize::from_usize(BUFFER_SIZE - 1),
5953 DEFAULT_SEGMENT_OPTIONS
5954 )),
5955 None
5956 )
5957 );
5958 assert_eq!(
5960 state.close(
5961 &counters.refs(),
5962 CloseReason::Shutdown,
5963 &SocketOptions::default_for_state_tests()
5964 ),
5965 Ok(NewlyClosed::No)
5966 );
5967 assert_eq!(
5968 state,
5969 State::LastAck(LastAck {
5970 snd: Send::default_for_test(send_buffer),
5971 closed_rcv: RecvParams {
5972 ack: TEST_IRS + 2,
5973 wnd: last_wnd,
5974 wnd_scale: last_wnd_scale,
5975 ts_opt: default_ts_opt_state(TEST_IRS + 2),
5976 }
5977 })
5978 );
5979 assert_eq!(
5981 state.poll_send_with_default_options(clock.now(), &counters.refs()),
5982 Some(Segment::with_data(
5983 TEST_ISS + 1,
5984 TEST_IRS + 2,
5985 last_wnd >> WindowScale::default(),
5986 DEFAULT_SEGMENT_OPTIONS,
5987 FragmentedPayload::new_contiguous(TEST_BYTES),
5988 ))
5989 );
5990 assert_eq!(
5992 state.poll_send_with_default_options(clock.now(), &counters.refs()),
5993 Some(Segment::new_assert_no_discard(
5994 SegmentHeader {
5995 seq: TEST_ISS + TEST_BYTES.len() + 1,
5996 ack: Some(TEST_IRS + 2),
5997 control: Some(Control::FIN),
5998 wnd: last_wnd >> WindowScale::default(),
5999 push: true,
6000 options: DEFAULT_SEGMENT_OPTIONS.into(),
6001 },
6002 FragmentedPayload::new_contiguous(&TEST_BYTES[..PARTIAL_LEN]),
6003 ))
6004 );
6005 clock.sleep(RTT);
6007 assert_eq!(
6008 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6009 Segment::ack(
6010 TEST_IRS + 2,
6011 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 1,
6012 UnscaledWindowSize::from(u16::MAX),
6013 DEFAULT_SEGMENT_OPTIONS
6014 ),
6015 clock.now(),
6016 &counters.refs(),
6017 ),
6018 (None, None)
6019 );
6020 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
6021 clock.sleep(Rto::DEFAULT.get());
6022 assert_eq!(
6024 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6025 Some(Segment::fin(
6026 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 1,
6027 TEST_IRS + 2,
6028 last_wnd >> WindowScale::default(),
6029 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6030 ))
6031 );
6032
6033 assert_eq!(
6035 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6036 Segment::ack(
6037 TEST_IRS + 2,
6038 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 2,
6039 UnscaledWindowSize::from(u16::MAX),
6040 DEFAULT_SEGMENT_OPTIONS
6041 ),
6042 clock.now(),
6043 &counters.refs(),
6044 ),
6045 (None, None)
6046 );
6047 assert_eq!(state, State::Closed(Closed { reason: None }));
6049 CounterExpectations {
6050 retransmits: 1,
6051 slow_start_retransmits: 1,
6052 timeouts: 1,
6053 established_closed: 1,
6054 ..Default::default()
6055 }
6056 .assert_counters(&counters);
6057 }
6058
6059 #[test]
6060 fn syn_rcvd_active_close() {
6061 let counters = FakeTcpCounters::default();
6062 let mut state: State<_, RingBuffer, NullBuffer, ()> = State::SynRcvd(SynRcvd {
6063 iss: TEST_ISS,
6064 irs: TEST_IRS,
6065 timestamp: None,
6066 retrans_timer: RetransTimer {
6067 at: FakeInstant::default(),
6068 rto: Rto::MIN,
6069 user_timeout_until: None,
6070 remaining_retries: Some(DEFAULT_MAX_RETRIES),
6071 },
6072 simultaneous_open: Some(()),
6073 buffer_sizes: Default::default(),
6074 smss: EffectiveMss::from_mss(
6075 Mss::DEFAULT_IPV4,
6076 MssSizeLimiters { timestamp_enabled: true },
6077 ),
6078 rcv_wnd_scale: WindowScale::default(),
6079 snd_wnd_scale: Some(WindowScale::default()),
6080 sack_permitted: SACK_PERMITTED,
6081 rcv: RecvParams {
6082 ack: TEST_IRS + 1,
6083 wnd: WindowSize::DEFAULT,
6084 wnd_scale: WindowScale::default(),
6085 ts_opt: default_ts_opt_state(TEST_IRS + 1),
6086 },
6087 });
6088 assert_eq!(
6089 state.close(
6090 &counters.refs(),
6091 CloseReason::Shutdown,
6092 &SocketOptions::default_for_state_tests()
6093 ),
6094 Ok(NewlyClosed::No)
6095 );
6096 assert_matches!(state, State::FinWait1(_));
6097 assert_eq!(
6098 state.poll_send_with_default_options(FakeInstant::default(), &counters.refs()),
6099 Some(Segment::fin(
6100 TEST_ISS + 1,
6101 TEST_IRS + 1,
6102 UnscaledWindowSize::from(u16::MAX),
6103 DEFAULT_SEGMENT_OPTIONS
6104 ))
6105 );
6106 }
6107
6108 #[test]
6109 fn established_active_close() {
6110 let mut clock = FakeInstantCtx::default();
6111 let counters = FakeTcpCounters::default();
6112 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
6113 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
6115 const PARTIAL_LEN: usize = 10;
6116 assert_eq!(send_buffer.enqueue_data(&TEST_BYTES[..PARTIAL_LEN]), PARTIAL_LEN);
6117 let mut state = State::Established(Established {
6119 snd: Send {
6120 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
6121 ..Send::default_for_test(send_buffer.clone())
6122 }
6123 .into(),
6124 rcv: Recv { mss: TEST_MSS, ..Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)) }
6125 .into(),
6126 });
6127 assert_eq!(
6128 state.close(
6129 &counters.refs(),
6130 CloseReason::Shutdown,
6131 &SocketOptions::default_for_state_tests()
6132 ),
6133 Ok(NewlyClosed::No)
6134 );
6135 assert_matches!(state, State::FinWait1(_));
6136 assert_eq!(
6137 state.close(
6138 &counters.refs(),
6139 CloseReason::Shutdown,
6140 &SocketOptions::default_for_state_tests()
6141 ),
6142 Err(CloseError::Closing)
6143 );
6144
6145 assert_eq!(
6147 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6148 Some(Segment::with_data(
6149 TEST_ISS + 1,
6150 TEST_IRS + 1,
6151 UnscaledWindowSize::from_usize(BUFFER_SIZE),
6152 DEFAULT_SEGMENT_OPTIONS,
6153 FragmentedPayload::new_contiguous(TEST_BYTES)
6154 ))
6155 );
6156
6157 assert_eq!(
6159 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6160 Some(Segment::new_assert_no_discard(
6161 SegmentHeader {
6162 seq: TEST_ISS + 1 + TEST_BYTES.len(),
6163 ack: Some(TEST_IRS + 1),
6164 control: Some(Control::FIN),
6165 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
6166 push: true,
6167 options: DEFAULT_SEGMENT_OPTIONS.into(),
6168 },
6169 FragmentedPayload::new_contiguous(&TEST_BYTES[..PARTIAL_LEN])
6170 ))
6171 );
6172
6173 assert_eq!(
6175 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
6176 Segment::with_data(
6177 TEST_IRS + 1,
6178 TEST_ISS + TEST_BYTES.len() + 1,
6179 UnscaledWindowSize::from(u16::MAX),
6180 DEFAULT_SEGMENT_OPTIONS,
6181 TEST_BYTES
6182 ),
6183 clock.now(),
6184 &counters.refs(),
6185 ),
6186 (
6187 Some(Segment::ack(
6188 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 2,
6189 TEST_IRS + TEST_BYTES.len() + 1,
6190 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len()),
6191 DEFAULT_SEGMENT_OPTIONS
6192 )),
6193 None
6194 )
6195 );
6196
6197 assert_eq!(
6198 state.read_with(|avail| {
6199 let got = avail.concat();
6200 assert_eq!(got, TEST_BYTES);
6201 got.len()
6202 }),
6203 TEST_BYTES.len()
6204 );
6205
6206 assert_eq!(state.poll_send_at(), Some(clock.now() + Rto::DEFAULT.get()));
6208
6209 clock.sleep(Rto::DEFAULT.get());
6212 assert_eq!(
6213 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6214 Some(Segment::new_assert_no_discard(
6215 SegmentHeader {
6216 seq: TEST_ISS + TEST_BYTES.len() + 1,
6217 ack: Some(TEST_IRS + TEST_BYTES.len() + 1),
6218 control: Some(Control::FIN),
6219 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
6220 push: true,
6221 options: default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP)
6222 .into(),
6223 },
6224 FragmentedPayload::new_contiguous(&TEST_BYTES[..PARTIAL_LEN]),
6225 ))
6226 );
6227
6228 assert_eq!(
6230 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6231 Segment::ack(
6232 TEST_IRS + TEST_BYTES.len() + 1,
6233 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 2,
6234 UnscaledWindowSize::from(u16::MAX),
6235 DEFAULT_SEGMENT_OPTIONS
6236 ),
6237 clock.now(),
6238 &counters.refs(),
6239 ),
6240 (None, None)
6241 );
6242 assert_matches!(state, State::FinWait2(_));
6243
6244 assert_eq!(
6246 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
6247 Segment::with_data(
6248 TEST_IRS + TEST_BYTES.len() + 1,
6249 TEST_ISS + TEST_BYTES.len() + 2,
6250 UnscaledWindowSize::from(u16::MAX),
6251 DEFAULT_SEGMENT_OPTIONS,
6252 TEST_BYTES
6253 ),
6254 clock.now(),
6255 &counters.refs(),
6256 ),
6257 (
6258 Some(Segment::ack(
6259 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 2,
6260 TEST_IRS + 2 * TEST_BYTES.len() + 1,
6261 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len()),
6262 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6263 )),
6264 None
6265 )
6266 );
6267
6268 assert_eq!(
6269 state.read_with(|avail| {
6270 let got = avail.concat();
6271 assert_eq!(got, TEST_BYTES);
6272 got.len()
6273 }),
6274 TEST_BYTES.len()
6275 );
6276
6277 assert_eq!(
6279 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6280 Segment::fin(
6281 TEST_IRS + 2 * TEST_BYTES.len() + 1,
6282 TEST_ISS + TEST_BYTES.len() + 2,
6283 UnscaledWindowSize::from(u16::MAX),
6284 DEFAULT_SEGMENT_OPTIONS
6285 ),
6286 clock.now(),
6287 &counters.refs(),
6288 ),
6289 (
6290 Some(Segment::ack(
6291 TEST_ISS + TEST_BYTES.len() + PARTIAL_LEN + 2,
6292 TEST_IRS + 2 * TEST_BYTES.len() + 2,
6293 UnscaledWindowSize::from_usize(BUFFER_SIZE - 1),
6294 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6295 )),
6296 None
6297 )
6298 );
6299
6300 assert_matches!(state, State::TimeWait(_));
6301
6302 const SMALLEST_DURATION: Duration = Duration::from_secs(1);
6303 assert_eq!(state.poll_send_at(), Some(clock.now() + MSL * 2));
6304 clock.sleep(MSL * 2 - SMALLEST_DURATION);
6305 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
6307 assert_matches!(state, State::TimeWait(_));
6308 clock.sleep(SMALLEST_DURATION);
6309 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
6311 assert_eq!(state, State::Closed(Closed { reason: None }));
6312 CounterExpectations {
6313 retransmits: 1,
6314 slow_start_retransmits: 1,
6315 timeouts: 1,
6316 established_closed: 1,
6317 ..Default::default()
6318 }
6319 .assert_counters(&counters);
6320 }
6321
6322 #[test]
6323 fn fin_wait_1_fin_ack_to_time_wait() {
6324 let counters = FakeTcpCounters::default();
6325 let mut state = State::FinWait1(FinWait1 {
6328 snd: Send { una: TEST_ISS + 1, ..Send::default_for_test_at(TEST_ISS + 2, NullBuffer) }
6329 .into(),
6330 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
6331 });
6332 assert_eq!(
6333 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6334 Segment::fin(
6335 TEST_IRS + 1,
6336 TEST_ISS + 2,
6337 UnscaledWindowSize::from(u16::MAX),
6338 DEFAULT_SEGMENT_OPTIONS
6339 ),
6340 FakeInstant::default(),
6341 &counters.refs(),
6342 ),
6343 (
6344 Some(Segment::ack(
6345 TEST_ISS + 2,
6346 TEST_IRS + 2,
6347 UnscaledWindowSize::from_usize(BUFFER_SIZE - 1),
6348 DEFAULT_SEGMENT_OPTIONS
6349 )),
6350 None
6351 ),
6352 );
6353 assert_matches!(state, State::TimeWait(_));
6354 }
6355
6356 #[test]
6357 fn simultaneous_close() {
6358 let mut clock = FakeInstantCtx::default();
6359 let counters = FakeTcpCounters::default();
6360 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
6361 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
6362
6363 let iss = ISS_1;
6364 let mut state = State::Established(Established {
6366 snd: Send::default_for_test_at(iss + 1, send_buffer.clone()).into(),
6367 rcv: Recv::default_for_test_at(iss + 1, RingBuffer::new(BUFFER_SIZE)).into(),
6368 });
6369 assert_eq!(
6370 state.close(
6371 &counters.refs(),
6372 CloseReason::Shutdown,
6373 &SocketOptions::default_for_state_tests()
6374 ),
6375 Ok(NewlyClosed::No)
6376 );
6377 assert_matches!(state, State::FinWait1(_));
6378 assert_eq!(
6379 state.close(
6380 &counters.refs(),
6381 CloseReason::Shutdown,
6382 &SocketOptions::default_for_state_tests()
6383 ),
6384 Err(CloseError::Closing)
6385 );
6386
6387 let fin = state.poll_send_with_default_options(clock.now(), &counters.refs());
6388 assert_eq!(
6389 fin,
6390 Some(Segment::new_assert_no_discard(
6391 SegmentHeader {
6392 seq: iss + 1,
6393 ack: Some(iss + 1),
6394 control: Some(Control::FIN),
6395 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
6396 push: true,
6397 options: DEFAULT_SEGMENT_OPTIONS.into(),
6398 },
6399 FragmentedPayload::new_contiguous(TEST_BYTES),
6400 ))
6401 );
6402 assert_eq!(
6403 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
6404 Segment::piggybacked_fin(
6405 iss + 1,
6406 iss + 1,
6407 UnscaledWindowSize::from_usize(BUFFER_SIZE),
6408 DEFAULT_SEGMENT_OPTIONS,
6409 TEST_BYTES,
6410 ),
6411 clock.now(),
6412 &counters.refs(),
6413 ),
6414 (
6415 Some(Segment::ack(
6416 iss + TEST_BYTES.len() + 2,
6417 iss + TEST_BYTES.len() + 2,
6418 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len() - 1),
6419 DEFAULT_SEGMENT_OPTIONS
6420 )),
6421 None
6422 )
6423 );
6424
6425 assert_matches!(state, State::Closing(_));
6428 assert_eq!(
6429 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6430 Segment::ack(
6431 iss + TEST_BYTES.len() + 2,
6432 iss + TEST_BYTES.len() + 2,
6433 UnscaledWindowSize::from_usize(BUFFER_SIZE - TEST_BYTES.len() - 1),
6434 DEFAULT_SEGMENT_OPTIONS
6435 ),
6436 clock.now(),
6437 &counters.refs(),
6438 ),
6439 (None, None)
6440 );
6441
6442 assert_matches!(state, State::TimeWait(_));
6445
6446 const SMALLEST_DURATION: Duration = Duration::from_secs(1);
6447 assert_eq!(state.poll_send_at(), Some(clock.now() + MSL * 2));
6448 clock.sleep(MSL * 2 - SMALLEST_DURATION);
6449 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
6451 assert_matches!(state, State::TimeWait(_));
6452 clock.sleep(SMALLEST_DURATION);
6453 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
6455 assert_eq!(state, State::Closed(Closed { reason: None }));
6456 CounterExpectations { established_closed: 1, ..Default::default() }
6457 .assert_counters(&counters);
6458 }
6459
6460 #[test]
6461 fn time_wait_restarts_timer() {
6462 let mut clock = FakeInstantCtx::default();
6463 let counters = FakeTcpCounters::default();
6464 let mut time_wait = State::<_, NullBuffer, NullBuffer, ()>::TimeWait(TimeWait {
6465 last_seq: TEST_ISS + 2,
6466 closed_rcv: RecvParams {
6467 ack: TEST_IRS + 2,
6468 wnd: WindowSize::DEFAULT,
6469 wnd_scale: WindowScale::default(),
6470 ts_opt: default_ts_opt_state(TEST_IRS + 1),
6471 },
6472 expiry: new_time_wait_expiry(clock.now()),
6473 });
6474
6475 assert_eq!(time_wait.poll_send_at(), Some(clock.now() + MSL * 2));
6476 clock.sleep(Duration::from_secs(1));
6477 assert_eq!(
6478 time_wait.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6479 Segment::fin(
6480 TEST_IRS + 2,
6481 TEST_ISS + 2,
6482 UnscaledWindowSize::from(u16::MAX),
6483 DEFAULT_SEGMENT_OPTIONS
6484 ),
6485 clock.now(),
6486 &counters.refs(),
6487 ),
6488 (
6489 Some(Segment::ack(
6490 TEST_ISS + 2,
6491 TEST_IRS + 2,
6492 UnscaledWindowSize::from(u16::MAX),
6493 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6494 )),
6495 None
6496 ),
6497 );
6498 assert_eq!(time_wait.poll_send_at(), Some(clock.now() + MSL * 2));
6499 }
6500
6501 #[test_case(
6502 State::Established(Established {
6503 snd: Send::default_for_test_at(TEST_ISS, NullBuffer).into(),
6504 rcv: Recv::default_for_test_at(TEST_IRS + u32::from(TEST_MSS), RingBuffer::default()).into(),
6505 }),
6506 Segment::with_data(
6507 TEST_IRS,
6508 TEST_ISS,
6509 UnscaledWindowSize::from(u16::MAX),
6510 DEFAULT_SEGMENT_OPTIONS,
6511 TEST_BYTES
6512 ) => Some(Segment::ack(
6513 TEST_ISS,
6514 TEST_IRS + u32::from(TEST_MSS),
6515 UnscaledWindowSize::from(u16::MAX),
6516 DEFAULT_SEGMENT_OPTIONS
6517 ));
6518 "retransmit data"
6519 )]
6520 #[test_case(
6521 State::SynRcvd(SynRcvd {
6522 iss: TEST_ISS,
6523 irs: TEST_IRS,
6524 timestamp: None,
6525 retrans_timer: RetransTimer {
6526 at: FakeInstant::default(),
6527 rto: Rto::MIN,
6528 user_timeout_until: None,
6529 remaining_retries: Some(DEFAULT_MAX_RETRIES),
6530 },
6531 simultaneous_open: None,
6532 buffer_sizes: BufferSizes::default(),
6533 smss: EffectiveMss::from_mss(
6534 Mss::DEFAULT_IPV4, MssSizeLimiters {timestamp_enabled: true }
6535 ),
6536 rcv_wnd_scale: WindowScale::default(),
6537 snd_wnd_scale: Some(WindowScale::default()),
6538 sack_permitted: SACK_PERMITTED,
6539 rcv: RecvParams {
6540 ack: TEST_IRS + 1,
6541 wnd: WindowSize::DEFAULT,
6542 wnd_scale: WindowScale::default(),
6543 ts_opt: default_ts_opt_state(TEST_IRS+1),
6544 },
6545 }),
6546 Segment::syn_ack(
6547 TEST_IRS,
6548 TEST_ISS + 1,
6549 UnscaledWindowSize::from(u16::MAX),
6550 HandshakeOptions {
6551 window_scale: Some(WindowScale::default()),
6552 timestamp: Some(DEFAULT_ACK_TS_OPT),
6553 ..Default::default()
6554 }) =>
6555 Some(Segment::ack(
6556 TEST_ISS + 1, TEST_IRS + 1, UnscaledWindowSize::from(u16::MAX), DEFAULT_SEGMENT_OPTIONS
6557 )); "retransmit syn_ack"
6558 )]
6559 fn ack_to_retransmitted_segment(
6561 mut state: State<FakeInstant, RingBuffer, NullBuffer, ()>,
6562 seg: Segment<&[u8]>,
6563 ) -> Option<Segment<()>> {
6564 let counters = FakeTcpCounters::default();
6565 let (reply, _): (_, Option<()>) = state
6566 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
6567 seg,
6568 FakeInstant::default(),
6569 &counters.refs(),
6570 );
6571 reply
6572 }
6573
6574 #[test]
6575 fn fast_retransmit() {
6576 let mut clock = FakeInstantCtx::default();
6577 let counters = FakeTcpCounters::default();
6578 let mut send_buffer = RingBuffer::default();
6579 let mss =
6580 EffectiveMss::from_mss(Mss::DEFAULT_IPV4, MssSizeLimiters { timestamp_enabled: true });
6581
6582 let first_payload_byte = b'A';
6583 let last_payload_byte = b'D';
6584
6585 for b in first_payload_byte..=last_payload_byte {
6586 assert_eq!(send_buffer.enqueue_data(&vec![b; usize::from(mss)]), usize::from(mss));
6587 }
6588 let mut state: State<_, _, _, ()> = State::Established(Established {
6589 snd: Send {
6590 congestion_control: CongestionControl::cubic_with_mss(EffectiveMss::from_mss(
6591 Mss::DEFAULT_IPV4,
6592 MssSizeLimiters { timestamp_enabled: true },
6593 )),
6594 ..Send::default_for_test_at(TEST_ISS, send_buffer.clone())
6595 }
6596 .into(),
6597 rcv: Recv::default_for_test_at(TEST_IRS, RingBuffer::default()).into(),
6598 });
6599
6600 assert_eq!(
6601 state.poll_send_with_default_options(clock.now(), &counters.refs(),),
6602 Some(Segment::with_data(
6603 TEST_ISS,
6604 TEST_IRS,
6605 UnscaledWindowSize::from(u16::MAX),
6606 DEFAULT_SEGMENT_OPTIONS,
6607 FragmentedPayload::new_contiguous(&vec![b'A'; usize::from(mss)])
6608 ))
6609 );
6610
6611 let mut dup_ack = |expected_byte: u8, counters: &TcpCountersRefs<'_>| {
6612 clock.sleep(Duration::from_millis(10));
6613 assert_eq!(
6614 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6615 Segment::ack(
6616 TEST_IRS,
6617 TEST_ISS,
6618 UnscaledWindowSize::from(u16::MAX),
6619 DEFAULT_SEGMENT_OPTIONS
6620 ),
6621 clock.now(),
6622 counters,
6623 ),
6624 (None, None)
6625 );
6626
6627 assert_eq!(
6628 state.poll_send_with_default_options(clock.now(), counters,),
6629 Some(Segment::new_assert_no_discard(
6630 SegmentHeader {
6631 seq: TEST_ISS
6632 + u32::from(expected_byte - first_payload_byte) * u32::from(mss),
6633 ack: Some(TEST_IRS),
6634 control: None,
6635 wnd: UnscaledWindowSize::from(u16::MAX),
6636 push: expected_byte == last_payload_byte,
6637 options: default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP)
6638 .into(),
6639 },
6640 FragmentedPayload::new_contiguous(&vec![expected_byte; usize::from(mss)])
6641 ))
6642 );
6643 };
6644
6645 CounterExpectations::default().assert_counters(&counters);
6648 dup_ack(b'B', &counters.refs());
6649 CounterExpectations { fast_recovery: 0, dup_acks: 1, ..Default::default() }
6650 .assert_counters(&counters);
6651 dup_ack(b'C', &counters.refs());
6652 CounterExpectations { fast_recovery: 0, dup_acks: 2, ..Default::default() }
6653 .assert_counters(&counters);
6654 dup_ack(b'A', &counters.refs());
6657 CounterExpectations {
6658 retransmits: 1,
6659 fast_recovery: 1,
6660 fast_retransmits: 1,
6661 dup_acks: 3,
6662 ..Default::default()
6663 }
6664 .assert_counters(&counters);
6665 dup_ack(b'D', &counters.refs());
6667 CounterExpectations {
6668 retransmits: 1,
6669 fast_recovery: 1,
6670 fast_retransmits: 1,
6671 dup_acks: 4,
6672 ..Default::default()
6673 }
6674 .assert_counters(&counters);
6675
6676 clock.sleep(Duration::from_millis(10));
6678 assert_eq!(
6679 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6680 Segment::ack(
6681 TEST_IRS,
6682 TEST_ISS + u32::from(Mss::DEFAULT_IPV4),
6683 UnscaledWindowSize::from(u16::MAX),
6684 DEFAULT_SEGMENT_OPTIONS
6685 ),
6686 clock.now(),
6687 &counters.refs(),
6688 ),
6689 (None, None)
6690 );
6691 let established = assert_matches!(state, State::Established(established) => established);
6692 assert_eq!(established.snd.congestion_control.inspect_cwnd().cwnd(), 2 * u32::from(mss));
6693 assert_eq!(established.snd.congestion_control.inspect_loss_recovery_mode(), None);
6694 CounterExpectations {
6695 retransmits: 1,
6696 fast_recovery: 1,
6697 fast_retransmits: 1,
6698 dup_acks: 4,
6699 loss_recovered: 1,
6700 ..Default::default()
6701 }
6702 .assert_counters(&counters);
6703 }
6704
6705 #[test]
6706 fn keep_alive() {
6707 let mut clock = FakeInstantCtx::default();
6708 let counters = FakeTcpCounters::default();
6709 let mut state: State<_, _, _, ()> = State::Established(Established {
6710 snd: Send::default_for_test_at(TEST_ISS, RingBuffer::default()).into(),
6711 rcv: Recv::default_for_test_at(TEST_IRS, RingBuffer::default()).into(),
6712 });
6713
6714 let socket_options = {
6715 let mut socket_options = SocketOptions::default_for_state_tests();
6716 socket_options.keep_alive.enabled = true;
6717 socket_options
6718 };
6719 let socket_options = &socket_options;
6720 let keep_alive = &socket_options.keep_alive;
6721
6722 assert_eq!(
6724 state.poll_send(
6725 &FakeStateMachineDebugId::default(),
6726 &counters.refs(),
6727 clock.now(),
6728 socket_options,
6729 ),
6730 Err(NewlyClosed::No),
6731 );
6732 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(keep_alive.idle.into())));
6735
6736 clock.sleep(Duration::from_secs(60 * 60));
6738 assert_eq!(
6739 state.on_segment::<&[u8], ClientlessBufferProvider>(
6740 &FakeStateMachineDebugId::default(),
6741 &counters.refs(),
6742 Segment::ack(
6743 TEST_IRS,
6744 TEST_ISS,
6745 UnscaledWindowSize::from(u16::MAX),
6746 DEFAULT_SEGMENT_OPTIONS
6747 ),
6748 clock.now(),
6749 socket_options,
6750 false, ),
6752 (None, None, DataAcked::No, NewlyClosed::No)
6753 );
6754 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(keep_alive.idle.into())),);
6756 clock.sleep(keep_alive.idle.into());
6757
6758 for _ in 0..keep_alive.count.get() {
6761 assert_eq!(
6762 state.poll_send(
6763 &FakeStateMachineDebugId::default(),
6764 &counters.refs(),
6765 clock.now(),
6766 socket_options,
6767 ),
6768 Ok(Segment::ack(
6769 TEST_ISS - 1,
6770 TEST_IRS,
6771 UnscaledWindowSize::from(u16::MAX),
6772 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6773 ))
6774 );
6775 clock.sleep(keep_alive.interval.into());
6776 assert_matches!(state, State::Established(_));
6777 }
6778
6779 assert_eq!(
6782 state.poll_send(
6783 &FakeStateMachineDebugId::default(),
6784 &counters.refs(),
6785 clock.now(),
6786 socket_options,
6787 ),
6788 Err(NewlyClosed::Yes),
6789 );
6790 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
6791 CounterExpectations {
6792 established_closed: 1,
6793 established_timedout: 1,
6794 ..Default::default()
6795 }
6796 .assert_counters(&counters);
6797 }
6798
6799 #[derive(Debug)]
6801 struct ReservingBuffer<B> {
6802 buffer: B,
6803 reserved_bytes: usize,
6804 }
6805
6806 impl<B: Buffer> Buffer for ReservingBuffer<B> {
6807 fn limits(&self) -> BufferLimits {
6808 self.buffer.limits()
6809 }
6810
6811 fn target_capacity(&self) -> usize {
6812 self.buffer.target_capacity()
6813 }
6814
6815 fn request_capacity(&mut self, size: usize) {
6816 self.buffer.request_capacity(size)
6817 }
6818 }
6819
6820 impl<B: SendBuffer> SendBuffer for ReservingBuffer<B> {
6821 type Payload<'a> = B::Payload<'a>;
6822
6823 fn mark_read(&mut self, count: usize) {
6824 self.buffer.mark_read(count)
6825 }
6826
6827 fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
6828 where
6829 F: FnOnce(B::Payload<'a>) -> R,
6830 {
6831 let Self { buffer, reserved_bytes } = self;
6832 buffer.peek_with(offset, |payload| {
6833 let len = payload.len();
6834 let new_len = len.saturating_sub(*reserved_bytes);
6835 f(payload.slice(0..new_len.try_into().unwrap_or(u32::MAX)))
6836 })
6837 }
6838 }
6839
6840 #[test_case(true, 0)]
6841 #[test_case(false, 0)]
6842 #[test_case(true, 1)]
6843 #[test_case(false, 1)]
6844 fn poll_send_len(has_fin: bool, reserved_bytes: usize) {
6845 const VALUE: u8 = 0xaa;
6846
6847 fn with_poll_send_result<const HAS_FIN: bool>(
6848 f: impl FnOnce(Segment<FragmentedPayload<'_, 2>>),
6849 reserved_bytes: usize,
6850 ) {
6851 const DATA_LEN: usize = 40;
6852 let buffer = ReservingBuffer {
6853 buffer: RingBuffer::with_data(DATA_LEN, &vec![VALUE; DATA_LEN]),
6854 reserved_bytes,
6855 };
6856 assert_eq!(buffer.limits().len, DATA_LEN);
6857
6858 let mut snd = Send::<FakeInstant, _, HAS_FIN>::default_for_test_at(TEST_ISS, buffer);
6859 let counters = FakeTcpCounters::default();
6860
6861 f(snd
6862 .poll_send(
6863 &FakeStateMachineDebugId::default(),
6864 &counters.refs(),
6865 &mut RecvParams {
6866 ack: TEST_ISS,
6867 wnd: WindowSize::DEFAULT,
6868 wnd_scale: WindowScale::ZERO,
6869 ts_opt: default_ts_opt_state(TEST_IRS + 1),
6870 },
6871 FakeInstant::default(),
6872 &SocketOptions::default_for_state_tests(),
6873 )
6874 .expect("has data"))
6875 }
6876
6877 let f = |segment: Segment<FragmentedPayload<'_, 2>>| {
6878 let segment_len = segment.len();
6879 let (SegmentHeader { .. }, data) = segment.into_parts();
6880 let data_len = data.len();
6881
6882 if has_fin && reserved_bytes == 0 {
6883 assert_eq!(
6884 segment_len,
6885 u32::try_from(data_len + 1).unwrap(),
6886 "FIN not accounted for"
6887 );
6888 } else {
6889 assert_eq!(segment_len, u32::try_from(data_len).unwrap());
6890 }
6891
6892 let mut target = vec![0; data_len];
6893 data.partial_copy(0, target.as_mut_slice());
6894 assert_eq!(target, vec![VALUE; data_len]);
6895 };
6896 match has_fin {
6897 true => with_poll_send_result::<true>(f, reserved_bytes),
6898 false => with_poll_send_result::<false>(f, reserved_bytes),
6899 }
6900 }
6901
6902 #[test]
6903 fn zero_window_probe() {
6904 let mut clock = FakeInstantCtx::default();
6905 let counters = FakeTcpCounters::default();
6906 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
6907 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
6908 let mut state = State::Established(Established {
6910 snd: Send {
6911 wnd: WindowSize::ZERO,
6912 wnd_max: WindowSize::ZERO,
6913 ..Send::default_for_test(send_buffer.clone())
6914 }
6915 .into(),
6916 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
6917 });
6918 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
6919 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(Rto::DEFAULT.get())));
6920
6921 clock.sleep(Rto::DEFAULT.get());
6923 assert_eq!(
6924 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6925 Some(Segment::with_data(
6926 TEST_ISS + 1,
6927 TEST_IRS + 1,
6928 UnscaledWindowSize::from_usize(BUFFER_SIZE),
6929 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6930 FragmentedPayload::new_contiguous(&TEST_BYTES[0..1])
6931 ))
6932 );
6933
6934 assert_eq!(
6936 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6937 Segment::ack(
6938 TEST_IRS + 1,
6939 TEST_ISS + 1,
6940 UnscaledWindowSize::from(0),
6941 DEFAULT_SEGMENT_OPTIONS
6942 ),
6943 clock.now(),
6944 &counters.refs(),
6945 ),
6946 (None, None)
6947 );
6948 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
6950 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(Rto::DEFAULT.get() * 2)));
6951
6952 clock.sleep(Rto::DEFAULT.get());
6954 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
6955
6956 clock.sleep(Rto::DEFAULT.get());
6958 assert_eq!(
6959 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6960 Some(Segment::with_data(
6961 TEST_ISS + 1,
6962 TEST_IRS + 1,
6963 UnscaledWindowSize::from_usize(BUFFER_SIZE),
6964 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
6965 FragmentedPayload::new_contiguous(&TEST_BYTES[0..1])
6966 ))
6967 );
6968
6969 assert_eq!(
6971 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
6972 Segment::ack(
6973 TEST_IRS + 1,
6974 TEST_ISS + 2,
6975 UnscaledWindowSize::from(u16::MAX),
6976 DEFAULT_SEGMENT_OPTIONS
6977 ),
6978 clock.now(),
6979 &counters.refs(),
6980 ),
6981 (None, None)
6982 );
6983 assert_eq!(state.poll_send_at(), None);
6984 assert_eq!(
6985 state.poll_send_with_default_options(clock.now(), &counters.refs()),
6986 Some(Segment::new_assert_no_discard(
6987 SegmentHeader {
6988 seq: TEST_ISS + 2,
6989 ack: Some(TEST_IRS + 1),
6990 control: None,
6991 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
6992 push: true,
6993 options: default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP)
6994 .into(),
6995 },
6996 FragmentedPayload::new_contiguous(&TEST_BYTES[1..])
6997 ))
6998 );
6999 }
7000
7001 #[test]
7002 fn nagle() {
7003 let clock = FakeInstantCtx::default();
7004 let counters = FakeTcpCounters::default();
7005 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
7006 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7008 const PARTIAL_LEN: usize = 10;
7009 assert_eq!(send_buffer.enqueue_data(&TEST_BYTES[..PARTIAL_LEN]), PARTIAL_LEN);
7010 let mut state: State<_, _, _, ()> = State::Established(Established {
7012 snd: Send {
7013 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
7014 ..Send::default_for_test(send_buffer.clone())
7015 }
7016 .into(),
7017 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
7018 });
7019 let mut socket_options =
7020 SocketOptions { nagle_enabled: true, ..SocketOptions::default_for_state_tests() };
7021
7022 assert_eq!(
7024 state.poll_send(
7025 &FakeStateMachineDebugId::default(),
7026 &counters.refs(),
7027 clock.now(),
7028 &socket_options
7029 ),
7030 Ok(Segment::with_data(
7031 TEST_ISS + 1,
7032 TEST_IRS + 1,
7033 UnscaledWindowSize::from_usize(BUFFER_SIZE),
7034 DEFAULT_SEGMENT_OPTIONS,
7035 FragmentedPayload::new_contiguous(TEST_BYTES)
7036 ))
7037 );
7038 assert_eq!(
7040 state.poll_send(
7041 &FakeStateMachineDebugId::default(),
7042 &counters.refs(),
7043 clock.now(),
7044 &socket_options
7045 ),
7046 Err(NewlyClosed::No)
7047 );
7048 socket_options.nagle_enabled = false;
7049 assert_eq!(
7050 state.poll_send(
7051 &FakeStateMachineDebugId::default(),
7052 &counters.refs(),
7053 clock.now(),
7054 &socket_options
7055 ),
7056 Ok(Segment::new_assert_no_discard(
7057 SegmentHeader {
7058 seq: TEST_ISS + TEST_BYTES.len() + 1,
7059 ack: Some(TEST_IRS + 1),
7060 control: None,
7061 wnd: UnscaledWindowSize::from_usize(BUFFER_SIZE),
7062 push: true,
7063 options: DEFAULT_SEGMENT_OPTIONS.into(),
7064 },
7065 FragmentedPayload::new_contiguous(&TEST_BYTES[..PARTIAL_LEN])
7066 ))
7067 );
7068 }
7069
7070 #[test]
7071 fn mss_option() {
7072 let mss = Mss::MIN;
7074 assert!(usize::from(mss) < TEST_BYTES.len());
7075
7076 let clock = FakeInstantCtx::default();
7077 let counters = FakeTcpCounters::default();
7078 let (syn_sent, syn) = Closed::<Initial>::connect(
7079 TEST_ISS,
7080 TIMESTAMP_OFFSET,
7081 clock.now(),
7082 (),
7083 Default::default(),
7084 mss,
7085 Mss::DEFAULT_IPV4,
7086 &SocketOptions::default_for_state_tests(),
7087 );
7088 let mut state = State::<_, RingBuffer, RingBuffer, ()>::SynSent(syn_sent);
7089
7090 let (seg, passive_open) = state
7092 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
7093 syn,
7094 clock.now(),
7095 &counters.refs(),
7096 );
7097 let syn_ack = seg.expect("expected SYN-ACK");
7098 assert_eq!(passive_open, None);
7099
7100 assert_eq!(
7102 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
7103 syn_ack,
7104 clock.now(),
7105 &counters.refs(),
7106 ),
7107 (
7108 Some(Segment::ack(
7109 TEST_ISS + 1,
7110 TEST_ISS + 1,
7111 UnscaledWindowSize::from(u16::MAX),
7112 DEFAULT_SEGMENT_OPTIONS
7113 )),
7114 None
7115 )
7116 );
7117 match state {
7118 State::Closed(_)
7119 | State::Listen(_)
7120 | State::SynRcvd(_)
7121 | State::SynSent(_)
7122 | State::LastAck(_)
7123 | State::FinWait1(_)
7124 | State::FinWait2(_)
7125 | State::Closing(_)
7126 | State::TimeWait(_) => {
7127 panic!("expected that we have entered established state, but got {:?}", state)
7128 }
7129 State::Established(Established { ref mut snd, rcv: _ })
7130 | State::CloseWait(CloseWait { ref mut snd, closed_rcv: _ }) => {
7131 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7132 }
7133 }
7134 let effective_mss =
7136 EffectiveMss::from_mss(mss, MssSizeLimiters { timestamp_enabled: true });
7137 assert_eq!(
7138 state.poll_send_with_default_options(clock.now(), &counters.refs()),
7139 Some(Segment::with_data(
7140 TEST_ISS + 1,
7141 TEST_ISS + 1,
7142 UnscaledWindowSize::from(u16::MAX),
7143 DEFAULT_SEGMENT_OPTIONS,
7144 FragmentedPayload::new_contiguous(&TEST_BYTES[..usize::from(effective_mss)]),
7145 ))
7146 );
7147 }
7148
7149 const TEST_USER_TIMEOUT: NonZeroDuration = NonZeroDuration::from_secs(2 * 60).unwrap();
7150
7151 #[test_case(Duration::from_millis(1), false, true; "retrans_max_retries")]
7155 #[test_case(Duration::from_secs(1), false, false; "retrans_no_max_retries")]
7156 #[test_case(Duration::from_millis(1), true, true; "zwp_max_retries")]
7157 #[test_case(Duration::from_secs(1), true, false; "zwp_no_max_retires")]
7158 fn user_timeout(rtt: Duration, zero_window_probe: bool, max_retries: bool) {
7159 let mut clock = FakeInstantCtx::default();
7160 let counters = FakeTcpCounters::default();
7161 let mut send_buffer = RingBuffer::new(BUFFER_SIZE);
7162 assert_eq!(send_buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7163 let mut state: State<_, _, _, ()> = State::Established(Established {
7165 snd: Send {
7166 rtt_estimator: Estimator::Measured { srtt: rtt, rtt_var: Duration::ZERO },
7167 ..Send::default_for_test(send_buffer.clone())
7168 }
7169 .into(),
7170 rcv: Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
7171 });
7172 let mut times = 0;
7173 let start = clock.now();
7174 let socket_options = SocketOptions {
7175 user_timeout: (!max_retries).then_some(TEST_USER_TIMEOUT),
7176 ..SocketOptions::default_for_state_tests()
7177 };
7178 while let Ok(seg) = state.poll_send(
7179 &FakeStateMachineDebugId::default(),
7180 &counters.refs(),
7181 clock.now(),
7182 &socket_options,
7183 ) {
7184 if zero_window_probe {
7185 let zero_window_ack = Segment::ack(
7186 seg.header().ack.unwrap(),
7187 seg.header().seq,
7188 UnscaledWindowSize::from(0),
7189 DEFAULT_SEGMENT_OPTIONS,
7190 );
7191 assert_matches!(
7192 state.on_segment::<(), ClientlessBufferProvider>(
7193 &FakeStateMachineDebugId::default(),
7194 &counters.refs(),
7195 zero_window_ack,
7196 clock.now(),
7197 &socket_options,
7198 false,
7199 ),
7200 (None, None, DataAcked::No, _newly_closed)
7201 );
7202
7203 assert_matches!(
7208 state.poll_send(
7209 &FakeStateMachineDebugId::default(),
7210 &counters.refs(),
7211 clock.now(),
7212 &socket_options,
7213 ),
7214 Err(NewlyClosed::No)
7215 );
7216 let inner_state = assert_matches!(state, State::Established(ref e) => e);
7217 assert_matches!(inner_state.snd.timer, Some(SendTimer::ZeroWindowProbe(_)));
7218 }
7219
7220 let deadline = state.poll_send_at().expect("must have a retransmission timer");
7221 clock.sleep(deadline.checked_duration_since(clock.now()).unwrap());
7222 times += 1;
7223 }
7224 let elapsed = clock.now().checked_duration_since(start).unwrap();
7225 if max_retries {
7226 assert_eq!(times, 1 + DEFAULT_MAX_RETRIES.get());
7227 } else {
7228 assert_eq!(elapsed, TEST_USER_TIMEOUT.get());
7229 assert!(times < DEFAULT_MAX_RETRIES.get());
7230 }
7231 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
7232 CounterExpectations {
7233 established_closed: 1,
7234 established_timedout: 1,
7235 fast_recovery: if zero_window_probe { 1 } else { 0 },
7236 timeouts: counters.stack_wide.timeouts.get(),
7239 retransmits: counters.stack_wide.retransmits.get(),
7240 slow_start_retransmits: counters.stack_wide.slow_start_retransmits.get(),
7241 dup_acks: counters.stack_wide.dup_acks.get(),
7242 ..Default::default()
7243 }
7244 .assert_counters(&counters);
7245 }
7246
7247 #[test]
7248 fn retrans_timer_backoff() {
7249 let mut clock = FakeInstantCtx::default();
7250 let mut timer = RetransTimer::new(
7251 clock.now(),
7252 Rto::DEFAULT,
7253 Some(TEST_USER_TIMEOUT),
7254 DEFAULT_MAX_RETRIES,
7255 );
7256 assert_eq!(timer.at, FakeInstant::from(Rto::DEFAULT.get()));
7257 clock.sleep(TEST_USER_TIMEOUT.get());
7258 timer.backoff(clock.now());
7259 assert_eq!(timer.at, FakeInstant::from(TEST_USER_TIMEOUT.get()));
7260 clock.sleep(Duration::from_secs(1));
7261 timer.backoff(clock.now());
7263 assert_eq!(timer.at, FakeInstant::from(TEST_USER_TIMEOUT.get()));
7265 }
7266
7267 #[test_case(
7268 State::Established(Established {
7269 snd: Send {
7270 rtt_estimator: Estimator::Measured {
7271 srtt: Rto::DEFAULT.get(),
7272 rtt_var: Duration::ZERO,
7273 },
7274 ..Send::default_for_test(RingBuffer::new(BUFFER_SIZE))
7275 }.into(),
7276 rcv: Recv::default_for_test(RingBuffer::new(
7277 TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize,
7278 )).into(),
7279 }); "established")]
7280 #[test_case(
7281 State::FinWait1(FinWait1 {
7282 snd: Send {
7283 rtt_estimator: Estimator::Measured {
7284 srtt: Rto::DEFAULT.get(),
7285 rtt_var: Duration::ZERO,
7286 },
7287 ..Send::default_for_test(RingBuffer::new(BUFFER_SIZE))
7288 }.into(),
7289 rcv: Recv::default_for_test(RingBuffer::new(
7290 TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize,
7291 )).into(),
7292 }); "fin_wait_1")]
7293 #[test_case(
7294 State::FinWait2(FinWait2 {
7295 last_seq: TEST_ISS + 1,
7296 rcv: Recv::default_for_test(RingBuffer::new(
7297 TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize,
7298 )),
7299 timeout_at: None,
7300 }); "fin_wait_2")]
7301 fn delayed_ack(mut state: State<FakeInstant, RingBuffer, RingBuffer, ()>) {
7302 let mut clock = FakeInstantCtx::default();
7303 let counters = FakeTcpCounters::default();
7304 let socket_options =
7305 SocketOptions { delayed_ack: true, ..SocketOptions::default_for_state_tests() };
7306 assert_eq!(
7307 state.on_segment::<_, ClientlessBufferProvider>(
7308 &FakeStateMachineDebugId::default(),
7309 &counters.refs(),
7310 Segment::with_data(
7311 TEST_IRS + 1,
7312 TEST_ISS + 1,
7313 UnscaledWindowSize::from(u16::MAX),
7314 DEFAULT_SEGMENT_OPTIONS,
7315 TEST_BYTES,
7316 ),
7317 clock.now(),
7318 &socket_options,
7319 false, ),
7321 (None, None, DataAcked::No, NewlyClosed::No)
7322 );
7323 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(ACK_DELAY_THRESHOLD)));
7324 clock.sleep(ACK_DELAY_THRESHOLD);
7325 assert_eq!(
7326 state.poll_send(
7327 &FakeStateMachineDebugId::default(),
7328 &counters.refs(),
7329 clock.now(),
7330 &socket_options
7331 ),
7332 Ok(Segment::ack(
7333 TEST_ISS + 1,
7334 TEST_IRS + 1 + TEST_BYTES.len(),
7335 UnscaledWindowSize::from_u32(2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE)),
7336 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
7337 ))
7338 );
7339 let full_segment_sized_payload =
7340 vec![b'0'; u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE) as usize];
7341
7342 let expect_last_window_update = (
7343 TEST_IRS + 1 + TEST_BYTES.len(),
7344 WindowSize::from_u32(2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE)).unwrap(),
7345 );
7346 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_last_window_update);
7347 assert_eq!(
7349 state.on_segment::<_, ClientlessBufferProvider>(
7350 &FakeStateMachineDebugId::default(),
7351 &counters.refs(),
7352 Segment::with_data(
7353 TEST_IRS + 1 + TEST_BYTES.len(),
7354 TEST_ISS + 1,
7355 UnscaledWindowSize::from(u16::MAX),
7356 DEFAULT_SEGMENT_OPTIONS,
7357 &full_segment_sized_payload[..],
7358 ),
7359 clock.now(),
7360 &socket_options,
7361 false, ),
7363 (None, None, DataAcked::No, NewlyClosed::No)
7364 );
7365 assert_eq!(state.poll_send_at(), Some(clock.now().panicking_add(ACK_DELAY_THRESHOLD)));
7367 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_last_window_update);
7370
7371 assert_eq!(
7374 state.on_segment::<_, ClientlessBufferProvider>(
7375 &FakeStateMachineDebugId::default(),
7376 &counters.refs(),
7377 Segment::with_data(
7378 TEST_IRS + 1 + TEST_BYTES.len() + full_segment_sized_payload.len(),
7379 TEST_ISS + 1,
7380 UnscaledWindowSize::from(u16::MAX),
7381 DEFAULT_SEGMENT_OPTIONS,
7382 &full_segment_sized_payload[..],
7383 ),
7384 clock.now(),
7385 &socket_options,
7386 false, ),
7388 (
7389 Some(Segment::ack(
7390 TEST_ISS + 1,
7391 TEST_IRS + 1 + TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE),
7392 UnscaledWindowSize::from(0),
7393 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
7394 )),
7395 None,
7396 DataAcked::No,
7397 NewlyClosed::No,
7398 )
7399 );
7400 assert_eq!(
7402 state.recv_mut().unwrap().last_window_update,
7403 (
7404 TEST_IRS + 1 + TEST_BYTES.len() + 2 * u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE),
7405 WindowSize::ZERO,
7406 )
7407 );
7408 assert_eq!(state.poll_send_at(), None);
7409 }
7410
7411 #[test_case(true; "sack permitted")]
7412 #[test_case(false; "sack not permitted")]
7413 fn immediate_ack_if_out_of_order_or_fin(sack_permitted: bool) {
7414 let clock = FakeInstantCtx::default();
7415 let counters = FakeTcpCounters::default();
7416 let socket_options =
7417 SocketOptions { delayed_ack: true, ..SocketOptions::default_for_state_tests() };
7418 let mut state: State<_, _, _, ()> = State::Established(Established {
7419 snd: Send::default_for_test(RingBuffer::new(BUFFER_SIZE)).into(),
7420 rcv: Recv {
7421 sack_permitted,
7422 ..Recv::default_for_test(RingBuffer::new(TEST_BYTES.len() + 1))
7423 }
7424 .into(),
7425 });
7426 let segment_start = TEST_IRS + 2;
7429 assert_eq!(
7430 state.on_segment::<_, ClientlessBufferProvider>(
7431 &FakeStateMachineDebugId::default(),
7432 &counters.refs(),
7433 Segment::with_data(
7434 segment_start,
7435 TEST_ISS + 1,
7436 UnscaledWindowSize::from(u16::MAX),
7437 DEFAULT_SEGMENT_OPTIONS,
7438 &TEST_BYTES[1..]
7439 ),
7440 clock.now(),
7441 &socket_options,
7442 false, ),
7444 (
7445 Some(Segment::ack(
7446 TEST_ISS + 1,
7447 TEST_IRS + 1,
7448 UnscaledWindowSize::from(u16::try_from(TEST_BYTES.len() + 1).unwrap()),
7449 SegmentOptions {
7450 sack_blocks: if sack_permitted {
7451 [SackBlock::try_new(
7452 segment_start,
7453 segment_start + u32::try_from(TEST_BYTES.len()).unwrap() - 1,
7454 )
7455 .unwrap()]
7456 .into_iter()
7457 .collect()
7458 } else {
7459 SackBlocks::default()
7460 },
7461 timestamp: Some(DEFAULT_ACK_TS_OPT),
7462 },
7463 )),
7464 None,
7465 DataAcked::No,
7466 NewlyClosed::No,
7467 )
7468 );
7469 assert_eq!(state.poll_send_at(), None);
7470 assert_eq!(
7473 state.on_segment::<_, ClientlessBufferProvider>(
7474 &FakeStateMachineDebugId::default(),
7475 &counters.refs(),
7476 Segment::with_data(
7477 TEST_IRS + 1,
7478 TEST_ISS + 1,
7479 UnscaledWindowSize::from(u16::MAX),
7480 DEFAULT_SEGMENT_OPTIONS,
7481 &TEST_BYTES[..1]
7482 ),
7483 clock.now(),
7484 &socket_options,
7485 false, ),
7487 (
7488 Some(Segment::ack(
7489 TEST_ISS + 1,
7490 TEST_IRS + 1 + TEST_BYTES.len(),
7491 UnscaledWindowSize::from(1),
7492 DEFAULT_SEGMENT_OPTIONS
7493 )),
7494 None,
7495 DataAcked::No,
7496 NewlyClosed::No
7497 )
7498 );
7499 assert_eq!(state.poll_send_at(), None);
7500 assert_eq!(
7502 state.on_segment::<(), ClientlessBufferProvider>(
7503 &FakeStateMachineDebugId::default(),
7504 &counters.refs(),
7505 Segment::fin(
7506 TEST_IRS + 1 + TEST_BYTES.len(),
7507 TEST_ISS + 1,
7508 UnscaledWindowSize::from(u16::MAX),
7509 DEFAULT_SEGMENT_OPTIONS
7510 ),
7511 clock.now(),
7512 &socket_options,
7513 false, ),
7515 (
7516 Some(Segment::ack(
7517 TEST_ISS + 1,
7518 TEST_IRS + 1 + TEST_BYTES.len() + 1,
7519 UnscaledWindowSize::from(0),
7520 DEFAULT_SEGMENT_OPTIONS
7521 )),
7522 None,
7523 DataAcked::No,
7524 NewlyClosed::No,
7525 )
7526 );
7527 assert_eq!(state.poll_send_at(), None);
7528 }
7529
7530 #[test]
7531 fn fin_wait2_timeout() {
7532 let mut clock = FakeInstantCtx::default();
7533 let counters = FakeTcpCounters::default();
7534 let mut state: State<_, _, NullBuffer, ()> = State::FinWait2(FinWait2 {
7535 last_seq: TEST_ISS,
7536 rcv: Recv::default_for_test_at(TEST_IRS, NullBuffer),
7537 timeout_at: None,
7538 });
7539 assert_eq!(
7540 state.close(
7541 &counters.refs(),
7542 CloseReason::Close { now: clock.now() },
7543 &SocketOptions::default_for_state_tests()
7544 ),
7545 Err(CloseError::Closing)
7546 );
7547 assert_eq!(
7548 state.poll_send_at(),
7549 Some(clock.now().panicking_add(DEFAULT_FIN_WAIT2_TIMEOUT))
7550 );
7551 clock.sleep(DEFAULT_FIN_WAIT2_TIMEOUT);
7552 assert_eq!(state.poll_send_with_default_options(clock.now(), &counters.refs()), None);
7553 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
7554 CounterExpectations {
7555 established_closed: 1,
7556 established_timedout: 1,
7557 ..Default::default()
7558 }
7559 .assert_counters(&counters);
7560 }
7561
7562 #[test_case(RetransTimer {
7563 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(100))),
7564 remaining_retries: None,
7565 at: FakeInstant::from(Duration::from_secs(1)),
7566 rto: Rto::new(Duration::from_secs(1)),
7567 }, FakeInstant::from(Duration::from_secs(1)) => true)]
7568 #[test_case(RetransTimer {
7569 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(100))),
7570 remaining_retries: None,
7571 at: FakeInstant::from(Duration::from_secs(2)),
7572 rto: Rto::new(Duration::from_secs(1)),
7573 }, FakeInstant::from(Duration::from_secs(1)) => false)]
7574 #[test_case(RetransTimer {
7575 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(100))),
7576 remaining_retries: Some(NonZeroU8::new(1).unwrap()),
7577 at: FakeInstant::from(Duration::from_secs(2)),
7578 rto: Rto::new(Duration::from_secs(1)),
7579 }, FakeInstant::from(Duration::from_secs(1)) => false)]
7580 #[test_case(RetransTimer {
7581 user_timeout_until: Some(FakeInstant::from(Duration::from_secs(1))),
7582 remaining_retries: Some(NonZeroU8::new(1).unwrap()),
7583 at: FakeInstant::from(Duration::from_secs(1)),
7584 rto: Rto::new(Duration::from_secs(1)),
7585 }, FakeInstant::from(Duration::from_secs(1)) => true)]
7586 fn send_timed_out(timer: RetransTimer<FakeInstant>, now: FakeInstant) -> bool {
7587 timer.timed_out(now)
7588 }
7589
7590 #[test_case(
7591 State::SynSent(SynSent{
7592 iss: TEST_ISS,
7593 timestamp: Some(FakeInstant::default()),
7594 retrans_timer: RetransTimer::new(
7595 FakeInstant::default(),
7596 Rto::MIN,
7597 NonZeroDuration::from_secs(60),
7598 DEFAULT_MAX_SYN_RETRIES,
7599 ),
7600 active_open: (),
7601 buffer_sizes: Default::default(),
7602 device_mss: Mss::DEFAULT_IPV4,
7603 default_mss: Mss::DEFAULT_IPV4,
7604 rcv_wnd_scale: WindowScale::default(),
7605 ts_opt: default_ts_opt_negotiation_state(),
7606 })
7607 => DEFAULT_MAX_SYN_RETRIES.get(); "syn_sent")]
7608 #[test_case(
7609 State::SynRcvd(SynRcvd{
7610 iss: TEST_ISS,
7611 irs: TEST_IRS,
7612 timestamp: Some(FakeInstant::default()),
7613 retrans_timer: RetransTimer::new(
7614 FakeInstant::default(),
7615 Rto::MIN,
7616 NonZeroDuration::from_secs(60),
7617 DEFAULT_MAX_SYNACK_RETRIES,
7618 ),
7619 simultaneous_open: None,
7620 buffer_sizes: BufferSizes::default(),
7621 smss: EffectiveMss::from_mss(
7622 Mss::DEFAULT_IPV4, MssSizeLimiters { timestamp_enabled: true }
7623 ),
7624 rcv_wnd_scale: WindowScale::default(),
7625 snd_wnd_scale: Some(WindowScale::default()),
7626 sack_permitted: SACK_PERMITTED,
7627 rcv: RecvParams {
7628 ack: TEST_IRS + 1,
7629 wnd: WindowSize::DEFAULT,
7630 wnd_scale: WindowScale::default(),
7631 ts_opt: default_ts_opt_state(TEST_IRS+1),
7632 },
7633 })
7634 => DEFAULT_MAX_SYNACK_RETRIES.get(); "syn_rcvd")]
7635 fn handshake_timeout(mut state: State<FakeInstant, RingBuffer, RingBuffer, ()>) -> u8 {
7636 let mut clock = FakeInstantCtx::default();
7637 let counters = FakeTcpCounters::default();
7638 let mut retransmissions = 0;
7639 clock.sleep_until(state.poll_send_at().expect("must have a retransmission timer"));
7640 while let Some(_seg) = state.poll_send_with_default_options(clock.now(), &counters.refs()) {
7641 let deadline = state.poll_send_at().expect("must have a retransmission timer");
7642 clock.sleep_until(deadline);
7643 retransmissions += 1;
7644 }
7645 assert_eq!(state, State::Closed(Closed { reason: Some(ConnectionError::TimedOut) }));
7646 CounterExpectations::default().assert_counters(&counters);
7647 retransmissions
7648 }
7649
7650 #[test_case(
7651 u16::MAX as usize, WindowScale::default(), Some(WindowScale::default())
7652 => (WindowScale::default(), WindowScale::default()))]
7653 #[test_case(
7654 u16::MAX as usize + 1, WindowScale::new(1).unwrap(), Some(WindowScale::default())
7655 => (WindowScale::new(1).unwrap(), WindowScale::default()))]
7656 #[test_case(
7657 u16::MAX as usize + 1, WindowScale::new(1).unwrap(), None
7658 => (WindowScale::default(), WindowScale::default()))]
7659 #[test_case(
7660 u16::MAX as usize, WindowScale::default(), Some(WindowScale::new(1).unwrap())
7661 => (WindowScale::default(), WindowScale::new(1).unwrap()))]
7662 fn window_scale(
7663 buffer_size: usize,
7664 syn_window_scale: WindowScale,
7665 syn_ack_window_scale: Option<WindowScale>,
7666 ) -> (WindowScale, WindowScale) {
7667 let mut clock = FakeInstantCtx::default();
7668 let counters = FakeTcpCounters::default();
7669 let (syn_sent, syn_seg) = Closed::<Initial>::connect(
7670 TEST_ISS,
7671 TIMESTAMP_OFFSET,
7672 clock.now(),
7673 (),
7674 BufferSizes { receive: buffer_size, ..Default::default() },
7675 DEVICE_MAXIMUM_SEGMENT_SIZE,
7676 Mss::DEFAULT_IPV4,
7677 &SocketOptions::default_for_state_tests(),
7678 );
7679 assert_eq!(
7680 syn_seg,
7681 Segment::syn(
7682 TEST_ISS,
7683 UnscaledWindowSize::from(u16::try_from(buffer_size).unwrap_or(u16::MAX)),
7684 HandshakeOptions {
7685 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
7686 window_scale: Some(syn_window_scale),
7687 sack_permitted: SACK_PERMITTED,
7688 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
7689 },
7690 )
7691 );
7692 let mut active = State::SynSent(syn_sent);
7693 clock.sleep(RTT / 2);
7694 let (seg, passive_open) = active
7695 .on_segment_with_default_options::<(), ClientlessBufferProvider>(
7696 Segment::syn_ack(
7697 TEST_IRS,
7698 TEST_ISS + 1,
7699 UnscaledWindowSize::from(u16::MAX),
7700 HandshakeOptions {
7701 mss: Some(Mss::DEFAULT_IPV4),
7702 window_scale: syn_ack_window_scale,
7703 sack_permitted: SACK_PERMITTED,
7704 timestamp: Some(DEFAULT_ACK_TS_OPT),
7705 },
7706 ),
7707 clock.now(),
7708 &counters.refs(),
7709 );
7710 assert_eq!(passive_open, None);
7711 assert_matches!(seg, Some(_));
7712
7713 let established: Established<FakeInstant, RingBuffer, NullBuffer> =
7714 assert_matches!(active, State::Established(established) => established);
7715
7716 assert_eq!(established.snd.wnd, WindowSize::DEFAULT);
7717
7718 (established.rcv.wnd_scale, established.snd.wnd_scale)
7719 }
7720
7721 #[test_case(
7722 u16::MAX as usize,
7723 Segment::syn_ack(
7724 TEST_IRS + 1 + u16::MAX as usize,
7725 TEST_ISS + 1,
7726 UnscaledWindowSize::from(u16::MAX),
7727 HandshakeOptions{timestamp: Some(DEFAULT_NON_ACK_TS_OPT), .. Default::default()},
7728 )
7729 )]
7730 #[test_case(
7731 u16::MAX as usize + 1,
7732 Segment::syn_ack(
7733 TEST_IRS + 1 + u16::MAX as usize,
7734 TEST_ISS + 1,
7735 UnscaledWindowSize::from(u16::MAX),
7736 HandshakeOptions{timestamp: Some(DEFAULT_NON_ACK_TS_OPT), .. Default::default()},
7737 )
7738 )]
7739 #[test_case(
7740 u16::MAX as usize,
7741 Segment::with_data(
7742 TEST_IRS + 1 + u16::MAX as usize,
7743 TEST_ISS + 1,
7744 UnscaledWindowSize::from(u16::MAX),
7745 DEFAULT_SEGMENT_OPTIONS,
7746 &TEST_BYTES[..],
7747 )
7748 )]
7749 #[test_case(
7750 u16::MAX as usize + 1,
7751 Segment::with_data(
7752 TEST_IRS + 1 + u16::MAX as usize,
7753 TEST_ISS + 1,
7754 UnscaledWindowSize::from(u16::MAX),
7755 DEFAULT_SEGMENT_OPTIONS,
7756 &TEST_BYTES[..],
7757 )
7758 )]
7759 fn window_scale_otw_seq(receive_buf_size: usize, otw_seg: impl Into<Segment<&'static [u8]>>) {
7760 let counters = FakeTcpCounters::default();
7761 let buffer_sizes = BufferSizes { send: 0, receive: receive_buf_size };
7762 let rcv_wnd_scale = buffer_sizes.rwnd().scale();
7763 let rcv = RecvParams {
7764 ack: TEST_IRS + 1,
7765 wnd_scale: WindowScale::default(),
7766 wnd: buffer_sizes.rwnd_unscaled() << WindowScale::default(),
7767 ts_opt: default_ts_opt_state(TEST_IRS + 1),
7768 };
7769 let mut syn_rcvd: State<_, RingBuffer, RingBuffer, ()> = State::SynRcvd(SynRcvd {
7770 iss: TEST_ISS,
7771 irs: TEST_IRS,
7772 timestamp: None,
7773 retrans_timer: RetransTimer::new(
7774 FakeInstant::default(),
7775 Rto::DEFAULT,
7776 NonZeroDuration::from_secs(10),
7777 DEFAULT_MAX_SYNACK_RETRIES,
7778 ),
7779 simultaneous_open: None,
7780 buffer_sizes: BufferSizes { send: 0, receive: receive_buf_size },
7781 smss: EffectiveMss::from_mss(
7782 Mss::DEFAULT_IPV4,
7783 MssSizeLimiters { timestamp_enabled: true },
7784 ),
7785 rcv_wnd_scale,
7786 snd_wnd_scale: WindowScale::new(1),
7787 sack_permitted: SACK_PERMITTED,
7788 rcv,
7789 });
7790
7791 assert_eq!(
7792 syn_rcvd.on_segment_with_default_options::<_, ClientlessBufferProvider>(
7793 otw_seg.into(),
7794 FakeInstant::default(),
7795 &counters.refs()
7796 ),
7797 (
7798 Some(Segment::ack(
7799 TEST_ISS + 1,
7800 TEST_IRS + 1,
7801 buffer_sizes.rwnd_unscaled(),
7802 DEFAULT_SEGMENT_OPTIONS
7803 )),
7804 None
7805 ),
7806 )
7807 }
7808
7809 #[test]
7810 fn poll_send_reserving_buffer() {
7811 const RESERVED_BYTES: usize = 3;
7812 let mut snd: Send<FakeInstant, _, false> = Send::default_for_test(ReservingBuffer {
7813 buffer: RingBuffer::with_data(TEST_BYTES.len(), TEST_BYTES),
7814 reserved_bytes: RESERVED_BYTES,
7815 });
7816
7817 let counters = FakeTcpCounters::default();
7818
7819 assert_eq!(
7820 snd.poll_send(
7821 &FakeStateMachineDebugId::default(),
7822 &counters.refs(),
7823 &mut RecvParams {
7824 ack: TEST_IRS + 1,
7825 wnd: WindowSize::DEFAULT,
7826 wnd_scale: WindowScale::ZERO,
7827 ts_opt: default_ts_opt_state(TEST_IRS + 1),
7828 },
7829 FakeInstant::default(),
7830 &SocketOptions::default_for_state_tests(),
7831 ),
7832 Some(Segment::with_data(
7833 TEST_ISS + 1,
7834 TEST_IRS + 1,
7835 WindowSize::DEFAULT >> WindowScale::default(),
7836 DEFAULT_SEGMENT_OPTIONS,
7837 FragmentedPayload::new_contiguous(&TEST_BYTES[..TEST_BYTES.len() - RESERVED_BYTES])
7838 ))
7839 );
7840
7841 assert_eq!(snd.nxt, TEST_ISS + 1 + (TEST_BYTES.len() - RESERVED_BYTES));
7842 }
7843
7844 #[test]
7845 fn rcv_silly_window_avoidance() {
7846 const MULTIPLE: usize = 3;
7847 const CAP: usize = TEST_BYTES.len() * MULTIPLE;
7848 let mut rcv: Recv<FakeInstant, RingBuffer> =
7849 Recv { mss: TEST_MSS, ..Recv::default_for_test_at(TEST_IRS, RingBuffer::new(CAP)) };
7850
7851 fn get_buffer(rcv: &mut Recv<FakeInstant, RingBuffer>) -> &mut RingBuffer {
7852 assert_matches!(
7853 &mut rcv.buffer,
7854 RecvBufferState::Open {buffer, .. } => buffer
7855 )
7856 }
7857
7858 assert_eq!(rcv.calculate_window_size().window_size, WindowSize::new(CAP).unwrap());
7860
7861 for _ in 0..MULTIPLE {
7862 assert_eq!(get_buffer(&mut rcv).enqueue_data(TEST_BYTES), TEST_BYTES.len());
7863 }
7864 let assembler = assert_matches!(&mut rcv.buffer,
7865 RecvBufferState::Open { assembler, .. } => assembler);
7866 assert_eq!(assembler.insert(TEST_IRS..TEST_IRS + CAP), CAP);
7867 assert_eq!(rcv.calculate_window_size().window_size, WindowSize::ZERO);
7869
7870 assert_eq!(get_buffer(&mut rcv).read_with(|_| 1), 1);
7873 assert_eq!(rcv.calculate_window_size().window_size, WindowSize::ZERO);
7874
7875 assert_eq!(get_buffer(&mut rcv).read_with(|_| TEST_BYTES.len()), TEST_BYTES.len());
7878 assert_eq!(
7879 rcv.calculate_window_size().window_size,
7880 WindowSize::new(TEST_BYTES.len() + 1).unwrap()
7881 );
7882 }
7883
7884 #[test]
7885 fn correct_window_scale_during_send() {
7887 let snd_wnd_scale = WindowScale::new(4).unwrap();
7888 let rcv_wnd_scale = WindowScale::new(8).unwrap();
7889 let wnd_size = WindowSize::new(1024).unwrap();
7890
7891 let counters = FakeTcpCounters::default();
7892 let new_snd = || Send {
7895 wnd: wnd_size,
7896 wnd_scale: snd_wnd_scale,
7897 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
7898 ..Send::default_for_test(RingBuffer::with_data(TEST_BYTES.len(), TEST_BYTES))
7899 };
7900 let new_rcv = || Recv {
7901 wnd_scale: rcv_wnd_scale,
7902 ..Recv::default_for_test(RingBuffer::new(wnd_size.into()))
7903 };
7904 for mut state in [
7905 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
7906 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
7907 State::Closing(Closing {
7908 snd: new_snd().queue_fin(),
7909 closed_rcv: RecvParams {
7910 ack: TEST_IRS + 1,
7911 wnd: wnd_size,
7912 wnd_scale: rcv_wnd_scale,
7913 ts_opt: default_ts_opt_state(TEST_IRS + 1),
7914 },
7915 }),
7916 State::CloseWait(CloseWait {
7917 snd: new_snd().into(),
7918 closed_rcv: RecvParams {
7919 ack: TEST_IRS + 1,
7920 wnd: wnd_size,
7921 wnd_scale: rcv_wnd_scale,
7922 ts_opt: default_ts_opt_state(TEST_IRS + 1),
7923 },
7924 }),
7925 State::LastAck(LastAck {
7926 snd: new_snd().queue_fin(),
7927 closed_rcv: RecvParams {
7928 ack: TEST_IRS + 1,
7929 wnd: wnd_size,
7930 wnd_scale: rcv_wnd_scale,
7931 ts_opt: default_ts_opt_state(TEST_IRS + 1),
7932 },
7933 }),
7934 ] {
7935 assert_eq!(
7936 state.poll_send_with_default_options(FakeInstant::default(), &counters.refs(),),
7937 Some(Segment::new_assert_no_discard(
7938 SegmentHeader {
7939 seq: TEST_ISS + 1,
7940 ack: Some(TEST_IRS + 1),
7941 control: None,
7942 wnd: UnscaledWindowSize::from(4),
7945 push: true,
7946 options: DEFAULT_SEGMENT_OPTIONS.into(),
7947 },
7948 FragmentedPayload::new_contiguous(TEST_BYTES)
7949 ))
7950 );
7951 }
7952 }
7953
7954 #[test_case(true; "prompted window update")]
7955 #[test_case(false; "unprompted window update")]
7956 fn snd_silly_window_avoidance(prompted_window_update: bool) {
7957 const CAP: usize = TEST_BYTES.len() * 2;
7958 let mut snd: Send<FakeInstant, RingBuffer, false> = Send {
7959 wl1: TEST_IRS,
7960 wl2: TEST_ISS,
7961 wnd: WindowSize::new(CAP).unwrap(),
7962 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
7963 ..Send::default_for_test(RingBuffer::new(CAP))
7964 };
7965
7966 let mut clock = FakeInstantCtx::default();
7967 let counters = FakeTcpCounters::default();
7968
7969 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7971 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
7972
7973 assert_eq!(
7975 snd.poll_send(
7976 &FakeStateMachineDebugId::default(),
7977 &counters.refs(),
7978 &mut RecvParams {
7979 ack: TEST_IRS + 1,
7980 wnd: WindowSize::DEFAULT,
7981 wnd_scale: WindowScale::ZERO,
7982 ts_opt: default_ts_opt_state(TEST_IRS + 1),
7983 },
7984 clock.now(),
7985 &SocketOptions::default_for_state_tests(),
7986 ),
7987 Some(Segment::with_data(
7988 TEST_ISS + 1,
7989 TEST_IRS + 1,
7990 UnscaledWindowSize::from(u16::MAX),
7991 DEFAULT_SEGMENT_OPTIONS,
7992 FragmentedPayload::new_contiguous(TEST_BYTES),
7993 )),
7994 );
7995
7996 assert_eq!(
7997 snd.process_ack(
7998 &FakeStateMachineDebugId::default(),
7999 &counters.refs(),
8000 TEST_IRS + 1,
8001 TEST_ISS + 1 + TEST_BYTES.len(),
8002 UnscaledWindowSize::from(0),
8003 &SackBlocks::EMPTY,
8004 true,
8005 &mut RecvParams {
8006 ack: TEST_IRS + 1,
8007 wnd_scale: WindowScale::default(),
8008 wnd: WindowSize::DEFAULT,
8009 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8010 },
8011 clock.now(),
8012 &SocketOptions::default(),
8013 ),
8014 (None, DataAcked::Yes)
8015 );
8016
8017 assert_eq!(
8020 snd.poll_send(
8021 &FakeStateMachineDebugId::default(),
8022 &counters.refs(),
8023 &mut RecvParams {
8024 ack: TEST_IRS + 1,
8025 wnd: WindowSize::DEFAULT,
8026 wnd_scale: WindowScale::ZERO,
8027 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8028 },
8029 clock.now(),
8030 &SocketOptions::default_for_state_tests(),
8031 ),
8032 None
8033 );
8034
8035 assert_eq!(
8036 snd.timer,
8037 Some(SendTimer::ZeroWindowProbe(RetransTimer::new(
8038 clock.now(),
8039 snd.rtt_estimator.rto(),
8040 None,
8041 DEFAULT_MAX_RETRIES,
8042 )))
8043 );
8044
8045 clock.sleep_until(snd.timer.as_ref().unwrap().expiry());
8046
8047 assert_eq!(
8048 snd.poll_send(
8049 &FakeStateMachineDebugId::default(),
8050 &counters.refs(),
8051 &mut RecvParams {
8052 ack: TEST_IRS + 1,
8053 wnd: WindowSize::DEFAULT,
8054 wnd_scale: WindowScale::ZERO,
8055 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8056 },
8057 clock.now(),
8058 &SocketOptions::default_for_state_tests(),
8059 ),
8060 Some(Segment::with_data(
8061 TEST_ISS + 1 + TEST_BYTES.len(),
8062 TEST_IRS + 1,
8063 UnscaledWindowSize::from(u16::MAX),
8064 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
8065 FragmentedPayload::new_contiguous(&TEST_BYTES[..1]),
8066 ))
8067 );
8068
8069 if prompted_window_update {
8070 assert_eq!(
8073 snd.process_ack(
8074 &FakeStateMachineDebugId::default(),
8075 &counters.refs(),
8076 TEST_IRS + 1,
8077 TEST_ISS + 1 + TEST_BYTES.len() + 1,
8078 UnscaledWindowSize::from(3),
8079 &SackBlocks::EMPTY,
8080 true,
8081 &mut RecvParams {
8082 ack: TEST_IRS + 1,
8083 wnd_scale: WindowScale::default(),
8084 wnd: WindowSize::DEFAULT,
8085 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8086 },
8087 clock.now(),
8088 &SocketOptions::default(),
8089 ),
8090 (None, DataAcked::Yes)
8091 );
8092 } else {
8093 assert_eq!(
8095 snd.process_ack(
8096 &FakeStateMachineDebugId::default(),
8097 &counters.refs(),
8098 TEST_IRS + 1,
8099 TEST_ISS + 1 + TEST_BYTES.len(),
8100 UnscaledWindowSize::from(0),
8101 &SackBlocks::EMPTY,
8102 true,
8103 &mut RecvParams {
8104 ack: TEST_IRS + 1,
8105 wnd_scale: WindowScale::default(),
8106 wnd: WindowSize::DEFAULT,
8107 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8108 },
8109 clock.now(),
8110 &SocketOptions::default(),
8111 ),
8112 (None, DataAcked::No)
8113 );
8114
8115 assert_eq!(
8118 snd.process_ack(
8119 &FakeStateMachineDebugId::default(),
8120 &counters.refs(),
8121 TEST_IRS + 1,
8122 TEST_ISS + 1 + TEST_BYTES.len(),
8123 UnscaledWindowSize::from(3),
8124 &SackBlocks::EMPTY,
8125 true,
8126 &mut RecvParams {
8127 ack: TEST_IRS + 1,
8128 wnd_scale: WindowScale::default(),
8129 wnd: WindowSize::DEFAULT,
8130 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8131 },
8132 clock.now(),
8133 &SocketOptions::default(),
8134 ),
8135 (None, DataAcked::No)
8136 );
8137 }
8138
8139 assert_eq!(
8141 snd.poll_send(
8142 &FakeStateMachineDebugId::default(),
8143 &counters.refs(),
8144 &mut RecvParams {
8145 ack: TEST_IRS + 1,
8146 wnd: WindowSize::DEFAULT,
8147 wnd_scale: WindowScale::ZERO,
8148 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8149 },
8150 clock.now(),
8151 &SocketOptions::default_for_state_tests(),
8152 ),
8153 None,
8154 );
8155 assert_eq!(
8156 snd.timer,
8157 Some(SendTimer::SWSProbe { at: clock.now().panicking_add(SWS_PROBE_TIMEOUT) })
8158 );
8159 clock.sleep(SWS_PROBE_TIMEOUT);
8160
8161 let seq_index = usize::from(prompted_window_update);
8164 assert_eq!(
8165 snd.poll_send(
8166 &FakeStateMachineDebugId::default(),
8167 &counters.refs(),
8168 &mut RecvParams {
8169 ack: TEST_IRS + 1,
8170 wnd: WindowSize::DEFAULT,
8171 wnd_scale: WindowScale::ZERO,
8172 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8173 },
8174 clock.now(),
8175 &SocketOptions::default_for_state_tests(),
8176 ),
8177 Some(Segment::with_data(
8178 TEST_ISS + 1 + TEST_BYTES.len() + seq_index,
8179 TEST_IRS + 1,
8180 UnscaledWindowSize::from(u16::MAX),
8181 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
8182 FragmentedPayload::new_contiguous(&TEST_BYTES[seq_index..3 + seq_index]),
8183 ))
8184 );
8185 }
8186
8187 #[test]
8188 fn snd_enter_zwp_on_negative_window_update() {
8189 const CAP: usize = TEST_BYTES.len() * 2;
8190 let mut snd: Send<FakeInstant, RingBuffer, false> = Send {
8191 wnd: WindowSize::new(CAP).unwrap(),
8192 wl1: TEST_IRS,
8193 wl2: TEST_ISS,
8194 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
8195 ..Send::default_for_test(RingBuffer::new(CAP))
8196 };
8197
8198 let clock = FakeInstantCtx::default();
8199 let counters = FakeTcpCounters::default();
8200
8201 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
8203 assert_eq!(snd.buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
8204
8205 assert_eq!(
8207 snd.poll_send(
8208 &FakeStateMachineDebugId::default(),
8209 &counters.refs(),
8210 &mut RecvParams {
8211 ack: TEST_IRS + 1,
8212 wnd: WindowSize::DEFAULT,
8213 wnd_scale: WindowScale::ZERO,
8214 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8215 },
8216 clock.now(),
8217 &SocketOptions::default_for_state_tests(),
8218 ),
8219 Some(Segment::with_data(
8220 TEST_ISS + 1,
8221 TEST_IRS + 1,
8222 UnscaledWindowSize::from(u16::MAX),
8223 DEFAULT_SEGMENT_OPTIONS,
8224 FragmentedPayload::new_contiguous(TEST_BYTES),
8225 )),
8226 );
8227
8228 assert_matches!(snd.timer, Some(SendTimer::Retrans(_)));
8231
8232 assert_eq!(
8240 snd.process_ack(
8241 &FakeStateMachineDebugId::default(),
8242 &counters.refs(),
8243 TEST_IRS + 1,
8244 TEST_ISS + 1 + TEST_BYTES.len(),
8245 UnscaledWindowSize::from(0),
8246 &SackBlocks::EMPTY,
8247 true,
8248 &mut RecvParams {
8249 ack: TEST_IRS + 1,
8250 wnd_scale: WindowScale::default(),
8251 wnd: WindowSize::DEFAULT,
8252 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8253 },
8254 clock.now(),
8255 &SocketOptions::default(),
8256 ),
8257 (None, DataAcked::Yes)
8258 );
8259
8260 assert_eq!(
8263 snd.poll_send(
8264 &FakeStateMachineDebugId::default(),
8265 &counters.refs(),
8266 &mut RecvParams {
8267 ack: TEST_IRS + 1,
8268 wnd: WindowSize::DEFAULT,
8269 wnd_scale: WindowScale::ZERO,
8270 ts_opt: default_ts_opt_state(TEST_IRS + 1),
8271 },
8272 clock.now(),
8273 &SocketOptions::default_for_state_tests(),
8274 ),
8275 None,
8276 );
8277 assert_matches!(snd.timer, Some(SendTimer::ZeroWindowProbe(_)));
8278 }
8279
8280 #[test]
8281 fn ack_uses_snd_max() {
8283 let counters = FakeTcpCounters::default();
8284 let mut clock = FakeInstantCtx::default();
8285 let mut buffer = RingBuffer::new(BUFFER_SIZE);
8286 assert_eq!(buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
8287 assert_eq!(buffer.enqueue_data(TEST_BYTES), TEST_BYTES.len());
8288
8289 let iss = ISS_1 + 1;
8291 let mut state: State<_, _, _, ()> = State::Established(Established {
8292 snd: Send {
8293 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
8294 ..Send::default_for_test_at(iss, buffer)
8295 }
8296 .into(),
8297 rcv: Recv {
8298 mss: TEST_MSS,
8299 ..Recv::default_for_test_at(iss, RingBuffer::new(BUFFER_SIZE))
8300 }
8301 .into(),
8302 });
8303
8304 assert_eq!(
8306 state.poll_send_with_default_options(clock.now(), &counters.refs()),
8307 Some(Segment::with_data(
8308 iss,
8309 iss,
8310 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8311 DEFAULT_SEGMENT_OPTIONS,
8312 FragmentedPayload::new_contiguous(TEST_BYTES),
8313 )),
8314 );
8315 assert_eq!(
8316 state.poll_send_with_default_options(clock.now(), &counters.refs()),
8317 Some(Segment::new_assert_no_discard(
8318 SegmentHeader {
8319 seq: iss + TEST_BYTES.len(),
8320 ack: Some(iss),
8321 control: None,
8322 wnd: UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8323 push: true,
8324 options: DEFAULT_SEGMENT_OPTIONS.into(),
8325 },
8326 FragmentedPayload::new_contiguous(TEST_BYTES),
8327 )),
8328 );
8329
8330 clock.sleep(Rto::DEFAULT.get());
8332 assert_eq!(
8333 state.poll_send_with_default_options(clock.now(), &counters.refs()),
8334 Some(Segment::with_data(
8335 iss,
8336 iss,
8337 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8338 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
8339 FragmentedPayload::new_contiguous(TEST_BYTES),
8340 )),
8341 );
8342
8343 assert_eq!(
8346 state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
8347 Segment::with_data(
8348 iss,
8349 iss,
8350 UnscaledWindowSize::from(u16::try_from(BUFFER_SIZE).unwrap()),
8351 DEFAULT_SEGMENT_OPTIONS,
8352 TEST_BYTES,
8353 ),
8354 clock.now(),
8355 &counters.refs(),
8356 ),
8357 (
8358 Some(Segment::ack(
8359 iss + 2 * TEST_BYTES.len(),
8360 iss + TEST_BYTES.len(),
8361 UnscaledWindowSize::from(
8362 u16::try_from(BUFFER_SIZE - TEST_BYTES.len()).unwrap()
8363 ),
8364 default_segment_options(timestamp_now(&clock), DEFAULT_TIMESTAMP),
8365 )),
8366 None,
8367 )
8368 );
8369 }
8370
8371 #[test_case(
8372 State::Closed(Closed { reason: None }),
8373 State::Closed(Closed { reason: None }) => NewlyClosed::No; "closed to closed")]
8374 #[test_case(
8375 State::SynSent(SynSent {
8376 iss: TEST_ISS,
8377 timestamp: Some(FakeInstant::default()),
8378 retrans_timer: RetransTimer::new(
8379 FakeInstant::default(),
8380 Rto::DEFAULT,
8381 None,
8382 DEFAULT_MAX_SYN_RETRIES,
8383 ),
8384 active_open: (),
8385 buffer_sizes: BufferSizes::default(),
8386 default_mss: Mss::DEFAULT_IPV4,
8387 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8388 rcv_wnd_scale: WindowScale::default(),
8389 ts_opt: default_ts_opt_negotiation_state(),
8390 }),
8391 State::Closed(Closed { reason: None }) => NewlyClosed::Yes; "non-closed to closed")]
8392 #[test_case(
8393 State::SynSent(SynSent {
8394 iss: TEST_ISS,
8395 timestamp: Some(FakeInstant::default()),
8396 retrans_timer: RetransTimer::new(
8397 FakeInstant::default(),
8398 Rto::DEFAULT,
8399 None,
8400 DEFAULT_MAX_SYN_RETRIES,
8401 ),
8402 active_open: (),
8403 buffer_sizes: BufferSizes::default(),
8404 default_mss: Mss::DEFAULT_IPV4,
8405 device_mss: DEVICE_MAXIMUM_SEGMENT_SIZE,
8406 rcv_wnd_scale: WindowScale::default(),
8407 ts_opt: default_ts_opt_negotiation_state(),
8408 },
8409 ),
8410 State::SynRcvd(SynRcvd {
8411 iss: TEST_ISS,
8412 irs: TEST_IRS,
8413 timestamp: None,
8414 retrans_timer: RetransTimer::new(
8415 FakeInstant::default(),
8416 Rto::DEFAULT,
8417 NonZeroDuration::from_secs(10),
8418 DEFAULT_MAX_SYNACK_RETRIES,
8419 ),
8420 simultaneous_open: None,
8421 buffer_sizes: BufferSizes { send: 0, receive: 0 },
8422 smss: EffectiveMss::from_mss(
8423 Mss::DEFAULT_IPV4, MssSizeLimiters{timestamp_enabled: true}
8424 ),
8425 rcv_wnd_scale: WindowScale::new(0).unwrap(),
8426 snd_wnd_scale: WindowScale::new(0),
8427 sack_permitted: SACK_PERMITTED,
8428 rcv: RecvParams{
8429 ack: TEST_IRS + 1,
8430 wnd: WindowSize::DEFAULT,
8431 wnd_scale: WindowScale::default(),
8432 ts_opt: default_ts_opt_state(TEST_IRS+1),
8433 }
8434 }) => NewlyClosed::No; "non-closed to non-closed")]
8435 fn transition_to_state(
8436 mut old_state: State<FakeInstant, RingBuffer, RingBuffer, ()>,
8437 new_state: State<FakeInstant, RingBuffer, RingBuffer, ()>,
8438 ) -> NewlyClosed {
8439 let counters = FakeTcpCounters::default();
8440 old_state.transition_to_state(&counters.refs(), new_state)
8441 }
8442
8443 #[test_case(true, false, false; "more than mss dequeued")]
8444 #[test_case(false, false, false; "less than mss dequeued")]
8445 #[test_case(true, true, false; "more than mss dequeued and delack")]
8446 #[test_case(false, true, false; "less than mss dequeued and delack")]
8447 #[test_case(true, false, true; "more than mss dequeued with sack")]
8448 fn poll_receive_data_dequeued_state(
8449 dequeue_more_than_mss: bool,
8450 delayed_ack: bool,
8451 sack: bool,
8452 ) {
8453 const BUFFER_SIZE: usize = TEST_BYTES.len();
8456
8457 let new_snd = || Send {
8458 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
8459 ..Send::default_for_test(NullBuffer)
8460 };
8461 let new_rcv =
8462 || Recv { mss: TEST_MSS, ..Recv::default_for_test(RingBuffer::new(BUFFER_SIZE)) };
8463
8464 let clock = FakeInstantCtx::default();
8465 let counters = FakeTcpCounters::default();
8466 for mut state in [
8467 State::Established(Established { snd: new_snd().into(), rcv: new_rcv().into() }),
8468 State::FinWait1(FinWait1 { snd: new_snd().queue_fin().into(), rcv: new_rcv().into() }),
8469 State::FinWait2(FinWait2 { last_seq: TEST_ISS + 1, rcv: new_rcv(), timeout_at: None }),
8470 ] {
8471 assert_matches!(state.poll_receive_data_dequeued(clock.now()), None);
8474 let expect_window_update = (TEST_IRS + 1, WindowSize::new(BUFFER_SIZE).unwrap());
8475 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_window_update);
8476
8477 let seg = state.on_segment_with_options::<_, ClientlessBufferProvider>(
8481 Segment::with_data(
8482 TEST_IRS + 1,
8483 TEST_ISS + 1,
8484 UnscaledWindowSize::from(0),
8485 DEFAULT_SEGMENT_OPTIONS,
8486 TEST_BYTES,
8487 ),
8488 clock.now(),
8489 &counters.refs(),
8490 &SocketOptions { delayed_ack, ..SocketOptions::default_for_state_tests() },
8491 );
8492
8493 let expect_ack = (!delayed_ack).then_some(Segment::ack(
8494 TEST_ISS + 1,
8495 TEST_IRS + 1 + TEST_BYTES.len(),
8496 UnscaledWindowSize::from((BUFFER_SIZE - TEST_BYTES.len()) as u16),
8497 DEFAULT_SEGMENT_OPTIONS,
8498 ));
8499 assert_eq!(seg, (expect_ack, None));
8500 assert_matches!(state.poll_receive_data_dequeued(clock.now()), None);
8501
8502 let expect_window_update = if delayed_ack {
8503 expect_window_update
8504 } else {
8505 (TEST_IRS + 1 + TEST_BYTES.len(), WindowSize::new(0).unwrap())
8506 };
8507 assert_eq!(state.recv_mut().unwrap().last_window_update, expect_window_update);
8508
8509 if dequeue_more_than_mss {
8510 assert_eq!(
8514 state.read_with(|available| {
8515 assert_eq!(available, &[TEST_BYTES]);
8516 available[0].len()
8517 }),
8518 TEST_BYTES.len()
8519 );
8520
8521 let expected_sack_blocks = if sack {
8525 let assembler = assert_matches!(
8526 &mut state.recv_mut().unwrap().buffer,
8527 RecvBufferState::Open { buffer: _, assembler } => assembler
8528 );
8529 let gap_start = TEST_IRS + u32::from(TEST_MSS) + 2;
8530 assert_eq!(assembler.insert(gap_start..gap_start + 1), 0);
8533 let expected_sack_blocks =
8534 assembler.sack_blocks(SackBlockSizeLimiters { timestamp_enabled: true });
8535 assert!(!expected_sack_blocks.is_empty());
8536 expected_sack_blocks
8537 } else {
8538 SackBlocks::EMPTY
8539 };
8540
8541 assert_eq!(
8542 state.poll_receive_data_dequeued(clock.now()),
8543 Some(Segment::ack(
8544 TEST_ISS + 1,
8545 TEST_IRS + 1 + TEST_BYTES.len(),
8546 UnscaledWindowSize::from(BUFFER_SIZE as u16),
8547 SegmentOptions {
8548 sack_blocks: expected_sack_blocks,
8549 timestamp: Some(DEFAULT_ACK_TS_OPT),
8550 },
8551 ))
8552 );
8553 assert_eq!(
8554 state.recv_mut().unwrap().last_window_update,
8555 (TEST_IRS + 1 + TEST_BYTES.len(), WindowSize::new(BUFFER_SIZE).unwrap())
8556 );
8557 assert!(state.recv_mut().unwrap().timer.is_none());
8559 } else {
8560 assert_eq!(
8564 state.read_with(|available| {
8565 assert_eq!(available, &[TEST_BYTES]);
8566 TEST_BYTES.len() / 2 - 1
8567 }),
8568 TEST_BYTES.len() / 2 - 1
8569 );
8570 assert_eq!(state.poll_receive_data_dequeued(clock.now()), None,);
8571 assert_eq!(
8572 state.recv_mut().unwrap().last_window_update,
8573 expect_window_update,
8575 );
8576 assert_eq!(state.recv_mut().unwrap().timer.is_some(), delayed_ack);
8577 }
8578 }
8579 }
8580
8581 #[test]
8582 fn poll_receive_data_dequeued_small_window() {
8583 const MSS: Mss = Mss::new(65000).unwrap();
8584 const WINDOW: WindowSize = WindowSize::from_u32(500).unwrap();
8585 let mut recv = Recv::<FakeInstant, _> {
8586 mss: EffectiveMss::from_mss(MSS, MssSizeLimiters { timestamp_enabled: true }),
8587 last_window_update: (TEST_IRS + 1, WindowSize::from_u32(1).unwrap()),
8588 ..Recv::default_for_test(RingBuffer::new(WINDOW.into()))
8589 };
8590 let seg = recv
8591 .poll_receive_data_dequeued(TEST_ISS, FakeInstant::default())
8592 .expect("generates segment");
8593 assert_eq!(seg.header().ack, Some(recv.nxt()));
8594 assert_eq!(seg.header().wnd << recv.wnd_scale, WINDOW);
8595 }
8596
8597 #[test]
8598 fn quickack_period() {
8599 let mut quickack = default_quickack_counter();
8600 let mut state = State::Established(Established::<FakeInstant, _, _> {
8601 snd: Send::default_for_test(NullBuffer).into(),
8602 rcv: Recv {
8603 remaining_quickacks: quickack,
8604 ..Recv::default_for_test(RingBuffer::default())
8605 }
8606 .into(),
8607 });
8608 let socket_options = SocketOptions { delayed_ack: true, ..Default::default() };
8609 let clock = FakeInstantCtx::default();
8610 let counters = FakeTcpCounters::default();
8611 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8612 while quickack != 0 {
8613 let seq = state.recv_mut().unwrap().nxt();
8614 let segment = Segment::new_assert_no_discard(
8615 SegmentHeader {
8616 seq,
8617 ack: Some(TEST_ISS + 1),
8618 options: DEFAULT_SEGMENT_OPTIONS.into(),
8619 ..Default::default()
8620 },
8621 &data[..],
8622 );
8623 let (seg, passive_open) = state.on_segment_with_options::<_, ClientlessBufferProvider>(
8624 segment,
8625 clock.now(),
8626 &counters.refs(),
8627 &socket_options,
8628 );
8629 let recv = state.recv_mut().unwrap();
8630 assert_matches!(recv.timer, None);
8631
8632 assert_eq!(passive_open, None);
8633 let seg = seg.expect("no segment generated");
8634 assert_eq!(seg.header().ack, Some(seq + u32::try_from(data.len()).unwrap()));
8635 assert_eq!(recv.remaining_quickacks, quickack - 1);
8636 quickack -= 1;
8637 state.buffers_mut().into_receive_buffer().unwrap().reset();
8638 }
8639
8640 let segment = Segment::new_assert_no_discard(
8642 SegmentHeader {
8643 seq: state.recv_mut().unwrap().nxt(),
8644 ack: Some(TEST_ISS + 1),
8645 options: DEFAULT_SEGMENT_OPTIONS.into(),
8646 ..Default::default()
8647 },
8648 &data[..],
8649 );
8650 let (seg, passive_open) = state.on_segment_with_options::<_, ClientlessBufferProvider>(
8651 segment,
8652 clock.now(),
8653 &counters.refs(),
8654 &socket_options,
8655 );
8656 assert_eq!(passive_open, None);
8657 assert_eq!(seg, None);
8658 assert_matches!(state.recv_mut().unwrap().timer, Some(ReceiveTimer::DelayedAck { .. }));
8659 }
8660
8661 #[test]
8662 fn quickack_reset_out_of_window() {
8663 let mut state = State::Established(Established::<FakeInstant, _, _> {
8664 snd: Send::default_for_test(NullBuffer).into(),
8665 rcv: Recv::default_for_test(RingBuffer::default()).into(),
8666 });
8667 let clock = FakeInstantCtx::default();
8668 let counters = FakeTcpCounters::default();
8669 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8670
8671 let segment = Segment::new_assert_no_discard(
8672 SegmentHeader {
8673 seq: state.recv_mut().unwrap().nxt() - i32::try_from(data.len() + 1).unwrap(),
8675 ack: Some(TEST_ISS + 1),
8676 options: DEFAULT_SEGMENT_OPTIONS.into(),
8677 ..Default::default()
8678 },
8679 &data[..],
8680 );
8681 let (seg, passive_open) = state
8682 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8683 segment,
8684 clock.now(),
8685 &counters.refs(),
8686 );
8687 assert_eq!(passive_open, None);
8688 let recv = state.recv_mut().unwrap();
8689 let seg = seg.expect("expected segment");
8690 assert_eq!(seg.header().ack, Some(recv.nxt()));
8691 assert_eq!(recv.remaining_quickacks, default_quickack_counter());
8692 }
8693
8694 #[test]
8695 fn quickack_reset_rto() {
8696 let mut clock = FakeInstantCtx::default();
8697 let mut state = State::Established(Established::<FakeInstant, _, _> {
8698 snd: Send::default_for_test(NullBuffer).into(),
8699 rcv: Recv {
8700 last_segment_at: Some(clock.now()),
8701 ..Recv::default_for_test(RingBuffer::default())
8702 }
8703 .into(),
8704 });
8705 let counters = FakeTcpCounters::default();
8706 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8707
8708 let segment = Segment::new_assert_no_discard(
8709 SegmentHeader {
8710 seq: state.recv_mut().unwrap().nxt(),
8711 ack: Some(TEST_ISS + 1),
8712 options: DEFAULT_SEGMENT_OPTIONS.into(),
8713 ..Default::default()
8714 },
8715 &data[..],
8716 );
8717 clock.sleep(Rto::DEFAULT.get());
8718 let (seg, passive_open) = state
8719 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8720 segment,
8721 clock.now(),
8722 &counters.refs(),
8723 );
8724 assert_eq!(passive_open, None);
8725 let recv = state.recv_mut().unwrap();
8726 let seg = seg.expect("expected segment");
8727 assert_eq!(seg.header().ack, Some(recv.nxt()));
8728 assert_eq!(recv.remaining_quickacks, default_quickack_counter() - 1);
8731 assert_eq!(recv.last_segment_at, Some(clock.now()));
8732 }
8733
8734 #[test_case(true; "sack permitted")]
8735 #[test_case(false; "sack not permitted")]
8736 fn receiver_selective_acks(sack_permitted: bool) {
8737 let mut state = State::Established(Established::<FakeInstant, _, _> {
8738 snd: Send::default_for_test(RingBuffer::default()).into(),
8739 rcv: Recv { sack_permitted, ..Recv::default_for_test(RingBuffer::default()) }.into(),
8740 });
8741 let clock = FakeInstantCtx::default();
8742 let counters = FakeTcpCounters::default();
8743 let data = vec![0u8; usize::from(DEVICE_MAXIMUM_SEGMENT_SIZE)];
8744 let mss = u32::from(DEVICE_MAXIMUM_SEGMENT_SIZE);
8745 let seg_start = TEST_IRS + 1 + mss;
8747 let segment = Segment::new_assert_no_discard(
8748 SegmentHeader {
8749 seq: seg_start,
8750 ack: Some(TEST_ISS + 1),
8751 wnd: WindowSize::DEFAULT >> WindowScale::default(),
8752 options: DEFAULT_SEGMENT_OPTIONS.into(),
8753 ..Default::default()
8754 },
8755 &data[..],
8756 );
8757 let (seg, passive_open) = state
8758 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8759 segment,
8760 clock.now(),
8761 &counters.refs(),
8762 );
8763 assert_eq!(passive_open, None);
8764 let seg = seg.expect("expected segment");
8765 assert_eq!(seg.header().ack, Some(TEST_IRS + 1));
8766 let expect = if sack_permitted {
8767 SackBlocks::from_iter([SackBlock::try_new(seg_start, seg_start + mss).unwrap()])
8768 } else {
8769 SackBlocks::default()
8770 };
8771 let sack_blocks =
8772 assert_matches!(&seg.header().options, Options::Segment(o) => &o.sack_blocks);
8773 assert_eq!(sack_blocks, &expect);
8774
8775 assert_eq!(
8777 state.buffers_mut().into_send_buffer().unwrap().enqueue_data(&data[..]),
8778 data.len()
8779 );
8780 let seg = state
8781 .poll_send_with_default_options(clock.now(), &counters.refs())
8782 .expect("generates segment");
8783 assert_eq!(seg.header().ack, Some(TEST_IRS + 1));
8784
8785 let sack_blocks =
8787 assert_matches!(&seg.header().options, Options::Segment(o) => &o.sack_blocks);
8788 assert_eq!(sack_blocks, &expect);
8789 let expect_len = mss - u32::try_from(seg.header().options.builder().bytes_len()).unwrap();
8792 assert_eq!(seg.len(), expect_len);
8793
8794 let segment = Segment::new_assert_no_discard(
8797 SegmentHeader {
8798 seq: TEST_IRS + 1,
8799 ack: Some(TEST_ISS + 1),
8800 options: DEFAULT_SEGMENT_OPTIONS.into(),
8801 ..Default::default()
8802 },
8803 &data[..],
8804 );
8805 let (seg, passive_open) = state
8806 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
8807 segment,
8808 clock.now(),
8809 &counters.refs(),
8810 );
8811 assert_eq!(passive_open, None);
8812 let seg = seg.expect("expected segment");
8813 assert_eq!(seg.header().ack, Some(TEST_IRS + (2 * mss) + 1));
8814 let sack_blocks =
8815 assert_matches!(&seg.header().options, Options::Segment(o) => &o.sack_blocks);
8816 assert_eq!(sack_blocks, &SackBlocks::default());
8817 }
8818
8819 #[derive(Debug)]
8820 enum RttTestScenario {
8821 AckOne,
8822 AckTwo,
8823 Retransmit,
8824 AckPartial,
8825 }
8826
8827 #[test_case(RttTestScenario::AckOne)]
8829 #[test_case(RttTestScenario::AckTwo)]
8830 #[test_case(RttTestScenario::Retransmit)]
8831 #[test_case(RttTestScenario::AckPartial)]
8832 fn rtt(scenario: RttTestScenario) {
8833 let mut state = State::Established(Established::<FakeInstant, _, _> {
8834 snd: Send {
8835 congestion_control: CongestionControl::cubic_with_mss(TEST_MSS),
8836 ..Send::default_for_test(RingBuffer::default())
8837 }
8838 .into(),
8839 rcv: Recv::default_for_test(RingBuffer::default()).into(),
8840 });
8841
8842 const CLOCK_STEP: Duration = Duration::from_millis(1);
8843
8844 let mut clock = FakeInstantCtx::default();
8845 let counters = FakeTcpCounters::default();
8846 for _ in 0..3 {
8847 assert_eq!(
8848 state.buffers_mut().into_send_buffer().unwrap().enqueue_data(TEST_BYTES),
8849 TEST_BYTES.len()
8850 );
8851 }
8852
8853 assert_eq!(state.assert_established().snd.rtt_sampler, RttSampler::NotTracking);
8854 let seg = state
8855 .poll_send_with_default_options(clock.now(), &counters.refs())
8856 .expect("generate segment");
8857 assert_eq!(seg.header().seq, TEST_ISS + 1);
8858 assert_eq!(seg.len(), u32::try_from(TEST_BYTES.len()).unwrap());
8859 let expect_sampler = RttSampler::Tracking {
8860 range: (TEST_ISS + 1)..(TEST_ISS + 1 + seg.len()),
8861 timestamp: clock.now(),
8862 };
8863 assert_eq!(state.assert_established().snd.rtt_sampler, expect_sampler);
8864 clock.sleep(CLOCK_STEP);
8866 let seg = state
8867 .poll_send_with_default_options(clock.now(), &counters.refs())
8868 .expect("generate segment");
8869 assert_eq!(seg.header().seq, TEST_ISS + 1 + TEST_BYTES.len());
8870 assert_eq!(seg.len(), u32::try_from(TEST_BYTES.len()).unwrap());
8871 let established = state.assert_established();
8873 assert_eq!(established.snd.rtt_sampler, expect_sampler);
8874
8875 assert_eq!(established.snd.rtt_estimator.srtt(), None);
8877
8878 let (retransmit, ack_number) = match scenario {
8879 RttTestScenario::AckPartial => (false, TEST_ISS + 1 + 1),
8880 RttTestScenario::AckOne => (false, TEST_ISS + 1 + TEST_BYTES.len()),
8881 RttTestScenario::AckTwo => (false, TEST_ISS + 1 + TEST_BYTES.len() * 2),
8882 RttTestScenario::Retransmit => (true, TEST_ISS + 1 + TEST_BYTES.len() * 2),
8883 };
8884
8885 if retransmit {
8886 let timeout = state.poll_send_at().expect("timeout should be present");
8888 clock.time = timeout;
8889 let seg = state
8890 .poll_send_with_default_options(clock.now(), &counters.refs())
8891 .expect("generate segment");
8892 assert_eq!(seg.header().seq, TEST_ISS + 1);
8894 assert_eq!(state.assert_established().snd.rtt_sampler, RttSampler::NotTracking);
8896 } else {
8897 clock.sleep(CLOCK_STEP);
8898 }
8899
8900 assert_eq!(
8901 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
8902 Segment::ack(
8903 TEST_IRS + 1,
8904 ack_number,
8905 WindowSize::DEFAULT >> WindowScale::default(),
8906 DEFAULT_SEGMENT_OPTIONS
8907 ),
8908 clock.now(),
8909 &counters.refs()
8910 ),
8911 (None, None)
8912 );
8913 let established = state.assert_established();
8914 assert_eq!(established.snd.rtt_sampler, RttSampler::NotTracking);
8916 if retransmit {
8917 assert_eq!(established.snd.rtt_estimator.srtt(), None);
8919 } else {
8920 assert_eq!(established.snd.rtt_estimator.srtt(), Some(CLOCK_STEP * 2));
8923 }
8924
8925 clock.sleep(CLOCK_STEP);
8926 let seg = state
8927 .poll_send_with_default_options(clock.now(), &counters.refs())
8928 .expect("generate segment");
8929 let seq = seg.header().seq;
8930 assert_eq!(seq, TEST_ISS + 1 + TEST_BYTES.len() * 2);
8931 let expect_sampler =
8932 RttSampler::Tracking { range: seq..(seq + seg.len()), timestamp: clock.now() };
8933 assert_eq!(state.assert_established().snd.rtt_sampler, expect_sampler);
8934
8935 clock.sleep(CLOCK_STEP);
8939 assert_eq!(
8940 state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
8941 Segment::ack(
8942 TEST_IRS + 1,
8943 TEST_ISS + 1 + TEST_BYTES.len() * 2,
8944 WindowSize::DEFAULT >> WindowScale::default(),
8945 DEFAULT_SEGMENT_OPTIONS
8946 ),
8947 clock.now(),
8948 &counters.refs()
8949 ),
8950 (None, None)
8951 );
8952 assert_eq!(state.assert_established().snd.rtt_sampler, expect_sampler);
8953 }
8954
8955 #[test]
8956 fn loss_recovery_skips_nagle() {
8957 let mut buffer = RingBuffer::default();
8958 let payload = "Hello World".as_bytes();
8959 assert_eq!(buffer.enqueue_data(payload), payload.len());
8960 let mut state = State::<_, _, _, ()>::Established(Established {
8961 snd: Send::default_for_test(buffer).into(),
8962 rcv: Recv::default_for_test(RingBuffer::default()).into(),
8963 });
8964
8965 let socket_options =
8966 SocketOptions { nagle_enabled: true, ..SocketOptions::default_for_state_tests() };
8967 let clock = FakeInstantCtx::default();
8968 let counters = FakeTcpCounters::default();
8969 let seg = state
8970 .poll_send(
8971 &FakeStateMachineDebugId::default(),
8972 &counters.refs(),
8973 clock.now(),
8974 &socket_options,
8975 )
8976 .expect("should not close");
8977 assert_eq!(seg.len(), u32::try_from(payload.len()).unwrap());
8978 let ack = Segment::ack(
8981 TEST_IRS + 1,
8982 seg.header().seq,
8983 WindowSize::DEFAULT >> WindowScale::default(),
8984 DEFAULT_SEGMENT_OPTIONS,
8985 );
8986
8987 let mut dup_acks = 0;
8988 let seg = loop {
8989 let (seg, passive_open, data_acked, newly_closed) = state
8990 .on_segment::<(), ClientlessBufferProvider>(
8991 &FakeStateMachineDebugId::default(),
8992 &counters.refs(),
8993 ack.clone(),
8994 clock.now(),
8995 &socket_options,
8996 false,
8997 );
8998 assert_eq!(seg, None);
8999 assert_eq!(passive_open, None);
9000 assert_eq!(data_acked, DataAcked::No);
9001 assert_eq!(newly_closed, NewlyClosed::No);
9002 dup_acks += 1;
9003
9004 match state.poll_send(
9005 &FakeStateMachineDebugId::default(),
9006 &counters.refs(),
9007 clock.now(),
9008 &socket_options,
9009 ) {
9010 Ok(seg) => break seg,
9011 Err(newly_closed) => {
9012 assert_eq!(newly_closed, NewlyClosed::No);
9013 assert!(
9014 dup_acks < DUP_ACK_THRESHOLD,
9015 "failed to retransmit after {dup_acks} dup acks"
9016 );
9017 }
9018 }
9019 };
9020 assert_eq!(seg.len(), u32::try_from(payload.len()).unwrap());
9021 assert_eq!(seg.header().seq, ack.header().ack.unwrap());
9022 }
9023
9024 #[test]
9025 fn sack_recovery_rearms_rto() {
9026 let mss = EffectiveMss::from_mss(
9027 DEVICE_MAXIMUM_SEGMENT_SIZE,
9028 MssSizeLimiters { timestamp_enabled: true },
9029 );
9030 let una = TEST_ISS + 1;
9031 let nxt = una + (u32::from(DUP_ACK_THRESHOLD) + 1) * u32::from(mss);
9032
9033 let mut congestion_control = CongestionControl::cubic_with_mss(mss);
9034 congestion_control.inflate_cwnd(20 * u32::from(mss));
9036 let mut state = State::<_, _, _, ()>::Established(Established {
9037 snd: Send {
9038 nxt,
9039 max: nxt,
9040 una,
9041 wl1: TEST_IRS + 1,
9042 wl2: una,
9043 congestion_control,
9044 ..Send::default_for_test(InfiniteSendBuffer::default())
9045 }
9046 .into(),
9047 rcv: Recv::default_for_test(RingBuffer::default()).into(),
9048 });
9049
9050 let socket_options = SocketOptions::default_for_state_tests();
9051 const RTT: Duration = Duration::from_millis(1);
9052 let mut clock = FakeInstantCtx::default();
9053 let counters = FakeTcpCounters::default();
9054 let seg = state
9056 .poll_send(
9057 &FakeStateMachineDebugId::default(),
9058 &counters.refs(),
9059 clock.now(),
9060 &socket_options,
9061 )
9062 .expect("should not close");
9063 assert_eq!(seg.len(), u32::from(mss));
9064 let start_rto = assert_matches!(
9065 state.assert_established().snd.timer,
9066 Some(SendTimer::Retrans(RetransTimer{at, ..})) => at
9067 );
9068 clock.sleep(RTT);
9069
9070 let ack = Segment::ack(
9072 TEST_IRS + 1,
9073 una,
9074 WindowSize::DEFAULT >> WindowScale::default(),
9075 SegmentOptions {
9076 sack_blocks: [SackBlock::try_new(
9077 nxt - u32::from(DUP_ACK_THRESHOLD) * u32::from(mss),
9078 nxt,
9079 )
9080 .unwrap()]
9081 .into_iter()
9082 .collect(),
9083 timestamp: Some(DEFAULT_ACK_TS_OPT),
9084 },
9085 );
9086 let (seg, passive_open, data_acked, newly_closed) = state
9087 .on_segment::<(), ClientlessBufferProvider>(
9088 &FakeStateMachineDebugId::default(),
9089 &counters.refs(),
9090 ack,
9091 clock.now(),
9092 &socket_options,
9093 false,
9094 );
9095 assert_eq!(seg, None);
9096 assert_eq!(passive_open, None);
9097 assert_eq!(data_acked, DataAcked::No);
9098 assert_eq!(newly_closed, NewlyClosed::No);
9099 assert_eq!(
9100 state.assert_established().snd.congestion_control.inspect_loss_recovery_mode(),
9101 Some(LossRecoveryMode::SackRecovery)
9102 );
9103
9104 let seg = state
9105 .poll_send(
9106 &FakeStateMachineDebugId::default(),
9107 &counters.refs(),
9108 clock.now(),
9109 &socket_options,
9110 )
9111 .expect("should not close");
9112 assert_eq!(seg.len(), u32::from(mss));
9113 assert_eq!(seg.header().seq, una);
9115 let new_rto = assert_matches!(
9117 state.assert_established().snd.timer,
9118 Some(SendTimer::Retrans(RetransTimer { at, .. })) => at
9119 );
9120 assert!(new_rto > start_rto, "{new_rto:?} > {start_rto:?}");
9121
9122 CounterExpectations {
9123 retransmits: 1,
9124 sack_recovery: 1,
9125 sack_retransmits: 1,
9126 dup_acks: 1,
9127 ..Default::default()
9128 }
9129 .assert_counters(&counters);
9130 }
9131
9132 enum SackPermitted {
9135 Yes,
9136 No,
9137 }
9138
9139 #[test_matrix(
9154 [1, 2, 3, 5, 20, 50],
9155 [SackPermitted::Yes, SackPermitted::No]
9156 )]
9157 fn congestion_window_limiting(theoretical_window: u32, sack_permitted: SackPermitted) {
9158 netstack3_base::testutil::set_logger_for_test();
9159
9160 let mss = EffectiveMss::from_mss(
9161 DEVICE_MAXIMUM_SEGMENT_SIZE,
9162 MssSizeLimiters { timestamp_enabled: true },
9163 );
9164 let generate_sack = match sack_permitted {
9165 SackPermitted::Yes => true,
9166 SackPermitted::No => false,
9167 };
9168
9169 let theoretical_window = theoretical_window * u32::from(mss);
9172
9173 let snd_wnd = WindowSize::MAX;
9175 let wnd_scale = snd_wnd.scale();
9176 let buffer = InfiniteSendBuffer::default();
9178
9179 let mut state = State::<FakeInstant, _, _, ()>::Established(Established {
9180 snd: Send {
9181 wnd: snd_wnd,
9182 wnd_max: snd_wnd,
9183 wnd_scale,
9184 congestion_control: CongestionControl::cubic_with_mss(mss),
9185 ..Send::default_for_test(buffer)
9186 }
9187 .into(),
9188 rcv: Recv { mss, ..Recv::default_for_test(RingBuffer::default()) }.into(),
9189 });
9190
9191 let socket_options = SocketOptions::default_for_state_tests();
9192 let mut clock = FakeInstantCtx::default();
9193 let counters = FakeTcpCounters::default();
9194
9195 assert!(state.assert_established().snd.congestion_control.in_slow_start());
9196
9197 let poll_until_empty =
9198 |state: &mut State<_, _, _, _>, segments: &mut Vec<(SeqNum, u32)>, now| loop {
9199 match state.poll_send(
9200 &FakeStateMachineDebugId::default(),
9201 &counters.refs(),
9202 now,
9203 &socket_options,
9204 ) {
9205 Ok(seg) => {
9206 assert_eq!(seg.len(), u32::from(mss));
9209 segments.push((seg.header().seq, seg.len()));
9210 }
9211 Err(closed) => {
9212 assert_eq!(closed, NewlyClosed::No);
9213 break;
9214 }
9215 }
9216 };
9217
9218 let mut pending_segments = Vec::new();
9219 let mut pending_acks = Vec::new();
9220 let mut receiver = Assembler::new(TEST_ISS + 1);
9221 let mut total_sent = 0;
9222 let mut total_sent_rounds = 0;
9223
9224 let mut loops = 500;
9226 let mut continue_running = |state: &mut State<_, _, _, _>| {
9227 loops -= 1;
9228 assert!(loops > 0, "test seems to have stalled");
9229
9230 const CONGESTION_EVENTS: u64 = 10;
9233 let event_count =
9234 counters.stack_wide.timeouts.get() + counters.stack_wide.loss_recovered.get();
9235 let congestion_control = &state.assert_established().snd.congestion_control;
9236 event_count <= CONGESTION_EVENTS
9237 || congestion_control.inspect_loss_recovery_mode().is_some() || congestion_control.in_slow_start()
9240 };
9241
9242 while continue_running(&mut state) {
9243 clock.sleep(Duration::from_millis(10));
9248 if pending_acks.is_empty() {
9249 poll_until_empty(&mut state, &mut pending_segments, clock.now());
9250 } else {
9251 for (ack, sack_blocks) in pending_acks.drain(..) {
9252 let seg: Segment<()> = Segment::ack(
9253 TEST_IRS + 1,
9254 ack,
9255 snd_wnd >> wnd_scale,
9256 SegmentOptions { sack_blocks, timestamp: Some(DEFAULT_ACK_TS_OPT) },
9257 );
9258 let (seg, passive_open, data_acked, newly_closed) = state
9259 .on_segment::<_, ClientlessBufferProvider>(
9260 &FakeStateMachineDebugId::default(),
9261 &counters.refs(),
9262 seg,
9263 clock.now(),
9264 &socket_options,
9265 false,
9266 );
9267
9268 assert_eq!(seg, None);
9269 assert_eq!(passive_open, None);
9270 assert_eq!(newly_closed, NewlyClosed::No);
9271 let _: DataAcked = data_acked;
9275
9276 poll_until_empty(&mut state, &mut pending_segments, clock.now());
9277 }
9278 }
9279
9280 let established = state.assert_established();
9281 let congestion_control = &established.snd.congestion_control;
9282 let ssthresh = congestion_control.slow_start_threshold();
9283 let cwnd = congestion_control.inspect_cwnd().cwnd();
9284 let in_slow_start = congestion_control.in_slow_start();
9285 let in_loss_recovery = congestion_control.inspect_loss_recovery_mode().is_some();
9286 let pipe = congestion_control.pipe();
9287 let sent = u32::try_from(pending_segments.len()).unwrap() * u32::from(mss);
9288 let recovery_counters = if generate_sack {
9289 (
9290 counters.stack_wide.sack_retransmits.get(),
9291 counters.stack_wide.sack_recovery.get(),
9292 )
9293 } else {
9294 (
9295 counters.stack_wide.fast_retransmits.get(),
9296 counters.stack_wide.fast_recovery.get(),
9297 )
9298 };
9299
9300 if !in_slow_start {
9301 total_sent += sent;
9302 total_sent_rounds += 1;
9303 }
9304
9305 log::debug!(
9308 "ssthresh={ssthresh}, \
9309 cwnd={cwnd}, \
9310 sent={sent}, \
9311 pipe={pipe}, \
9312 in_slow_start={in_slow_start}, \
9313 in_loss_recovery={in_loss_recovery}, \
9314 total_retransmits={}, \
9315 (retransmits,recovery)={:?}",
9316 counters.stack_wide.retransmits.get(),
9317 recovery_counters,
9318 );
9319
9320 if pending_segments.is_empty() {
9321 assert_matches!(established.snd.timer, Some(SendTimer::Retrans(_)));
9322 clock.sleep_until(state.poll_send_at().expect("must have timeout"));
9324 log::debug!("RTO");
9325 continue;
9326 }
9327
9328 let mut available = theoretical_window;
9329 for (seq, len) in pending_segments.drain(..) {
9330 if available < len {
9332 break;
9333 }
9334 available -= len;
9335 if seq.after_or_eq(receiver.nxt()) {
9337 let _: usize = receiver.insert(seq..(seq + len));
9338 }
9339 let sack_blocks = if generate_sack {
9340 receiver.sack_blocks(SackBlockSizeLimiters { timestamp_enabled: true })
9341 } else {
9342 SackBlocks::default()
9343 };
9344 pending_acks.push((receiver.nxt(), sack_blocks));
9345 }
9346 }
9347
9348 let avg_sent = total_sent / total_sent_rounds;
9351 let tolerance = (theoretical_window / 3).max(u32::from(mss));
9357 let low_range = theoretical_window - tolerance;
9358 let high_range = theoretical_window + tolerance;
9359 assert!(
9360 avg_sent >= low_range && avg_sent <= high_range,
9361 "{low_range} <= {avg_sent} <= {high_range}"
9362 );
9363 }
9364
9365 #[test]
9368 fn out_of_order_ack_with_sack_blocks() {
9369 let send_segments = u32::from(DUP_ACK_THRESHOLD + 2);
9370 let mss = EffectiveMss::from_mss(
9371 DEVICE_MAXIMUM_SEGMENT_SIZE,
9372 MssSizeLimiters { timestamp_enabled: true },
9373 );
9374
9375 let send_bytes = send_segments * u32::from(mss);
9376 let snd_wnd = WindowSize::from_u32(send_bytes).unwrap();
9378 let wnd_scale = snd_wnd.scale();
9379 let mut congestion_control = CongestionControl::cubic_with_mss(mss);
9380 congestion_control.inflate_cwnd(snd_wnd.into());
9381
9382 let start = TEST_ISS + 1;
9383
9384 let mut state = State::<FakeInstant, _, _, ()>::Established(Established {
9385 snd: Send {
9386 congestion_control,
9387 wnd_scale,
9388 wnd: snd_wnd,
9389 wnd_max: snd_wnd,
9390 ..Send::default_for_test_at(
9391 start,
9392 RepeatingSendBuffer::new(usize::try_from(send_bytes).unwrap()),
9393 )
9394 }
9395 .into(),
9396 rcv: Recv::default_for_test(RingBuffer::default()).into(),
9397 });
9398 let socket_options = SocketOptions::default_for_state_tests();
9399 let clock = FakeInstantCtx::default();
9400 let counters = FakeTcpCounters::default();
9401 let sent = core::iter::from_fn(|| {
9402 match state.poll_send(
9403 &FakeStateMachineDebugId::default(),
9404 &counters.refs(),
9405 clock.now(),
9406 &socket_options,
9407 ) {
9408 Ok(seg) => Some(seg.len()),
9409 Err(newly_closed) => {
9410 assert_eq!(newly_closed, NewlyClosed::No);
9411 None
9412 }
9413 }
9414 })
9415 .sum::<u32>();
9416 assert_eq!(sent, send_segments * u32::from(mss));
9417
9418 let end = state.assert_established().snd.nxt;
9420 let seg =
9421 Segment::<()>::ack(TEST_IRS + 1, end, snd_wnd >> wnd_scale, DEFAULT_SEGMENT_OPTIONS);
9422 assert_eq!(
9423 state.on_segment::<_, ClientlessBufferProvider>(
9424 &FakeStateMachineDebugId::default(),
9425 &counters.refs(),
9426 seg,
9427 clock.now(),
9428 &socket_options,
9429 false
9430 ),
9431 (None, None, DataAcked::Yes, NewlyClosed::No)
9432 );
9433 assert_eq!(state.assert_established().snd.congestion_control.pipe(), 0);
9434 assert_matches!(
9435 state.poll_send(
9436 &FakeStateMachineDebugId::default(),
9437 &counters.refs(),
9438 clock.now(),
9439 &socket_options
9440 ),
9441 Err(NewlyClosed::No)
9442 );
9443
9444 let sack_block = SackBlock::try_new(
9447 start + u32::from(mss),
9448 start + u32::from(DUP_ACK_THRESHOLD + 1) * u32::from(mss),
9449 )
9450 .unwrap();
9451 assert!(sack_block.right().before(end));
9452 let seg = Segment::<()>::ack(
9453 TEST_IRS + 1,
9454 start,
9455 snd_wnd >> wnd_scale,
9456 SegmentOptions {
9457 sack_blocks: [sack_block].into_iter().collect(),
9458 timestamp: Some(DEFAULT_ACK_TS_OPT),
9459 },
9460 );
9461 assert_eq!(
9462 state.on_segment::<_, ClientlessBufferProvider>(
9463 &FakeStateMachineDebugId::default(),
9464 &counters.refs(),
9465 seg,
9466 clock.now(),
9467 &socket_options,
9468 false
9469 ),
9470 (None, None, DataAcked::No, NewlyClosed::No)
9471 );
9472 let congestion_control = &state.assert_established().snd.congestion_control;
9475 assert_eq!(congestion_control.pipe(), 0);
9476 assert_eq!(congestion_control.inspect_loss_recovery_mode(), None);
9477 assert_matches!(
9479 state.poll_send(
9480 &FakeStateMachineDebugId::default(),
9481 &counters.refs(),
9482 clock.now(),
9483 &socket_options
9484 ),
9485 Err(NewlyClosed::No)
9486 );
9487 }
9488
9489 #[test]
9490 fn push_segments() {
9491 let send_segments = 16;
9492 let mss = EffectiveMss::from_mss(
9493 DEVICE_MAXIMUM_SEGMENT_SIZE,
9494 MssSizeLimiters { timestamp_enabled: true },
9495 );
9496 let send_bytes = send_segments * usize::from(mss);
9497 let snd_wnd = WindowSize::from_u32(4 * u32::from(mss)).unwrap();
9500 let wnd_scale = snd_wnd.scale();
9501 let mut state = State::<FakeInstant, _, _, ()>::Established(Established {
9502 snd: Send {
9503 congestion_control: CongestionControl::cubic_with_mss(mss),
9504 wnd_scale,
9505 wnd: snd_wnd,
9506 wnd_max: snd_wnd,
9507 ..Send::default_for_test(RepeatingSendBuffer::new(send_bytes))
9508 }
9509 .into(),
9510 rcv: Recv::default_for_test(RingBuffer::default()).into(),
9511 });
9512 let socket_options = SocketOptions::default_for_state_tests();
9513 let clock = FakeInstantCtx::default();
9514 let counters = FakeTcpCounters::default();
9515
9516 for i in 0..send_segments {
9517 let seg = state
9518 .poll_send(
9519 &FakeStateMachineDebugId::default(),
9520 &counters.refs(),
9521 clock.now(),
9522 &socket_options,
9523 )
9524 .expect("produces segment");
9525 let is_last = i == (send_segments - 1);
9526 let is_periodic = i != 0 && i % 2 == 0;
9530 assert!(!(is_last && is_periodic));
9533 assert_eq!(seg.header().push, is_last || is_periodic, "at {i}");
9534 let ack = Segment::ack(
9535 TEST_IRS + 1,
9536 seg.header().seq + seg.len(),
9537 snd_wnd >> wnd_scale,
9538 DEFAULT_SEGMENT_OPTIONS,
9539 );
9540 assert_eq!(
9541 state.on_segment::<(), ClientlessBufferProvider>(
9542 &FakeStateMachineDebugId::default(),
9543 &counters.refs(),
9544 ack,
9545 clock.now(),
9546 &socket_options,
9547 false
9548 ),
9549 (None, None, DataAcked::Yes, NewlyClosed::No)
9550 );
9551 }
9552 }
9553
9554 #[test]
9555 fn connect_with_timestamp_option() {
9556 let mut alice_clock = FakeInstantCtx::default();
9557 let mut bob_clock = FakeInstantCtx::default();
9558 let counters = FakeTcpCounters::default();
9559
9560 const ALICE_OFFSET: Timestamp<Milliseconds> = Timestamp::new(1000);
9563 const BOB_OFFSET: Timestamp<Milliseconds> = Timestamp::new(2000);
9564 let alice_time1 = (ALICE_OFFSET + alice_clock.now().offset).discard_unit();
9565 let bob_time1 = (BOB_OFFSET + bob_clock.now().offset).discard_unit();
9566 assert_ne!(alice_time1, bob_time1);
9567
9568 let (alice_state, syn_seg) = Closed::<Initial>::connect(
9571 ISS_1,
9572 ALICE_OFFSET,
9573 alice_clock.now(),
9574 (),
9575 Default::default(),
9576 *TEST_MSS.mss(),
9577 Mss::DEFAULT_IPV4,
9578 &SocketOptions::default_for_state_tests(),
9579 );
9580 assert_eq!(syn_seg.header().control, Some(Control::SYN));
9581 assert_eq!(syn_seg.header().ack, None);
9582 assert_eq!(
9583 *syn_seg.header().options.timestamp(),
9584 Some(TimestampOption::new(alice_time1, TS_ECHO_REPLY_FOR_NON_ACKS))
9585 );
9586 let mut alice_state = State::<_, RingBuffer, RingBuffer, _>::SynSent(alice_state);
9587
9588 let mut bob_state =
9592 State::<_, RingBuffer, RingBuffer, _>::Listen(Closed::<Initial>::listen(
9593 ISS_2,
9594 BOB_OFFSET,
9595 Default::default(),
9596 DEVICE_MAXIMUM_SEGMENT_SIZE,
9597 Mss::DEFAULT_IPV4,
9598 None,
9599 ));
9600 let syn_ack_seg = assert_matches!(
9601 bob_state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
9602 syn_seg,
9603 bob_clock.now(),
9604 &counters.refs(),
9605 ),
9606 (Some(syn_ack_seg), _) => syn_ack_seg
9607 );
9608 assert_eq!(syn_ack_seg.header().control, Some(Control::SYN));
9609 assert_eq!(syn_ack_seg.header().ack, Some(ISS_1 + 1));
9610 assert_eq!(
9611 *syn_ack_seg.header().options.timestamp(),
9612 Some(TimestampOption::new(bob_time1, alice_time1))
9613 );
9614
9615 let ack_seg = assert_matches!(
9618 alice_state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
9619 syn_ack_seg,
9620 alice_clock.now(),
9621 &counters.refs(),
9622 ),
9623 (Some(ack_seg), _) => ack_seg
9624 );
9625 assert_eq!(ack_seg.header().control, None);
9626 assert_eq!(ack_seg.header().ack, Some(ISS_2 + 1));
9627 assert_eq!(
9628 *ack_seg.header().options.timestamp(),
9629 Some(TimestampOption::new(alice_time1, bob_time1))
9630 );
9631 assert_matches!(
9632 bob_state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
9633 ack_seg,
9634 bob_clock.now(),
9635 &counters.refs(),
9636 ),
9637 (None, _)
9638 );
9639
9640 alice_clock.sleep(RTT);
9645 bob_clock.sleep(2 * RTT);
9646
9647 let alice_time2 = (ALICE_OFFSET + alice_clock.now().offset).discard_unit();
9648 let bob_time2 = (BOB_OFFSET + bob_clock.now().offset).discard_unit();
9649 assert_ne!(alice_time2, bob_time2);
9650
9651 assert_eq!(
9654 alice_state
9655 .buffers_mut()
9656 .into_send_buffer()
9657 .expect("should have a send buffer")
9658 .enqueue_data(TEST_BYTES),
9659 TEST_BYTES.len()
9660 );
9661 let data_seg = alice_state
9662 .poll_send(
9663 &FakeStateMachineDebugId::default(),
9664 &counters.refs(),
9665 alice_clock.now(),
9666 &SocketOptions::default_for_state_tests(),
9667 )
9668 .expect("poll_send should succeed");
9669 assert_eq!(data_seg.header().control, None);
9670 assert_eq!(data_seg.header().ack, Some(ISS_2 + 1));
9671 assert_eq!(
9672 *data_seg.header().options.timestamp(),
9673 Some(TimestampOption::new(alice_time2, bob_time1))
9674 );
9675
9676 let ack_seg = assert_matches!(
9680 bob_state.on_segment_with_default_options::<_, ClientlessBufferProvider>(
9681 data_seg,
9682 bob_clock.now(),
9683 &counters.refs(),
9684 ),
9685 (Some(ack_seg), _) => ack_seg
9686 );
9687 assert_eq!(ack_seg.header().control, None);
9688 assert_eq!(ack_seg.header().ack, Some(ISS_1 + TEST_BYTES.len() + 1));
9689 assert_eq!(
9690 *ack_seg.header().options.timestamp(),
9691 Some(TimestampOption::new(bob_time2, alice_time2))
9692 );
9693 assert_matches!(
9694 alice_state.on_segment_with_default_options::<(), ClientlessBufferProvider>(
9695 ack_seg,
9696 alice_clock.now(),
9697 &counters.refs(),
9698 ),
9699 (None, _)
9700 );
9701 }
9702
9703 #[test]
9704 fn connect_without_timestamp_option() {
9705 let clock = FakeInstantCtx::default();
9706 let counters = FakeTcpCounters::default();
9707 let (state, seg) = Closed::<Initial>::connect(
9708 TEST_ISS,
9709 TIMESTAMP_OFFSET,
9710 clock.now(),
9711 (),
9712 Default::default(),
9713 DEVICE_MAXIMUM_SEGMENT_SIZE,
9714 Mss::DEFAULT_IPV4,
9715 &SocketOptions::default_for_state_tests(),
9716 );
9717 assert_eq!(
9719 seg,
9720 Segment::syn(
9721 TEST_ISS,
9722 UnscaledWindowSize::from(u16::MAX),
9723 HandshakeOptions {
9724 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
9725 window_scale: Some(WindowScale::default()),
9726 sack_permitted: SACK_PERMITTED,
9727 timestamp: Some(DEFAULT_NON_ACK_TS_OPT),
9728 },
9729 )
9730 );
9731
9732 let mut state = State::SynSent::<_, RingBuffer, RingBuffer, _>(state);
9733
9734 let (seg, passive_open) = state
9737 .on_segment_with_default_options::<(), ClientlessBufferProvider>(
9738 Segment::syn_ack(
9739 TEST_IRS,
9740 TEST_ISS + 1,
9741 UnscaledWindowSize::from(u16::MAX),
9742 HandshakeOptions {
9743 mss: Some(DEVICE_MAXIMUM_SEGMENT_SIZE),
9744 window_scale: Some(WindowScale::default()),
9745 sack_permitted: SACK_PERMITTED,
9746 timestamp: None,
9747 },
9748 ),
9749 clock.now(),
9750 &counters.refs(),
9751 );
9752 assert_eq!(passive_open, None);
9753 assert_eq!(
9754 seg,
9755 Some(Segment::ack(
9756 TEST_ISS + 1,
9757 TEST_IRS + 1,
9758 UnscaledWindowSize::from(u16::MAX),
9759 SegmentOptions { sack_blocks: SackBlocks::EMPTY, timestamp: None }
9760 ))
9761 );
9762
9763 let (wl1, wl2, ts_opt, mss) = assert_matches!(
9765 &state,
9766 State::Established(Established {
9767 snd: Takeable(Some(Send { wl1, wl2, .. })),
9768 rcv: Takeable(Some(Recv { ts_opt, mss, ..})),
9769 }) => (wl1, wl2, ts_opt, mss)
9770 );
9771 assert_eq!(*wl1, TEST_IRS);
9772 assert_eq!(*wl2, TEST_ISS + 1);
9773 assert_eq!(*ts_opt, TimestampOptionState::Disabled);
9774 assert_eq!(
9776 *mss,
9777 EffectiveMss::from_mss(
9778 DEVICE_MAXIMUM_SEGMENT_SIZE,
9779 MssSizeLimiters { timestamp_enabled: false }
9780 )
9781 );
9782 }
9783
9784 #[test]
9785 fn segments_with_missing_timestamp_option() {
9786 let clock = FakeInstantCtx::default();
9787 let counters = FakeTcpCounters::default();
9788 let mut established = State::Established(Established {
9790 snd: Send::default_for_test(NullBuffer).into(),
9791 rcv: Recv {
9792 ts_opt: default_ts_opt_state(TEST_IRS + 1),
9793 ..Recv::default_for_test(RingBuffer::new(BUFFER_SIZE))
9794 }
9795 .into(),
9796 });
9797
9798 let (seg, passive_open) = established
9802 .on_segment_with_default_options::<_, ClientlessBufferProvider>(
9803 Segment::with_data(
9804 TEST_IRS + 1,
9805 TEST_ISS + 1,
9806 UnscaledWindowSize::from(0),
9807 SegmentOptions { sack_blocks: SackBlocks::EMPTY, timestamp: None },
9808 TEST_BYTES,
9809 ),
9810 clock.now(),
9811 &counters.refs(),
9812 );
9813 assert_eq!(passive_open, None);
9814 assert_eq!(
9815 seg,
9816 Some(Segment::ack(
9817 TEST_ISS + 1,
9818 TEST_IRS + 1 + TEST_BYTES.len(),
9819 UnscaledWindowSize::from((BUFFER_SIZE - TEST_BYTES.len()) as u16),
9820 DEFAULT_SEGMENT_OPTIONS,
9821 )),
9822 );
9823 assert_eq!(
9824 established.read_with(|available| {
9825 assert_eq!(available, &[TEST_BYTES]);
9826 available[0].len()
9827 }),
9828 TEST_BYTES.len()
9829 );
9830 }
9831}