diff --git a/tests/integration-tests/tests/recursor_tests.rs b/tests/integration-tests/tests/recursor_tests.rs index 06ed338a..1fee7891 100644 --- a/tests/integration-tests/tests/recursor_tests.rs +++ b/tests/integration-tests/tests/recursor_tests.rs @@ -24,12 +24,13 @@ use hickory_client::op::{Message, MessageType, Query}; use hickory_client::rr::{rdata, Name, RData, Record, RecordType}; use hickory_integration::mock_client::*; use hickory_proto::DnsHandle; -use hickory_proto::error::ProtoError; +use hickory_proto::error::{ProtoError, ProtoErrorKind}; use hickory_proto::rr::LowerName; use hickory_proto::serialize::txt::Parser; use hickory_proto::xfer::{DnsRequest, DnsResponse}; use hickory_recursor::{ErrorKind, Recursor}; use hickory_resolver::config::*; +use hickory_resolver::error::ResolveErrorKind; use hickory_resolver::name_server::ConnectionProvider; use hickory_resolver::name_server::{NameServer, NameServerPool}; use hickory_server::authority::{Catalog, LookupError, LookupOptions, ZoneType}; @@ -107,6 +108,7 @@ example-org-cname.example.com. CNAME example.org. inline-org-cname.example.com. CNAME inline.org. double-cname.sub.example.com. CNAME inline-org-cname.example.org. cycle-a.example.com. CNAME cycle-b.org. +intractable-cname.example.com. CNAME nonexistent.org. "#; const ZONE_ORG: &str = r#" @@ -604,3 +606,30 @@ fn test_cname_cycle() { assert!(matches!(lookup_err.kind(), ErrorKind::Timeout)); } + +/// Test that the recursor responds with an error when following CNAMEs to non-existent records, +/// rather than (for example) returning partial results. +#[test] +fn test_cname_to_nonexistent_record() { + logger("DEBUG"); + + let query = Query::query(Name::from_str("intractable-cname.example.com.").unwrap(), RecordType::A); + + let roots = NameServerPool::from_nameservers( + Default::default(), + vec![mock_nameserver(NS_ROOT)], + vec![], + ); + let recursor = Recursor::new_with_pool(roots, 1024, 1048576).unwrap(); + + let now = Instant::now(); + let lookup_err = block_on(recursor.resolve(query, now)).unwrap_err(); + + assert!(matches!(lookup_err.kind(), + ErrorKind::Resolve(resolve_error) if matches!(resolve_error.kind(), + ResolveErrorKind::Proto(proto_error) if matches!(proto_error.kind(), + ProtoErrorKind::NoRecordsFound { .. } + ) + ) + )); +}