Skip to content

Commit

Permalink
mark outgoing packets with ECN
Browse files Browse the repository at this point in the history
TODO:
* Probe ECN for each path.
* Validate ECN counts in ACKs.
  • Loading branch information
ghedo committed Jul 23, 2022
1 parent f4bd0cb commit ecd9c6c
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
10 changes: 9 additions & 1 deletion quiche/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,9 @@ pub struct SendInfo {
///
/// [Pacing]: index.html#pacing
pub at: time::Instant,

/// The ECN marking for the outgoing packet.
pub ecn: u8,
}

/// Represents information carried by `CONNECTION_CLOSE` frames.
Expand Down Expand Up @@ -3035,6 +3038,8 @@ impl Connection {
to: send_path.peer_addr(),

at: send_path.recovery.get_packet_send_time(),

ecn: 0x01, // ECT(0)
};

Ok((done, info))
Expand Down Expand Up @@ -6105,7 +6110,9 @@ impl Connection {
frame::Frame::Ping => (),

frame::Frame::ACK {
ranges, ack_delay, ..
ranges,
ack_delay,
ecn_counts,
} => {
let ack_delay = ack_delay
.checked_mul(2_u64.pow(
Expand Down Expand Up @@ -6137,6 +6144,7 @@ impl Connection {
let (lost_packets, lost_bytes) = p.recovery.on_ack_received(
&ranges,
ack_delay,
ecn_counts,
epoch,
handshake_status,
now,
Expand Down
1 change: 1 addition & 0 deletions quiche/src/recovery/delivery_rate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ mod tests {
r.on_ack_received(
&acked,
25,
None,
packet::EPOCH_APPLICATION,
HandshakeStatus::default(),
now,
Expand Down
42 changes: 40 additions & 2 deletions quiche/src/recovery/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ pub struct Recovery {

max_datagram_size: usize,

ecn_ce_counts: [u64; packet::EPOCH_COUNT],

cubic_state: cubic::State,

// HyStart++.
Expand Down Expand Up @@ -244,6 +246,8 @@ impl Recovery {

max_datagram_size: recovery_config.max_send_udp_payload_size,

ecn_ce_counts: [0, 0, 0],

cc_ops: recovery_config.cc_ops,

delivery_rate: delivery_rate::Rate::default(),
Expand Down Expand Up @@ -379,8 +383,8 @@ impl Recovery {

pub fn on_ack_received(
&mut self, ranges: &ranges::RangeSet, ack_delay: u64,
epoch: packet::Epoch, handshake_status: HandshakeStatus, now: Instant,
trace_id: &str,
ecn_counts: Option<packet::EcnCounts>, epoch: packet::Epoch,
handshake_status: HandshakeStatus, now: Instant, trace_id: &str,
) -> Result<(usize, usize)> {
let largest_acked = ranges.last().unwrap();

Expand All @@ -401,6 +405,7 @@ impl Recovery {
let mut has_ack_eliciting = false;

let mut largest_newly_acked_pkt_num = 0;
let mut largest_newly_acked_size = 0;
let mut largest_newly_acked_sent_time = now;

let mut newly_acked = Vec::new();
Expand Down Expand Up @@ -461,6 +466,7 @@ impl Recovery {
}

largest_newly_acked_pkt_num = unacked.pkt_num;
largest_newly_acked_size = unacked.size;
largest_newly_acked_sent_time = unacked.time_sent;

self.acked[epoch].append(&mut unacked.frames);
Expand Down Expand Up @@ -519,6 +525,16 @@ impl Recovery {
}
}

if let Some(ecn_counts) = ecn_counts {
self.process_ecn(
ecn_counts,
largest_newly_acked_size,
largest_newly_acked_sent_time,
epoch,
now,
);
}

// Detect and mark lost packets without removing them from the sent
// packets list.
let (lost_packets, lost_bytes) =
Expand Down Expand Up @@ -954,6 +970,22 @@ impl Recovery {
}
}

fn process_ecn(
&mut self, ecn_counts: packet::EcnCounts, largest_acked_size: usize,
largest_acked_sent_time: Instant, epoch: packet::Epoch, now: Instant,
) {
if ecn_counts.ecn_ce_count > self.ecn_ce_counts[epoch] {
self.ecn_ce_counts[epoch] = ecn_counts.ecn_ce_count;

self.congestion_event(
largest_acked_size,
largest_acked_sent_time,
epoch,
now,
);
}
}

fn congestion_event(
&mut self, lost_bytes: usize, time_sent: Instant, epoch: packet::Epoch,
now: Instant,
Expand Down Expand Up @@ -1476,6 +1508,7 @@ mod tests {
r.on_ack_received(
&acked,
25,
None,
packet::EPOCH_APPLICATION,
HandshakeStatus::default(),
now,
Expand Down Expand Up @@ -1561,6 +1594,7 @@ mod tests {
r.on_ack_received(
&acked,
25,
None,
packet::EPOCH_APPLICATION,
HandshakeStatus::default(),
now,
Expand Down Expand Up @@ -1710,6 +1744,7 @@ mod tests {
r.on_ack_received(
&acked,
25,
None,
packet::EPOCH_APPLICATION,
HandshakeStatus::default(),
now,
Expand Down Expand Up @@ -1869,6 +1904,7 @@ mod tests {
r.on_ack_received(
&acked,
25,
None,
packet::EPOCH_APPLICATION,
HandshakeStatus::default(),
now,
Expand All @@ -1888,6 +1924,7 @@ mod tests {
r.on_ack_received(
&acked,
25,
None,
packet::EPOCH_APPLICATION,
HandshakeStatus::default(),
now,
Expand Down Expand Up @@ -1967,6 +2004,7 @@ mod tests {
r.on_ack_received(
&acked,
10,
None,
packet::EPOCH_APPLICATION,
HandshakeStatus::default(),
now,
Expand Down

0 comments on commit ecd9c6c

Please sign in to comment.