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 5b1e3d2 commit 5be8143
Showing 1 changed file with 40 additions and 4 deletions.
44 changes: 40 additions & 4 deletions quiche/src/cid.rs
Expand Up @@ -455,10 +455,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 @@ -917,6 +918,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 5be8143

Please sign in to comment.