Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

recovery: support maximum PTO #1583

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions quiche/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,8 @@
max_stream_window: u64,

disable_dcid_reuse: bool,

max_pto: time::Duration,
}

// See https://quicwg.org/base-drafts/rfc9000.html#section-15
Expand Down Expand Up @@ -779,6 +781,7 @@
max_stream_window: stream::MAX_STREAM_WINDOW,

disable_dcid_reuse: false,
max_pto: time::Duration::MAX,
})
}

Expand Down Expand Up @@ -1209,6 +1212,16 @@
pub fn set_disable_dcid_reuse(&mut self, v: bool) {
self.disable_dcid_reuse = v;
}

/// Sets the maximum Probe Timeout
///
/// PTO is a function of RTT and can get large. Configure a max PTO to limit
/// how large it can get.
///
/// The default value is [`Duration::MAX`]

Check warning on line 1221 in quiche/src/lib.rs

View workflow job for this annotation

GitHub Actions / quiche

unresolved link to `Duration::MAX`

Check warning on line 1221 in quiche/src/lib.rs

View workflow job for this annotation

GitHub Actions / quiche

unresolved link to `Duration::MAX`
pub fn set_max_pto(&mut self, v: time::Duration) {
self.max_pto = v;
}
}

/// A QUIC connection.
Expand Down
26 changes: 25 additions & 1 deletion quiche/src/recovery/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub struct Recovery {
loss_detection_timer: Option<Instant>,

pto_count: u32,
max_pto: Duration,

time_of_last_sent_ack_eliciting_pkt:
[Option<Instant>; packet::Epoch::count()],
Expand Down Expand Up @@ -177,6 +178,7 @@ pub struct RecoveryConfig {
hystart: bool,
pacing: bool,
max_pacing_rate: Option<u64>,
max_pto: Duration,
}

impl RecoveryConfig {
Expand All @@ -188,6 +190,7 @@ impl RecoveryConfig {
hystart: config.hystart,
pacing: config.pacing,
max_pacing_rate: config.max_pacing_rate,
max_pto: config.max_pto,
}
}
}
Expand All @@ -201,6 +204,7 @@ impl Recovery {
loss_detection_timer: None,

pto_count: 0,
max_pto: recovery_config.max_pto,

time_of_last_sent_ack_eliciting_pkt: [None; packet::Epoch::count()],

Expand Down Expand Up @@ -723,7 +727,10 @@ impl Recovery {
}

pub fn pto(&self) -> Duration {
self.rtt() + cmp::max(self.rttvar * 4, GRANULARITY)
cmp::min(
self.rtt() + cmp::max(self.rttvar * 4, GRANULARITY),
self.max_pto,
)
}

pub fn delivery_rate(&self) -> u64 {
Expand Down Expand Up @@ -2184,6 +2191,23 @@ mod tests {
now + Duration::from_secs_f64(12000.0 / pacing_rate as f64)
);
}

#[test]
fn max_pto() {
let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
cfg.set_max_pto(Duration::from_secs(10));

let mut r = Recovery::new(&cfg);
r.update_rtt(Duration::from_millis(100), Duration::ZERO, Instant::now());
assert!(
r.pto() < Duration::from_secs(10),
"pto not unnecessarily limited"
);

r.update_rtt(Duration::from_secs(60), Duration::ZERO, Instant::now());

assert_eq!(r.pto(), Duration::from_secs(10), "pto limited");
}
}

mod bbr;
Expand Down
Loading