Skip to content

Commit c5399fb

Browse files
committed
refactor: Make Use TxtLookup type in favor of &[Record]
1 parent babec3a commit c5399fb

File tree

1 file changed

+27
-32
lines changed

1 file changed

+27
-32
lines changed

iroh/src/dns/node_info.rs

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,9 @@ impl NodeInfo {
162162
self.into()
163163
}
164164

165-
/// Parses a [`NodeInfo`] from a set of DNS records.
166-
pub fn from_hickory_records(records: &[hickory_resolver::proto::rr::Record]) -> Result<Self> {
167-
let attrs = TxtAttrs::from_hickory_records(records)?;
165+
/// Parses a [`NodeInfo`] from a TXT records lookup.
166+
pub fn from_hickory_lookup(lookup: hickory_resolver::lookup::TxtLookup) -> Result<Self> {
167+
let attrs = TxtAttrs::from_hickory_lookup(lookup)?;
168168
Ok(attrs.into())
169169
}
170170

@@ -240,13 +240,9 @@ impl<T: FromStr + Display + Hash + Ord> TxtAttrs<T> {
240240
}
241241

242242
/// Creates [`TxtAttrs`] from a node id and an iterator of "{key}={value}" strings.
243-
pub fn from_strings(
244-
node_id: NodeId,
245-
strings: impl Iterator<Item = Result<String>>,
246-
) -> Result<Self> {
243+
pub fn from_strings(node_id: NodeId, strings: impl Iterator<Item = String>) -> Result<Self> {
247244
let mut attrs: BTreeMap<T, Vec<String>> = BTreeMap::new();
248245
for s in strings {
249-
let s = s?;
250246
let mut parts = s.split('=');
251247
let (Some(key), Some(value)) = (parts.next(), parts.next()) else {
252248
continue;
@@ -262,7 +258,7 @@ impl<T: FromStr + Display + Hash + Ord> TxtAttrs<T> {
262258
async fn lookup(resolver: &TokioResolver, name: Name) -> Result<Self> {
263259
let name = ensure_iroh_txt_label(name)?;
264260
let lookup = resolver.txt_lookup(name).await?;
265-
let attrs = Self::from_hickory_records(lookup.as_lookup().records())?;
261+
let attrs = Self::from_hickory_lookup(lookup)?;
266262
Ok(attrs)
267263
}
268264

@@ -311,29 +307,23 @@ impl<T: FromStr + Display + Hash + Ord> TxtAttrs<T> {
311307
_ => None,
312308
});
313309

314-
let txt_strs = txt_data.filter_map(|s| String::try_from(s.clone()).ok().map(Ok));
310+
let txt_strs = txt_data.filter_map(|s| String::try_from(s.clone()).ok());
315311
Self::from_strings(node_id, txt_strs)
316312
}
317313

318-
/// Parses a set of DNS resource records.
319-
pub fn from_hickory_records(records: &[hickory_resolver::proto::rr::Record]) -> Result<Self> {
320-
use hickory_resolver::proto::rr;
321-
let mut records = records.iter().filter_map(|rr| match rr.data() {
322-
rr::RData::TXT(txt) => {
323-
node_id_from_hickory_name(rr.name()).map(|node_id| (node_id, txt))
314+
/// Parses a TXT records lookup.
315+
pub fn from_hickory_lookup(lookup: hickory_resolver::lookup::TxtLookup) -> Result<Self> {
316+
let node_id = node_id_from_hickory_name(lookup.query().name())
317+
.ok_or_else(|| anyhow!("invalid DNS answer: not a query for _iroh.z32encodedpubkey"))?;
318+
319+
let strings = lookup.as_lookup().record_iter().filter_map(|record| {
320+
match node_id_from_hickory_name(record.name()) {
321+
// Filter out only TXT record answers that match the node_id we searched for.
322+
Some(n) if n == node_id => record.data().as_txt().map(|txt| txt.to_string()),
323+
_ => None,
324324
}
325-
_ => None,
326325
});
327-
let (node_id, first) = records.next().ok_or_else(|| {
328-
anyhow!("invalid DNS answer: no TXT record with name _iroh.z32encodedpubkey found")
329-
})?;
330-
let strings = records.map(|(n, txt)| {
331-
if n == node_id {
332-
Ok(txt.to_string())
333-
} else {
334-
Err(anyhow!("invalid DNS answer: all _iroh txt records must belong to the same node domain"))
335-
}
336-
}).chain(Some(Ok(first.to_string())));
326+
337327
Self::from_strings(node_id, strings)
338328
}
339329

@@ -410,10 +400,14 @@ fn node_domain(node_id: &NodeId, origin: &str) -> Result<Name> {
410400

411401
#[cfg(test)]
412402
mod tests {
413-
use std::{collections::BTreeSet, str::FromStr};
403+
use std::{collections::BTreeSet, str::FromStr, sync::Arc};
414404

415405
use hickory_resolver::{
416-
proto::rr::{rdata::TXT, RData, Record},
406+
lookup::Lookup,
407+
proto::{
408+
op::Query,
409+
rr::{rdata::TXT, RData, Record, RecordType},
410+
},
417411
Name,
418412
};
419413
use iroh_base::{NodeId, SecretKey};
@@ -460,7 +454,8 @@ mod tests {
460454
let name = Name::from_utf8(
461455
"_iroh.dgjpkxyn3zyrk3zfads5duwdgbqpkwbjxfj4yt7rezidr3fijccy.dns.iroh.link.",
462456
)?;
463-
let test_records = [
457+
let query = Query::query(name.clone(), RecordType::TXT);
458+
let records = [
464459
Record::from_rdata(
465460
name.clone(),
466461
30,
@@ -479,9 +474,9 @@ mod tests {
479474
])),
480475
),
481476
];
477+
let lookup = Lookup::new_with_max_ttl(query, Arc::new(records));
482478

483-
let node_info = NodeInfo::from_hickory_records(&test_records)?;
484-
479+
let node_info = NodeInfo::from_hickory_lookup(lookup.into())?;
485480
assert_eq!(
486481
node_info,
487482
NodeInfo {

0 commit comments

Comments
 (0)