@@ -139,7 +139,15 @@ impl RequestHandler for Catalog {
139
139
MessageType :: Query => match request. op_code ( ) {
140
140
OpCode :: Query => {
141
141
debug ! ( "query received: {}" , request. id( ) ) ;
142
- let info = self . lookup ( request, response_edns, response_handle) . await ;
142
+ let info = self
143
+ . lookup ( request, response_edns, response_handle)
144
+ . await
145
+ . unwrap_or_else ( |e| match e {
146
+ LookupError :: ResponseCode ( code) => {
147
+ ResponseInfo :: response_code_error ( request. header ( ) . id ( ) , code)
148
+ }
149
+ _ => ResponseInfo :: unknown ( request. header ( ) . id ( ) ) ,
150
+ } ) ;
143
151
144
152
Ok ( info)
145
153
}
@@ -346,7 +354,7 @@ impl Catalog {
346
354
request : & Request ,
347
355
response_edns : Option < Edns > ,
348
356
response_handle : R ,
349
- ) -> ResponseInfo {
357
+ ) -> Result < ResponseInfo , LookupError > {
350
358
let request_info = request. request_info ( ) ;
351
359
let authority = self . find ( request_info. query . name ( ) ) ;
352
360
@@ -365,20 +373,18 @@ impl Catalog {
365
373
// if this is empty then the there are no authorities registered that can handle the request
366
374
let response = MessageResponseBuilder :: new ( Some ( request. raw_query ( ) ) ) ;
367
375
368
- let result = send_response (
376
+ send_response (
369
377
response_edns,
370
378
response. error_msg ( request. header ( ) , ResponseCode :: Refused ) ,
371
379
response_handle,
372
380
)
373
- . await ;
381
+ . await
382
+ . map_err ( |e| {
383
+ debug ! ( "failed to send response: {}" , e) ;
384
+ LookupError :: Io ( e)
385
+ } ) ?;
374
386
375
- match result {
376
- Err ( e) => {
377
- debug ! ( "failed to send response: {}" , e) ;
378
- ResponseInfo :: serve_failed ( )
379
- }
380
- Ok ( r) => r,
381
- }
387
+ Err ( LookupError :: ResponseCode ( ResponseCode :: Refused ) )
382
388
}
383
389
}
384
390
@@ -405,7 +411,7 @@ async fn lookup<'a, R: ResponseHandler + Unpin>(
405
411
request : & Request ,
406
412
response_edns : Option < Edns > ,
407
413
response_handle : R ,
408
- ) -> ResponseInfo {
414
+ ) -> Result < ResponseInfo , LookupError > {
409
415
let query = request_info. query ;
410
416
debug ! (
411
417
"request: {} found authority: {}" ,
@@ -421,7 +427,7 @@ async fn lookup<'a, R: ResponseHandler + Unpin>(
421
427
query,
422
428
request. edns ( ) ,
423
429
)
424
- . await ;
430
+ . await ? ;
425
431
426
432
let response = MessageResponseBuilder :: new ( Some ( request. raw_query ( ) ) ) . build (
427
433
response_header,
@@ -431,15 +437,12 @@ async fn lookup<'a, R: ResponseHandler + Unpin>(
431
437
sections. additionals . iter ( ) ,
432
438
) ;
433
439
434
- let result = send_response ( response_edns. clone ( ) , response, response_handle. clone ( ) ) . await ;
435
-
436
- match result {
437
- Err ( e) => {
438
- debug ! ( "error sending response: {}" , e) ;
439
- ResponseInfo :: serve_failed ( )
440
- }
441
- Ok ( i) => i,
442
- }
440
+ send_response ( response_edns. clone ( ) , response, response_handle. clone ( ) )
441
+ . await
442
+ . map_err ( |e| {
443
+ debug ! ( "failed to send response: {}" , e) ;
444
+ LookupError :: Io ( e)
445
+ } )
443
446
}
444
447
445
448
#[ allow( unused_variables) ]
@@ -473,7 +476,7 @@ async fn build_response(
473
476
request_header : & Header ,
474
477
query : & LowerQuery ,
475
478
edns : Option < & Edns > ,
476
- ) -> ( Header , LookupSections ) {
479
+ ) -> Result < ( Header , LookupSections ) , LookupError > {
477
480
let lookup_options = lookup_options_for_edns ( edns) ;
478
481
479
482
// log algorithms being requested
@@ -501,14 +504,14 @@ async fn build_response(
501
504
request_id,
502
505
query,
503
506
)
504
- . await
507
+ . await ?
505
508
}
506
509
ZoneType :: Forward | ZoneType :: Hint => {
507
- send_forwarded_response ( future, request_header, & mut response_header) . await
510
+ send_forwarded_response ( future, request_header, & mut response_header) . await ?
508
511
}
509
512
} ;
510
513
511
- ( response_header, sections)
514
+ Ok ( ( response_header, sections) )
512
515
}
513
516
514
517
async fn send_authoritative_response (
@@ -518,7 +521,7 @@ async fn send_authoritative_response(
518
521
lookup_options : LookupOptions ,
519
522
request_id : u16 ,
520
523
query : & LowerQuery ,
521
- ) -> LookupSections {
524
+ ) -> Result < LookupSections , LookupError > {
522
525
// In this state we await the records, on success we transition to getting
523
526
// NS records, which indicate an authoritative response.
524
527
//
@@ -533,12 +536,12 @@ async fn send_authoritative_response(
533
536
// TODO: there are probably other error cases that should just drop through (FormErr, ServFail)
534
537
Err ( LookupError :: ResponseCode ( ResponseCode :: Refused ) ) => {
535
538
response_header. set_response_code ( ResponseCode :: Refused ) ;
536
- return LookupSections {
537
- answers : Box :: new ( AuthLookup :: default ( ) ) as Box < dyn LookupObject > ,
538
- ns : Box :: new ( AuthLookup :: default ( ) ) as Box < dyn LookupObject > ,
539
- soa : Box :: new ( AuthLookup :: default ( ) ) as Box < dyn LookupObject > ,
540
- additionals : Box :: new ( AuthLookup :: default ( ) ) as Box < dyn LookupObject > ,
541
- } ;
539
+ return Ok ( LookupSections {
540
+ answers : Box :: < AuthLookup > :: default ( ) ,
541
+ ns : Box :: < AuthLookup > :: default ( ) ,
542
+ soa : Box :: < AuthLookup > :: default ( ) ,
543
+ additionals : Box :: < AuthLookup > :: default ( ) ,
544
+ } ) ;
542
545
}
543
546
Err ( e) => {
544
547
if e. is_nx_domain ( ) {
@@ -607,19 +610,19 @@ async fn send_authoritative_response(
607
610
) ,
608
611
} ;
609
612
610
- LookupSections {
613
+ Ok ( LookupSections {
611
614
answers,
612
615
ns : ns. unwrap_or_else ( || Box :: new ( AuthLookup :: default ( ) ) as Box < dyn LookupObject > ) ,
613
616
soa : soa. unwrap_or_else ( || Box :: new ( AuthLookup :: default ( ) ) as Box < dyn LookupObject > ) ,
614
617
additionals,
615
- }
618
+ } )
616
619
}
617
620
618
621
async fn send_forwarded_response (
619
622
future : impl Future < Output = Result < Box < dyn LookupObject > , LookupError > > ,
620
623
request_header : & Header ,
621
624
response_header : & mut Header ,
622
- ) -> LookupSections {
625
+ ) -> Result < LookupSections , LookupError > {
623
626
response_header. set_recursion_available ( true ) ;
624
627
response_header. set_authoritative ( false ) ;
625
628
@@ -634,26 +637,31 @@ async fn send_forwarded_response(
634
637
request_header. id( )
635
638
) ;
636
639
637
- Box :: new ( EmptyLookup )
640
+ return Err ( LookupError :: ResponseCode ( ResponseCode :: Refused ) ) ;
638
641
} else {
639
642
match future. await {
640
643
Err ( e) => {
644
+ debug ! ( "error resolving: {}" , e) ;
645
+ if e. is_io ( ) || e. is_unknown ( ) {
646
+ return Err ( e) ;
647
+ }
648
+
649
+ // If the server responds with NXDomain we want to copy this behavior
641
650
if e. is_nx_domain ( ) {
642
651
response_header. set_response_code ( ResponseCode :: NXDomain ) ;
643
652
}
644
- debug ! ( "error resolving: {}" , e) ;
645
653
Box :: new ( EmptyLookup )
646
654
}
647
655
Ok ( rsp) => rsp,
648
656
}
649
657
} ;
650
658
651
- LookupSections {
659
+ Ok ( LookupSections {
652
660
answers,
653
- ns : Box :: new ( AuthLookup :: default ( ) ) as Box < dyn LookupObject > ,
654
- soa : Box :: new ( AuthLookup :: default ( ) ) as Box < dyn LookupObject > ,
655
- additionals : Box :: new ( AuthLookup :: default ( ) ) as Box < dyn LookupObject > ,
656
- }
661
+ ns : Box :: < AuthLookup > :: default ( ) ,
662
+ soa : Box :: < AuthLookup > :: default ( ) ,
663
+ additionals : Box :: < AuthLookup > :: default ( ) ,
664
+ } )
657
665
}
658
666
659
667
struct LookupSections {
0 commit comments