diff --git a/packages/conformance-tests/src/resolver/dns/scenarios.rs b/packages/conformance-tests/src/resolver/dns/scenarios.rs index f696691a..39470b83 100644 --- a/packages/conformance-tests/src/resolver/dns/scenarios.rs +++ b/packages/conformance-tests/src/resolver/dns/scenarios.rs @@ -1,6 +1,6 @@ use std::net::Ipv4Addr; -use dns_test::client::{Client, Dnssec, Recurse}; +use dns_test::client::{Client, DigSettings}; use dns_test::name_server::NameServer; use dns_test::record::{Record, RecordType}; use dns_test::zone_file::Root; @@ -44,13 +44,9 @@ fn can_resolve() -> Result<()> { let resolver_ip_addr = resolver.ipv4_addr(); let client = Client::new(&network)?; - let output = client.dig( - Recurse::Yes, - Dnssec::No, - resolver_ip_addr, - RecordType::A, - &needle_fqdn, - )?; + + let settings = *DigSettings::default().recurse(); + let output = client.dig(settings, resolver_ip_addr, RecordType::A, &needle_fqdn)?; assert!(output.status.is_noerror()); @@ -94,13 +90,8 @@ fn nxdomain() -> Result<()> { let resolver_ip_addr = resolver.ipv4_addr(); let client = Client::new(&network)?; - let output = client.dig( - Recurse::Yes, - Dnssec::No, - resolver_ip_addr, - RecordType::A, - &needle_fqdn, - )?; + let settings = *DigSettings::default().recurse(); + let output = client.dig(settings, resolver_ip_addr, RecordType::A, &needle_fqdn)?; assert!(dbg!(output).status.is_nxdomain()); diff --git a/packages/conformance-tests/src/resolver/dnssec/rfc4035/section_4/section_4_1.rs b/packages/conformance-tests/src/resolver/dnssec/rfc4035/section_4/section_4_1.rs index 9772e309..233ea95c 100644 --- a/packages/conformance-tests/src/resolver/dnssec/rfc4035/section_4/section_4_1.rs +++ b/packages/conformance-tests/src/resolver/dnssec/rfc4035/section_4/section_4_1.rs @@ -1,4 +1,4 @@ -use dns_test::client::{Client, Dnssec, Recurse}; +use dns_test::client::{Client, DigSettings}; use dns_test::name_server::NameServer; use dns_test::record::RecordType; use dns_test::tshark::{Capture, Direction}; @@ -20,13 +20,8 @@ fn edns_support() -> Result<()> { let mut tshark = resolver.eavesdrop()?; let client = Client::new(network)?; - let ans = client.dig( - Recurse::Yes, - Dnssec::Yes, - resolver.ipv4_addr(), - RecordType::SOA, - &FQDN::ROOT, - )?; + let settings = *DigSettings::default().authentic_data().recurse(); + let ans = client.dig(settings, resolver.ipv4_addr(), RecordType::SOA, &FQDN::ROOT)?; assert!(ans.status.is_servfail()); tshark.wait_for_capture()?; diff --git a/packages/conformance-tests/src/resolver/dnssec/scenarios/secure.rs b/packages/conformance-tests/src/resolver/dnssec/scenarios/secure.rs index 7ae7e3cc..b3571ce2 100644 --- a/packages/conformance-tests/src/resolver/dnssec/scenarios/secure.rs +++ b/packages/conformance-tests/src/resolver/dnssec/scenarios/secure.rs @@ -1,6 +1,6 @@ use std::net::Ipv4Addr; -use dns_test::client::{Client, Dnssec, Recurse}; +use dns_test::client::{Client, DigSettings}; use dns_test::name_server::NameServer; use dns_test::record::{Record, RecordType}; use dns_test::zone_file::Root; @@ -31,13 +31,8 @@ fn can_validate_without_delegation() -> Result<()> { let resolver_addr = resolver.ipv4_addr(); let client = Client::new(&network)?; - let output = client.dig( - Recurse::Yes, - Dnssec::Yes, - resolver_addr, - RecordType::SOA, - &FQDN::ROOT, - )?; + let settings = *DigSettings::default().recurse().authentic_data(); + let output = client.dig(settings, resolver_addr, RecordType::SOA, &FQDN::ROOT)?; assert!(output.status.is_noerror()); assert!(output.flags.authenticated_data); @@ -103,19 +98,14 @@ fn can_validate_with_delegation() -> Result<()> { let resolver_addr = resolver.ipv4_addr(); let client = Client::new(&network)?; - let output = client.dig( - Recurse::Yes, - Dnssec::Yes, - resolver_addr, - RecordType::A, - &needle_fqdn, - )?; + let settings = *DigSettings::default().recurse().authentic_data(); + let output = client.dig(settings, resolver_addr, RecordType::A, &needle_fqdn)?; assert!(output.status.is_noerror()); assert!(output.flags.authenticated_data); - let [a, _rrsig] = output.answer.try_into().unwrap(); + let [a] = output.answer.try_into().unwrap(); let a = a.try_into_a().unwrap(); assert_eq!(needle_fqdn, a.fqdn); diff --git a/packages/dns-test/src/client.rs b/packages/dns-test/src/client.rs index 484fb2c7..85e99eb1 100644 --- a/packages/dns-test/src/client.rs +++ b/packages/dns-test/src/client.rs @@ -53,16 +53,17 @@ impl Client { pub fn dig( &self, - recurse: Recurse, - dnssec: Dnssec, + settings: DigSettings, server: Ipv4Addr, record_type: RecordType, fqdn: &FQDN, ) -> Result { let output = self.inner.stdout(&[ "dig", - recurse.as_str(), - dnssec.as_str(), + settings.rdflag(), + settings.do_bit(), + settings.adflag(), + settings.cdflag(), &format!("@{server}"), record_type.as_str(), fqdn.as_str(), @@ -72,32 +73,68 @@ impl Client { } } -#[derive(Clone, Copy)] -pub enum Dnssec { - Yes, - No, +#[derive(Clone, Copy, Default)] +pub struct DigSettings { + adflag: bool, + cdflag: bool, + dnssec: bool, + recurse: bool, } -impl Dnssec { - fn as_str(&self) -> &'static str { - match self { - Self::Yes => "+dnssec", - Self::No => "+nodnssec", +impl DigSettings { + /// Sets the AD bit in the query + pub fn authentic_data(&mut self) -> &mut Self { + self.adflag = true; + self + } + + fn adflag(&self) -> &'static str { + if self.adflag { + "+adflag" + } else { + "+noadflag" } } -} -#[derive(Clone, Copy)] -pub enum Recurse { - Yes, - No, -} + /// Sets the CD bit in the query + pub fn checking_disabled(&mut self) -> &mut Self { + self.cdflag = true; + self + } -impl Recurse { - fn as_str(&self) -> &'static str { - match self { - Self::Yes => "+recurse", - Self::No => "+norecurse", + fn cdflag(&self) -> &'static str { + if self.cdflag { + "+cdflag" + } else { + "+nocdflag" + } + } + + /// Sets the DO bit in the query + pub fn dnssec(&mut self) -> &mut Self { + self.dnssec = true; + self + } + + fn do_bit(&self) -> &'static str { + if self.dnssec { + "+dnssec" + } else { + "+nodnssec" + } + } + + /// Sets the RD bit in the query + pub fn recurse(&mut self) -> &mut Self { + self.recurse = true; + self + } + + fn rdflag(&self) -> &'static str { + if self.recurse { + "+recurse" + } else { + "+norecurse" } } } @@ -184,11 +221,12 @@ impl FromStr for DigOutput { #[derive(Debug, Default, PartialEq)] pub struct DigFlags { - pub qr: bool, - pub recursion_desired: bool, - pub recursion_available: bool, - pub authoritative_answer: bool, pub authenticated_data: bool, + pub authoritative_answer: bool, + pub checking_disabled: bool, + pub qr: bool, + pub recursion_available: bool, + pub recursion_desired: bool, } impl FromStr for DigFlags { @@ -200,6 +238,7 @@ impl FromStr for DigFlags { let mut recursion_available = false; let mut authoritative_answer = false; let mut authenticated_data = false; + let mut checking_disabled = false; for flag in input.split_whitespace() { match flag { @@ -208,16 +247,18 @@ impl FromStr for DigFlags { "ra" => recursion_available = true, "aa" => authoritative_answer = true, "ad" => authenticated_data = true, + "cd" => checking_disabled = true, _ => return Err(format!("unknown flag: {flag}").into()), } } Ok(Self { - qr, - recursion_desired, - recursion_available, - authoritative_answer, authenticated_data, + authoritative_answer, + checking_disabled, + qr, + recursion_available, + recursion_desired, }) } } diff --git a/packages/dns-test/src/name_server.rs b/packages/dns-test/src/name_server.rs index 449ff210..5015ab74 100644 --- a/packages/dns-test/src/name_server.rs +++ b/packages/dns-test/src/name_server.rs @@ -295,7 +295,7 @@ fn nsd_conf(fqdn: &FQDN) -> String { #[cfg(test)] mod tests { - use crate::client::{Client, Dnssec, Recurse}; + use crate::client::{Client, DigSettings}; use crate::record::RecordType; use super::*; @@ -307,13 +307,7 @@ mod tests { let ip_addr = tld_ns.ipv4_addr(); let client = Client::new(&network)?; - let output = client.dig( - Recurse::No, - Dnssec::No, - ip_addr, - RecordType::SOA, - &FQDN::COM, - )?; + let output = client.dig(DigSettings::default(), ip_addr, RecordType::SOA, &FQDN::COM)?; assert!(output.status.is_noerror()); @@ -338,8 +332,7 @@ mod tests { let client = Client::new(&network)?; let output = client.dig( - Recurse::No, - Dnssec::No, + DigSettings::default(), ipv4_addr, RecordType::NS, &FQDN::COM, @@ -364,13 +357,8 @@ mod tests { let ns_addr = tld_ns.ipv4_addr(); let client = Client::new(&network)?; - let output = client.dig( - Recurse::No, - Dnssec::Yes, - ns_addr, - RecordType::SOA, - &FQDN::ROOT, - )?; + let settings = *DigSettings::default().dnssec(); + let output = client.dig(settings, ns_addr, RecordType::SOA, &FQDN::ROOT)?; assert!(output.status.is_noerror()); diff --git a/packages/dns-test/src/tshark.rs b/packages/dns-test/src/tshark.rs index ecc39740..0aef4397 100644 --- a/packages/dns-test/src/tshark.rs +++ b/packages/dns-test/src/tshark.rs @@ -244,7 +244,7 @@ struct Ip { #[cfg(test)] mod tests { - use crate::client::{Client, Dnssec, Recurse}; + use crate::client::{Client, DigSettings}; use crate::name_server::NameServer; use crate::record::{Record, RecordType}; use crate::zone_file::Root; @@ -260,8 +260,7 @@ mod tests { let client = Client::new(network)?; let resp = client.dig( - Recurse::No, - Dnssec::No, + DigSettings::default(), ns.ipv4_addr(), RecordType::SOA, &FQDN::ROOT, @@ -322,13 +321,8 @@ mod tests { let resolver_addr = resolver.ipv4_addr(); let client = Client::new(network)?; - let output = client.dig( - Recurse::Yes, - Dnssec::No, - dbg!(resolver_addr), - RecordType::A, - root_ns.fqdn(), - )?; + let settings = *DigSettings::default().recurse(); + let output = client.dig(settings, dbg!(resolver_addr), RecordType::A, root_ns.fqdn())?; assert!(output.status.is_noerror());