@@ -5,7 +5,7 @@ use s2n_quic_core::{
5
5
packet:: number:: PacketNumberSpace ,
6
6
path:: MINIMUM_MTU ,
7
7
recovery:: { CongestionController , CubicCongestionController , RTTEstimator } ,
8
- time:: { Clock , NoopClock } ,
8
+ time:: { Clock , NoopClock , Timestamp } ,
9
9
} ;
10
10
use std:: {
11
11
env,
@@ -22,10 +22,10 @@ fn slow_start_unlimited_test() {
22
22
}
23
23
24
24
#[ test]
25
- fn five_mb_loss_test ( ) {
25
+ fn loss_at_3mb_test ( ) {
26
26
let cc = CubicCongestionController :: new ( MINIMUM_MTU ) ;
27
27
28
- five_mb_loss ( cc, 150 ) . finish ( ) ;
28
+ loss_at_3mb ( cc, 135 ) . finish ( ) ;
29
29
}
30
30
31
31
#[ derive( Debug ) ]
@@ -170,29 +170,20 @@ fn slow_start_unlimited<CC: CongestionController>(
170
170
}
171
171
}
172
172
173
- /// Simulates a network that experienced loss at a 5MB congestion window
174
- fn five_mb_loss < CC : CongestionController > (
173
+ /// Simulates a network that experienced loss at a 3MB congestion window
174
+ fn loss_at_3mb < CC : CongestionController > (
175
175
mut congestion_controller : CC ,
176
176
num_rounds : usize ,
177
177
) -> Simulation {
178
178
let time_zero = NoopClock . get_time ( ) ;
179
179
let mut rtt_estimator = RTTEstimator :: new ( Duration :: from_millis ( 0 ) ) ;
180
180
let mut rounds = Vec :: with_capacity ( num_rounds) ;
181
181
182
- // Ensure the congestion window is always fully utilized
182
+ // Ensure the congestion window is fully utilized
183
183
congestion_controller. on_packet_sent ( time_zero, u32:: MAX as usize ) ;
184
184
185
- // Start the window at 5MB
186
- congestion_controller. on_packet_ack ( time_zero, 5_000_000 , & rtt_estimator, time_zero) ;
187
-
188
- // Exit slow start
189
- congestion_controller. on_congestion_event ( time_zero) ;
190
-
191
185
let mut ack_receive_time = time_zero + Duration :: from_millis ( 1 ) ;
192
186
193
- // Exit recovery
194
- congestion_controller. on_packet_ack ( ack_receive_time, 1 , & rtt_estimator, ack_receive_time) ;
195
-
196
187
// Update the rtt with 200 ms
197
188
rtt_estimator. update_rtt (
198
189
Duration :: from_millis ( 0 ) ,
@@ -202,34 +193,61 @@ fn five_mb_loss<CC: CongestionController>(
202
193
PacketNumberSpace :: ApplicationData ,
203
194
) ;
204
195
205
- for round in 0 ..num_rounds {
196
+ let mut slow_start_round = 0 ;
197
+
198
+ while congestion_controller. congestion_window ( ) < 3_000_000 && slow_start_round < num_rounds {
199
+ ack_receive_time += Duration :: from_millis ( 200 ) ;
200
+
201
+ // Ack the full congestion window
202
+ ack_cwnd ( & mut congestion_controller, & rtt_estimator, ack_receive_time) ;
203
+
204
+ rounds. push ( Round {
205
+ number : slow_start_round,
206
+ cwnd : congestion_controller. congestion_window ( ) ,
207
+ } ) ;
208
+
209
+ slow_start_round += 1 ;
210
+ }
211
+
212
+ // Lose a packet to exit slow start
213
+ congestion_controller. on_packets_lost ( MINIMUM_MTU as u32 , false , ack_receive_time) ;
214
+
215
+ for round in slow_start_round..num_rounds {
206
216
rounds. push ( Round {
207
217
number : round,
208
218
cwnd : congestion_controller. congestion_window ( ) ,
209
219
} ) ;
210
220
211
221
ack_receive_time += Duration :: from_millis ( 200 ) ;
212
222
213
- let mut cwnd = congestion_controller. congestion_window ( ) ;
214
-
215
223
// Ack the full congestion window
216
- while cwnd > MINIMUM_MTU as u32 {
217
- congestion_controller. on_packet_ack (
218
- ack_receive_time,
219
- MINIMUM_MTU as usize ,
220
- & rtt_estimator,
221
- ack_receive_time,
222
- ) ;
223
- cwnd -= MINIMUM_MTU as u32 ;
224
- // Ensure the congestion window is always fully utilized by sending a packet the
225
- // same size as the one that we just acked.
226
- congestion_controller. on_packet_sent ( ack_receive_time, MINIMUM_MTU as usize ) ;
227
- }
224
+ ack_cwnd ( & mut congestion_controller, & rtt_estimator, ack_receive_time) ;
228
225
}
229
226
230
227
Simulation {
231
- name : "5MB Loss" ,
228
+ name : "Loss at 3MB " ,
232
229
cc : core:: any:: type_name :: < CC > ( ) ,
233
230
rounds,
234
231
}
235
232
}
233
+
234
+ /// Acknowledge a full congestion window of packets
235
+ fn ack_cwnd < CC : CongestionController > (
236
+ congestion_controller : & mut CC ,
237
+ rtt_estimator : & RTTEstimator ,
238
+ timestamp : Timestamp ,
239
+ ) {
240
+ let mut cwnd = congestion_controller. congestion_window ( ) ;
241
+ while cwnd >= MINIMUM_MTU as u32 {
242
+ congestion_controller. on_packet_ack (
243
+ timestamp,
244
+ MINIMUM_MTU as usize ,
245
+ rtt_estimator,
246
+ timestamp,
247
+ ) ;
248
+ cwnd -= MINIMUM_MTU as u32 ;
249
+ // Ensure the congestion window is always fully utilized by sending a packet the
250
+ // same size as the one that we just acked.
251
+ congestion_controller. on_packet_sent ( timestamp, MINIMUM_MTU as usize ) ;
252
+ }
253
+ }
0 commit comments