Skip to content

Commit

Permalink
cid: always retire CIDs with seqnum lower than retire prior to
Browse files Browse the repository at this point in the history
When a NEW_CONNECTION_ID frame with a seqnum lower than previously
received retire prior to is received, the new CID needs to be
immediately retired. However, if the CID was already queued to be
retired we would keep processing it instead of just ignoring it.
  • Loading branch information
ghedo committed Mar 12, 2024
1 parent 3398cea commit a983998
Showing 1 changed file with 40 additions and 4 deletions.
44 changes: 40 additions & 4 deletions quiche/src/cid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,10 +476,11 @@ impl ConnectionIdentifiers {
// received NEW_CONNECTION_ID frame MUST send a corresponding
// RETIRE_CONNECTION_ID frame that retires the newly received connection
// ID, unless it has already done so for that sequence number.
if seq < self.largest_peer_retire_prior_to &&
!self.retire_dcid_seqs.contains(&seq)
{
self.retire_dcid_seqs.push_back(seq);
if seq < self.largest_peer_retire_prior_to {
if !self.retire_dcid_seqs.contains(&seq) {
self.retire_dcid_seqs.push_back(seq);
}

return Ok(retired_path_ids);
}

Expand Down Expand Up @@ -938,6 +939,41 @@ mod tests {
assert_eq!(ids.dcids.len(), 1);
}

#[test]
fn new_dcid_reordered() {
let (scid, _) = create_cid_and_reset_token(16);
let (dcid, _) = create_cid_and_reset_token(16);

let mut ids = ConnectionIdentifiers::new(2, &scid, 0, None);
ids.set_initial_dcid(dcid, None, Some(0));

assert_eq!(ids.available_dcids(), 0);
assert_eq!(ids.dcids.len(), 1);

// Skip DCID #1 (e.g due to packet loss) and insert DCID #2.
let (dcid, rt) = create_cid_and_reset_token(16);
assert!(ids.new_dcid(dcid.clone(), 2, rt, 1).is_ok());
assert_eq!(ids.dcids.len(), 1);

let (dcid, rt) = create_cid_and_reset_token(16);
assert!(ids.new_dcid(dcid.clone(), 3, rt, 2).is_ok());
assert_eq!(ids.dcids.len(), 2);

let (dcid, rt) = create_cid_and_reset_token(16);
assert!(ids.new_dcid(dcid.clone(), 4, rt, 3).is_ok());
assert_eq!(ids.dcids.len(), 2);

// Insert DCID #1 (e.g due to packet reordering).
let (dcid, rt) = create_cid_and_reset_token(16);
assert!(ids.new_dcid(dcid.clone(), 1, rt, 0).is_ok());
assert_eq!(ids.dcids.len(), 2);

// Try inserting DCID #1 again (e.g. due to retransmission).
let (dcid, rt) = create_cid_and_reset_token(16);
assert!(ids.new_dcid(dcid.clone(), 1, rt, 0).is_ok());
assert_eq!(ids.dcids.len(), 2);
}

#[test]
fn retire_scids() {
let (scid, _) = create_cid_and_reset_token(16);
Expand Down

0 comments on commit a983998

Please sign in to comment.