Skip to content

Commit 9947411

Browse files
author
Wenjie Li
committed
Add lifetime to CID to avoid future change on CID generator trait that breaks compatibility
1 parent f5b2e77 commit 9947411

File tree

3 files changed

+34
-15
lines changed

3 files changed

+34
-15
lines changed

quinn-proto/src/cid_generator.rs

+23-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1+
use std::time::Duration;
2+
13
use rand::RngCore;
24

35
use crate::shared::ConnectionId;
46
use crate::MAX_CID_SIZE;
57

68
/// Generates connection IDs for incoming connections
79
pub trait ConnectionIdGenerator: Send {
8-
/// Generates a new CID
10+
/// Generates a new CID with finite lifetime
911
///
1012
/// Connection IDs MUST NOT contain any information that can be used by
1113
/// an external observer (that is, one that does not cooperate with the
1214
/// issuer) to correlate them with other connection IDs for the same
1315
/// connection.
14-
fn generate_cid(&mut self) -> ConnectionId;
16+
///
17+
/// Connection IDs will be proactively retired if lifetime is given (under development).
18+
fn generate_cid(&mut self) -> (ConnectionId, Option<Duration>);
1519
/// Returns the length of a CID for cononections created by this generator
1620
fn cid_len(&self) -> usize;
1721
}
@@ -20,25 +24,38 @@ pub trait ConnectionIdGenerator: Send {
2024
#[derive(Debug, Clone, Copy)]
2125
pub struct RandomConnectionIdGenerator {
2226
cid_len: usize,
27+
lifetime: Option<Duration>,
2328
}
2429
impl Default for RandomConnectionIdGenerator {
2530
fn default() -> Self {
26-
Self { cid_len: 8 }
31+
Self {
32+
cid_len: 8,
33+
lifetime: None,
34+
}
2735
}
2836
}
2937
impl RandomConnectionIdGenerator {
3038
/// Initialize Random CID generator with a fixed CID length (which must be less or equal to MAX_CID_SIZE)
3139
pub fn new(cid_len: usize) -> Self {
3240
debug_assert!(cid_len <= MAX_CID_SIZE);
33-
Self { cid_len }
41+
Self {
42+
cid_len,
43+
..RandomConnectionIdGenerator::default()
44+
}
45+
}
46+
47+
/// Set the lifetime of CIDs created by this generator
48+
pub fn set_lifetime(&mut self, d: Duration) -> &mut Self {
49+
self.lifetime = Some(d);
50+
self
3451
}
3552
}
3653
impl ConnectionIdGenerator for RandomConnectionIdGenerator {
37-
fn generate_cid(&mut self) -> ConnectionId {
54+
fn generate_cid(&mut self) -> (ConnectionId, Option<Duration>) {
3855
let mut bytes_arr = [0; MAX_CID_SIZE];
3956
rand::thread_rng().fill_bytes(&mut bytes_arr[..self.cid_len]);
4057

41-
ConnectionId::new(&bytes_arr[..self.cid_len])
58+
(ConnectionId::new(&bytes_arr[..self.cid_len]), self.lifetime)
4259
}
4360

4461
/// Provide the length of dst_cid in short header packet

quinn-proto/src/endpoint.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ where
345345
if self.is_full() {
346346
return Err(ConnectError::TooManyConnections);
347347
}
348-
let remote_id = RandomConnectionIdGenerator::new(MAX_CID_SIZE).generate_cid();
348+
let (remote_id, _) = RandomConnectionIdGenerator::new(MAX_CID_SIZE).generate_cid();
349349
trace!(initial_dcid = %remote_id);
350350
let (ch, conn) = self.add_connection(
351351
remote_id,
@@ -363,7 +363,7 @@ where
363363
fn send_new_identifiers(&mut self, ch: ConnectionHandle, num: u64) -> ConnectionEvent {
364364
let mut ids = vec![];
365365
for _ in 0..num {
366-
let id = self.new_cid();
366+
let (id, _) = self.new_cid();
367367
self.connection_ids.insert(id, ch);
368368
let meta = &mut self.connections[ch];
369369
meta.cids_issued += 1;
@@ -378,11 +378,11 @@ where
378378
ConnectionEvent(ConnectionEventInner::NewIdentifiers(ids))
379379
}
380380

381-
fn new_cid(&mut self) -> ConnectionId {
381+
fn new_cid(&mut self) -> (ConnectionId, Option<Duration>) {
382382
loop {
383-
let cid = self.local_cid_generator.generate_cid();
383+
let (cid, lifetime) = self.local_cid_generator.generate_cid();
384384
if !self.connection_ids.contains_key(&cid) {
385-
break cid;
385+
break (cid, lifetime);
386386
}
387387
assert!(self.local_cid_generator.cid_len() > 0);
388388
}
@@ -396,7 +396,7 @@ where
396396
opts: ConnectionOpts<S>,
397397
now: Instant,
398398
) -> Result<(ConnectionHandle, Connection<S>), ConnectError> {
399-
let loc_cid = self.new_cid();
399+
let (loc_cid, _) = self.new_cid();
400400
let (server_config, tls, transport_config) = match opts {
401401
ConnectionOpts::Client {
402402
config,
@@ -509,7 +509,7 @@ where
509509
}
510510

511511
// Local CID used for stateless packets
512-
let temp_loc_cid = self.new_cid();
512+
let (temp_loc_cid, _) = self.new_cid();
513513
let server_config = self.server_config.as_ref().unwrap();
514514

515515
if self.incoming_handshakes == server_config.accept_buffer as usize

quinn-proto/src/token.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,11 @@ mod test {
153153
rand::thread_rng().fill_bytes(&mut key);
154154
let key = <hmac::Key as HmacKey>::new(&key).unwrap();
155155
let addr = SocketAddr::new(Ipv6Addr::LOCALHOST.into(), 4433);
156-
let retry_src_cid = RandomConnectionIdGenerator::new(MAX_CID_SIZE).generate_cid();
156+
let (retry_src_cid, _) = RandomConnectionIdGenerator::new(MAX_CID_SIZE).generate_cid();
157157
let token = RetryToken {
158-
orig_dst_cid: RandomConnectionIdGenerator::new(MAX_CID_SIZE).generate_cid(),
158+
orig_dst_cid: RandomConnectionIdGenerator::new(MAX_CID_SIZE)
159+
.generate_cid()
160+
.0,
159161
issued: UNIX_EPOCH + Duration::new(42, 0), // Fractional seconds would be lost
160162
};
161163
let encoded = token.encode(&key, &addr, &retry_src_cid);

0 commit comments

Comments
 (0)