Skip to content

Commit a74e9cb

Browse files
fix(s2n-quic-transport): don't let cwnd drop below initial cwnd when MTU decreases (#2308)
1 parent 9af5d19 commit a74e9cb

9 files changed

+113
-15
lines changed

quic/s2n-quic-core/src/recovery/bbr.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -532,8 +532,6 @@ impl CongestionController for BbrCongestionController {
532532
//# window measured in bytes [RFC4821].
533533

534534
//= https://www.rfc-editor.org/rfc/rfc9002#section-7.2
535-
//= type=exception
536-
//= reason=The maximum datagram size remains at the minimum (1200 bytes) during the handshake
537535
//# If the maximum datagram size is decreased in order to complete the
538536
//# handshake, the congestion window SHOULD be set to the new initial
539537
//# congestion window.
@@ -542,8 +540,11 @@ impl CongestionController for BbrCongestionController {
542540
let old_max_datagram_size = self.max_datagram_size;
543541
self.max_datagram_size = max_datagram_size;
544542

545-
self.cwnd =
543+
let cwnd =
546544
((self.cwnd as f32 / old_max_datagram_size as f32) * max_datagram_size as f32) as u32;
545+
let initial_window = Self::initial_window(max_datagram_size, &Default::default());
546+
547+
self.cwnd = max(cwnd, initial_window);
547548
}
548549

549550
#[inline]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: quic/s2n-quic-core/src/recovery/bbr/tests.rs
3+
expression: ""
4+
---
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: quic/s2n-quic-core/src/recovery/bbr/tests.rs
3+
expression: ""
4+
---
5+

quic/s2n-quic-core/src/recovery/bbr/tests.rs

+37-1
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ fn control_update_required() {
11031103
}
11041104

11051105
#[test]
1106-
fn on_mtu_update() {
1106+
fn on_mtu_update_increase() {
11071107
let mut mtu = 5000;
11081108
let mut bbr = BbrCongestionController::new(mtu, Default::default());
11091109
let mut publisher = event::testing::Publisher::snapshot();
@@ -1118,6 +1118,42 @@ fn on_mtu_update() {
11181118
assert_eq!(bbr.cwnd, 200_000);
11191119
}
11201120

1121+
#[test]
1122+
fn on_mtu_update_decrease_smaller_than_initial_window() {
1123+
let mut mtu = 9000;
1124+
let mut bbr = BbrCongestionController::new(mtu, Default::default());
1125+
let mut publisher = event::testing::Publisher::snapshot();
1126+
let mut publisher = PathPublisher::new(&mut publisher, path::Id::test_id());
1127+
1128+
bbr.cwnd = 18_000;
1129+
1130+
mtu = 1350;
1131+
bbr.on_mtu_update(mtu, &mut publisher);
1132+
1133+
assert_eq!(bbr.max_datagram_size, mtu);
1134+
1135+
// updated initial window is 10 x MTU = 10 x 1350
1136+
assert_eq!(bbr.cwnd, 13_500);
1137+
}
1138+
1139+
#[test]
1140+
fn on_mtu_update_decrease_larger_than_initial_window() {
1141+
let mut mtu = 9000;
1142+
let mut bbr = BbrCongestionController::new(mtu, Default::default());
1143+
let mut publisher = event::testing::Publisher::snapshot();
1144+
let mut publisher = PathPublisher::new(&mut publisher, path::Id::test_id());
1145+
1146+
bbr.cwnd = 180_000;
1147+
1148+
mtu = 1350;
1149+
bbr.on_mtu_update(mtu, &mut publisher);
1150+
1151+
assert_eq!(bbr.max_datagram_size, mtu);
1152+
1153+
// Congestion window is still 20 packets based on the updated MTU
1154+
assert_eq!(bbr.cwnd, 27_000);
1155+
}
1156+
11211157
/// Helper method to move the given BBR congestion controller into the
11221158
/// ProbeBW state with the given CyclePhase
11231159
fn enter_probe_bw_state<Pub: Publisher>(

quic/s2n-quic-core/src/recovery/cubic.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,6 @@ impl CongestionController for CubicCongestionController {
451451
//# limit to compensate for the size of the actual packets.
452452

453453
//= https://www.rfc-editor.org/rfc/rfc9002#section-7.2
454-
//= type=exception
455-
//= reason=The maximum datagram size remains at the minimum (1200 bytes) during the handshake
456454
//# If the maximum datagram size is decreased in order to complete the
457455
//# handshake, the congestion window SHOULD be set to the new initial
458456
//# congestion window.
@@ -462,8 +460,12 @@ impl CongestionController for CubicCongestionController {
462460
self.max_datagram_size = max_datagram_size;
463461
self.cubic.max_datagram_size = max_datagram_size;
464462

465-
self.congestion_window =
463+
let congestion_window =
466464
(self.congestion_window / old_max_datagram_size as f32) * max_datagram_size as f32;
465+
let initial_window =
466+
Self::initial_window(&self.cubic, max_datagram_size, &Default::default());
467+
468+
self.congestion_window = max(congestion_window as u32, initial_window) as f32;
467469
}
468470

469471
//= https://www.rfc-editor.org/rfc/rfc9002#section-6.4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: quic/s2n-quic-core/src/recovery/cubic/tests.rs
3+
expression: ""
4+
---
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: quic/s2n-quic-core/src/recovery/cubic/tests.rs
3+
expression: ""
4+
---
5+

quic/s2n-quic-core/src/recovery/cubic/tests.rs

+47-8
Original file line numberDiff line numberDiff line change
@@ -790,25 +790,64 @@ fn on_packet_lost_persistent_congestion() {
790790
#[test]
791791
fn on_mtu_update_increase() {
792792
let mut mtu = 5000;
793-
let cwnd_in_packets = 100_000f32;
794-
let cwnd_in_bytes = cwnd_in_packets / mtu as f32;
793+
let cwnd_in_bytes = 100_000f32;
795794
let mut cc = CubicCongestionController::new(mtu, Default::default());
796795
let mut publisher = event::testing::Publisher::snapshot();
797796
let mut publisher = PathPublisher::new(&mut publisher, path::Id::test_id());
798-
cc.congestion_window = cwnd_in_packets;
797+
cc.congestion_window = cwnd_in_bytes;
799798

800799
mtu = 10000;
801800
cc.on_mtu_update(mtu, &mut publisher);
802801
assert_eq!(cc.max_datagram_size, mtu);
803802
assert_eq!(cc.cubic.max_datagram_size, mtu);
804803

805804
assert_delta!(cc.congestion_window, 200_000.0, 0.001);
805+
}
806806

807-
//= https://www.rfc-editor.org/rfc/rfc8899#section-3
808-
//= type=test
809-
//# An update to the PLPMTU (or MPS) MUST NOT increase the congestion
810-
//# window measured in bytes [RFC4821].
811-
assert_delta!(cc.congestion_window / mtu as f32, cwnd_in_bytes, 0.001);
807+
//= https://www.rfc-editor.org/rfc/rfc9002#section-7.2
808+
//= type=test
809+
//# If the maximum datagram size changes during the connection, the
810+
//# initial congestion window SHOULD be recalculated with the new size.
811+
812+
//= https://www.rfc-editor.org/rfc/rfc9002#section-7.2
813+
//= type=test
814+
//# If the maximum datagram size is decreased in order to complete the
815+
//# handshake, the congestion window SHOULD be set to the new initial
816+
//# congestion window.
817+
#[test]
818+
fn on_mtu_update_decrease_smaller_than_initial_window() {
819+
let mut mtu = 9000;
820+
let cwnd_in_bytes = 18_000f32;
821+
let mut cc = CubicCongestionController::new(mtu, Default::default());
822+
let mut publisher = event::testing::Publisher::snapshot();
823+
let mut publisher = PathPublisher::new(&mut publisher, path::Id::test_id());
824+
cc.congestion_window = cwnd_in_bytes;
825+
826+
mtu = 1350;
827+
cc.on_mtu_update(mtu, &mut publisher);
828+
assert_eq!(cc.max_datagram_size, mtu);
829+
assert_eq!(cc.cubic.max_datagram_size, mtu);
830+
831+
// updated initial window is 10 x MTU = 10 x 1350
832+
assert_delta!(cc.congestion_window, 13_500.0, 0.001);
833+
}
834+
835+
#[test]
836+
fn on_mtu_update_decrease_larger_than_initial_window() {
837+
let mut mtu = 9000;
838+
let cwnd_in_bytes = 180_000f32;
839+
let mut cc = CubicCongestionController::new(mtu, Default::default());
840+
let mut publisher = event::testing::Publisher::snapshot();
841+
let mut publisher = PathPublisher::new(&mut publisher, path::Id::test_id());
842+
cc.congestion_window = cwnd_in_bytes;
843+
844+
mtu = 1350;
845+
cc.on_mtu_update(mtu, &mut publisher);
846+
assert_eq!(cc.max_datagram_size, mtu);
847+
assert_eq!(cc.cubic.max_datagram_size, mtu);
848+
849+
// Congestion window is still 20 packets based on the updated MTU
850+
assert_delta!(cc.congestion_window, 27_000.0, 0.001);
812851
}
813852

814853
//= https://www.rfc-editor.org/rfc/rfc9002#section-6.4

0 commit comments

Comments
 (0)