in neqo-transport/src/connection/mod.rs [1066:1133]
fn next_delay(&mut self, now: Instant, paced: bool) -> Duration {
qtrace!("[{self}] Get callback delay {now:?}");
// Only one timer matters when closing...
if let State::Closing { timeout, .. } | State::Draining { timeout, .. } = self.state {
self.hrtime.update(Self::LOOSE_TIMER_RESOLUTION);
return timeout.duration_since(now);
}
let mut delays = SmallVec::<[_; 7]>::new();
if let Some(ack_time) = self.acks.ack_time(now) {
qtrace!("[{self}] Delayed ACK timer {ack_time:?}");
delays.push(ack_time);
}
if let Some(p) = self.paths.primary() {
let path = p.borrow();
let rtt = path.rtt();
let pto = rtt.pto(self.confirmed());
let idle_time = self.idle_timeout.expiry(now, pto);
qtrace!("[{self}] Idle timer {idle_time:?}");
delays.push(idle_time);
if self.streams.need_keep_alive() {
if let Some(keep_alive_time) = self.idle_timeout.next_keep_alive(now, pto) {
qtrace!("[{self}] Keep alive timer {keep_alive_time:?}");
delays.push(keep_alive_time);
}
}
if let Some(lr_time) = self.loss_recovery.next_timeout(&path) {
qtrace!("[{self}] Loss recovery timer {lr_time:?}");
delays.push(lr_time);
}
if paced {
if let Some(pace_time) = path.sender().next_paced(rtt.estimate()) {
qtrace!("[{self}] Pacing timer {pace_time:?}");
delays.push(pace_time);
}
}
if let Some(path_time) = self.paths.next_timeout(pto) {
qtrace!("[{self}] Path probe timer {path_time:?}");
delays.push(path_time);
}
}
if let Some(key_update_time) = self.crypto.states.update_time() {
qtrace!("[{self}] Key update timer {key_update_time:?}");
delays.push(key_update_time);
}
// `release_resumption_token_timer` is not considered here, because
// it is not important enough to force the application to set a
// timeout for it It is expected that other activities will
// drive it.
let earliest = delays.into_iter().min().expect("at least one delay");
// TODO(agrover, mt) - need to analyze and fix #47
// rather than just clamping to zero here.
debug_assert!(earliest > now);
let delay = earliest.saturating_duration_since(now);
qdebug!("[{self}] delay duration {delay:?}");
self.hrtime.update(delay / 4);
delay
}