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

Commit

Permalink
Merge pull request #54 from ferrous-systems/ja-ds-query
Browse files Browse the repository at this point in the history
resolver: test that DS query is sent to parent zone
  • Loading branch information
japaric authored May 22, 2024
2 parents 3a54e69 + 261b9f4 commit b3b2143
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 6 deletions.
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

0 comments on commit b3b2143

Please sign in to comment.