@@ -16,7 +16,9 @@ use thiserror::Error;
16
16
use tracing:: { debug, error, trace, warn} ;
17
17
18
18
use crate :: {
19
- cid_generator:: { ConnectionIdGenerator , RandomConnectionIdGenerator } ,
19
+ cid_generator:: {
20
+ ConnectionIdGenerator , RandomConnectionIdGenerator , ZeroLengthConnectionIdGenerator ,
21
+ } ,
20
22
coding:: BufMutExt ,
21
23
config:: { ClientConfig , EndpointConfig , ServerConfig } ,
22
24
connection:: { Connection , ConnectionError } ,
@@ -44,7 +46,7 @@ pub struct Endpoint {
44
46
rng : StdRng ,
45
47
index : ConnectionIndex ,
46
48
connections : Slab < ConnectionMeta > ,
47
- local_cid_generator : Arc < dyn ConnectionIdGenerator > ,
49
+ local_cid_generator : Option < Arc < dyn ConnectionIdGenerator > > ,
48
50
config : Arc < EndpointConfig > ,
49
51
server_config : Option < Arc < ServerConfig > > ,
50
52
/// Whether the underlying UDP socket promises not to fragment packets
@@ -144,7 +146,10 @@ impl Endpoint {
144
146
let datagram_len = data. len ( ) ;
145
147
let ( first_decode, remaining) = match PartialDecode :: new (
146
148
data,
147
- & * self . local_cid_generator ,
149
+ self . local_cid_generator . as_ref ( ) . map_or (
150
+ & ZeroLengthConnectionIdGenerator as & dyn ConnectionIdGenerator ,
151
+ |x| & * * x,
152
+ ) ,
148
153
& self . config . supported_versions ,
149
154
self . config . grease_quic_bit ,
150
155
) {
@@ -302,8 +307,8 @@ impl Endpoint {
302
307
if !first_decode. is_initial ( )
303
308
&& self
304
309
. 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 ( ) )
307
312
{
308
313
debug ! ( "dropping packet with invalid CID" ) ;
309
314
return None ;
@@ -400,7 +405,7 @@ impl Endpoint {
400
405
let params = TransportParameters :: new (
401
406
& config. transport ,
402
407
& self . config ,
403
- self . local_cid_generator . as_ref ( ) ,
408
+ self . local_cid_generator . is_some ( ) ,
404
409
loc_cid,
405
410
None ,
406
411
) ;
@@ -453,12 +458,11 @@ impl Endpoint {
453
458
/// Generate a connection ID for `ch`
454
459
fn new_cid ( & mut self , ch : ConnectionHandle ) -> ConnectionId {
455
460
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 {
458
462
// 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 ( ) ;
462
466
if let hash_map:: Entry :: Vacant ( e) = self . index . connection_ids . entry ( cid) {
463
467
e. insert ( ch) ;
464
468
break cid;
@@ -589,7 +593,7 @@ impl Endpoint {
589
593
let mut params = TransportParameters :: new (
590
594
& server_config. transport ,
591
595
& self . config ,
592
- self . local_cid_generator . as_ref ( ) ,
596
+ self . local_cid_generator . is_some ( ) ,
593
597
loc_cid,
594
598
Some ( & server_config) ,
595
599
) ;
@@ -680,10 +684,7 @@ impl Endpoint {
680
684
// bytes. If this is a Retry packet, then the length must instead match our usual CID
681
685
// length. If we ever issue non-Retry address validation tokens via `NEW_TOKEN`, then we'll
682
686
// 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 ( ) {
687
688
debug ! (
688
689
"rejecting connection due to invalid DCID length {}" ,
689
690
header. dst_cid. len( )
@@ -730,7 +731,10 @@ impl Endpoint {
730
731
// with established connections. In the unlikely event that a collision occurs
731
732
// between two connections in the initial phase, both will fail fast and may be
732
733
// 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 ( ) ) ;
734
738
735
739
let token = RetryToken {
736
740
orig_dst_cid : incoming. packet . header . dst_cid ,
@@ -860,7 +864,10 @@ impl Endpoint {
860
864
// We don't need to worry about CID collisions in initial closes because the peer
861
865
// shouldn't respond, and if it does, and the CID collides, we'll just drop the
862
866
// 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 ( ) ) ;
864
871
let number = PacketNumber :: U8 ( 0 ) ;
865
872
let header = Header :: Initial ( InitialHeader {
866
873
dst_cid : * remote_id,
0 commit comments