make dig
queries more configurable
switch from enum arguments like `Recurse` and `Dnssec` to a build-pattern-based `Settings` struct
This commit is contained in:
parent
df344e57b1
commit
b87ae21d2a
|
@ -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());
|
||||
|
||||
|
|
|
@ -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()?;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -53,16 +53,17 @@ impl Client {
|
|||
|
||||
pub fn dig(
|
||||
&self,
|
||||
recurse: Recurse,
|
||||
dnssec: Dnssec,
|
||||
settings: DigSettings,
|
||||
server: Ipv4Addr,
|
||||
record_type: RecordType,
|
||||
fqdn: &FQDN,
|
||||
) -> Result<DigOutput> {
|
||||
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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user