@@ -462,59 +462,8 @@ impl Connection {
462462 let mut datagram_start = 0 ;
463463 let mut segment_size = usize:: from ( self . path . current_mtu ( ) ) ;
464464
465- // Send PATH_CHALLENGE for a previous path if necessary
466- if let Some ( ( prev_cid, ref mut prev_path) ) = self . prev_path {
467- if prev_path. challenge_pending {
468- prev_path. challenge_pending = false ;
469- let token = prev_path
470- . challenge
471- . expect ( "previous path challenge pending without token" ) ;
472- let destination = prev_path. remote ;
473- debug_assert_eq ! (
474- self . highest_space,
475- SpaceId :: Data ,
476- "PATH_CHALLENGE queued without 1-RTT keys"
477- ) ;
478- buf. reserve ( MIN_INITIAL_SIZE as usize ) ;
479-
480- let buf_capacity = buf. capacity ( ) ;
481-
482- // Use the previous CID to avoid linking the new path with the previous path. We
483- // don't bother accounting for possible retirement of that prev_cid because this is
484- // sent once, immediately after migration, when the CID is known to be valid. Even
485- // if a post-migration packet caused the CID to be retired, it's fair to pretend
486- // this is sent first.
487- let mut builder = PacketBuilder :: new (
488- now,
489- SpaceId :: Data ,
490- prev_cid,
491- buf,
492- buf_capacity,
493- 0 ,
494- false ,
495- self ,
496- ) ?;
497- trace ! ( "validating previous path with PATH_CHALLENGE {:08x}" , token) ;
498- buf. write ( frame:: FrameType :: PATH_CHALLENGE ) ;
499- buf. write ( token) ;
500- self . stats . frame_tx . path_challenge += 1 ;
501-
502- // An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame
503- // to at least the smallest allowed maximum datagram size of 1200 bytes,
504- // unless the anti-amplification limit for the path does not permit
505- // sending a datagram of this size
506- builder. pad_to ( MIN_INITIAL_SIZE ) ;
507-
508- builder. finish ( self , buf) ;
509- self . stats . udp_tx . on_sent ( 1 , buf. len ( ) ) ;
510- return Some ( Transmit {
511- destination,
512- size : buf. len ( ) ,
513- ecn : None ,
514- segment_size : None ,
515- src_ip : self . local_ip ,
516- } ) ;
517- }
465+ if let Some ( challenge) = self . send_path_challenge ( now, buf) {
466+ return Some ( challenge) ;
518467 }
519468
520469 // If we need to send a probe, make sure we have something to send.
@@ -1034,6 +983,64 @@ impl Connection {
1034983 } )
1035984 }
1036985
986+ /// Send PATH_CHALLENGE for a previous path if necessary
987+ fn send_path_challenge ( & mut self , now : Instant , buf : & mut Vec < u8 > ) -> Option < Transmit > {
988+ let ( prev_cid, prev_path) = self . prev_path . as_mut ( ) ?;
989+ if !prev_path. challenge_pending {
990+ return None ;
991+ }
992+ prev_path. challenge_pending = false ;
993+ let token = prev_path
994+ . challenge
995+ . expect ( "previous path challenge pending without token" ) ;
996+ let destination = prev_path. remote ;
997+ debug_assert_eq ! (
998+ self . highest_space,
999+ SpaceId :: Data ,
1000+ "PATH_CHALLENGE queued without 1-RTT keys"
1001+ ) ;
1002+ buf. reserve ( MIN_INITIAL_SIZE as usize ) ;
1003+
1004+ let buf_capacity = buf. capacity ( ) ;
1005+
1006+ // Use the previous CID to avoid linking the new path with the previous path. We
1007+ // don't bother accounting for possible retirement of that prev_cid because this is
1008+ // sent once, immediately after migration, when the CID is known to be valid. Even
1009+ // if a post-migration packet caused the CID to be retired, it's fair to pretend
1010+ // this is sent first.
1011+ let mut builder = PacketBuilder :: new (
1012+ now,
1013+ SpaceId :: Data ,
1014+ * prev_cid,
1015+ buf,
1016+ buf_capacity,
1017+ 0 ,
1018+ false ,
1019+ self ,
1020+ ) ?;
1021+ trace ! ( "validating previous path with PATH_CHALLENGE {:08x}" , token) ;
1022+ buf. write ( frame:: FrameType :: PATH_CHALLENGE ) ;
1023+ buf. write ( token) ;
1024+ self . stats . frame_tx . path_challenge += 1 ;
1025+
1026+ // An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame
1027+ // to at least the smallest allowed maximum datagram size of 1200 bytes,
1028+ // unless the anti-amplification limit for the path does not permit
1029+ // sending a datagram of this size
1030+ builder. pad_to ( MIN_INITIAL_SIZE ) ;
1031+
1032+ builder. finish ( self , buf) ;
1033+ self . stats . udp_tx . on_sent ( 1 , buf. len ( ) ) ;
1034+
1035+ Some ( Transmit {
1036+ destination,
1037+ size : buf. len ( ) ,
1038+ ecn : None ,
1039+ segment_size : None ,
1040+ src_ip : self . local_ip ,
1041+ } )
1042+ }
1043+
10371044 /// Indicate what types of frames are ready to send for the given space
10381045 fn space_can_send ( & self , space_id : SpaceId , frame_space_1rtt : usize ) -> SendableFrames {
10391046 if self . spaces [ space_id] . crypto . is_none ( )
0 commit comments