@@ -462,59 +462,8 @@ impl Connection {
462
462
let mut datagram_start = 0 ;
463
463
let mut segment_size = usize:: from ( self . path . current_mtu ( ) ) ;
464
464
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) ;
518
467
}
519
468
520
469
// If we need to send a probe, make sure we have something to send.
@@ -1034,6 +983,64 @@ impl Connection {
1034
983
} )
1035
984
}
1036
985
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
+
1037
1044
/// Indicate what types of frames are ready to send for the given space
1038
1045
fn space_can_send ( & self , space_id : SpaceId , frame_space_1rtt : usize ) -> SendableFrames {
1039
1046
if self . spaces [ space_id] . crypto . is_none ( )
0 commit comments