Skip to content

Commit d0379f5

Browse files
committed
Only populate local_cid_state when CIDs are in use
1 parent 6f27faa commit d0379f5

File tree

2 files changed

+50
-60
lines changed

2 files changed

+50
-60
lines changed

quinn-proto/src/connection/cid_state.rs

+1-19
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,12 @@ pub(super) struct CidState {
2121
prev_retire_seq: u64,
2222
/// Sequence number to set in retire_prior_to field in NEW_CONNECTION_ID frame
2323
retire_seq: u64,
24-
/// cid length used to decode short packet
25-
cid_len: usize,
2624
//// cid lifetime
2725
cid_lifetime: Option<Duration>,
2826
}
2927

3028
impl CidState {
31-
pub(crate) fn new(
32-
cid_len: usize,
33-
cid_lifetime: Option<Duration>,
34-
now: Instant,
35-
issued: u64,
36-
) -> Self {
29+
pub(crate) fn new(cid_lifetime: Option<Duration>, now: Instant, issued: u64) -> Self {
3730
let mut active_seq = FxHashSet::default();
3831
// Add sequence number of CIDs used in handshaking into tracking set
3932
for seq in 0..issued {
@@ -45,7 +38,6 @@ impl CidState {
4538
active_seq,
4639
prev_retire_seq: 0,
4740
retire_seq: 0,
48-
cid_len,
4941
cid_lifetime,
5042
};
5143
// Track lifetime of CIDs used in handshaking
@@ -158,11 +150,6 @@ impl CidState {
158150
sequence: u64,
159151
limit: u64,
160152
) -> Result<bool, TransportError> {
161-
if self.cid_len == 0 {
162-
return Err(TransportError::PROTOCOL_VIOLATION(
163-
"RETIRE_CONNECTION_ID when CIDs aren't in use",
164-
));
165-
}
166153
if sequence > self.issued {
167154
debug!(
168155
sequence,
@@ -181,11 +168,6 @@ impl CidState {
181168
Ok(limit > self.active_seq.len() as u64)
182169
}
183170

184-
/// Length of local Connection IDs
185-
pub(crate) fn cid_len(&self) -> usize {
186-
self.cid_len
187-
}
188-
189171
/// The value for `retire_prior_to` field in `NEW_CONNECTION_ID` frame
190172
pub(crate) fn retire_prior_to(&self) -> u64 {
191173
self.retire_seq

quinn-proto/src/connection/mod.rs

+49-41
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,8 @@ pub struct Connection {
231231
streams: StreamsState,
232232
/// Surplus remote CIDs for future use on new paths
233233
rem_cids: CidQueue,
234-
// Attributes of CIDs generated by local peer
235-
local_cid_state: CidState,
234+
/// Attributes of CIDs generated by local peer, if in use
235+
local_cid_state: Option<CidState>,
236236
/// State of the unreliable datagram extension
237237
datagrams: DatagramState,
238238
/// Connection level statistics
@@ -281,12 +281,14 @@ impl Connection {
281281
crypto,
282282
handshake_cid: loc_cid,
283283
rem_handshake_cid: rem_cid,
284-
local_cid_state: CidState::new(
285-
cid_gen.cid_len(),
286-
cid_gen.cid_lifetime(),
287-
now,
288-
if pref_addr_cid.is_some() { 2 } else { 1 },
289-
),
284+
local_cid_state: match cid_gen.cid_len() {
285+
0 => None,
286+
_ => Some(CidState::new(
287+
cid_gen.cid_lifetime(),
288+
now,
289+
if pref_addr_cid.is_some() { 2 } else { 1 },
290+
)),
291+
},
290292
path: PathData::new(remote, allow_mtud, None, now, path_validated, &config),
291293
allow_mtud,
292294
local_ip,
@@ -1088,7 +1090,8 @@ impl Connection {
10881090
}
10891091
}
10901092
NewIdentifiers(ids, now) => {
1091-
self.local_cid_state.new_cids(&ids, now);
1093+
let cid_state = self.local_cid_state.as_mut().unwrap();
1094+
cid_state.new_cids(&ids, now);
10921095
ids.into_iter().rev().for_each(|frame| {
10931096
self.spaces[SpaceId::Data].pending.new_cids.push(frame);
10941097
});
@@ -1098,7 +1101,9 @@ impl Connection {
10981101
.get(Timer::PushNewCid)
10991102
.map_or(true, |x| x <= now)
11001103
{
1101-
self.reset_cid_retirement();
1104+
if let Some(t) = cid_state.next_timeout() {
1105+
self.timers.set(Timer::PushNewCid, t);
1106+
}
11021107
}
11031108
}
11041109
}
@@ -1149,12 +1154,13 @@ impl Connection {
11491154
}
11501155
Timer::Pacing => trace!("pacing timer expired"),
11511156
Timer::PushNewCid => {
1157+
let cid_state = self.local_cid_state.as_mut().unwrap();
11521158
// Update `retire_prior_to` field in NEW_CONNECTION_ID frame
1153-
let num_new_cid = self.local_cid_state.on_cid_timeout().into();
1159+
let num_new_cid = cid_state.on_cid_timeout().into();
11541160
if !self.state.is_closed() {
11551161
trace!(
11561162
"push a new cid to peer RETIRE_PRIOR_TO field {}",
1157-
self.local_cid_state.retire_prior_to()
1163+
cid_state.retire_prior_to()
11581164
);
11591165
self.endpoint_events
11601166
.push_back(EndpointEventInner::NeedIdentifiers(now, num_new_cid));
@@ -1860,12 +1866,6 @@ impl Connection {
18601866
self.timers.set(Timer::KeepAlive, now + interval);
18611867
}
18621868

1863-
fn reset_cid_retirement(&mut self) {
1864-
if let Some(t) = self.local_cid_state.next_timeout() {
1865-
self.timers.set(Timer::PushNewCid, t);
1866-
}
1867-
}
1868-
18691869
/// Handle the already-decrypted first packet from the client
18701870
///
18711871
/// Decrypting the first packet in the `Endpoint` allows stateless packet handling to be more
@@ -2756,8 +2756,12 @@ impl Connection {
27562756
self.streams.received_stop_sending(id, error_code);
27572757
}
27582758
Frame::RetireConnectionId { sequence } => {
2759-
let allow_more_cids = self
2760-
.local_cid_state
2759+
let cid_state = self.local_cid_state.as_mut().ok_or_else(|| {
2760+
TransportError::PROTOCOL_VIOLATION(
2761+
"RETIRE_CONNECTION_ID when CIDs aren't in use",
2762+
)
2763+
})?;
2764+
let allow_more_cids = cid_state
27612765
.on_cid_retirement(sequence, self.peer_params.issue_cids_limit())?;
27622766
self.endpoint_events
27632767
.push_back(EndpointEventInner::RetireConnectionId(
@@ -2999,7 +3003,7 @@ impl Connection {
29993003

30003004
/// Issue an initial set of connection IDs to the peer upon connection
30013005
fn issue_first_cids(&mut self, now: Instant) {
3002-
if self.local_cid_state.cid_len() == 0 {
3006+
if self.local_cid_state.is_none() {
30033007
return;
30043008
}
30053009

@@ -3169,25 +3173,27 @@ impl Connection {
31693173
}
31703174

31713175
// NEW_CONNECTION_ID
3172-
while buf.len() + 44 < max_size {
3173-
let issued = match space.pending.new_cids.pop() {
3174-
Some(x) => x,
3175-
None => break,
3176-
};
3177-
trace!(
3178-
sequence = issued.sequence,
3179-
id = %issued.id,
3180-
"NEW_CONNECTION_ID"
3181-
);
3182-
frame::NewConnectionId {
3183-
sequence: issued.sequence,
3184-
retire_prior_to: self.local_cid_state.retire_prior_to(),
3185-
id: issued.id,
3186-
reset_token: issued.reset_token,
3176+
if let Some(cid_state) = self.local_cid_state.as_ref() {
3177+
while buf.len() + 44 < max_size {
3178+
let issued = match space.pending.new_cids.pop() {
3179+
Some(x) => x,
3180+
None => break,
3181+
};
3182+
trace!(
3183+
sequence = issued.sequence,
3184+
id = %issued.id,
3185+
"NEW_CONNECTION_ID"
3186+
);
3187+
frame::NewConnectionId {
3188+
sequence: issued.sequence,
3189+
retire_prior_to: cid_state.retire_prior_to(),
3190+
id: issued.id,
3191+
reset_token: issued.reset_token,
3192+
}
3193+
.encode(buf);
3194+
sent.retransmits.get_or_create().new_cids.push(issued);
3195+
self.stats.frame_tx.new_connection_id += 1;
31873196
}
3188-
.encode(buf);
3189-
sent.retransmits.get_or_create().new_cids.push(issued);
3190-
self.stats.frame_tx.new_connection_id += 1;
31913197
}
31923198

31933199
// RETIRE_CONNECTION_ID
@@ -3481,14 +3487,16 @@ impl Connection {
34813487

34823488
#[cfg(test)]
34833489
pub(crate) fn active_local_cid_seq(&self) -> (u64, u64) {
3484-
self.local_cid_state.active_seq()
3490+
self.local_cid_state
3491+
.as_ref()
3492+
.map_or((u64::MAX, u64::MIN), |state| state.active_seq())
34853493
}
34863494

34873495
/// Instruct the peer to replace previously issued CIDs by sending a NEW_CONNECTION_ID frame
34883496
/// with updated `retire_prior_to` field set to `v`
34893497
#[cfg(test)]
34903498
pub(crate) fn rotate_local_cid(&mut self, v: u64, now: Instant) {
3491-
let n = self.local_cid_state.assign_retire_seq(v);
3499+
let n = self.local_cid_state.as_mut().unwrap().assign_retire_seq(v);
34923500
self.endpoint_events
34933501
.push_back(EndpointEventInner::NeedIdentifiers(now, n));
34943502
}

0 commit comments

Comments
 (0)