diff --git a/quinn-proto/src/connection/mtud.rs b/quinn-proto/src/connection/mtud.rs index b690731b41..7e6fc1d8ae 100644 --- a/quinn-proto/src/connection/mtud.rs +++ b/quinn-proto/src/connection/mtud.rs @@ -83,9 +83,14 @@ impl MtuDiscovery { self.current_mtu = self.current_mtu.min(peer_max_udp_payload_size); if let Some(state) = self.state.as_mut() { - // MTUD is only active after the connection has been fully established, so it is - // guaranteed we will receive the peer's transport parameters before we start probing - debug_assert!(matches!(state.phase, Phase::Initial)); + // It is possible for black hole detection to trigger before the connection has been + // fully established, if the initial MTU is greater the minimum MTU. We should never + // send probes before the connection has been fully established and we have received + // the peer's transport parameters though. + debug_assert!( + !matches!(state.phase, Phase::Searching(_)), + "Transport parameters received after MTU probing started" + ); state.peer_max_udp_payload_size = peer_max_udp_payload_size; } } @@ -450,9 +455,9 @@ impl BlackHoleDetector { }; // If a loss burst contains a packet smaller than the minimum MTU or a more recently // transmitted packet, it is not suspicious. - if burst.smallest_packet_size < self.min_mtu + if burst.smallest_packet_size <= self.min_mtu || (burst.latest_non_probe < self.largest_post_loss_packet - && burst.smallest_packet_size < self.acked_mtu) + && burst.smallest_packet_size <= self.acked_mtu) { return; } @@ -733,10 +738,14 @@ mod tests { #[cfg(debug_assertions)] #[test] - #[should_panic] - fn mtu_discovery_with_peer_max_udp_payload_size_after_search_panics() { + #[should_panic(expected = "Transport parameters received after MTU probing started")] + fn mtu_discovery_with_peer_max_udp_payload_size_during_search_panics() { let mut mtud = default_mtud(); - drive_to_completion(&mut mtud, Instant::now(), 1500); + assert!(mtud.poll_transmit(Instant::now(), 0).is_some()); + assert!(matches!( + mtud.state.as_ref().unwrap().phase, + Phase::Searching(_) + )); mtud.on_peer_max_udp_payload_size_received(1300); }