in quic/s2n-quic-core/src/recovery/simulation.rs [363:427]
fn send_and_ack<CC: CongestionController>(
congestion_controller: &mut CC,
rtt_estimator: &RttEstimator,
timestamp: Timestamp,
bytes: usize,
) {
let random = &mut random::testing::Generator::default();
let mut tx_remaining = bytes;
let mut rx_remaining = 0;
let mut now = timestamp;
let ack_receive_time = now + rtt_estimator.min_rtt();
// Allow acks to start being received after this time, to simulate
// acks arriving while sending is paused by the pacer.
let earliest_ack_receive_time = ack_receive_time - Duration::from_millis(50);
let sending_full_cwnd = bytes as u32 == congestion_controller.congestion_window();
let mut publisher = event::testing::Publisher::no_snapshot();
let mut publisher = PathPublisher::new(&mut publisher, path::Id::test_id());
let mut packet_info = None;
while tx_remaining > 0 || rx_remaining > 0 {
while tx_remaining > 0 {
if let Some(edt) = congestion_controller.earliest_departure_time() {
if !edt.has_elapsed(now) {
// We are blocked by the pacer, stop sending and fast forward to the earliest departure time
now = edt;
break;
}
}
let bytes_sent = tx_remaining.min(MINIMUM_MAX_DATAGRAM_SIZE as usize);
let app_limited = tx_remaining - bytes_sent == 0 && !sending_full_cwnd;
packet_info = Some(congestion_controller.on_packet_sent(
now,
bytes_sent,
Some(app_limited),
rtt_estimator,
&mut publisher,
));
tx_remaining -= bytes_sent;
rx_remaining += bytes_sent;
}
if tx_remaining == 0 {
// Nothing left to send, so fast forward to when we receive acks for everything
now = ack_receive_time;
}
while now >= earliest_ack_receive_time && rx_remaining > 0 {
let bytes_acked = rx_remaining.min(MINIMUM_MAX_DATAGRAM_SIZE as usize);
congestion_controller.on_ack(
now,
bytes_acked,
packet_info.unwrap(),
rtt_estimator,
random,
now,
&mut publisher,
);
rx_remaining -= bytes_acked;
}
}
}