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

fix: No time-based loss detection before largest_acked & fixes #1998

Draft
wants to merge 76 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
5aae826
tmp
larseggert Jul 21, 2024
776fcf4
Cleanup
larseggert Jul 21, 2024
7334fac
Finalize test
larseggert Jul 21, 2024
b6e05e3
Argh
larseggert Jul 22, 2024
2af5add
Fix
larseggert Jul 22, 2024
49e2836
Suggestion from @mxinden
larseggert Jul 22, 2024
4f1fdcb
Merge branch 'main' into 0rtt-tmp
larseggert Jul 22, 2024
84c628b
Merge branch 'main' into 0rtt-tmp
larseggert Jul 22, 2024
150881f
Suggestion from @martinthomson
larseggert Jul 22, 2024
4bf8205
Wording
larseggert Jul 22, 2024
a0b7ddf
Only do this when we don't have a largest_acked
larseggert Jul 22, 2024
4d22083
Minimize diff
larseggert Jul 22, 2024
3a36c97
Merge branch 'main' into 0rtt-tmp
larseggert Jul 22, 2024
4f40dee
Expose `on_congestion_event`
larseggert Jul 23, 2024
d1bc820
Add comment
larseggert Jul 23, 2024
5e1ea67
Apply suggestions from code review
larseggert Jul 23, 2024
0781c72
More suggestions from @mxinden; thanks
larseggert Jul 23, 2024
3bb4c9d
Merge branch 'main' into 0rtt-tmp
larseggert Jul 25, 2024
b651b3c
Merge branch 'main' into 0rtt-tmp
larseggert Jul 30, 2024
76c32f3
Potential fix?
larseggert Jul 31, 2024
8e99822
Merge branch '0rtt-tmp' of github.com:larseggert/neqo into 0rtt-tmp
larseggert Jul 31, 2024
bb5769e
Revert "Potential fix?"
larseggert Jul 31, 2024
76944b5
Merge branch 'main' into 0rtt-tmp
larseggert Aug 1, 2024
92f07f9
Merge branch 'main' into 0rtt-tmp
larseggert Aug 9, 2024
cd84b61
fmt
larseggert Aug 9, 2024
1b6a81d
Fixes
larseggert Aug 9, 2024
56fd7dd
Merge branch 'main' into 0rtt-tmp
larseggert Aug 9, 2024
52f0ecc
Merge branch 'main' into 0rtt-tmp
larseggert Aug 13, 2024
faa52c8
Merge branch 'main' into 0rtt-tmp
larseggert Aug 13, 2024
bd6bd7e
Merge branch 'main' into 0rtt-tmp
larseggert Aug 15, 2024
9156292
Robustify (?)
larseggert Aug 16, 2024
fca99af
Nits
larseggert Aug 16, 2024
467abe5
Merge branch 'main' into 0rtt-tmp
larseggert Aug 16, 2024
4d0adfd
Merge branch 'main' into 0rtt-tmp
larseggert Aug 21, 2024
6bc89bb
Merge branch 'main' into 0rtt-tmp
larseggert Aug 22, 2024
53c7bc7
Use my patched simulator image (for now)
larseggert Aug 22, 2024
d8f6a24
Merge branch 'main' into 0rtt-tmp
larseggert Sep 5, 2024
97b6be8
Revert QNS image
larseggert Sep 5, 2024
b29a832
Fixes
larseggert Sep 5, 2024
34fa79c
Add debugs suggested by @mxinden
larseggert Sep 6, 2024
3e32945
POssible fix
larseggert Sep 6, 2024
17190e9
More drastic fix
larseggert Sep 6, 2024
bfde87f
fmt
larseggert Sep 6, 2024
e1c18c5
Remove debug logging
larseggert Sep 6, 2024
02bede7
Update test
larseggert Sep 9, 2024
9356346
Do not encode long RTT guesses in resumption tokens
larseggert Sep 9, 2024
de91e32
trace
larseggert Sep 9, 2024
f6113fa
Merge branch 'main' into 0rtt-tmp
larseggert Sep 9, 2024
91a3ae6
Also RTX 0-RTT
larseggert Sep 9, 2024
a756007
Merge branch '0rtt-tmp' of github.com:larseggert/neqo into 0rtt-tmp
larseggert Sep 9, 2024
8d88c24
fmt
larseggert Sep 9, 2024
63aa0bd
debug
larseggert Sep 9, 2024
4fa5b10
No pacing for zerortt test
larseggert Sep 9, 2024
1c83522
log resumption
larseggert Sep 9, 2024
d1d3898
Log type of saved datagram
larseggert Sep 10, 2024
15b7521
Separate out the `resumption` test
larseggert Sep 10, 2024
094d78e
Merge branch 'main' into 0rtt-tmp
larseggert Sep 10, 2024
838942e
fmt
larseggert Sep 10, 2024
3b7fe10
Discard Initial keys after first Handshake packet is sent
larseggert Sep 10, 2024
c2e20ff
Revert
larseggert Sep 11, 2024
ddabf57
Fix?
larseggert Sep 11, 2024
6749838
Remove unused fn
larseggert Sep 11, 2024
8f4c566
ACK
larseggert Sep 11, 2024
73f2929
Maybe Handshake ping
larseggert Sep 11, 2024
af765b6
picoquic bug
larseggert Sep 12, 2024
60af704
Merge branch 'main' into 0rtt-tmp
larseggert Sep 13, 2024
36a77b0
Merge branch '0rtt-tmp' of github.com:larseggert/neqo into 0rtt-tmp
larseggert Sep 13, 2024
f3f2775
Merge branch 'main' into 0rtt-tmp
larseggert Sep 13, 2024
758f214
Merge branch '0rtt-tmp' of github.com:larseggert/neqo into 0rtt-tmp
larseggert Sep 13, 2024
8b3663d
Merge
larseggert Sep 13, 2024
230714d
Merge
larseggert Sep 13, 2024
8fd763e
Rename test and turn off grease
larseggert Sep 13, 2024
0385874
Cleanups
larseggert Sep 13, 2024
7004906
Minimize diff
larseggert Sep 16, 2024
88c8a1f
Merge branch 'main' into 0rtt-tmp
larseggert Sep 18, 2024
d94af34
Merge fixes
larseggert Sep 18, 2024
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
2 changes: 1 addition & 1 deletion neqo-bin/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ impl Args {
}
"resumption" => {
if self.urls.len() < 2 {
qerror!("Warning: resumption test won't work without >1 URL");
qerror!("Warning: resumption tests won't work without >1 URL");
exit(127);
}
self.shared.use_old_http = true;
Expand Down
70 changes: 35 additions & 35 deletions neqo-transport/src/cc/classic_cc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,41 @@ impl<T: WindowAdjustment> CongestionControl for ClassicCongestionControl<T> {
congestion || persistent_congestion
}

/// Handle a congestion event.
/// Returns true if this was a true congestion event.
fn on_congestion_event(&mut self, last_packet: &SentPacket) -> bool {
// Start a new congestion event if lost or ECN CE marked packet was sent
// after the start of the previous congestion recovery period.
if !self.after_recovery_start(last_packet) {
return false;
}

let (cwnd, acked_bytes) = self.cc_algorithm.reduce_cwnd(
self.congestion_window,
self.acked_bytes,
self.max_datagram_size(),
);
self.congestion_window = max(cwnd, self.cwnd_min());
self.acked_bytes = acked_bytes;
self.ssthresh = self.congestion_window;
qdebug!(
[self],
"Cong event -> recovery; cwnd {}, ssthresh {}",
self.congestion_window,
self.ssthresh
);
qlog::metrics_updated(
&self.qlog,
&[
QlogMetric::CongestionWindow(self.congestion_window),
QlogMetric::SsThresh(self.ssthresh),
QlogMetric::InRecovery(true),
],
);
self.set_state(State::RecoveryStart);
true
}

/// Report received ECN CE mark(s) to the congestion controller as a
/// congestion event.
///
Expand Down Expand Up @@ -537,41 +572,6 @@ impl<T: WindowAdjustment> ClassicCongestionControl<T> {
!self.state.transient() && self.recovery_start.map_or(true, |pn| packet.pn() >= pn)
}

/// Handle a congestion event.
/// Returns true if this was a true congestion event.
fn on_congestion_event(&mut self, last_packet: &SentPacket) -> bool {
// Start a new congestion event if lost or ECN CE marked packet was sent
// after the start of the previous congestion recovery period.
if !self.after_recovery_start(last_packet) {
return false;
}

let (cwnd, acked_bytes) = self.cc_algorithm.reduce_cwnd(
self.congestion_window,
self.acked_bytes,
self.max_datagram_size(),
);
self.congestion_window = max(cwnd, self.cwnd_min());
self.acked_bytes = acked_bytes;
self.ssthresh = self.congestion_window;
qdebug!(
[self],
"Cong event -> recovery; cwnd {}, ssthresh {}",
self.congestion_window,
self.ssthresh
);
qlog::metrics_updated(
&self.qlog,
&[
QlogMetric::CongestionWindow(self.congestion_window),
QlogMetric::SsThresh(self.ssthresh),
QlogMetric::InRecovery(true),
],
);
self.set_state(State::RecoveryStart);
true
}

fn app_limited(&self) -> bool {
if self.bytes_in_flight >= self.congestion_window {
false
Expand Down
5 changes: 5 additions & 0 deletions neqo-transport/src/cc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ pub trait CongestionControl: Display + Debug {
lost_packets: &[SentPacket],
) -> bool;

/// Initiate a congestion response.
///
/// Returns true if the congestion window was reduced.
fn on_congestion_event(&mut self, last_packet: &SentPacket) -> bool;

/// Returns true if the congestion window was reduced.
fn on_ecn_ce_received(&mut self, largest_acked_pkt: &SentPacket) -> bool;

Expand Down
35 changes: 18 additions & 17 deletions neqo-transport/src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,8 +634,8 @@ impl Connection {
/// only use it where a more precise value is not important.
fn pto(&self) -> Duration {
self.paths.primary().map_or_else(
|| RttEstimate::default().pto(PacketNumberSpace::ApplicationData),
|p| p.borrow().rtt().pto(PacketNumberSpace::ApplicationData),
|| RttEstimate::default().pto(self.confirmed()),
|p| p.borrow().rtt().pto(self.confirmed()),
)
}

Expand Down Expand Up @@ -1058,7 +1058,7 @@ impl Connection {
if let Some(p) = self.paths.primary() {
let path = p.borrow();
let rtt = path.rtt();
let pto = rtt.pto(PacketNumberSpace::ApplicationData);
let pto = rtt.pto(self.confirmed());

let idle_time = self.idle_timeout.expiry(now, pto);
qtrace!([self], "Idle/keepalive timer {:?}", idle_time);
Expand Down Expand Up @@ -1525,7 +1525,7 @@ impl Connection {
let mut dcid = None;

qtrace!([self], "{} input {}", path.borrow(), hex(&**d));
let pto = path.borrow().rtt().pto(PacketNumberSpace::ApplicationData);
let pto = path.borrow().rtt().pto(self.confirmed());

// Handle each packet in the datagram.
while !slc.is_empty() {
Expand Down Expand Up @@ -2138,7 +2138,7 @@ impl Connection {
// or the PTO timer fired: probe.
true
} else {
let pto = path.borrow().rtt().pto(PacketNumberSpace::ApplicationData);
let pto = path.borrow().rtt().pto(self.confirmed());
if !builder.packet_empty() {
// The packet only contains an ACK. Check whether we want to
// force an ACK with a PING so we can stop tracking packets.
Expand Down Expand Up @@ -2419,13 +2419,15 @@ impl Connection {
self.loss_recovery.on_packet_sent(path, sent);
}

if *space == PacketNumberSpace::Handshake
&& self.role == Role::Server
&& self.state == State::Confirmed
{
// We could discard handshake keys in set_state,
// but wait until after sending an ACK.
self.discard_keys(PacketNumberSpace::Handshake, now);
if *space == PacketNumberSpace::Handshake {
if self.role == Role::Client {
// We're sending a Handshake packet, so we can discard Initial keys.
self.discard_keys(PacketNumberSpace::Initial, now);
} else if self.role == Role::Server && self.state == State::Confirmed {
// We could discard handshake keys in set_state,
// but wait until after sending an ACK.
self.discard_keys(PacketNumberSpace::Handshake, now);
}
}
}

Expand Down Expand Up @@ -2776,18 +2778,17 @@ impl Connection {
self.set_initial_limits();
}
if self.crypto.install_keys(self.role)? {
if self.role == Role::Client {
// We won't acknowledge Initial packets as a result of this, but the
// server can rely on implicit acknowledgment.
self.discard_keys(PacketNumberSpace::Initial, now);
}
self.saved_datagrams.make_available(CryptoSpace::Handshake);
}
}

Ok(())
}

fn confirmed(&self) -> bool {
self.state == State::Confirmed
}

fn set_confirmed(&mut self) -> Res<()> {
self.set_state(State::Confirmed);
if self.conn_params.pmtud_enabled() {
Expand Down
15 changes: 12 additions & 3 deletions neqo-transport/src/connection/tests/ecn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,19 @@ fn handshake_delay_with_ecn_blackhole() {
drop_ecn_marked_datagrams(),
);

let pto = DEFAULT_RTT * 3;
let half_rtt = DEFAULT_RTT / 2;
assert_eq!(
(finish - start).as_millis() / DEFAULT_RTT.as_millis(),
15,
"expected 6 RTT for client to detect blackhole, 6 RTT for server to detect blackhole and 3 RTT for handshake to be confirmed.",
(finish - start),
(1 + 2 + 4) * pto + // Client RTOs its CI w/ECN twice (3x total)
half_rtt + // Fourth CI w/o ECN being delivered
(1 + 2 + 4) * pto + // Server RTOs its CI w/ECN twice (3x total)
half_rtt + // Fourth SI w/o ECN being delivered
half_rtt + // Client ACK
half_rtt + // Client Handshake/Short
half_rtt + // Server HandshakeDone
half_rtt + // Client ACK
half_rtt
);
}

Expand Down
Loading