diff --git a/quic/s2n-quic-core/src/event/generated.rs b/quic/s2n-quic-core/src/event/generated.rs index 5561dfa15a..4463609f3a 100644 --- a/quic/s2n-quic-core/src/event/generated.rs +++ b/quic/s2n-quic-core/src/event/generated.rs @@ -581,6 +581,12 @@ pub mod api { #[non_exhaustive] #[doc = " An early packet using the configured InitialMtu was lost"] InitialMtuPacketLost {}, + #[non_exhaustive] + #[doc = " An early packet using the configured InitialMtu was acknowledged by the peer"] + InitialMtuPacketAcknowledged {}, + #[non_exhaustive] + #[doc = " MTU probes larger than the current MTU were not acknowledged"] + LargerProbesLost {}, } #[derive(Clone, Debug)] #[non_exhaustive] @@ -998,12 +1004,14 @@ pub mod api { } #[derive(Clone, Debug)] #[non_exhaustive] - #[doc = " The maximum transmission unit (MTU) for the path has changed"] + #[doc = " The maximum transmission unit (MTU) and/or MTU probing status for the path has changed"] pub struct MtuUpdated { pub path_id: u64, #[doc = " The maximum QUIC datagram size, not including UDP and IP headers"] pub mtu: u16, pub cause: MtuUpdatedCause, + #[doc = " The search for the maximum MTU has completed for now"] + pub search_complete: bool, } impl Event for MtuUpdated { const NAME: &'static str = "connectivity:mtu_updated"; @@ -2217,8 +2225,9 @@ pub mod tracing { path_id, mtu, cause, + search_complete, } = event; - tracing :: event ! (target : "mtu_updated" , parent : id , tracing :: Level :: DEBUG , path_id = tracing :: field :: debug (path_id) , mtu = tracing :: field :: debug (mtu) , cause = tracing :: field :: debug (cause)); + tracing :: event ! (target : "mtu_updated" , parent : id , tracing :: Level :: DEBUG , path_id = tracing :: field :: debug (path_id) , mtu = tracing :: field :: debug (mtu) , cause = tracing :: field :: debug (cause) , search_complete = tracing :: field :: debug (search_complete)); } #[inline] fn on_slow_start_exited( @@ -3521,6 +3530,10 @@ pub mod builder { Blackhole, #[doc = " An early packet using the configured InitialMtu was lost"] InitialMtuPacketLost, + #[doc = " An early packet using the configured InitialMtu was acknowledged by the peer"] + InitialMtuPacketAcknowledged, + #[doc = " MTU probes larger than the current MTU were not acknowledged"] + LargerProbesLost, } impl IntoEvent for MtuUpdatedCause { #[inline] @@ -3531,6 +3544,8 @@ pub mod builder { Self::ProbeAcknowledged => ProbeAcknowledged {}, Self::Blackhole => Blackhole {}, Self::InitialMtuPacketLost => InitialMtuPacketLost {}, + Self::InitialMtuPacketAcknowledged => InitialMtuPacketAcknowledged {}, + Self::LargerProbesLost => LargerProbesLost {}, } } } @@ -4253,12 +4268,14 @@ pub mod builder { } } #[derive(Clone, Debug)] - #[doc = " The maximum transmission unit (MTU) for the path has changed"] + #[doc = " The maximum transmission unit (MTU) and/or MTU probing status for the path has changed"] pub struct MtuUpdated { pub path_id: u64, #[doc = " The maximum QUIC datagram size, not including UDP and IP headers"] pub mtu: u16, pub cause: MtuUpdatedCause, + #[doc = " The search for the maximum MTU has completed for now"] + pub search_complete: bool, } impl IntoEvent for MtuUpdated { #[inline] @@ -4267,11 +4284,13 @@ pub mod builder { path_id, mtu, cause, + search_complete, } = self; api::MtuUpdated { path_id: path_id.into_event(), mtu: mtu.into_event(), cause: cause.into_event(), + search_complete: search_complete.into_event(), } } } diff --git a/quic/s2n-quic-core/src/path/mtu.rs b/quic/s2n-quic-core/src/path/mtu.rs index 6428ffd8ea..c77f43af44 100644 --- a/quic/s2n-quic-core/src/path/mtu.rs +++ b/quic/s2n-quic-core/src/path/mtu.rs @@ -52,6 +52,10 @@ pub mod testing { #[derive(Clone, Debug, PartialEq, Eq)] enum State { + /// EARLY_SEARCH_REQUESTED indicates the initial MTU was configured higher + /// than the base MTU, to allow for quick confirmation or rejection of the + /// initial MTU + EarlySearchRequested, //= https://www.rfc-editor.org/rfc/rfc8899#section-5.2 //# The DISABLED state is the initial state before probing has started. Disabled, @@ -67,10 +71,20 @@ enum State { } impl State { + /// Returns true if the MTU controller is in the early search requested state + fn is_early_search_requested(&self) -> bool { + matches!(self, State::EarlySearchRequested) + } + /// Returns true if the MTU controller is in the disabled state fn is_disabled(&self) -> bool { matches!(self, State::Disabled) } + + /// Returns true if the MTU controller is in the search complete state + fn is_search_complete(&self) -> bool { + matches!(self, State::SearchComplete) + } } //= https://www.rfc-editor.org/rfc/rfc8899#section-5.1.2 @@ -536,8 +550,20 @@ impl Controller { } .min(max_udp_payload); + let state = if plpmtu > base_plpmtu { + // The initial MTU has been configured higher than the base MTU + State::EarlySearchRequested + } else if initial_probed_size - base_plpmtu < PROBE_THRESHOLD { + // The next probe size is within the probe threshold of the + // base MTU, so no probing will occur and the search is complete + State::SearchComplete + } else { + // Otherwise wait for regular MTU probing to be enabled + State::Disabled + }; + Self { - state: State::Disabled, + state, base_plpmtu, plpmtu, probed_size: initial_probed_size, @@ -554,7 +580,7 @@ impl Controller { #[inline] pub fn enable(&mut self) { // ensure we haven't already enabled the controller - ensure!(self.state == State::Disabled); + ensure!(self.state.is_disabled() || self.state.is_early_search_requested()); // TODO: Look up current MTU in a cache. If there is a cache hit // move directly to SearchComplete and arm the PMTU raise timer. @@ -583,6 +609,25 @@ impl Controller { path_id: path::Id, publisher: &mut Pub, ) { + if self.state.is_early_search_requested() && sent_bytes > self.base_plpmtu { + if self.is_next_probe_size_above_threshold() { + // Early probing has succeeded, but the max MTU is higher still so + // wait for regular MTU probing to be enabled to attempt higher MTUs + self.state = State::Disabled; + } else { + self.state = State::SearchComplete; + } + + // Publish an `on_mtu_updated` event since the cause + // and possibly search_complete status have changed + publisher.on_mtu_updated(event::builder::MtuUpdated { + path_id: path_id.into_event(), + mtu: self.plpmtu, + cause: MtuUpdatedCause::InitialMtuPacketAcknowledged, + search_complete: self.state.is_search_complete(), + }); + } + // no need to process anything in the disabled state ensure!(self.state != State::Disabled); @@ -609,12 +654,6 @@ impl Controller { &mut congestion_controller::PathPublisher::new(publisher, path_id), ); - publisher.on_mtu_updated(event::builder::MtuUpdated { - path_id: path_id.into_event(), - mtu: self.plpmtu, - cause: MtuUpdatedCause::ProbeAcknowledged, - }); - self.update_probed_size(); //= https://www.rfc-editor.org/rfc/rfc8899#section-8 @@ -625,6 +664,13 @@ impl Controller { // Subsequent probe packets are sent based on the round trip transmission and // acknowledgement/loss of a packet, so the interval will be at least 1 RTT. self.request_new_search(Some(transmit_time)); + + publisher.on_mtu_updated(event::builder::MtuUpdated { + path_id: path_id.into_event(), + mtu: self.plpmtu, + cause: MtuUpdatedCause::ProbeAcknowledged, + search_complete: self.state.is_search_complete(), + }); } } } @@ -647,28 +693,39 @@ impl Controller { ) { // MTU probes are only sent in the application data space, but since early packet // spaces will use the `InitialMtu` prior to MTU probing being enabled, we need - // to check for potentially MTU-related packet loss even when MTU probing is disabled - ensure!(self.state.is_disabled() || packet_number.space().is_application_data()); + // to check for potentially MTU-related packet loss if an early search has been requested + ensure!( + self.state.is_early_search_requested() || packet_number.space().is_application_data() + ); match &self.state { - State::Disabled => { - if lost_bytes > self.base_plpmtu && self.plpmtu > self.base_plpmtu { - // MTU probing hasn't been enabled yet, but since the initial MTU was configured - // higher than the base PLPMTU and this setting resulted in a lost packet - // we drop back down to the base PLPMTU. - self.plpmtu = self.base_plpmtu; - - congestion_controller.on_mtu_update( - self.plpmtu, - &mut congestion_controller::PathPublisher::new(publisher, path_id), - ); - - publisher.on_mtu_updated(event::builder::MtuUpdated { - path_id: path_id.into_event(), - mtu: self.plpmtu, - cause: MtuUpdatedCause::InitialMtuPacketLost, - }) + State::Disabled => {} + State::EarlySearchRequested => { + // MTU probing hasn't been enabled yet, but since the initial MTU was configured + // higher than the base PLPMTU and this setting resulted in a lost packet + // we drop back down to the base PLPMTU. + self.plpmtu = self.base_plpmtu; + + congestion_controller.on_mtu_update( + self.plpmtu, + &mut congestion_controller::PathPublisher::new(publisher, path_id), + ); + + if self.is_next_probe_size_above_threshold() { + // Resume regular probing when the MTU controller is enabled + self.state = State::Disabled; + } else { + // The next probe is within the threshold, so move directly + // to the SearchComplete state + self.state = State::SearchComplete; } + + publisher.on_mtu_updated(event::builder::MtuUpdated { + path_id: path_id.into_event(), + mtu: self.plpmtu, + cause: MtuUpdatedCause::InitialMtuPacketLost, + search_complete: self.state.is_search_complete(), + }) } State::Searching(probe_pn, _) if *probe_pn == packet_number => { // The MTU probe was lost @@ -678,6 +735,16 @@ impl Controller { self.max_probe_size = self.probed_size; self.update_probed_size(); self.request_new_search(None); + + if self.is_search_completed() { + // Emit an on_mtu_updated event as the search has now completed + publisher.on_mtu_updated(event::builder::MtuUpdated { + path_id: path_id.into_event(), + mtu: self.plpmtu, + cause: MtuUpdatedCause::LargerProbesLost, + search_complete: true, + }) + } } else { // Try the same probe size again self.state = State::SearchRequested @@ -716,6 +783,11 @@ impl Controller { self.probed_size as usize } + /// Returns true if probing for the MTU has completed + pub fn is_search_completed(&self) -> bool { + self.state.is_search_complete() + } + /// Sets `probed_size` to the next MTU size to probe for based on a binary search #[inline] fn update_probed_size(&mut self) { @@ -731,6 +803,11 @@ impl Controller { current + ((max - current) / 2) } + #[inline] + fn is_next_probe_size_above_threshold(&self) -> bool { + self.probed_size - self.plpmtu >= PROBE_THRESHOLD + } + /// Requests a new search to be initiated /// /// If `last_probe_time` is supplied, the PMTU Raise Timer will be armed as @@ -738,7 +815,7 @@ impl Controller { /// of the current PLPMTU #[inline] fn request_new_search(&mut self, last_probe_time: Option) { - if self.probed_size - self.plpmtu >= PROBE_THRESHOLD { + if self.is_next_probe_size_above_threshold() { self.probe_count = 0; self.state = State::SearchRequested; } else { @@ -778,6 +855,7 @@ impl Controller { path_id: path_id.into_event(), mtu: self.plpmtu, cause: MtuUpdatedCause::Blackhole, + search_complete: self.state.is_search_complete(), }) } @@ -789,7 +867,7 @@ impl Controller { self.max_probe_size = self.max_udp_payload; self.update_probed_size(); - if self.probed_size - self.plpmtu >= PROBE_THRESHOLD { + if self.is_next_probe_size_above_threshold() { // There is still some room to try a larger MTU again, // so arm the pmtu raise timer self.pmtu_raise_timer.set(timestamp); diff --git a/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_search_requested.snap b/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_search_requested.snap index 5613806647..f72cac3dab 100644 --- a/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_search_requested.snap +++ b/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_search_requested.snap @@ -2,4 +2,4 @@ source: quic/s2n-quic-core/src/path/mtu/tests.rs expression: "" --- -MtuUpdated { path_id: 0, mtu: 1472, cause: ProbeAcknowledged } +MtuUpdated { path_id: 0, mtu: 1472, cause: ProbeAcknowledged, search_complete: false } diff --git a/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_within_threshold.snap b/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_within_threshold.snap index 1a976f4c2b..29bb63d9c4 100644 --- a/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_within_threshold.snap +++ b/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_within_threshold.snap @@ -2,4 +2,4 @@ source: quic/s2n-quic-core/src/path/mtu/tests.rs expression: "" --- -MtuUpdated { path_id: 0, mtu: 1200, cause: ProbeAcknowledged } +MtuUpdated { path_id: 0, mtu: 1200, cause: ProbeAcknowledged, search_complete: true } diff --git a/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_within_threshold_of_max_plpmtu.snap b/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_within_threshold_of_max_plpmtu.snap index 5613806647..eb39b445a2 100644 --- a/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_within_threshold_of_max_plpmtu.snap +++ b/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_ack_within_threshold_of_max_plpmtu.snap @@ -2,4 +2,4 @@ source: quic/s2n-quic-core/src/path/mtu/tests.rs expression: "" --- -MtuUpdated { path_id: 0, mtu: 1472, cause: ProbeAcknowledged } +MtuUpdated { path_id: 0, mtu: 1472, cause: ProbeAcknowledged, search_complete: true } diff --git a/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_loss_black_hole.snap b/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_loss_black_hole.snap index 77ff032991..a551e0388a 100644 --- a/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_loss_black_hole.snap +++ b/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_loss_black_hole.snap @@ -2,4 +2,4 @@ source: quic/s2n-quic-core/src/path/mtu/tests.rs expression: "" --- -MtuUpdated { path_id: 0, mtu: 1200, cause: Blackhole } +MtuUpdated { path_id: 0, mtu: 1200, cause: Blackhole, search_complete: true } diff --git a/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_loss_initial_mtu_configured.snap b/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_loss_initial_mtu_configured.snap index 7a273417f2..500d06ee9f 100644 --- a/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_loss_initial_mtu_configured.snap +++ b/quic/s2n-quic-core/src/path/mtu/snapshots/quic__s2n-quic-core__src__path__mtu__tests__events__on_packet_loss_initial_mtu_configured.snap @@ -2,94 +2,143 @@ source: quic/s2n-quic-core/src/path/mtu/tests.rs expression: "" --- -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1492, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1492, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1492, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 1492, cause: InitialMtuPacketLost } -MtuUpdated { path_id: 0, mtu: 3972, cause: InitialMtuPacketLost } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: true } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: true } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: true } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: true } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: true } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: true } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: true } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1492, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1492, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1492, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1200, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1210, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1272, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1422, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1472, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 1492, cause: InitialMtuPacketLost, search_complete: false } +MtuUpdated { path_id: 0, mtu: 3972, cause: InitialMtuPacketLost, search_complete: false } diff --git a/quic/s2n-quic-core/src/path/mtu/tests.rs b/quic/s2n-quic-core/src/path/mtu/tests.rs index dfc10c4db9..ce34b593cc 100644 --- a/quic/s2n-quic-core/src/path/mtu/tests.rs +++ b/quic/s2n-quic-core/src/path/mtu/tests.rs @@ -190,6 +190,7 @@ fn min_max_mtu() { ); assert_eq!(MINIMUM_MAX_DATAGRAM_SIZE, controller.plpmtu); assert_eq!(MINIMUM_MAX_DATAGRAM_SIZE, controller.base_plpmtu); + assert!(controller.is_search_completed()); } #[test] @@ -306,7 +307,7 @@ fn new_initial_and_base_mtu() { controller.max_datagram_size() ); assert_eq!(0, controller.probe_count); - assert_eq!(State::Disabled, controller.state); + assert_eq!(State::EarlySearchRequested, controller.state); assert!(!controller.pmtu_raise_timer.is_armed()); // probe a value halfway to the max mtu assert_eq!( @@ -412,6 +413,7 @@ fn on_packet_ack_within_threshold() { Some(now + PMTU_RAISE_TIMER_DURATION), controller.next_expiration() ); + assert!(controller.is_search_completed()); // Enough time passes that its time to try raising the PMTU again let now = now + PMTU_RAISE_TIMER_DURATION; @@ -422,6 +424,7 @@ fn on_packet_ack_within_threshold() { MINIMUM_MAX_DATAGRAM_SIZE + (max_udp_payload - MINIMUM_MAX_DATAGRAM_SIZE) / 2, controller.probed_size ); + assert!(!controller.is_search_completed()); } #[test] @@ -446,6 +449,7 @@ fn on_packet_ack_within_threshold_of_max_plpmtu() { assert_eq!(1, cc.on_mtu_update); assert_eq!(State::SearchComplete, controller.state); assert!(!controller.pmtu_raise_timer.is_armed()); + assert!(controller.is_search_completed()); } //= https://www.rfc-editor.org/rfc/rfc8899#section-5.3.2 @@ -480,6 +484,7 @@ fn on_packet_ack_search_requested() { assert_eq!(1, cc.on_mtu_update); assert_eq!(State::SearchRequested, controller.state); assert!(!controller.pmtu_raise_timer.is_armed()); + assert!(!controller.is_search_completed()); } #[test] @@ -712,6 +717,7 @@ fn on_packet_loss_black_hole() { Some(now + BLACK_HOLE_COOL_OFF_DURATION), controller.pmtu_raise_timer.next_expiration() ); + assert!(controller.is_search_completed()); } #[test] @@ -784,9 +790,36 @@ fn on_packet_loss_initial_mtu_configured() { let addr = inet::SocketAddress::IpV4(SocketAddressV4::new(ip, 443)); let mut publisher = Publisher::snapshot(); - for max_mtu in [MINIMUM_MTU, 1300, 1450, 1500, 1520, 4000, 9000] { - for initial_mtu in [MINIMUM_MTU, 1300, 1450, 1500, 1520, 4000, 9000] { - for base_mtu in [MINIMUM_MTU, 1300, 1450, 1500, 1520, 4000, 9000] { + for max_mtu in [ + MINIMUM_MTU, + MINIMUM_MTU + 10, + 1300, + 1450, + 1500, + 1520, + 4000, + 9000, + ] { + for initial_mtu in [ + MINIMUM_MTU, + MINIMUM_MTU + 10, + 1300, + 1450, + 1500, + 1520, + 4000, + 9000, + ] { + for base_mtu in [ + MINIMUM_MTU, + MINIMUM_MTU + 10, + 1300, + 1450, + 1500, + 1520, + 4000, + 9000, + ] { let mtu_config = Config { max_mtu: max_mtu.try_into().unwrap(), initial_mtu: initial_mtu.min(max_mtu).try_into().unwrap(), @@ -801,7 +834,7 @@ fn on_packet_loss_initial_mtu_configured() { controller.on_packet_loss( pn, - mtu_config.initial_mtu.into(), + original_plpmtu, false, now, &mut cc, @@ -811,7 +844,11 @@ fn on_packet_loss_initial_mtu_configured() { if original_plpmtu > base_plpmtu { // the MTU was updated - assert_eq!(1, cc.on_mtu_update); + assert_eq!( + 1, cc.on_mtu_update, + "base {} init {} max {} original_plpmtu {}, base_plpmtu {}", + base_plpmtu, initial_mtu, max_mtu, original_plpmtu, base_plpmtu + ); assert_eq!(base_plpmtu, controller.plpmtu); } else { // everything remains the same since we are operating at the base plpmtu @@ -819,8 +856,15 @@ fn on_packet_loss_initial_mtu_configured() { assert_eq!(original_plpmtu, controller.plpmtu); } - // MTU controller is still disabled - assert_eq!(State::Disabled, controller.state); + if controller.probed_sized() - controller.max_datagram_size() + < PROBE_THRESHOLD as usize + { + assert_eq!(State::SearchComplete, controller.state); + assert!(controller.is_search_completed()); + } else { + // MTU controller is still disabled + assert_eq!(State::Disabled, controller.state); + } } } } diff --git a/quic/s2n-quic-events/events/common.rs b/quic/s2n-quic-events/events/common.rs index 31691c5a38..9b1878135f 100644 --- a/quic/s2n-quic-events/events/common.rs +++ b/quic/s2n-quic-events/events/common.rs @@ -963,6 +963,10 @@ enum MtuUpdatedCause { Blackhole, /// An early packet using the configured InitialMtu was lost InitialMtuPacketLost, + /// An early packet using the configured InitialMtu was acknowledged by the peer + InitialMtuPacketAcknowledged, + /// MTU probes larger than the current MTU were not acknowledged + LargerProbesLost, } /// A bandwidth delivery rate estimate with associated metadata diff --git a/quic/s2n-quic-events/events/connection.rs b/quic/s2n-quic-events/events/connection.rs index 98a06f426f..557a3ce2b0 100644 --- a/quic/s2n-quic-events/events/connection.rs +++ b/quic/s2n-quic-events/events/connection.rs @@ -297,12 +297,14 @@ pub struct KeepAliveTimerExpired { } #[event("connectivity:mtu_updated")] -/// The maximum transmission unit (MTU) for the path has changed +/// The maximum transmission unit (MTU) and/or MTU probing status for the path has changed struct MtuUpdated { path_id: u64, /// The maximum QUIC datagram size, not including UDP and IP headers mtu: u16, cause: MtuUpdatedCause, + /// The search for the maximum MTU has completed for now + search_complete: bool, } #[event("recovery:slow_start_exited")] diff --git a/quic/s2n-quic-transport/src/connection/connection_impl.rs b/quic/s2n-quic-transport/src/connection/connection_impl.rs index b7b3b875b6..2471ee7933 100644 --- a/quic/s2n-quic-transport/src/connection/connection_impl.rs +++ b/quic/s2n-quic-transport/src/connection/connection_impl.rs @@ -626,6 +626,10 @@ impl connection::Trait for ConnectionImpl { .mtu_controller .max_datagram_size() as u16, cause: MtuUpdatedCause::NewPath, + search_complete: path_manager + .active_path() + .mtu_controller + .is_search_completed(), }); let wakeup_handle = Arc::from(parameters.wakeup_handle); diff --git a/quic/s2n-quic-transport/src/path/manager.rs b/quic/s2n-quic-transport/src/path/manager.rs index 6f5b7a7e49..1997c47111 100644 --- a/quic/s2n-quic-transport/src/path/manager.rs +++ b/quic/s2n-quic-transport/src/path/manager.rs @@ -482,6 +482,7 @@ impl Manager { path_id: new_path_id.into_event(), mtu: path.mtu_controller.max_datagram_size() as u16, cause: MtuUpdatedCause::NewPath, + search_complete: path.mtu_controller.is_search_completed(), }); // create a new path diff --git a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__active_connection_migration_disabled.snap b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__active_connection_migration_disabled.snap index f9a9956f74..036737922f 100644 --- a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__active_connection_migration_disabled.snap +++ b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__active_connection_migration_disabled.snap @@ -4,6 +4,6 @@ expression: "" --- ConnectionIdUpdated { path_id: 0, cid_consumer: Local, previous: 0x01, current: 0x69643032 } PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:1, remote_cid: 0x69643032, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x69643032, remote_addr: 127.0.0.2:1, remote_cid: 0x69643033, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:1, remote_cid: 0x69643032, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.3:1, remote_cid: 0x69643032, id: 2, is_active: false } } -MtuUpdated { path_id: 2, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 2, mtu: 1200, cause: NewPath, search_complete: false } diff --git a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__adding_new_path.snap b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__adding_new_path.snap index 72f311bf5e..853ee92f16 100644 --- a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__adding_new_path.snap +++ b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__adding_new_path.snap @@ -3,4 +3,4 @@ source: quic/s2n-quic-transport/src/path/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:8001, remote_cid: 0x01, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:8001, remote_cid: 0x01, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } diff --git a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_challenge_behavior.snap b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_challenge_behavior.snap index 37717a9da1..2136b31c1d 100644 --- a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_challenge_behavior.snap +++ b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_challenge_behavior.snap @@ -3,5 +3,5 @@ source: quic/s2n-quic-transport/src/path/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:8001, remote_cid: 0x01, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:8001, remote_cid: 0x01, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } ActivePathUpdated { previous: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:8001, remote_cid: 0x01, id: 0, is_active: false }, active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:8001, remote_cid: 0x01, id: 1, is_active: true } } diff --git a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_new_path_abandon_timer.snap b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_new_path_abandon_timer.snap index 346ed64e3b..ba5f02e7a8 100644 --- a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_new_path_abandon_timer.snap +++ b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_new_path_abandon_timer.snap @@ -3,6 +3,6 @@ source: quic/s2n-quic-transport/src/path/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:8001, remote_cid: 0x01, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:8001, remote_cid: 0x01, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } ActivePathUpdated { previous: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:8001, remote_cid: 0x01, id: 0, is_active: false }, active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:8001, remote_cid: 0x01, id: 1, is_active: true } } PathChallengeUpdated { path_challenge_status: Abandoned, path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:8001, remote_cid: 0x01, id: 0, is_active: true }, challenge_data: [123, 122, 121, 120, 127, 126, 125, 124] } diff --git a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_use_max_ack_delay_from_active_path.snap b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_use_max_ack_delay_from_active_path.snap index 72f311bf5e..853ee92f16 100644 --- a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_use_max_ack_delay_from_active_path.snap +++ b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__connection_migration_use_max_ack_delay_from_active_path.snap @@ -3,4 +3,4 @@ source: quic/s2n-quic-transport/src/path/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:8001, remote_cid: 0x01, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:8001, remote_cid: 0x01, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } diff --git a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__limit_number_of_connection_migrations.snap b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__limit_number_of_connection_migrations.snap index 92294ff3a7..c646fe3053 100644 --- a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__limit_number_of_connection_migrations.snap +++ b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__limit_number_of_connection_migrations.snap @@ -3,14 +3,14 @@ source: quic/s2n-quic-transport/src/path/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:1, remote_cid: 0x01, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:1, remote_cid: 0x01, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } ActivePathUpdated { previous: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:1, remote_cid: 0x01, id: 0, is_active: false }, active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:1, remote_cid: 0x01, id: 1, is_active: true } } PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:1, remote_cid: 0x01, id: 1, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:2, remote_cid: 0x01, id: 2, is_active: false } } -MtuUpdated { path_id: 2, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 2, mtu: 1200, cause: NewPath, search_complete: false } ActivePathUpdated { previous: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:1, remote_cid: 0x01, id: 1, is_active: false }, active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:2, remote_cid: 0x01, id: 2, is_active: true } } PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:2, remote_cid: 0x01, id: 2, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:3, remote_cid: 0x01, id: 3, is_active: false } } -MtuUpdated { path_id: 3, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 3, mtu: 1200, cause: NewPath, search_complete: false } ActivePathUpdated { previous: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:2, remote_cid: 0x01, id: 2, is_active: false }, active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:3, remote_cid: 0x01, id: 3, is_active: true } } PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:3, remote_cid: 0x01, id: 3, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:4, remote_cid: 0x01, id: 4, is_active: false } } -MtuUpdated { path_id: 4, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 4, mtu: 1200, cause: NewPath, search_complete: false } ActivePathUpdated { previous: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:3, remote_cid: 0x01, id: 3, is_active: false }, active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:4, remote_cid: 0x01, id: 4, is_active: true } } diff --git a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__temporary_until_authenticated.snap b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__temporary_until_authenticated.snap index da066aad00..e0965f526d 100644 --- a/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__temporary_until_authenticated.snap +++ b/quic/s2n-quic-transport/src/path/manager/snapshots/quic__s2n-quic-transport__src__path__manager__tests__events__temporary_until_authenticated.snap @@ -3,9 +3,9 @@ source: quic/s2n-quic-transport/src/path/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:8001, remote_cid: 0x01, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:8001, remote_cid: 0x01, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:8001, remote_cid: 0x01, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.3:8001, remote_cid: 0x01, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } ActivePathUpdated { previous: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:8001, remote_cid: 0x01, id: 0, is_active: false }, active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.3:8001, remote_cid: 0x01, id: 1, is_active: true } } PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.3:8001, remote_cid: 0x01, id: 1, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:8001, remote_cid: 0x01, id: 2, is_active: false } } -MtuUpdated { path_id: 2, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 2, mtu: 1200, cause: NewPath, search_complete: false } diff --git a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__detect_lost_packets_persistent_congestion_path_aware.snap b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__detect_lost_packets_persistent_congestion_path_aware.snap index 899f91028e..5446c5700e 100644 --- a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__detect_lost_packets_persistent_congestion_path_aware.snap +++ b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__detect_lost_packets_persistent_congestion_path_aware.snap @@ -3,4 +3,4 @@ source: quic/s2n-quic-transport/src/recovery/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } diff --git a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__no_rtt_update_when_receiving_packet_on_different_path.snap b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__no_rtt_update_when_receiving_packet_on_different_path.snap index 39580427f7..7be5d87893 100644 --- a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__no_rtt_update_when_receiving_packet_on_different_path.snap +++ b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__no_rtt_update_when_receiving_packet_on_different_path.snap @@ -3,7 +3,7 @@ source: quic/s2n-quic-transport/src/recovery/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } AckRangeReceived { packet_header: OneRtt { number: 0 }, path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false }, ack_range: 0..=0 } RecoveryMetrics { path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false }, min_rtt: 333ms, smoothed_rtt: 333ms, latest_rtt: 333ms, rtt_variance: 166.5ms, max_ack_delay: 100ms, pto_count: 0, congestion_window: 15000, bytes_in_flight: 0, congestion_limited: false } AckRangeReceived { packet_header: OneRtt { number: 1 }, path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, ack_range: 1..=1 } diff --git a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__on_packet_sent.snap b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__on_packet_sent.snap index bd70e9b79c..ab1084e436 100644 --- a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__on_packet_sent.snap +++ b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__on_packet_sent.snap @@ -3,5 +3,5 @@ source: quic/s2n-quic-transport/src/recovery/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } EcnStateChanged { path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, state: Unknown } diff --git a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__on_packet_sent_across_multiple_paths.snap b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__on_packet_sent_across_multiple_paths.snap index 899f91028e..5446c5700e 100644 --- a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__on_packet_sent_across_multiple_paths.snap +++ b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__on_packet_sent_across_multiple_paths.snap @@ -3,4 +3,4 @@ source: quic/s2n-quic-transport/src/recovery/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } diff --git a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_congestion_controller.snap b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_congestion_controller.snap index 283178b60b..7254f0d592 100644 --- a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_congestion_controller.snap +++ b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_congestion_controller.snap @@ -3,6 +3,6 @@ source: quic/s2n-quic-transport/src/recovery/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } AckRangeReceived { packet_header: OneRtt { number: 1 }, path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, ack_range: 1..=2 } RecoveryMetrics { path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, min_rtt: 333ms, smoothed_rtt: 333ms, latest_rtt: 333ms, rtt_variance: 166.5ms, max_ack_delay: 100ms, pto_count: 0, congestion_window: 15000, bytes_in_flight: 128, congestion_limited: false } diff --git a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_pto_timer.snap b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_pto_timer.snap index 407a369705..4fa86afbc6 100644 --- a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_pto_timer.snap +++ b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_pto_timer.snap @@ -3,7 +3,7 @@ source: quic/s2n-quic-transport/src/recovery/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } AckRangeReceived { packet_header: OneRtt { number: 1 }, path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, ack_range: 1..=1 } RecoveryMetrics { path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, min_rtt: 500ms, smoothed_rtt: 500ms, latest_rtt: 500ms, rtt_variance: 250ms, max_ack_delay: 100ms, pto_count: 0, congestion_window: 15000, bytes_in_flight: 128, congestion_limited: false } AckRangeReceived { packet_header: OneRtt { number: 2 }, path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false }, ack_range: 2..=2 } diff --git a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_update_pto_timer.snap b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_update_pto_timer.snap index ba7c08421a..d88317e569 100644 --- a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_update_pto_timer.snap +++ b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__process_new_acked_packets_update_pto_timer.snap @@ -3,7 +3,7 @@ source: quic/s2n-quic-transport/src/recovery/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } AckRangeReceived { packet_header: OneRtt { number: 1 }, path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, ack_range: 1..=1 } RecoveryMetrics { path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, min_rtt: 500ms, smoothed_rtt: 500ms, latest_rtt: 500ms, rtt_variance: 250ms, max_ack_delay: 100ms, pto_count: 0, congestion_window: 15000, bytes_in_flight: 128, congestion_limited: false } AckRangeReceived { packet_header: OneRtt { number: 2 }, path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, ack_range: 2..=2 } diff --git a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__remove_lost_packets_persistent_congestion_path_aware.snap b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__remove_lost_packets_persistent_congestion_path_aware.snap index 62269a8ea9..4f18916553 100644 --- a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__remove_lost_packets_persistent_congestion_path_aware.snap +++ b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__remove_lost_packets_persistent_congestion_path_aware.snap @@ -3,7 +3,7 @@ source: quic/s2n-quic-transport/src/recovery/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } PacketLost { packet_header: OneRtt { number: 9 }, path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: true }, bytes_lost: 1, is_mtu_probe: false } PacketLost { packet_header: OneRtt { number: 10 }, path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false }, bytes_lost: 1, is_mtu_probe: false } Congestion { path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false }, source: PacketLoss } diff --git a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__rtt_update_when_receiving_ack_from_multiple_paths.snap b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__rtt_update_when_receiving_ack_from_multiple_paths.snap index b9323c75b2..a3e58f2545 100644 --- a/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__rtt_update_when_receiving_ack_from_multiple_paths.snap +++ b/quic/s2n-quic-transport/src/recovery/manager/snapshots/quic__s2n-quic-transport__src__recovery__manager__tests__events__rtt_update_when_receiving_ack_from_multiple_paths.snap @@ -3,6 +3,6 @@ source: quic/s2n-quic-transport/src/recovery/manager/tests.rs expression: "" --- PathCreated { active: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, new: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.2:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 1, is_active: false } } -MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath } +MtuUpdated { path_id: 1, mtu: 1200, cause: NewPath, search_complete: false } AckRangeReceived { packet_header: OneRtt { number: 0 }, path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, ack_range: 0..=1 } RecoveryMetrics { path: Path { local_addr: 0.0.0.0:0, local_cid: 0x4c6f63616c4900000000000000004c6f63616c49, remote_addr: 127.0.0.1:80, remote_cid: 0x5065657249640000000000000000506565724964, id: 0, is_active: true }, min_rtt: 700ms, smoothed_rtt: 700ms, latest_rtt: 700ms, rtt_variance: 350ms, max_ack_delay: 100ms, pto_count: 0, congestion_window: 15000, bytes_in_flight: 128, congestion_limited: false } diff --git a/quic/s2n-quic/src/tests/mtu.rs b/quic/s2n-quic/src/tests/mtu.rs index 16b9cf5ab5..fb0280f785 100644 --- a/quic/s2n-quic/src/tests/mtu.rs +++ b/quic/s2n-quic/src/tests/mtu.rs @@ -99,7 +99,7 @@ fn mtu_updates( .start()?; let addr = start_server(server)?; // we need a large payload to allow for multiple rounds of MTU probing - start_client(client, addr, Data::new(10_000_000))?; + start_client(client, addr, Data::new(20_000_000))?; Ok(addr) }) .unwrap(); @@ -134,12 +134,22 @@ mtu_test!( // we should then successfully probe for 1500 (minus headers = 1472) let first_probe = events[1].clone(); assert_eq!(first_probe.mtu, 1472); + assert!(!first_probe.search_complete); + assert!(matches!( + first_probe.cause, + events::MtuUpdatedCause::ProbeAcknowledged { .. } + )); // we binary search upwards 9001 // this isn't the maximum mtu we'd find in practice, just the maximum mtu we // find with a payload of 10_000_000 bytes. let last_probe = events.last().unwrap(); assert_eq!(last_probe.mtu, 8943); + assert!(last_probe.search_complete); + assert!(matches!( + last_probe.cause, + events::MtuUpdatedCause::ProbeAcknowledged { .. } + )); } ); @@ -159,6 +169,33 @@ mtu_test!( let last_mtu = events.last().unwrap(); // ETHERNET_MTU - UDP_HEADER_LEN - IPV4_HEADER_LEN assert_eq!(last_mtu.mtu, 1472); + assert!(last_mtu.search_complete); + assert!(matches!( + last_mtu.cause, + events::MtuUpdatedCause::LargerProbesLost { .. } + )); + } +); + +// The network can support the maximum sized UDP packet +mtu_test!( + fn mtu_probe_max_jumbo_frame_test(server, client) { + let events = mtu_updates( + server, + client, + None, + InitialMtu::default().into(), + BaseMtu::default().into(), + u16::MAX, + u16::MAX, + ); + let last_mtu = events.last().unwrap(); + assert_eq!(last_mtu.mtu, 65475); + assert!(last_mtu.search_complete); + assert!(matches!( + last_mtu.cause, + events::MtuUpdatedCause::ProbeAcknowledged { .. } + )); } ); @@ -172,6 +209,7 @@ mtu_test!( .unwrap(); // 1250 - UDP_HEADER_LEN - IPV4_HEADER_LEN assert_eq!(base_mtu.mtu, 1222); + assert!(!base_mtu.search_complete); } ); @@ -182,6 +220,7 @@ mtu_test!( let first_mtu = events.first().unwrap(); // 2000 - UDP_HEADER_LEN - IPV4_HEADER_LEN assert_eq!(first_mtu.mtu, 1972); + assert!(!first_mtu.search_complete); } ); @@ -192,8 +231,10 @@ mtu_test!( let first_mtu = events.first().unwrap(); // 1228 - UDP_HEADER_LEN - IPV4_HEADER_LEN assert_eq!(first_mtu.mtu, 1200); + assert!(!first_mtu.search_complete); let last_mtu = events.last().unwrap(); assert_eq!(last_mtu.mtu, 8943); + assert!(last_mtu.search_complete); } ); @@ -211,6 +252,7 @@ mtu_test!( let first_mtu = events.first().unwrap(); // 1528 - UDP_HEADER_LEN - IPV4_HEADER_LEN assert_eq!(first_mtu.mtu, 1300); + assert!(!first_mtu.search_complete); } ); @@ -235,6 +277,7 @@ mtu_test!( ); let first_mtu = events.first().unwrap(); assert_eq!(first_mtu.mtu, 1300); + assert!(!first_mtu.search_complete); } ); @@ -251,6 +294,7 @@ mtu_test!( let events = mtu_updates(server, client, Some(config), 1228, BaseMtu::default().into(), 9_001, 10_000); let last_mtu = events.last().unwrap(); assert_eq!(last_mtu.mtu, 5_936); + assert!(last_mtu.search_complete); } ); @@ -264,10 +308,21 @@ mtu_test!( let last_mtu = events.last().unwrap(); // First try the initial MTU assert_eq!(first_mtu.mtu, 1972); + assert!(!first_mtu.search_complete); // Next drop down to the base MTU assert_eq!(second_mtu.mtu, 1200); + assert!(!second_mtu.search_complete); + assert!(matches!( + second_mtu.cause, + events::MtuUpdatedCause::InitialMtuPacketLost { .. } + )); // Eventually reach the MTU the network supports assert_eq!(last_mtu.mtu, 1500); + assert!(last_mtu.search_complete); + assert!(matches!( + last_mtu.cause, + events::MtuUpdatedCause::ProbeAcknowledged { .. } + )); } ); @@ -279,8 +334,18 @@ mtu_test!( let last_mtu = events.last().unwrap(); // First try the initial MTU assert_eq!(first_mtu.mtu, 8973); + assert!(matches!( + first_mtu.cause, + events::MtuUpdatedCause::NewPath { .. } + )); + assert!(!first_mtu.search_complete); // Stay on this MTU since the network supports it assert_eq!(last_mtu.mtu, 8973); + assert!(last_mtu.search_complete); + assert!(matches!( + last_mtu.cause, + events::MtuUpdatedCause::InitialMtuPacketAcknowledged { .. } + )); } ); @@ -294,10 +359,40 @@ mtu_test!( let last_mtu = events.last().unwrap(); // First try the initial MTU assert_eq!(first_mtu.mtu, 8_973); + assert!(!first_mtu.search_complete); + assert!(matches!( + first_mtu.cause, + events::MtuUpdatedCause::NewPath { .. } + )); // Next drop down to the base MTU assert_eq!(second_mtu.mtu, 1472); + assert!(!second_mtu.search_complete); + assert!(matches!( + second_mtu.cause, + events::MtuUpdatedCause::InitialMtuPacketLost { .. } + )); // Eventually reach the MTU the network supports assert_eq!(last_mtu.mtu, 2_496); + assert!(last_mtu.search_complete); + assert!(matches!( + last_mtu.cause, + events::MtuUpdatedCause::ProbeAcknowledged { .. } + )); + + } +); + +// MTU probing has been disabled by setting BaseMTU = InitialMTU = MaxMTU +mtu_test!( + fn mtu_probing_disabled(server, client) { + let events = mtu_updates(server, client, None, BaseMtu::default().into(), BaseMtu::default().into(), BaseMtu::default().into(), 10_000); + let first_mtu = events.first().unwrap(); + assert_eq!(first_mtu.mtu, 1200); + assert!(first_mtu.search_complete); + assert!(matches!( + first_mtu.cause, + events::MtuUpdatedCause::NewPath { .. } + )); } ); @@ -348,8 +443,12 @@ fn mtu_loss_no_blackhole() { }) .unwrap(); + let events = events.lock().unwrap().clone(); + // MTU remained jumbo despite the packet loss - assert_eq!(8943, events.lock().unwrap().last().unwrap().mtu); + let last_mtu = events.last().unwrap(); + assert_eq!(8943, last_mtu.mtu); + assert!(last_mtu.search_complete); } // if the MTU is decreased after an MTU probe previously raised the MTU for the path, @@ -395,8 +494,16 @@ fn mtu_blackhole() { }) .unwrap(); + let events = events.lock().unwrap().clone(); + // MTU dropped to the minimum - assert_eq!(1200, events.lock().unwrap().last().unwrap().mtu); + let last_mtu = events.last().unwrap(); + assert_eq!(1200, last_mtu.mtu); + assert!(last_mtu.search_complete); + assert!(matches!( + last_mtu.cause, + events::MtuUpdatedCause::Blackhole { .. } + )); } // ensure the server enforces the minimum MTU for all initial packets