Skip to content
This repository has been archived by the owner on Jun 7, 2024. It is now read-only.

resolver: test that DS query is sent to parent zone #54

Merged
merged 2 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/conformance-tests/src/resolver/dnssec/rfc4035.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
mod section_3;
mod section_4;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod section_3_1;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod section_3_1_4;
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use dns_test::{
client::{Client, DigSettings},
name_server::{Graph, NameServer, Sign},
record::RecordType,
tshark::{Capture, Direction},
Network, Resolver, Result, FQDN,
};

#[test]
#[ignore]
fn on_clients_ds_query_it_queries_the_parent_zone() -> Result<()> {
let network = Network::new()?;

let leaf_ns = NameServer::new(&dns_test::PEER, FQDN::NAMESERVERS, &network)?;

let Graph {
nameservers,
root,
trust_anchor,
} = Graph::build(leaf_ns, Sign::Yes)?;

let mut com_ns_addr = None;
for nameserver in &nameservers {
if nameserver.zone() == &FQDN::COM {
com_ns_addr = Some(nameserver.ipv4_addr());
}
}
let com_ns_addr = com_ns_addr.expect("com. NS not found");

let trust_anchor = &trust_anchor.unwrap();
let resolver = Resolver::new(&network, root)
.trust_anchor(trust_anchor)
.start(&dns_test::SUBJECT)?;

let mut tshark = resolver.eavesdrop()?;

let resolver_addr = resolver.ipv4_addr();

let client = Client::new(&network)?;
let settings = *DigSettings::default().recurse();
let output = client.dig(settings, resolver_addr, RecordType::DS, &FQDN::NAMESERVERS)?;

tshark.wait_for_capture()?;

let captures = tshark.terminate()?;

// check that we were able to retrieve the DS record
assert!(output.status.is_noerror());
let [record] = output.answer.try_into().unwrap();
let ds = record.try_into_ds().unwrap();
assert_eq!(ds.zone, FQDN::NAMESERVERS);

// check that DS query was forwarded to the `com.` (parent zone) nameserver
let client_addr = client.ipv4_addr();
let mut outgoing_ds_query_count = 0;
for Capture { message, direction } in captures {
if let Direction::Outgoing { destination } = direction {
if destination != client_addr {
let queries = message.as_value()["Queries"]
.as_object()
.expect("expected Object");
for query in queries.keys() {
if query.contains("type DS") {
assert!(query.contains("nameservers.com"));
assert_eq!(com_ns_addr, destination);

outgoing_ds_query_count += 1;
}
}
}
}
}

assert_eq!(1, outgoing_ds_query_count);

Ok(())
}
20 changes: 14 additions & 6 deletions packages/dns-test/src/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ impl Record {
}
.into()
}

pub fn try_into_ds(self) -> CoreResult<DS, Self> {
if let Self::DS(v) = self {
Ok(v)
} else {
Err(self)
}
}
}

impl FromStr for Record {
Expand Down Expand Up @@ -327,12 +335,12 @@ impl fmt::Display for DNSKEY {

#[derive(Clone, Debug)]
pub struct DS {
zone: FQDN,
ttl: u32,
key_tag: u16,
algorithm: u8,
digest_type: u8,
digest: String,
pub zone: FQDN,
pub ttl: u32,
pub key_tag: u16,
pub algorithm: u8,
pub digest_type: u8,
pub digest: String,
}

impl FromStr for DS {
Expand Down
4 changes: 4 additions & 0 deletions packages/dns-test/src/tshark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ impl Message {
.ok()
}

pub fn as_value(&self) -> &serde_json::Value {
&self.inner
}

fn opt_record(&self) -> Option<&serde_json::Value> {
for (key, value) in self.inner.get("Additional records")?.as_object()? {
if key.ends_with(": type OPT") {
Expand Down