in neqo-transport/src/connection/mod.rs [977:1034]
fn process_timer(&mut self, now: Instant) {
match &self.state {
// Only the client runs timers while waiting for Initial packets.
State::WaitInitial => debug_assert_eq!(self.role, Role::Client),
// If Closing or Draining, check if it is time to move to Closed.
State::Closing { error, timeout } | State::Draining { error, timeout } => {
if *timeout <= now {
let st = State::Closed(error.clone());
self.set_state(st, now);
qinfo!("Closing timer expired");
return;
}
}
State::Closed(_) => {
qdebug!("Timer fired while closed");
return;
}
_ => (),
}
let pto = self.pto();
if self.idle_timeout.expired(now, pto) {
qinfo!("[{self}] idle timeout expired");
self.set_state(
State::Closed(CloseReason::Transport(Error::IdleTimeout)),
now,
);
return;
}
if self.state.closing() {
qtrace!("[{self}] Closing, not processing other timers");
return;
}
self.streams.cleanup_closed_streams();
let res = self.crypto.states.check_key_update(now);
self.absorb_error(now, res);
if let Some(path) = self.paths.primary() {
let lost = self.loss_recovery.timeout(&path, now);
self.handle_lost_packets(&lost);
qlog::packets_lost(&self.qlog, &lost, now);
}
if self.release_resumption_token_timer.is_some() {
self.create_resumption_token(now);
}
if !self
.paths
.process_timeout(now, pto, &mut self.stats.borrow_mut())
{
qinfo!("[{self}] last available path failed");
self.absorb_error::<Error>(now, Err(Error::NoAvailablePath));
}
}