@@ -21,7 +21,7 @@ use crate::{
2121 cid_generator:: ConnectionIdGenerator ,
2222 cid_queue:: CidQueue ,
2323 coding:: { BufExt , BufMutExt , UnexpectedEnd } ,
24- config:: { EndpointConfig , ServerConfig , TransportConfig } ,
24+ config:: { EndpointConfig , Racenonce , ServerConfig , TransportConfig } ,
2525 connection:: PathId ,
2626 shared:: ConnectionId ,
2727} ;
@@ -118,6 +118,9 @@ macro_rules! make_struct {
118118
119119 // Multipath extension
120120 pub ( crate ) initial_max_path_id: Option <PathId >,
121+
122+ // Racenonce
123+ pub ( crate ) racenonce: Option <Racenonce >,
121124 }
122125
123126 // We deliberately don't implement the `Default` trait, since that would be public, and
@@ -143,6 +146,7 @@ macro_rules! make_struct {
143146 write_order: None ,
144147 address_discovery_role: address_discovery:: Role :: Disabled ,
145148 initial_max_path_id: None ,
149+ racenonce: None
146150 }
147151 }
148152 }
@@ -157,6 +161,7 @@ impl TransportParameters {
157161 endpoint_config : & EndpointConfig ,
158162 cid_gen : & dyn ConnectionIdGenerator ,
159163 initial_src_cid : ConnectionId ,
164+ racenonce : Option < Racenonce > ,
160165 server_config : Option < & ServerConfig > ,
161166 rng : & mut impl RngCore ,
162167 ) -> Self {
@@ -193,6 +198,7 @@ impl TransportParameters {
193198 address_discovery_role : config. address_discovery_role ,
194199 // TODO(@divma): TransportConfig or..?
195200 initial_max_path_id : config. initial_max_path_id . map ( PathId :: from) ,
201+ racenonce,
196202 ..Self :: default ( )
197203 }
198204 }
@@ -409,6 +415,13 @@ impl TransportParameters {
409415 w. write ( val) ;
410416 }
411417 }
418+ TransportParameterId :: Racenonce => {
419+ if let Some ( val) = self . racenonce {
420+ w. write_var ( id as u64 ) ;
421+ w. write_var ( val. len ( ) as u64 ) ;
422+ w. put_slice ( & val) ;
423+ }
424+ }
412425 id => {
413426 macro_rules! write_params {
414427 { $( $( #[ $doc: meta] ) * $name: ident ( $id: ident) = $default: expr, ) * } => {
@@ -535,6 +548,14 @@ impl TransportParameters {
535548 params. initial_max_path_id = Some ( value) ;
536549 tracing:: debug!( initial_max_path_id=%value, "multipath enabled" ) ;
537550 }
551+ TransportParameterId :: Racenonce => {
552+ if len != 32 || params. racenonce . is_some ( ) {
553+ return Err ( Error :: Malformed ) ;
554+ }
555+ let mut val = [ 0 ; 32 ] ;
556+ r. copy_to_slice ( & mut val) ;
557+ params. racenonce = Some ( val) ;
558+ }
538559 _ => {
539560 macro_rules! parse {
540561 { $( $( #[ $doc: meta] ) * $name: ident ( $id: ident) = $default: expr, ) * } => {
@@ -703,11 +724,13 @@ pub(crate) enum TransportParameterId {
703724
704725 // https://datatracker.ietf.org/doc/html/draft-ietf-quic-multipath
705726 InitialMaxPathId = 0x0f739bbc1b666d0c ,
727+
728+ Racenonce = 0x0f138193fac ,
706729}
707730
708731impl TransportParameterId {
709732 /// Array with all supported transport parameter IDs
710- const SUPPORTED : [ Self ; 23 ] = [
733+ const SUPPORTED : [ Self ; 24 ] = [
711734 Self :: MaxIdleTimeout ,
712735 Self :: MaxUdpPayloadSize ,
713736 Self :: InitialMaxData ,
@@ -731,6 +754,7 @@ impl TransportParameterId {
731754 Self :: MinAckDelayDraft07 ,
732755 Self :: ObservedAddr ,
733756 Self :: InitialMaxPathId ,
757+ Self :: Racenonce ,
734758 ] ;
735759}
736760
@@ -772,6 +796,7 @@ impl TryFrom<u64> for TransportParameterId {
772796 id if Self :: MinAckDelayDraft07 == id => Self :: MinAckDelayDraft07 ,
773797 id if Self :: ObservedAddr == id => Self :: ObservedAddr ,
774798 id if Self :: InitialMaxPathId == id => Self :: InitialMaxPathId ,
799+ id if Self :: Racenonce == id => Self :: Racenonce ,
775800 _ => return Err ( ( ) ) ,
776801 } ;
777802 Ok ( param)
@@ -812,6 +837,7 @@ mod test {
812837 min_ack_delay : Some ( 2_000u32 . into ( ) ) ,
813838 address_discovery_role : address_discovery:: Role :: SendOnly ,
814839 initial_max_path_id : Some ( PathId :: MAX ) ,
840+ racenonce : Some ( [ 42u8 ; 32 ] ) ,
815841 ..TransportParameters :: default ( )
816842 } ;
817843 params. write ( & mut buf) ;
0 commit comments