@@ -220,9 +220,6 @@ impl ForwardPlugin {
220220
221221 last_error = Some ( e) ;
222222 attempts += 1 ;
223- if !self . core . health_checks_enabled {
224- break ;
225- }
226223 }
227224 }
228225 }
@@ -436,6 +433,52 @@ mod tests {
436433 assert_eq ! ( answer. to_string( ) , "9.9.9.9" ) ;
437434 }
438435
436+ #[ tokio:: test]
437+ async fn test_sequential_failover_without_health_checks ( ) {
438+ // health checks off (the default): a dead first upstream must not
439+ // stop the backup upstream from being tried
440+ let black_hole = UdpSocket :: bind ( "127.0.0.1:0" ) . await . unwrap ( ) ;
441+ let dead = black_hole. local_addr ( ) . unwrap ( ) . to_string ( ) ;
442+ tokio:: spawn ( async move {
443+ // swallow queries forever
444+ let mut buf = vec ! [ 0u8 ; 4096 ] ;
445+ loop {
446+ if black_hole. recv_from ( & mut buf) . await . is_err ( ) {
447+ break ;
448+ }
449+ }
450+ } ) ;
451+
452+ let alive = spawn_udp_upstream ( "9.9.9.9" , None ) . await ;
453+ let core = Forward :: new (
454+ vec ! [ Upstream :: new( dead) , Upstream :: new( alive) ] ,
455+ Duration :: from_millis ( 300 ) ,
456+ LoadBalanceStrategy :: RoundRobin ,
457+ ) ;
458+ let plugin = ForwardPlugin {
459+ core,
460+ current : AtomicUsize :: new ( 0 ) ,
461+ concurrent_queries : false ,
462+ tag : None ,
463+ } ;
464+
465+ let mut req = Message :: new ( ) ;
466+ req. set_id ( 0x4242 ) ;
467+ req. add_question ( Question :: new (
468+ "failover.example.com" ,
469+ RecordType :: A ,
470+ RecordClass :: IN ,
471+ ) ) ;
472+
473+ let mut ctx = Context :: new ( req) ;
474+ plugin
475+ . execute ( & mut ctx)
476+ . await
477+ . expect ( "backup upstream should answer" ) ;
478+ let response = ctx. response ( ) . expect ( "response set" ) ;
479+ assert_eq ! ( response. id( ) , 0x4242 ) ;
480+ }
481+
439482 #[ tokio:: test]
440483 async fn test_forward_udp_times_out_when_no_response ( ) {
441484 let black_hole = UdpSocket :: bind ( "127.0.0.1:0" ) . await . unwrap ( ) ;
0 commit comments