@@ -16,7 +16,9 @@ use thiserror::Error;
1616use tracing:: { debug, error, trace, warn} ;
1717
1818use crate :: {
19- cid_generator:: { ConnectionIdGenerator , RandomConnectionIdGenerator } ,
19+ cid_generator:: {
20+ ConnectionIdGenerator , RandomConnectionIdGenerator , ZeroLengthConnectionIdGenerator ,
21+ } ,
2022 coding:: BufMutExt ,
2123 config:: { ClientConfig , EndpointConfig , ServerConfig } ,
2224 connection:: { Connection , ConnectionError } ,
@@ -44,7 +46,7 @@ pub struct Endpoint {
4446 rng : StdRng ,
4547 index : ConnectionIndex ,
4648 connections : Slab < ConnectionMeta > ,
47- local_cid_generator : Arc < dyn ConnectionIdGenerator > ,
49+ local_cid_generator : Option < Arc < dyn ConnectionIdGenerator > > ,
4850 config : Arc < EndpointConfig > ,
4951 server_config : Option < Arc < ServerConfig > > ,
5052 /// Whether the underlying UDP socket promises not to fragment packets
@@ -144,7 +146,10 @@ impl Endpoint {
144146 let datagram_len = data. len ( ) ;
145147 let ( first_decode, remaining) = match PartialDecode :: new (
146148 data,
147- & * self . local_cid_generator ,
149+ self . local_cid_generator . as_ref ( ) . map_or (
150+ & ZeroLengthConnectionIdGenerator as & dyn ConnectionIdGenerator ,
151+ |x| & * * x,
152+ ) ,
148153 & self . config . supported_versions ,
149154 self . config . grease_quic_bit ,
150155 ) {
@@ -302,8 +307,8 @@ impl Endpoint {
302307 if !first_decode. is_initial ( )
303308 && self
304309 . local_cid_generator
305- . validate ( first_decode . dst_cid ( ) )
306- . is_err ( )
310+ . as_ref ( )
311+ . map_or ( false , |gen| gen . validate ( first_decode . dst_cid ( ) ) . is_err ( ) )
307312 {
308313 debug ! ( "dropping packet with invalid CID" ) ;
309314 return None ;
@@ -400,7 +405,7 @@ impl Endpoint {
400405 let params = TransportParameters :: new (
401406 & config. transport ,
402407 & self . config ,
403- self . local_cid_generator . as_ref ( ) ,
408+ self . local_cid_generator . is_some ( ) ,
404409 loc_cid,
405410 None ,
406411 ) ;
@@ -453,12 +458,11 @@ impl Endpoint {
453458 /// Generate a connection ID for `ch`
454459 fn new_cid ( & mut self , ch : ConnectionHandle ) -> ConnectionId {
455460 loop {
456- let cid = self . local_cid_generator . generate_cid ( ) ;
457- if cid. len ( ) == 0 {
461+ let Some ( cid_generator) = self . local_cid_generator . as_ref ( ) else {
458462 // Zero-length CID; nothing to track
459- debug_assert_eq ! ( self . local_cid_generator . cid_len ( ) , 0 ) ;
460- return cid ;
461- }
463+ return ConnectionId :: EMPTY ;
464+ } ;
465+ let cid = cid_generator . generate_cid ( ) ;
462466 if let hash_map:: Entry :: Vacant ( e) = self . index . connection_ids . entry ( cid) {
463467 e. insert ( ch) ;
464468 break cid;
@@ -589,7 +593,7 @@ impl Endpoint {
589593 let mut params = TransportParameters :: new (
590594 & server_config. transport ,
591595 & self . config ,
592- self . local_cid_generator . as_ref ( ) ,
596+ self . local_cid_generator . is_some ( ) ,
593597 loc_cid,
594598 Some ( & server_config) ,
595599 ) ;
@@ -680,10 +684,7 @@ impl Endpoint {
680684 // bytes. If this is a Retry packet, then the length must instead match our usual CID
681685 // length. If we ever issue non-Retry address validation tokens via `NEW_TOKEN`, then we'll
682686 // also need to validate CID length for those after decoding the token.
683- if header. dst_cid . len ( ) < 8
684- && ( !header. token_pos . is_empty ( )
685- && header. dst_cid . len ( ) != self . local_cid_generator . cid_len ( ) )
686- {
687+ if header. dst_cid . len ( ) < 8 && !header. token_pos . is_empty ( ) {
687688 debug ! (
688689 "rejecting connection due to invalid DCID length {}" ,
689690 header. dst_cid. len( )
@@ -730,7 +731,10 @@ impl Endpoint {
730731 // with established connections. In the unlikely event that a collision occurs
731732 // between two connections in the initial phase, both will fail fast and may be
732733 // retried by the application layer.
733- let loc_cid = self . local_cid_generator . generate_cid ( ) ;
734+ let loc_cid = self
735+ . local_cid_generator
736+ . as_ref ( )
737+ . map_or ( ConnectionId :: EMPTY , |gen| gen. generate_cid ( ) ) ;
734738
735739 let token = RetryToken {
736740 orig_dst_cid : incoming. packet . header . dst_cid ,
@@ -860,7 +864,10 @@ impl Endpoint {
860864 // We don't need to worry about CID collisions in initial closes because the peer
861865 // shouldn't respond, and if it does, and the CID collides, we'll just drop the
862866 // unexpected response.
863- let local_id = self . local_cid_generator . generate_cid ( ) ;
867+ let local_id = self
868+ . local_cid_generator
869+ . as_ref ( )
870+ . map_or ( ConnectionId :: EMPTY , |gen| gen. generate_cid ( ) ) ;
864871 let number = PacketNumber :: U8 ( 0 ) ;
865872 let header = Header :: Initial ( InitialHeader {
866873 dst_cid : * remote_id,
0 commit comments