From dc7bb61ae04a643054606d8027301694df32b7c1 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 13:15:13 +0100 Subject: [PATCH 01/23] Add initial support for the ldns-testns command. --- src/commands/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 8d2a2114..1623fb6b 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -4,6 +4,7 @@ pub mod key2ds; pub mod keygen; pub mod notify; pub mod nsec3hash; +pub mod testns; pub mod update; use clap::crate_version; @@ -65,6 +66,10 @@ pub enum Command { #[command(name = "key2ds")] Key2ds(key2ds::Key2ds), + /// Simple fake nameserver tool + #[command(name = "testns")] + TestNs(self::testns::TestNs), + /// Send an UPDATE packet #[command(name = "update")] Update(self::update::Update), @@ -87,6 +92,7 @@ impl Command { Self::Nsec3Hash(nsec3hash) => nsec3hash.execute(env), Self::Key2ds(key2ds) => key2ds.execute(env), Self::Notify(notify) => notify.execute(env), + Self::TestNs(testns) => testns.execute(env), Self::Update(update) => update.execute(env), Self::Help(help) => help.execute(), Self::Report(s) => { From 6c10ed488635e128ee85f4e065b13954228548f7 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 13:41:24 +0100 Subject: [PATCH 02/23] Add initial support for the ldns-testns command. --- Cargo.lock | 2 +- Cargo.toml | 5 +- src/commands/testns.rs | 199 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 src/commands/testns.rs diff --git a/Cargo.lock b/Cargo.lock index 958daa20..ce310de9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain.git?branch=initial-nsec3-generation#5efcccfabd4535a40c8981fc36f89ca73899c3b4" +source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#4a47c2e08d3514f9f2b6f98e00098582f767dff1" dependencies = [ "arc-swap", "bytes", diff --git a/Cargo.toml b/Cargo.toml index ff61413d..c470d18a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,13 +20,14 @@ ring = ["domain/ring"] bytes = "1.8.0" chrono = "0.4.38" clap = { version = "4.3.4", features = ["cargo", "derive"] } -domain = { git = "https://github.com/NLnetLabs/domain.git", branch = "initial-nsec3-generation", features = [ +domain = { git = "https://github.com/NLnetLabs/domain.git", branch = "extend-stelline-for-ldns-testns", features = [ "bytes", "net", "resolv", "tsig", "unstable-client-transport", "unstable-sign", + "unstable-stelline", "unstable-validate", "unstable-validator", "zonefile", @@ -43,6 +44,6 @@ _unused_lazy_static = { package = "lazy_static", version = "1.0.2" } test_bin = "0.4.0" tempfile = "3.14.0" regex = "1.11.1" -domain = { git = "https://github.com/NLnetLabs/domain.git", branch = "initial-nsec3-generation", features = [ +domain = { git = "https://github.com/NLnetLabs/domain.git", branch = "extend-stelline-for-ldns-testns", features = [ "unstable-stelline", ] } diff --git a/src/commands/testns.rs b/src/commands/testns.rs new file mode 100644 index 00000000..c2d81cf5 --- /dev/null +++ b/src/commands/testns.rs @@ -0,0 +1,199 @@ +use core::future::pending; + +use std::ffi::OsString; +use std::path::PathBuf; +use std::sync::Arc; + +use crate::env::Env; +use crate::error::Error; +use crate::Args; + +use domain::base::wire::Composer; +use domain::dep::octseq::{OctetsBuilder, Truncate}; +use domain::net::server::buf::VecBufSource; +use domain::net::server::dgram::DgramServer; +use domain::net::server::message::Request; +use domain::net::server::service::{CallResult, ServiceError, ServiceResult}; +use domain::net::server::stream::StreamServer; +use domain::net::server::util::service_fn; +use domain::stelline::client::CurrStepValue; +use domain::stelline::parse_stelline::{self, Stelline}; +use domain::stelline::server::do_server; +use lexopt::Arg; +use tokio::net::{TcpListener, UdpSocket}; + +use super::{parse_os, Command, LdnsCommand}; + +#[derive(Clone, Debug, clap::Args, PartialEq, Eq)] +pub struct TestNs { + /// Listens on the specified port, default 53. + #[arg(short = 'p', value_name = "PORT")] + port: Option, + + /// Datafile + #[arg()] + datafile: PathBuf, +} + +const LDNS_HELP: &str = "\ +Usage: ldns-testns [options] + -p listens on the specified port, default 53. +The program answers queries with canned replies from the datafile.\ +"; + +impl LdnsCommand for TestNs { + const NAME: &'static str = "testns"; + const HELP: &'static str = LDNS_HELP; + const COMPATIBLE_VERSION: &'static str = "1.8.4"; + + fn parse_ldns>(args: I) -> Result { + let mut port = 53; + let mut datafile = None; + + let mut parser = lexopt::Parser::from_args(args); + + while let Some(arg) = parser.next()? { + match arg { + Arg::Short('p') => { + let val = parser.value()?; + port = parse_os("port (-p)", &val)?; + } + Arg::Value(val) => { + if datafile.is_some() { + return Err("Only one datafile is allowed".into()); + } + datafile = Some(val); + } + Arg::Short('v') => return Ok(Self::report_version()), + Arg::Short(x) => return Err(format!("Invalid short option: -{x}").into()), + Arg::Long(x) => { + return Err(format!("Long options are not supported, but `--{x}` given").into()) + } + } + } + + let Some(datafile) = datafile else { + return Err("No datafile given".into()); + }; + + Ok(Args::from(Command::TestNs(Self { + port: Some(port), + datafile: datafile.into(), + }))) + } +} + +impl TestNs { + pub fn execute(self, env: impl Env) -> Result<(), Error> { + let runtime = tokio::runtime::Runtime::new().unwrap(); + runtime.block_on(self.run(&env)) + } + + /// Run the command as an async function + pub async fn run(self, _env: &impl Env) -> Result<(), Error> { + let mut datafile = std::fs::read_to_string(&self.datafile)?; + + if !datafile.contains("RANGE_BEGIN") { + datafile.insert_str(0, "RANGE_BEGIN 0 999\n"); + datafile.push_str("RANGE_END\n"); + } + if !datafile.contains("SCENARIO_BEGIN") { + datafile.insert_str(0, "SCENARIO_BEGIN Scenario to emulate\n"); + datafile.push_str("SCENARIO_END\n"); + } + if !datafile.contains("CONFIG_END") { + datafile.insert_str(0, "CONFIG_END\n"); + } + + let stelline = Arc::new(parse_stelline::parse_file( + datafile.as_bytes(), + self.datafile.to_str().unwrap(), + )); + + let svc = service_fn(refuse_service, stelline); + + let sock = UdpSocket::bind(format!("127.0.0.1:{}", self.port.unwrap())) + .await + .unwrap(); + let listener = TcpListener::bind(format!("127.0.0.1:{}", self.port.unwrap())) + .await + .unwrap(); + + let udp_srv = DgramServer::new(sock, VecBufSource, svc.clone()); + tokio::spawn(async move { udp_srv.run().await }); + + let tcp_srv = StreamServer::new(listener, VecBufSource, svc); + tokio::spawn(async move { tcp_srv.run().await }); + + Ok(pending().await) + } +} + +fn refuse_service( + req: Request>, + stelline: Arc, +) -> ServiceResult { + let step_value = CurrStepValue::new(); + match do_server(&req, &stelline, &step_value) { + Some(builder) => Ok(CallResult::new(builder)), + None => Err(ServiceError::Refused), + } +} + +// Hacky work around for the fact that StreamTarget::default() calls +// Target::default() which in our case creates an empty Vec, which will then +// cause a panic when the Stelline code creates an empty target via the +// Default trait thereby invoking truncate() which attempts to truncate to len +// + 2, but truncation of len + 2 is a NO-OP and then the Vec doesn't have the +// expected two leading TCP stream length header bytes and an out of bounds +// access occurs. +#[derive(Clone)] +struct AtLeastTwoBytesVec(Vec); + +impl Default for AtLeastTwoBytesVec { + fn default() -> Self { + Self(vec![0, 0]) + } +} + +impl std::ops::Deref for AtLeastTwoBytesVec { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::ops::DerefMut for AtLeastTwoBytesVec { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl Composer for AtLeastTwoBytesVec {} + +impl Truncate for AtLeastTwoBytesVec { + fn truncate(&mut self, len: usize) { + self.0.truncate(len); + } +} + +impl AsMut<[u8]> for AtLeastTwoBytesVec { + fn as_mut(&mut self) -> &mut [u8] { + self.0.as_mut() + } +} + +impl AsRef<[u8]> for AtLeastTwoBytesVec { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + +impl OctetsBuilder for AtLeastTwoBytesVec { + type AppendError = as OctetsBuilder>::AppendError; + + fn append_slice(&mut self, slice: &[u8]) -> Result<(), Self::AppendError> { + self.0.append_slice(slice) + } +} From cdf382de2c42b271984042aae51e869957846d35 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 13:44:06 +0100 Subject: [PATCH 03/23] Add missing selector for ldns. --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index c8b435f2..e95ac7ef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ use env::Env; use error::Error; pub use self::args::Args; +use commands::testns::TestNs; pub mod args; pub mod commands; @@ -39,6 +40,7 @@ pub fn try_ldns_compatibility>( "notify" => Notify::parse_ldns_args(args_iter), "keygen" => Keygen::parse_ldns_args(args_iter), "nsec3-hash" => Nsec3Hash::parse_ldns_args(args_iter), + "testns" => TestNs::parse_ldns_args(args_iter), "update" => Update::parse_ldns_args(args_iter), _ => return Err(format!("Unrecognized ldns command 'ldns-{binary_name}'").into()), }; From 47117b0223c67f54ec974cbaded94201bd6aea9a Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 14:06:17 +0100 Subject: [PATCH 04/23] Log listening to be compatible with ldns-testns as expected by the OpenDNSSEC test suite. --- src/commands/testns.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/commands/testns.rs b/src/commands/testns.rs index c2d81cf5..b8889261 100644 --- a/src/commands/testns.rs +++ b/src/commands/testns.rs @@ -33,6 +33,10 @@ pub struct TestNs { /// Datafile #[arg()] datafile: PathBuf, + + /// Running in LDNS mode? + #[arg(skip)] + is_ldns: bool, } const LDNS_HELP: &str = "\ @@ -79,6 +83,7 @@ impl LdnsCommand for TestNs { Ok(Args::from(Command::TestNs(Self { port: Some(port), datafile: datafile.into(), + is_ldns: true, }))) } } @@ -90,7 +95,8 @@ impl TestNs { } /// Run the command as an async function - pub async fn run(self, _env: &impl Env) -> Result<(), Error> { + pub async fn run(self, env: &impl Env) -> Result<(), Error> { + let port = self.port.unwrap(); let mut datafile = std::fs::read_to_string(&self.datafile)?; if !datafile.contains("RANGE_BEGIN") { @@ -112,13 +118,15 @@ impl TestNs { let svc = service_fn(refuse_service, stelline); - let sock = UdpSocket::bind(format!("127.0.0.1:{}", self.port.unwrap())) - .await - .unwrap(); - let listener = TcpListener::bind(format!("127.0.0.1:{}", self.port.unwrap())) + let sock = UdpSocket::bind(format!("127.0.0.1:{port}")).await.unwrap(); + let listener = TcpListener::bind(format!("127.0.0.1:{port}")) .await .unwrap(); + if self.is_ldns { + writeln!(env.stdout(), "Listening on port {port}"); + } + let udp_srv = DgramServer::new(sock, VecBufSource, svc.clone()); tokio::spawn(async move { udp_srv.run().await }); From 880a74ad993193ba4b02536359e213e55ed0d823 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 15:39:30 +0100 Subject: [PATCH 05/23] Support the verbose flag. --- src/commands/testns.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/commands/testns.rs b/src/commands/testns.rs index b8889261..c6d927b6 100644 --- a/src/commands/testns.rs +++ b/src/commands/testns.rs @@ -29,6 +29,10 @@ pub struct TestNs { /// Listens on the specified port, default 53. #[arg(short = 'p', value_name = "PORT")] port: Option, + + /// Verbose output. + #[arg(short = 'v') + verbose: bool, /// Datafile #[arg()] @@ -52,6 +56,7 @@ impl LdnsCommand for TestNs { fn parse_ldns>(args: I) -> Result { let mut port = 53; + let mut verbose = false; let mut datafile = None; let mut parser = lexopt::Parser::from_args(args); @@ -62,6 +67,9 @@ impl LdnsCommand for TestNs { let val = parser.value()?; port = parse_os("port (-p)", &val)?; } + Arg::Short('v') => { + verbose = true: + } Arg::Value(val) => { if datafile.is_some() { return Err("Only one datafile is allowed".into()); @@ -82,6 +90,7 @@ impl LdnsCommand for TestNs { Ok(Args::from(Command::TestNs(Self { port: Some(port), + verbose, datafile: datafile.into(), is_ldns: true, }))) @@ -123,7 +132,7 @@ impl TestNs { .await .unwrap(); - if self.is_ldns { + if self.is_ldns && self.verbose { writeln!(env.stdout(), "Listening on port {port}"); } From d0e07cff57cac366514b87f2eadd7f02a9c1b5bc Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 16:08:27 +0100 Subject: [PATCH 06/23] Compulation fix. --- src/commands/testns.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/testns.rs b/src/commands/testns.rs index c6d927b6..a717b325 100644 --- a/src/commands/testns.rs +++ b/src/commands/testns.rs @@ -31,7 +31,7 @@ pub struct TestNs { port: Option, /// Verbose output. - #[arg(short = 'v') + #[arg(short = 'v')] verbose: bool, /// Datafile From 669587e8b45ce1f9899513800a69908d2d21bf68 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 16:55:19 +0100 Subject: [PATCH 07/23] Compulation fix. --- src/commands/testns.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/commands/testns.rs b/src/commands/testns.rs index a717b325..dac2d673 100644 --- a/src/commands/testns.rs +++ b/src/commands/testns.rs @@ -68,7 +68,7 @@ impl LdnsCommand for TestNs { port = parse_os("port (-p)", &val)?; } Arg::Short('v') => { - verbose = true: + verbose = true; } Arg::Value(val) => { if datafile.is_some() { @@ -76,7 +76,6 @@ impl LdnsCommand for TestNs { } datafile = Some(val); } - Arg::Short('v') => return Ok(Self::report_version()), Arg::Short(x) => return Err(format!("Invalid short option: -{x}").into()), Arg::Long(x) => { return Err(format!("Long options are not supported, but `--{x}` given").into()) From e999fd673085ff56c32198a12abeccd0fd91ab3d Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:09:12 +0100 Subject: [PATCH 08/23] Bump domain. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index ce310de9..c20e9b03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#4a47c2e08d3514f9f2b6f98e00098582f767dff1" +source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#161935709a163c8f689193b80495d75774d0d226" dependencies = [ "arc-swap", "bytes", From 350dc3cd845979b74b74a6536909c81a0ff02554 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:15:29 +0100 Subject: [PATCH 09/23] Bump domain. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index c20e9b03..291d1aec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#161935709a163c8f689193b80495d75774d0d226" +source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#c863d5999b9f1e68d879f8e492b2a2e8842c064e" dependencies = [ "arc-swap", "bytes", From eb9e6bef91fb3eb1062812e086191e1196559f36 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 21:13:22 +0100 Subject: [PATCH 10/23] Log matches ala the real ldns-testns. --- src/commands/testns.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/commands/testns.rs b/src/commands/testns.rs index dac2d673..2c870852 100644 --- a/src/commands/testns.rs +++ b/src/commands/testns.rs @@ -1,5 +1,3 @@ -use core::future::pending; - use std::ffi::OsString; use std::path::PathBuf; use std::sync::Arc; @@ -21,6 +19,7 @@ use domain::stelline::parse_stelline::{self, Stelline}; use domain::stelline::server::do_server; use lexopt::Arg; use tokio::net::{TcpListener, UdpSocket}; +use tokio::sync::mpsc::Sender; use super::{parse_os, Command, LdnsCommand}; @@ -29,7 +28,7 @@ pub struct TestNs { /// Listens on the specified port, default 53. #[arg(short = 'p', value_name = "PORT")] port: Option, - + /// Verbose output. #[arg(short = 'v')] verbose: bool, @@ -124,7 +123,9 @@ impl TestNs { self.datafile.to_str().unwrap(), )); - let svc = service_fn(refuse_service, stelline); + let (tx, mut rx) = tokio::sync::mpsc::channel(1); + + let svc = service_fn(refuse_service, (stelline, tx)); let sock = UdpSocket::bind(format!("127.0.0.1:{port}")).await.unwrap(); let listener = TcpListener::bind(format!("127.0.0.1:{port}")) @@ -141,17 +142,29 @@ impl TestNs { let tcp_srv = StreamServer::new(listener, VecBufSource, svc); tokio::spawn(async move { tcp_srv.run().await }); - Ok(pending().await) + while let Some(msg) = rx.recv().await { + if self.is_ldns && self.verbose { + writeln!(env.stdout(), "{}", msg); + } + } + + Ok(()) } } fn refuse_service( req: Request>, - stelline: Arc, + (stelline, tx): (Arc, Sender), ) -> ServiceResult { let step_value = CurrStepValue::new(); match do_server(&req, &stelline, &step_value) { - Some(builder) => Ok(CallResult::new(builder)), + Some(builder) => { + let tx = tx.clone(); + tokio::spawn(async move { + tx.send("comparepkt: match!".to_string()).await.unwrap(); + }); + Ok(CallResult::new(builder)) + } None => Err(ServiceError::Refused), } } From f46e32882be33ed5f5cf2ed18c5c89a47c1b80bd Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 21:39:53 +0100 Subject: [PATCH 11/23] Bump domain. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 291d1aec..6c5782d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#c863d5999b9f1e68d879f8e492b2a2e8842c064e" +source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#c4ca4df6fea889ec7e23aae1e3d636439c75302c" dependencies = [ "arc-swap", "bytes", From 2e668793695de2df1aea37a2354099203d1737c3 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 21:58:34 +0100 Subject: [PATCH 12/23] Bump domain. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 6c5782d4..8b7d43e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#c4ca4df6fea889ec7e23aae1e3d636439c75302c" +source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#84d17aaa7317ef9f8a7f2b84def585ef29dac50e" dependencies = [ "arc-swap", "bytes", From 19e97bcfe87147909f224d2ba738450d65589be3 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 22:12:53 +0100 Subject: [PATCH 13/23] Output more info when a query is not matched. --- src/commands/testns.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/commands/testns.rs b/src/commands/testns.rs index 2c870852..8ed87528 100644 --- a/src/commands/testns.rs +++ b/src/commands/testns.rs @@ -157,16 +157,19 @@ fn refuse_service( (stelline, tx): (Arc, Sender), ) -> ServiceResult { let step_value = CurrStepValue::new(); - match do_server(&req, &stelline, &step_value) { + let tx = tx.clone(); + let (res, msg) = match do_server(&req, &stelline, &step_value) { Some(builder) => { - let tx = tx.clone(); - tokio::spawn(async move { - tx.send("comparepkt: match!".to_string()).await.unwrap(); - }); - Ok(CallResult::new(builder)) + (Ok(CallResult::new(builder)), "comparepkt: match!".to_string()) } - None => Err(ServiceError::Refused), - } + None => { + (Err(ServiceError::Refused), format!("comparepkt: no match for request {req:?}")) + } + }; + tokio::spawn(async move { + tx.send(msg).await.unwrap(); + }); + res } // Hacky work around for the fact that StreamTarget::default() calls From 20f21ee86b2a6a00661c6098d321d49ca7cf827f Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 22:14:34 +0100 Subject: [PATCH 14/23] Output more info when the request is not matched. --- src/commands/testns.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/testns.rs b/src/commands/testns.rs index 8ed87528..75dbc4b3 100644 --- a/src/commands/testns.rs +++ b/src/commands/testns.rs @@ -163,7 +163,7 @@ fn refuse_service( (Ok(CallResult::new(builder)), "comparepkt: match!".to_string()) } None => { - (Err(ServiceError::Refused), format!("comparepkt: no match for request {req:?}")) + (Err(ServiceError::Refused), format!("comparepkt: no match to question {:?}", req.message().first_question())) } }; tokio::spawn(async move { From c490353d227d36fe1599519fcaa6dd8f2d935a7a Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 22:14:59 +0100 Subject: [PATCH 15/23] Cargo fmt. --- src/commands/testns.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/commands/testns.rs b/src/commands/testns.rs index 75dbc4b3..ff2a3d22 100644 --- a/src/commands/testns.rs +++ b/src/commands/testns.rs @@ -159,12 +159,17 @@ fn refuse_service( let step_value = CurrStepValue::new(); let tx = tx.clone(); let (res, msg) = match do_server(&req, &stelline, &step_value) { - Some(builder) => { - (Ok(CallResult::new(builder)), "comparepkt: match!".to_string()) - } - None => { - (Err(ServiceError::Refused), format!("comparepkt: no match to question {:?}", req.message().first_question())) - } + Some(builder) => ( + Ok(CallResult::new(builder)), + "comparepkt: match!".to_string(), + ), + None => ( + Err(ServiceError::Refused), + format!( + "comparepkt: no match to question {:?}", + req.message().first_question() + ), + ), }; tokio::spawn(async move { tx.send(msg).await.unwrap(); From c1a155ca6fc943cdfaf4614a01e569b1cdee3348 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 22:25:27 +0100 Subject: [PATCH 16/23] Bump domain. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 8b7d43e8..211d3b4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#84d17aaa7317ef9f8a7f2b84def585ef29dac50e" +source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#2a3fb9cacda79e3126abf274c73c576ef5d6a5ea" dependencies = [ "arc-swap", "bytes", From 8c1d25587d84ec14cb0bf1ffb88171ef773348cb Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 22:35:24 +0100 Subject: [PATCH 17/23] Dump query info on match too. --- src/commands/testns.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/commands/testns.rs b/src/commands/testns.rs index ff2a3d22..4226f02f 100644 --- a/src/commands/testns.rs +++ b/src/commands/testns.rs @@ -161,7 +161,10 @@ fn refuse_service( let (res, msg) = match do_server(&req, &stelline, &step_value) { Some(builder) => ( Ok(CallResult::new(builder)), - "comparepkt: match!".to_string(), + format!( + "comparepkt: match! for question {:?}", + req.message().first_question() + ), ), None => ( Err(ServiceError::Refused), From 02a20355d50e2a65f10d2c8a7af03ca31c3f463e Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 23:04:29 +0100 Subject: [PATCH 18/23] Bump domain. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 211d3b4f..9dd80e46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#2a3fb9cacda79e3126abf274c73c576ef5d6a5ea" +source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#e186f1fd398caa12625546021c2c3e56c6eec5aa" dependencies = [ "arc-swap", "bytes", From ffce3c58c2e4ff44590fec55eb7aed4d83031b22 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 23:10:59 +0100 Subject: [PATCH 19/23] Bump domain. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 9dd80e46..3ee7bc7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#e186f1fd398caa12625546021c2c3e56c6eec5aa" +source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#c2aff80b6e95193b0628b10b095d9c66cc3ad229" dependencies = [ "arc-swap", "bytes", From 2e20218b6e66ccc16f2c2630c8aac66d3ba92ec3 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 23:29:40 +0100 Subject: [PATCH 20/23] Bump domain. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 3ee7bc7d..24b90acd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#c2aff80b6e95193b0628b10b095d9c66cc3ad229" +source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#b4481895f8343952a107d5f9b41e34fc2f3e88bf" dependencies = [ "arc-swap", "bytes", From 05543c3fa4a09148e359640234a2cc497a83d38a Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 26 Feb 2025 23:58:19 +0100 Subject: [PATCH 21/23] Bump domain. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 24b90acd..6cadee8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#b4481895f8343952a107d5f9b41e34fc2f3e88bf" +source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#3668a9a730a68550bc5c68db245c43ab8f5d208d" dependencies = [ "arc-swap", "bytes", From b6a368a0cb22d73df5126d7c5771916a12f01d95 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Thu, 27 Feb 2025 10:59:13 +0100 Subject: [PATCH 22/23] Bump domain and output more info about the matched request and issued response. --- Cargo.lock | 2 +- src/commands/testns.rs | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6cadee8a..4a21c242 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#3668a9a730a68550bc5c68db245c43ab8f5d208d" +source = "git+https://github.com/NLnetLabs/domain.git?branch=extend-stelline-for-ldns-testns#4e7adbc290ad0a0ac3d40cfdff39bae7df7c7b8b" dependencies = [ "arc-swap", "bytes", diff --git a/src/commands/testns.rs b/src/commands/testns.rs index 4226f02f..5b8b6b45 100644 --- a/src/commands/testns.rs +++ b/src/commands/testns.rs @@ -125,7 +125,7 @@ impl TestNs { let (tx, mut rx) = tokio::sync::mpsc::channel(1); - let svc = service_fn(refuse_service, (stelline, tx)); + let svc = service_fn(answer_from_datafile, (stelline, tx)); let sock = UdpSocket::bind(format!("127.0.0.1:{port}")).await.unwrap(); let listener = TcpListener::bind(format!("127.0.0.1:{port}")) @@ -152,20 +152,22 @@ impl TestNs { } } -fn refuse_service( +fn answer_from_datafile( req: Request>, (stelline, tx): (Arc, Sender), ) -> ServiceResult { let step_value = CurrStepValue::new(); let tx = tx.clone(); let (res, msg) = match do_server(&req, &stelline, &step_value) { - Some(builder) => ( - Ok(CallResult::new(builder)), + Some((builder, (range_idx, entry_idx))) => { + let q = req.message().first_question(); + let hdr = builder.header(); + let ans = format!("{:?}", builder.as_message().answer()); + (Ok(CallResult::new(builder)), format!( - "comparepkt: match! for question {:?}", - req.message().first_question() - ), - ), + "comparepkt: match! at range {range_idx} entry {entry_idx} for question {q:?} with header {hdr:?} and answer {ans}", + )) + } None => ( Err(ServiceError::Refused), format!( From b7a0cc1326b640039e13f8416ed66320702bf42e Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Thu, 27 Feb 2025 11:12:27 +0100 Subject: [PATCH 23/23] Better output format. --- src/commands/testns.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/commands/testns.rs b/src/commands/testns.rs index 5b8b6b45..94f8773a 100644 --- a/src/commands/testns.rs +++ b/src/commands/testns.rs @@ -162,10 +162,12 @@ fn answer_from_datafile( Some((builder, (range_idx, entry_idx))) => { let q = req.message().first_question(); let hdr = builder.header(); - let ans = format!("{:?}", builder.as_message().answer()); + let hdr_opcode = hdr.opcode(); + let hdr_rcode = hdr.rcode(); + let hdr_flags = hdr.flags(); (Ok(CallResult::new(builder)), format!( - "comparepkt: match! at range {range_idx} entry {entry_idx} for question {q:?} with header {hdr:?} and answer {ans}", + "comparepkt: match! at range {range_idx} entry {entry_idx} for question {q:?} with reply header {hdr_opcode}/{hdr_rcode}/{hdr_flags}", )) } None => (