From 94b55f1c111814913d9d2b92a485056593a239b3 Mon Sep 17 00:00:00 2001 From: Andreas Rottmann Date: Tue, 20 Aug 2024 00:39:45 +0200 Subject: [PATCH 1/4] [WIP] Update to latest `trust-dns` This is an intermediate step before switching to `hickory-dns`, which is `trust-dns`'s new name. TODO: Test --- Cargo.lock | 349 ++++++++++++++++++++++-------------------- Cargo.toml | 4 +- src/backend.rs | 41 +++-- src/bin/tdns.rs | 2 +- src/query.rs | 22 +-- src/record.rs | 22 +-- src/update.rs | 20 ++- src/update_message.rs | 4 +- src/util.rs | 2 +- tests/mock/mod.rs | 26 ++-- 10 files changed, 256 insertions(+), 236 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f37d26..cc9eb08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,7 +155,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -204,15 +204,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] - [[package]] name = "digest" version = "0.10.7" @@ -232,14 +223,14 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] name = "enum-as-inner" -version = "0.3.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570d109b813e904becc80d8d5da38376818a143348413f7149f1340fe04754d4" +checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.75", ] [[package]] @@ -442,11 +433,10 @@ dependencies = [ [[package]] name = "idna" -version = "0.2.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -461,24 +451,15 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - [[package]] name = "ipconfig" -version = "0.2.2" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.3.19", + "socket2", "widestring", - "winapi", + "windows-sys 0.48.0", "winreg", ] @@ -546,12 +527,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "memchr" version = "2.7.4" @@ -576,7 +551,7 @@ dependencies = [ "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -588,12 +563,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - [[package]] name = "num-traits" version = "0.2.19" @@ -618,17 +587,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.3" @@ -636,21 +594,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -661,9 +605,9 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.3", + "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -684,12 +628,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "ppv-lite86" version = "0.2.20" @@ -787,15 +725,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.3" @@ -815,6 +744,21 @@ dependencies = [ "quick-error", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -827,26 +771,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "serde" -version = "1.0.208" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.208" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.75", -] - [[package]] name = "sha2" version = "0.10.8" @@ -890,24 +814,19 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.3.19" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ - "cfg-if", "libc", - "winapi", + "windows-sys 0.52.0", ] [[package]] -name = "socket2" -version = "0.5.7" +name = "spin" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys", -] +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "strsim" @@ -1016,25 +935,6 @@ dependencies = [ "syn 2.0.75", ] -[[package]] -name = "time" -version = "0.3.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" -dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde", - "time-core", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - [[package]] name = "tinyvec" version = "1.8.0" @@ -1060,12 +960,12 @@ dependencies = [ "bytes", "libc", "mio", - "parking_lot 0.12.3", + "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.7", + "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1079,31 +979,61 @@ dependencies = [ "syn 2.0.75", ] +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.75", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + [[package]] name = "trust-dns-client" -version = "0.20.4" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4ef9b9bde0559b78a4abb00339143750085f05e5a453efb7b8bef1061f09dc" +checksum = "14135e72c7e6d4c9b6902d4437881a8598f0145dbb2e3f86f92dbad845b61e63" dependencies = [ "cfg-if", "data-encoding", "futures-channel", "futures-util", - "lazy_static", - "log", + "once_cell", "radix_trie", "rand", "thiserror", - "time", "tokio", + "tracing", "trust-dns-proto", ] [[package]] name = "trust-dns-proto" -version = "0.20.4" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca94d4e9feb6a181c690c4040d7a24ef34018d8313ac5044a61d21222ae24e31" +checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" dependencies = [ "async-trait", "cfg-if", @@ -1112,35 +1042,37 @@ dependencies = [ "futures-channel", "futures-io", "futures-util", - "idna 0.2.3", + "idna 0.4.0", "ipnet", - "lazy_static", - "log", + "once_cell", "rand", + "ring", "smallvec", "thiserror", "tinyvec", "tokio", + "tracing", "url", ] [[package]] name = "trust-dns-resolver" -version = "0.20.4" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecae383baad9995efaa34ce8e57d12c3f305e545887472a492b838f4b5cfb77a" +checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" dependencies = [ "cfg-if", "futures-util", "ipconfig", - "lazy_static", - "log", "lru-cache", - "parking_lot 0.11.2", + "once_cell", + "parking_lot", + "rand", "resolv-conf", "smallvec", "thiserror", "tokio", + "tracing", "trust-dns-proto", ] @@ -1183,6 +1115,12 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "url" version = "2.5.2" @@ -1267,11 +1205,21 @@ version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "widestring" -version = "0.4.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" @@ -1301,7 +1249,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", ] [[package]] @@ -1310,7 +1267,22 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -1319,28 +1291,46 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1353,24 +1343,48 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -1379,11 +1393,12 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winreg" -version = "0.6.2" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c9167e7..e8e7218 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,8 +16,8 @@ maintenance = { status = "actively-developed" } [dependencies] async-trait = "0.1.57" -trust-dns-client = "0.20.0" -trust-dns-resolver = "0.20.0" +trust-dns-client = { version = "0.23.2", features = ["dnssec-ring"] } +trust-dns-resolver = "0.23.2" structopt = "0.3.1" futures = "0.3.1" anyhow = "1.0" diff --git a/src/backend.rs b/src/backend.rs index 0416ff4..51d2fae 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -11,9 +11,9 @@ use trust_dns_client::{ }; use trust_dns_resolver::{ config::{NameServerConfig, Protocol, ResolverConfig, ResolverOpts}, - error::ResolveError, + error::{ResolveError, ResolveResult}, lookup, lookup_ip, - proto::{error::ProtoError, xfer::dns_request::DnsRequestOptions}, + proto::error::ProtoError, TokioAsyncResolver, }; @@ -28,30 +28,26 @@ pub trait Resolver: Clone { name: rr::Name, rtype: rr::RecordType, ) -> Result; - async fn lookup_ip(&self, host: rr::Name) -> Result; - async fn lookup_soa(&self, name: rr::Name) -> Result; - async fn lookup_ns(&self, name: rr::Name) -> Result; + async fn lookup_ip(&self, host: rr::Name) -> ResolveResult; + async fn lookup_soa(&self, name: rr::Name) -> ResolveResult; + async fn lookup_ns(&self, name: rr::Name) -> ResolveResult; } #[async_trait] impl Resolver for TokioAsyncResolver { - async fn lookup( - &self, - name: rr::Name, - rtype: rr::RecordType, - ) -> Result { - TokioAsyncResolver::lookup(self, name, rtype, DnsRequestOptions::default()).await + async fn lookup(&self, name: rr::Name, rtype: rr::RecordType) -> ResolveResult { + TokioAsyncResolver::lookup(self, name, rtype).await } - async fn lookup_ip(&self, host: rr::Name) -> Result { + async fn lookup_ip(&self, host: rr::Name) -> ResolveResult { TokioAsyncResolver::lookup_ip(self, host).await } - async fn lookup_soa(&self, name: rr::Name) -> Result { + async fn lookup_soa(&self, name: rr::Name) -> ResolveResult { TokioAsyncResolver::soa_lookup(self, name).await } - async fn lookup_ns(&self, name: rr::Name) -> Result { + async fn lookup_ns(&self, name: rr::Name) -> ResolveResult { TokioAsyncResolver::ns_lookup(self, name).await } } @@ -65,8 +61,8 @@ pub trait Backend: Clone { runtime: &Runtime, addr: SocketAddr, ) -> Result; - fn open_resolver(&mut self, addr: SocketAddr) -> Result; - fn open_system_resolver(&mut self) -> Result; + fn open_resolver(&mut self, addr: SocketAddr) -> Self::Resolver; + fn open_system_resolver(&mut self) -> ResolveResult; } #[derive(Debug, Clone)] @@ -89,11 +85,11 @@ impl Backend for TcpBackend { Ok(client) } - fn open_resolver(&mut self, addr: SocketAddr) -> Result { + fn open_resolver(&mut self, addr: SocketAddr) -> Self::Resolver { make_resolver(addr, Protocol::Tcp) } - fn open_system_resolver(&mut self) -> Result { + fn open_system_resolver(&mut self) -> ResolveResult { TokioAsyncResolver::tokio_from_system_conf() } } @@ -117,22 +113,23 @@ impl Backend for UdpBackend { Ok(client) } - fn open_resolver(&mut self, addr: SocketAddr) -> Result { + fn open_resolver(&mut self, addr: SocketAddr) -> Self::Resolver { make_resolver(addr, Protocol::Udp) } - fn open_system_resolver(&mut self) -> Result { + fn open_system_resolver(&mut self) -> ResolveResult { TokioAsyncResolver::tokio_from_system_conf() } } -fn make_resolver(addr: SocketAddr, protocol: Protocol) -> Result { +fn make_resolver(addr: SocketAddr, protocol: Protocol) -> TokioAsyncResolver { let mut config = ResolverConfig::new(); config.add_name_server(NameServerConfig { socket_addr: addr, protocol, tls_dns_name: None, - trust_nx_responses: true, + trust_negative_responses: true, + bind_addr: None, }); TokioAsyncResolver::tokio(config, ResolverOpts::default()) } diff --git a/src/bin/tdns.rs b/src/bin/tdns.rs index a734da1..59f702b 100644 --- a/src/bin/tdns.rs +++ b/src/bin/tdns.rs @@ -300,7 +300,7 @@ fn open_resolver( addr: Option, ) -> Result { if let Some(addr) = addr { - Ok(dns.open_resolver(addr)?) + Ok(dns.open_resolver(addr)) } else { Ok(dns.open_system_resolver()?) } diff --git a/src/query.rs b/src/query.rs index ff5684f..7317c41 100644 --- a/src/query.rs +++ b/src/query.rs @@ -8,9 +8,9 @@ use chrono::DateTime; use data_encoding::{Encoding, BASE32, BASE64, HEXLOWER}; use futures::stream::{FuturesUnordered, Stream}; +use trust_dns_client::proto::rr::dnssec::Nsec3HashAlgorithm; use trust_dns_client::rr::{ self, - dnssec::Nsec3HashAlgorithm, rdata::{self, caa, DNSSECRData}, }; use trust_dns_resolver::error::ResolveError; @@ -241,9 +241,7 @@ impl<'a> fmt::Display for DisplayRData<'a> { } } // TODO: What to do with records that have no specified presentation? - NULL(_) | OPT(_) | Unknown { .. } | ZERO | HINFO(_) | HTTPS(_) | SVCB(_) => { - write!(f, "{:?}", self.0)? - } + _ => write!(f, "{:?}", self.0)?, } Ok(()) } @@ -368,11 +366,9 @@ impl<'a> fmt::Display for DisplayDNSSECRData<'a> { )?; } Unknown { rdata, .. } => { - // This is dubiuos, and I'm not sure how we can even end up here. - if let Some(data) = rdata.anything() { - write!(f, "{}", DisplayEncoded(&BASE64, data))?; - } + write!(f, "{}", DisplayEncoded(&BASE64, rdata.anything()))?; } + _ => todo!(), } Ok(()) } @@ -443,18 +439,22 @@ pub fn write_record( ) -> io::Result<()> { match format { DisplayFormat::Short => { - write!(writer, "{}", DisplayRData(record.rdata()))?; + if let Some(rdata) = record.data() { + write!(writer, "{}", DisplayRData(rdata))?; + } } DisplayFormat::Zone => { write!( writer, - "{} {} {} {} {}", + "{} {} {} {}", record.name(), record.ttl(), record.dns_class(), record.record_type(), - DisplayRData(record.rdata()), )?; + if let Some(rdata) = record.data() { + write!(writer, " {}", DisplayRData(rdata))?; + } } } Ok(()) diff --git a/src/record.rs b/src/record.rs index d119df6..23dda00 100644 --- a/src/record.rs +++ b/src/record.rs @@ -115,8 +115,10 @@ impl<'a> Iterator for RsDataIter<'a> { fn next(&mut self) -> Option { use RsDataIterInner::*; match &mut self.0 { - A(iter) => iter.next().map(|item| rr::RData::A(*item)), - AAAA(iter) => iter.next().map(|item| rr::RData::AAAA(*item)), + A(iter) => iter.next().map(|item| rr::RData::A(rr::rdata::A(*item))), + AAAA(iter) => iter + .next() + .map(|item| rr::RData::AAAA(rr::rdata::AAAA(*item))), TXT(iter) => iter .next() .map(|item| rr::RData::TXT(rdata::TXT::new(vec![item.into()]))), @@ -290,22 +292,20 @@ impl TryFrom<&[rr::Record]> for RecordSet { 0 => Err(TryFromRecordsError::Empty), 1 => { let key = keys.iter().next().unwrap(); - // TODO: I'm not sure if `trust-dns` actually guarantees that - // these `unwrap` calls never panic, but I'd guess so. I should - // study its code and submit a documentation patch to clarify - // behavior in either case. let data = match key.record_type { - rr::RecordType::A => { - RsData::A(rrs.iter().map(|rr| *rr.rdata().as_a().unwrap()).collect()) - } + rr::RecordType::A => RsData::A( + rrs.iter() + .filter_map(|rr| Some(rr.data()?.as_a()?.0)) + .collect(), + ), rr::RecordType::AAAA => RsData::AAAA( rrs.iter() - .map(|rr| *rr.rdata().as_aaaa().unwrap()) + .filter_map(|rr| Some(rr.data()?.as_aaaa()?.0)) .collect(), ), rr::RecordType::TXT => RsData::TXT( rrs.iter() - .map(|rr| txt_string(rr.rdata().as_txt().unwrap())) + .filter_map(|rr| Some(txt_string(rr.data()?.as_txt()?))) .collect::>()?, ), rtype => return Err(TryFromRecordsError::UnsupportedType(rtype)), diff --git a/src/update.rs b/src/update.rs index 939ef77..5e751d1 100644 --- a/src/update.rs +++ b/src/update.rs @@ -181,8 +181,8 @@ where return Err(anyhow!("SOA record for {} not found", options.zone)); }; let mut server = dns.open(runtime, master).await?; - // TODO: probably should check response - server.send(message).await?; + // TODO: probably should check responses + let _reponses: Vec<_> = server.send(message).try_collect().await?; Ok(()) } @@ -219,7 +219,7 @@ async fn poll_for_update( options: Rc, ) -> anyhow::Result<()> where - I: IntoIterator, + I: IntoIterator, D: Backend, { let results: FuturesUnordered<_> = authorative @@ -229,7 +229,7 @@ where runtime, dns.clone(), resolver.clone(), - server_name, + server_name.0, Rc::clone(&options), ) }) @@ -262,17 +262,21 @@ where let options = Rc::clone(&options); let query = options.get_query(); loop { - if let Ok(response) = server + if let Ok(responses) = server .lookup(query.clone(), DnsRequestOptions::default()) + .try_collect::>() .await { - let answers = response.answers(); - let hit = options.expectation.satisfied_by(answers); + let answers: Vec<_> = responses + .into_iter() + .flat_map(|response| response.into_message().take_answers()) + .collect(); + let hit = options.expectation.satisfied_by(&answers); if options.verbose { if hit { println!("{}: match found", &server_name); } else { - let rset = match RecordSet::try_from(answers) { + let rset = match RecordSet::try_from(&answers[..]) { Ok(rs) => format!("{}", rs.data()), Err(e) => format!("{}", e), }; diff --git a/src/update_message.rs b/src/update_message.rs index 2881574..1038e09 100644 --- a/src/update_message.rs +++ b/src/update_message.rs @@ -1,6 +1,6 @@ use trust_dns_client::{ op::{Message, MessageType, OpCode, Query, UpdateMessage}, - rr::{rdata::NULL, DNSClass, Name, RData, Record, RecordSet, RecordType}, + rr::{DNSClass, Name, Record, RecordSet, RecordType}, }; // This code is taken from `update_message.rs` in the `trust_dns` crate, and @@ -110,7 +110,7 @@ pub fn delete_rrset(mut record: Record, zone_origin: Name) -> Message { // the TTL should be 0 record.set_ttl(0); // the rdata must be null to delete all rrsets - record.set_rdata(RData::NULL(NULL::new())); + record.set_data(None); message.add_update(record); message diff --git a/src/util.rs b/src/util.rs index 7e43c80..b779c8e 100644 --- a/src/util.rs +++ b/src/util.rs @@ -42,7 +42,7 @@ impl SocketName { Ok(SocketAddr::new(ip, port)) } else { Err(ResolveErrorKind::NoRecordsFound { - query: lookup.query().clone(), + query: Box::new(lookup.query().clone()), soa: None, negative_ttl: None, response_code: ResponseCode::NXDomain, diff --git a/tests/mock/mod.rs b/tests/mock/mod.rs index dad5fa9..e437e84 100644 --- a/tests/mock/mod.rs +++ b/tests/mock/mod.rs @@ -7,9 +7,9 @@ use std::{ use anyhow::anyhow; use async_trait::async_trait; -use futures::future; +use futures::{future, stream}; use trust_dns_client::{ - op::update_message::UpdateMessage, + op::UpdateMessage, proto::{ error::ProtoError, op::{Message, OpCode, Query}, @@ -29,6 +29,7 @@ use tdns_cli::{Backend, Resolver, Runtime}; pub type Handle = Arc>; pub type FutureResult = future::Ready>; +pub type ResultStream = stream::Once>; #[derive(Debug, Clone)] pub struct Zone(Vec); @@ -50,17 +51,20 @@ impl Zone { .iter_mut() .find(|r| r.record_type() == update.record_type() && r.name() == update.name()) { - record.set_rdata(update.rdata().clone()); + record.set_data(update.data().cloned()); } } } pub fn parse_rdata(rtype: &str, rdata: &str) -> anyhow::Result { - use rr::{rdata::SOA, RData}; + use rr::{ + rdata::{NS, SOA}, + RData, + }; match rtype { "A" => Ok(RData::A(rdata.parse()?)), "AAAA" => Ok(RData::AAAA(rdata.parse()?)), - "NS" => Ok(RData::NS(rdata.parse()?)), + "NS" => Ok(RData::NS(NS(rdata.parse()?))), "SOA" => { let parts: Vec<_> = rdata.split(' ').collect(); // This quite ugly -- is there a better way? @@ -146,8 +150,8 @@ impl Backend for MockBackend { ) -> Result { Ok(self.open_client(addr)) } - fn open_resolver(&mut self, addr: SocketAddr) -> Result { - Ok(self.open_client(addr)) + fn open_resolver(&mut self, addr: SocketAddr) -> Self::Resolver { + self.open_client(addr) } fn open_system_resolver(&mut self) -> Result { if let Some(addr) = self.resolv_conf { @@ -198,14 +202,14 @@ impl Server { message.add_answer(record); } } - Ok(message.into()) + DnsResponse::from_message(message) } OpCode::Update => { let mut zone = self.zone.lock().unwrap(); for update in request.updates() { zone.update(update); } - Ok(Message::new().into()) + DnsResponse::from_message(Message::new()) } _ => unimplemented!(), } @@ -214,11 +218,11 @@ impl Server { impl DnsHandle for Client { type Error = ProtoError; - type Response = FutureResult; + type Response = ResultStream; fn send>(&mut self, request: R) -> Self::Response { let mut server = self.0.lock().unwrap(); - future::ready(server.request(request.into())) + stream::once(future::ready(server.request(request.into()))) } } From 965bfefdb153969d7a1e55d3d27186ce24407ac4 Mon Sep 17 00:00:00 2001 From: Andreas Rottmann Date: Fri, 6 Sep 2024 16:52:09 +0200 Subject: [PATCH 2/4] [WIP] Migrate to hickory-dns --- Cargo.lock | 135 +++++++++++++++++++++--------------------- Cargo.toml | 4 +- src/backend.rs | 6 +- src/bin/tdns.rs | 4 +- src/query.rs | 6 +- src/record.rs | 2 +- src/tsig.rs | 8 +-- src/update.rs | 8 +-- src/update_message.rs | 4 +- src/util.rs | 4 +- 10 files changed, 90 insertions(+), 91 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc9eb08..c2c4f61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -388,6 +388,71 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hickory-client" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab9683b08d8f8957a857b0236455d80e1886eaa8c6178af556aa7871fb61b55" +dependencies = [ + "cfg-if", + "data-encoding", + "futures-channel", + "futures-util", + "hickory-proto", + "once_cell", + "radix_trie", + "rand", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "hickory-proto" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.4.0", + "ipnet", + "once_cell", + "rand", + "ring", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "hmac" version = "0.12.1" @@ -896,14 +961,14 @@ dependencies = [ "data-encoding", "digest", "futures", + "hickory-client", + "hickory-resolver", "hmac", "once_cell", "rand", "sha2", "structopt", "tokio", - "trust-dns-client", - "trust-dns-resolver", ] [[package]] @@ -1010,72 +1075,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "trust-dns-client" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14135e72c7e6d4c9b6902d4437881a8598f0145dbb2e3f86f92dbad845b61e63" -dependencies = [ - "cfg-if", - "data-encoding", - "futures-channel", - "futures-util", - "once_cell", - "radix_trie", - "rand", - "thiserror", - "tokio", - "tracing", - "trust-dns-proto", -] - -[[package]] -name = "trust-dns-proto" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.4.0", - "ipnet", - "once_cell", - "rand", - "ring", - "smallvec", - "thiserror", - "tinyvec", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" -dependencies = [ - "cfg-if", - "futures-util", - "ipconfig", - "lru-cache", - "once_cell", - "parking_lot", - "rand", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "tracing", - "trust-dns-proto", -] - [[package]] name = "typenum" version = "1.17.0" diff --git a/Cargo.toml b/Cargo.toml index e8e7218..1b98da7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,8 +16,8 @@ maintenance = { status = "actively-developed" } [dependencies] async-trait = "0.1.57" -trust-dns-client = { version = "0.23.2", features = ["dnssec-ring"] } -trust-dns-resolver = "0.23.2" +hickory-client = { version = "0.24.1", features = ["dnssec-ring"] } +hickory-resolver = "0.24.1" structopt = "0.3.1" futures = "0.3.1" anyhow = "1.0" diff --git a/src/backend.rs b/src/backend.rs index 51d2fae..522838f 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -3,13 +3,13 @@ use std::net::SocketAddr; use async_trait::async_trait; use tokio::net::{TcpStream, UdpSocket}; -use trust_dns_client::{ +use hickory_client::{ client::{AsyncClient, ClientFuture, ClientHandle}, rr, tcp::TcpClientStream, udp::UdpClientStream, }; -use trust_dns_resolver::{ +use hickory_resolver::{ config::{NameServerConfig, Protocol, ResolverConfig, ResolverOpts}, error::{ResolveError, ResolveResult}, lookup, lookup_ip, @@ -78,7 +78,7 @@ impl Backend for TcpBackend { runtime: &Runtime, addr: SocketAddr, ) -> Result { - use trust_dns_resolver::proto::iocompat::AsyncIoTokioAsStd; + use hickory_resolver::proto::iocompat::AsyncIoTokioAsStd; let (stream, sender) = TcpClientStream::>::new(addr); let (client, bg) = AsyncClient::new(Box::new(stream), sender, None).await?; runtime.spawn(bg); diff --git a/src/bin/tdns.rs b/src/bin/tdns.rs index 59f702b..2847ba4 100644 --- a/src/bin/tdns.rs +++ b/src/bin/tdns.rs @@ -11,8 +11,8 @@ use data_encoding::BASE64; use futures::{future, StreamExt}; use structopt::StructOpt; use tokio::runtime::Runtime; -use trust_dns_client::{proto::error::ProtoError, rr}; -use trust_dns_resolver::error::{ResolveError, ResolveErrorKind}; +use hickory_client::{proto::error::ProtoError, rr}; +use hickory_resolver::error::{ResolveError, ResolveErrorKind}; use tdns_cli::{ query::{self, perform_query, Query}, diff --git a/src/query.rs b/src/query.rs index 7317c41..5d5282b 100644 --- a/src/query.rs +++ b/src/query.rs @@ -8,12 +8,12 @@ use chrono::DateTime; use data_encoding::{Encoding, BASE32, BASE64, HEXLOWER}; use futures::stream::{FuturesUnordered, Stream}; -use trust_dns_client::proto::rr::dnssec::Nsec3HashAlgorithm; -use trust_dns_client::rr::{ +use hickory_client::proto::rr::dnssec::Nsec3HashAlgorithm; +use hickory_client::rr::{ self, rdata::{self, caa, DNSSECRData}, }; -use trust_dns_resolver::error::ResolveError; +use hickory_resolver::error::ResolveError; use crate::Resolver; diff --git a/src/record.rs b/src/record.rs index 23dda00..9719816 100644 --- a/src/record.rs +++ b/src/record.rs @@ -7,7 +7,7 @@ use std::{ string::FromUtf8Error, }; -use trust_dns_client::rr::{self, rdata}; +use hickory_client::rr::{self, rdata}; /// This is a representation of the record set as described in RFC 2136. /// diff --git a/src/tsig.rs b/src/tsig.rs index 806b551..0c32e98 100644 --- a/src/tsig.rs +++ b/src/tsig.rs @@ -6,14 +6,14 @@ use std::{ }; use digest::KeyInit; -use hmac::{Hmac, Mac}; -use once_cell::sync::Lazy; -use trust_dns_client::{ +use hickory_client::{ op, proto::error::{ProtoError, ProtoResult}, rr, serialize::binary::{BinEncodable, BinEncoder}, }; +use hmac::{Hmac, Mac}; +use once_cell::sync::Lazy; #[derive(Debug)] pub enum Error { @@ -198,7 +198,7 @@ impl TryFrom for rr::RData { encoder.set_canonical_names(true); tsig.emit(&mut encoder)?; Ok(rr::RData::Unknown { - code: 250, + code: rr::RecordType::Unknown(250), rdata: rr::rdata::null::NULL::with(encoded), }) } diff --git a/src/update.rs b/src/update.rs index 5e751d1..c38fb16 100644 --- a/src/update.rs +++ b/src/update.rs @@ -8,12 +8,12 @@ use std::{ use anyhow::anyhow; use futures::stream::{FuturesUnordered, TryStreamExt}; -use tokio::time::{sleep, timeout}; -use trust_dns_client::{ +use hickory_client::{ op::{Message, Query}, proto::xfer::{DnsHandle, DnsRequestOptions}, rr, }; +use tokio::time::{sleep, timeout}; use crate::{ record::{RecordSet, RsData}, @@ -180,7 +180,7 @@ where } else { return Err(anyhow!("SOA record for {} not found", options.zone)); }; - let mut server = dns.open(runtime, master).await?; + let server = dns.open(runtime, master).await?; // TODO: probably should check responses let _reponses: Vec<_> = server.send(message).try_collect().await?; Ok(()) @@ -257,7 +257,7 @@ where if options.exclude.contains(&ip) { return Ok(()); } - let mut server = dns.open(runtime, SocketAddr::new(ip, 53)).await?; + let server = dns.open(runtime, SocketAddr::new(ip, 53)).await?; let server_name = server_name.clone(); let options = Rc::clone(&options); let query = options.get_query(); diff --git a/src/update_message.rs b/src/update_message.rs index 1038e09..ee72bf1 100644 --- a/src/update_message.rs +++ b/src/update_message.rs @@ -1,9 +1,9 @@ -use trust_dns_client::{ +use hickory_client::{ op::{Message, MessageType, OpCode, Query, UpdateMessage}, rr::{DNSClass, Name, Record, RecordSet, RecordType}, }; -// This code is taken from `update_message.rs` in the `trust_dns` crate, and +// This code is taken from `update_message.rs` in the `hickory` crate, and // adapted to omit EDNS. pub fn create(rrset: RecordSet, zone_origin: Name) -> Message { // TODO: assert non-empty rrset? diff --git a/src/util.rs b/src/util.rs index b779c8e..1685c96 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,8 +5,8 @@ use std::{ str::FromStr, }; -use trust_dns_client::{op::ResponseCode, proto::error::ProtoError, rr}; -use trust_dns_resolver::error::{ResolveError, ResolveErrorKind}; +use hickory_client::{op::ResponseCode, proto::error::ProtoError, rr}; +use hickory_resolver::error::{ResolveError, ResolveErrorKind}; use crate::Resolver; From d1ff9d36b0b61939e78f455ffb3fd33e95eaccbb Mon Sep 17 00:00:00 2001 From: Alexander Huemer Date: Sat, 21 Feb 2026 23:58:24 +0100 Subject: [PATCH 3/4] Specify type explicitly --- src/update.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/update.rs b/src/update.rs index c38fb16..bef3c49 100644 --- a/src/update.rs +++ b/src/update.rs @@ -234,7 +234,7 @@ where ) }) .collect(); - results.try_collect().await?; + results.try_collect::<()>().await?; Ok(()) } From ee6cabbc4e56b531fa1dd69d0b78cc8555580ab9 Mon Sep 17 00:00:00 2001 From: Alexander Huemer Date: Sun, 22 Feb 2026 00:00:43 +0100 Subject: [PATCH 4/4] Refer to lifetime consistently --- src/record.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/record.rs b/src/record.rs index 9719816..73b0bb7 100644 --- a/src/record.rs +++ b/src/record.rs @@ -54,7 +54,7 @@ impl RecordSet { &self.data } - pub fn iter_data(&self) -> RsDataIter { + pub fn iter_data(&self) -> RsDataIter<'_> { let inner = match &self.data { RsData::TXT(txts) => RsDataIterInner::TXT(txts.iter()), RsData::A(addrs) => RsDataIterInner::A(addrs.iter()),