@@ -231,8 +231,8 @@ pub struct Connection {
231
231
streams : StreamsState ,
232
232
/// Surplus remote CIDs for future use on new paths
233
233
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 > ,
236
236
/// State of the unreliable datagram extension
237
237
datagrams : DatagramState ,
238
238
/// Connection level statistics
@@ -281,12 +281,14 @@ impl Connection {
281
281
crypto,
282
282
handshake_cid : loc_cid,
283
283
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
+ } ,
290
292
path : PathData :: new ( remote, allow_mtud, None , now, path_validated, & config) ,
291
293
allow_mtud,
292
294
local_ip,
@@ -1088,7 +1090,8 @@ impl Connection {
1088
1090
}
1089
1091
}
1090
1092
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) ;
1092
1095
ids. into_iter ( ) . rev ( ) . for_each ( |frame| {
1093
1096
self . spaces [ SpaceId :: Data ] . pending . new_cids . push ( frame) ;
1094
1097
} ) ;
@@ -1098,7 +1101,9 @@ impl Connection {
1098
1101
. get ( Timer :: PushNewCid )
1099
1102
. map_or ( true , |x| x <= now)
1100
1103
{
1101
- self . reset_cid_retirement ( ) ;
1104
+ if let Some ( t) = cid_state. next_timeout ( ) {
1105
+ self . timers . set ( Timer :: PushNewCid , t) ;
1106
+ }
1102
1107
}
1103
1108
}
1104
1109
}
@@ -1149,12 +1154,13 @@ impl Connection {
1149
1154
}
1150
1155
Timer :: Pacing => trace ! ( "pacing timer expired" ) ,
1151
1156
Timer :: PushNewCid => {
1157
+ let cid_state = self . local_cid_state . as_mut ( ) . unwrap ( ) ;
1152
1158
// 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 ( ) ;
1154
1160
if !self . state . is_closed ( ) {
1155
1161
trace ! (
1156
1162
"push a new cid to peer RETIRE_PRIOR_TO field {}" ,
1157
- self . local_cid_state . retire_prior_to( )
1163
+ cid_state . retire_prior_to( )
1158
1164
) ;
1159
1165
self . endpoint_events
1160
1166
. push_back ( EndpointEventInner :: NeedIdentifiers ( now, num_new_cid) ) ;
@@ -1860,12 +1866,6 @@ impl Connection {
1860
1866
self . timers . set ( Timer :: KeepAlive , now + interval) ;
1861
1867
}
1862
1868
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
-
1869
1869
/// Handle the already-decrypted first packet from the client
1870
1870
///
1871
1871
/// Decrypting the first packet in the `Endpoint` allows stateless packet handling to be more
@@ -2756,8 +2756,12 @@ impl Connection {
2756
2756
self . streams . received_stop_sending ( id, error_code) ;
2757
2757
}
2758
2758
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
2761
2765
. on_cid_retirement ( sequence, self . peer_params . issue_cids_limit ( ) ) ?;
2762
2766
self . endpoint_events
2763
2767
. push_back ( EndpointEventInner :: RetireConnectionId (
@@ -2999,7 +3003,7 @@ impl Connection {
2999
3003
3000
3004
/// Issue an initial set of connection IDs to the peer upon connection
3001
3005
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 ( ) {
3003
3007
return ;
3004
3008
}
3005
3009
@@ -3169,25 +3173,27 @@ impl Connection {
3169
3173
}
3170
3174
3171
3175
// 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 ;
3187
3196
}
3188
- . encode ( buf) ;
3189
- sent. retransmits . get_or_create ( ) . new_cids . push ( issued) ;
3190
- self . stats . frame_tx . new_connection_id += 1 ;
3191
3197
}
3192
3198
3193
3199
// RETIRE_CONNECTION_ID
@@ -3481,14 +3487,16 @@ impl Connection {
3481
3487
3482
3488
#[ cfg( test) ]
3483
3489
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 ( ) )
3485
3493
}
3486
3494
3487
3495
/// Instruct the peer to replace previously issued CIDs by sending a NEW_CONNECTION_ID frame
3488
3496
/// with updated `retire_prior_to` field set to `v`
3489
3497
#[ cfg( test) ]
3490
3498
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) ;
3492
3500
self . endpoint_events
3493
3501
. push_back ( EndpointEventInner :: NeedIdentifiers ( now, n) ) ;
3494
3502
}
0 commit comments