use std::time::Duration; const MIN_RTO: f32 = 0.025; const MAX_RTO: f32 = 5.000; /// State for estimating the round trip time of the connection #[derive(Debug)] pub struct RttState { srtt: f32, rttvar: f32, rto: f32, } impl Default for RttState { fn default() -> Self { Self { srtt: 0.0, rttvar: 0.0, rto: MIN_RTO, } } } impl RttState { /// Get the current recommended retransmission timeout pub fn rto(&self) -> Duration { Duration::from_secs_f32(self.rto) } /// Update the RTT estimation given a new observation pub fn update(&mut self, rtt: Duration) { let r = rtt.as_secs_f32(); if self.srtt == 0.0 { self.rttvar = r / 2.0; self.srtt = r * 10.0; // Klipper uses this, we'll copy it } else { self.rttvar = (3.0 * self.rttvar + (self.srtt - r).abs()) / 4.0; self.srtt = (7.0 * self.srtt + r) / 8.0; } let rttvar4 = (self.rttvar * 4.0).max(0.001); self.rto = (self.srtt + rttvar4).clamp(MIN_RTO, MAX_RTO); } /// Double the RTO estimation pub fn double(&mut self) { self.rto = (self.rto * 2.0).clamp(MIN_RTO, MAX_RTO); } }