@@ -324,24 +324,25 @@ impl Endpoint {
324324 let mut msgs = Vec :: new ( ) ;
325325 let ( udp_addr, derp_region, _should_ping) = self . addr_for_send ( & now) ;
326326 if let Some ( derp_region) = derp_region {
327- // TODO(@divma):: this is cli_ping, never used. Intentionally commented out
328- // if let Some(msg) = self.start_ping(SendAddr::Derp(derp_region), DiscoPingPurpose::Cli) {
329- // msgs.push(msg);
330- // }
327+ if let Some ( msg) = self . start_ping ( SendAddr :: Derp ( derp_region) , DiscoPingPurpose :: Cli ) {
328+ msgs. push ( msg) ;
329+ }
331330 }
332331 if let Some ( udp_addr) = udp_addr {
333332 if self . is_best_addr_valid ( now) {
334333 // Already have an active session, so just ping the address we're using.
335334 // Otherwise "tailscale ping" results to a node on the local network
336335 // can look like they're bouncing between, say 10.0.0.0/9 and the peer's
337336 // IPv6 address, both 1ms away, and it's random who replies first.
338- if let Some ( msg) = self . start_ping ( udp_addr . into ( ) , DiscoPingPurpose :: Cli ) {
337+ if let Some ( msg) = self . start_ping ( SendAddr :: Udp ( udp_addr ) , DiscoPingPurpose :: Cli ) {
339338 msgs. push ( msg) ;
340339 }
341340 } else {
342341 let eps: Vec < _ > = self . direct_addr_state . keys ( ) . cloned ( ) . collect ( ) ;
343342 for ep in eps {
344- if let Some ( msg) = self . start_ping ( ep, DiscoPingPurpose :: Cli ) {
343+ if let Some ( msg) =
344+ self . start_ping ( SendAddr :: Udp ( ep. into ( ) ) , DiscoPingPurpose :: Cli )
345+ {
345346 msgs. push ( msg) ;
346347 }
347348 }
@@ -400,18 +401,17 @@ impl Endpoint {
400401 }
401402 }
402403
403- // TODO(@divma): intentionally changed to prove we don't ping via relay.
404- fn start_ping ( & mut self , ip_port : IpPort , purpose : DiscoPingPurpose ) -> Option < PingAction > {
405- if derp_only_mode ( ) {
404+ fn start_ping ( & mut self , dst : SendAddr , purpose : DiscoPingPurpose ) -> Option < PingAction > {
405+ if derp_only_mode ( ) && !dst. is_derp ( ) {
406406 // don't attempt any hole punching in derp only mode
407407 warn ! ( "in `DEV_DERP_ONLY` mode, ignoring request to start a hole punching attempt." ) ;
408408 return None ;
409409 }
410- info ! ( "start ping to {}: {:?}" , ip_port , purpose) ;
410+ info ! ( "start ping to {}: {:?}" , dst , purpose) ;
411411 let tx_id = stun:: TransactionId :: default ( ) ;
412412 Some ( PingAction :: SendPing {
413413 id : self . id ,
414- dst : SendAddr :: Udp ( ip_port . into ( ) ) ,
414+ dst,
415415 dst_key : self . public_key ,
416416 tx_id,
417417 purpose,
@@ -477,6 +477,17 @@ impl Endpoint {
477477
478478 fn send_pings ( & mut self , now : Instant , send_call_me_maybe : bool ) -> Vec < PingAction > {
479479 let mut msgs = Vec :: new ( ) ;
480+
481+ if let Some ( ( region, state) ) = self . derp_region . as_ref ( ) {
482+ if state. needs_ping ( & now) {
483+ if let Some ( msg) =
484+ self . start_ping ( SendAddr :: Derp ( * region) , DiscoPingPurpose :: Discovery )
485+ {
486+ msgs. push ( msg)
487+ }
488+ }
489+ }
490+
480491 if derp_only_mode ( ) {
481492 // don't send or respond to any hole punching pings if we are in
482493 // derp only mode
@@ -511,7 +522,9 @@ impl Endpoint {
511522 debug ! ( "disco: send, starting discovery for {:?}" , self . public_key) ;
512523 }
513524
514- if let Some ( msg) = self . start_ping ( ep, DiscoPingPurpose :: Discovery ) {
525+ if let Some ( msg) =
526+ self . start_ping ( SendAddr :: Udp ( ep. into ( ) ) , DiscoPingPurpose :: Discovery )
527+ {
515528 msgs. push ( msg) ;
516529 }
517530 }
@@ -725,24 +738,43 @@ impl Endpoint {
725738 let now = Instant :: now ( ) ;
726739 let latency = now - sp. at ;
727740
728- if let SendAddr :: Udp ( addr) = src {
729- let key = self . public_key ;
730- match self . direct_addr_state . get_mut ( & addr. into ( ) ) {
731- None => {
732- info ! ( "disco: ignoring pong: {}" , sp. to) ;
733- // This is no longer an endpoint we care about.
734- return peer_map_insert;
741+ match src {
742+ SendAddr :: Udp ( addr) => {
743+ let key = self . public_key ;
744+ match self . direct_addr_state . get_mut ( & addr. into ( ) ) {
745+ None => {
746+ info ! ( "disco: ignoring pong: {}" , sp. to) ;
747+ // This is no longer an endpoint we care about.
748+ return peer_map_insert;
749+ }
750+ Some ( st) => {
751+ peer_map_insert = Some ( ( addr, key) ) ;
752+ st. add_pong_reply ( PongReply {
753+ latency,
754+ pong_at : now,
755+ from : src,
756+ pong_src : m. src ,
757+ } ) ;
758+ }
735759 }
736- Some ( st) => {
737- peer_map_insert = Some ( ( addr, key) ) ;
738- st. add_pong_reply ( PongReply {
760+ }
761+ SendAddr :: Derp ( region) => match self . derp_region . as_mut ( ) {
762+ Some ( ( home_region, state) ) if * home_region == region => {
763+ state. add_pong_reply ( PongReply {
739764 latency,
740765 pong_at : now,
741766 from : src,
742767 pong_src : m. src ,
743768 } ) ;
744769 }
745- }
770+ other => {
771+ // if we are here then we sent this ping, but the region changed
772+ // waiting for the response. It was either set to None or changed to
773+ // another region. This should either never happen or be extremely
774+ // unlikely. Log and ignore for now
775+ warn ! ( stored=?other, received=?region, "disco: ignoring pong via derp for region different to last one stored" ) ;
776+ }
777+ } ,
746778 }
747779
748780 info ! (
@@ -950,7 +982,9 @@ impl Endpoint {
950982 "stayin alive ping for {}: {:?} {:?}" ,
951983 udp_addr, elapsed, now
952984 ) ;
953- if let Some ( msg) = self . start_ping ( udp_addr. into ( ) , DiscoPingPurpose :: StayinAlive ) {
985+ if let Some ( msg) =
986+ self . start_ping ( SendAddr :: Udp ( udp_addr) , DiscoPingPurpose :: StayinAlive )
987+ {
954988 return vec ! [ msg] ;
955989 }
956990 }
0 commit comments