Skip to content

Commit

Permalink
lib: add basic large RTT jump detection
Browse files Browse the repository at this point in the history
  • Loading branch information
LPardue committed Nov 20, 2024
1 parent 57bdafd commit da0cd22
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 2 deletions.
3 changes: 3 additions & 0 deletions quiche/include/quiche.h
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,9 @@ typedef struct {
// The estimated round-trip time variation (in nanoseconds).
uint64_t rttvar;

// The number of large jumps in round-trip time observed.
uint64_t rtt_jumps;

// The size of the path's congestion window in bytes.
size_t cwnd;

Expand Down
2 changes: 2 additions & 0 deletions quiche/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,7 @@ pub struct PathStats {
rtt: u64,
min_rtt: u64,
rttvar: u64,
rtt_jumps: u64,
cwnd: usize,
sent_bytes: u64,
recv_bytes: u64,
Expand Down Expand Up @@ -1332,6 +1333,7 @@ pub extern fn quiche_conn_path_stats(
out.rtt = stats.rtt.as_nanos() as u64;
out.min_rtt = stats.min_rtt.unwrap_or_default().as_nanos() as u64;
out.rttvar = stats.rttvar.as_nanos() as u64;
out.rtt_jumps = stats.rtt_jumps;
out.cwnd = stats.cwnd;
out.sent_bytes = stats.sent_bytes;
out.recv_bytes = stats.recv_bytes;
Expand Down
8 changes: 6 additions & 2 deletions quiche/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ impl Path {
rtt: self.recovery.rtt(),
min_rtt: self.recovery.min_rtt(),
rttvar: self.recovery.rttvar(),
rtt_jumps: self.recovery.rtt_jumps(),
cwnd: self.recovery.cwnd(),
sent_bytes: self.sent_bytes,
recv_bytes: self.recv_bytes,
Expand Down Expand Up @@ -866,6 +867,9 @@ pub struct PathStats {
/// variation.
pub rttvar: time::Duration,

/// The number of large jumps in round-trip time observed.
pub rtt_jumps: u64,

/// The size of the connection's congestion window in bytes.
pub cwnd: usize,

Expand Down Expand Up @@ -910,8 +914,8 @@ impl std::fmt::Debug for PathStats {
)?;
write!(
f,
"recv={} sent={} lost={} retrans={} rtt={:?} min_rtt={:?} rttvar={:?} cwnd={}",
self.recv, self.sent, self.lost, self.retrans, self.rtt, self.min_rtt, self.rttvar, self.cwnd,
"recv={} sent={} lost={} retrans={} rtt={:?} min_rtt={:?} rttvar={:?} rtt_jumps={} cwnd={}",
self.recv, self.sent, self.lost, self.retrans, self.rtt, self.min_rtt, self.rttvar, self.rtt_jumps, self.cwnd,
)?;

write!(
Expand Down
5 changes: 5 additions & 0 deletions quiche/src/recovery/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,10 @@ impl Recovery {
self.rtt_stats.rttvar
}

pub fn rtt_jumps(&self) -> u64 {
self.rtt_stats.rtt_jumps
}

pub fn pto(&self) -> Duration {
self.rtt() + cmp::max(self.rtt_stats.rttvar * 4, GRANULARITY)
}
Expand Down Expand Up @@ -961,6 +965,7 @@ impl std::fmt::Debug for Recovery {
write!(f, "srtt={:?} ", self.rtt_stats.smoothed_rtt)?;
write!(f, "min_rtt={:?} ", *self.rtt_stats.min_rtt)?;
write!(f, "rttvar={:?} ", self.rtt_stats.rttvar)?;
write!(f, "rtt_jumps={:?} ", self.rtt_stats.rtt_jumps)?;
write!(f, "cwnd={} ", self.cwnd())?;
write!(f, "ssthresh={} ", self.congestion.ssthresh)?;
write!(f, "bytes_in_flight={} ", self.bytes_in_flight)?;
Expand Down
10 changes: 10 additions & 0 deletions quiche/src/recovery/rtt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pub(crate) const INITIAL_RTT: Duration = Duration::from_millis(333);

pub(crate) const RTT_WINDOW: Duration = Duration::from_secs(300);

const JUMP_THRESHOLD: u32 = 3;

pub struct RttStats {
pub(super) latest_rtt: Duration,

Expand All @@ -45,6 +47,8 @@ pub struct RttStats {
pub(super) max_ack_delay: Duration,

pub(super) first_rtt_sample: Option<Instant>,

pub(super) rtt_jumps: u64,
}

impl std::fmt::Debug for RttStats {
Expand All @@ -54,6 +58,7 @@ impl std::fmt::Debug for RttStats {
.field("srtt", &self.smoothed_rtt)
.field("minrtt", &*self.min_rtt)
.field("rttvar", &self.rttvar)
.field("rtt_jumps", &self.rtt_jumps)
.finish()
}
}
Expand All @@ -67,6 +72,7 @@ impl RttStats {
rttvar: INITIAL_RTT / 2,
first_rtt_sample: None,
max_ack_delay,
rtt_jumps: 0,
}
}

Expand Down Expand Up @@ -98,6 +104,10 @@ impl RttStats {
adjusted_rtt = latest_rtt - ack_delay;
}

if adjusted_rtt >= self.smoothed_rtt * JUMP_THRESHOLD {
self.rtt_jumps += 1;
}

self.rttvar = self.rttvar * 3 / 4 +
Duration::from_nanos(
self.smoothed_rtt
Expand Down

0 comments on commit da0cd22

Please sign in to comment.