From b5d259d8a7a4d2046292a9a2788f63e1080a6911 Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Thu, 21 Mar 2024 17:51:40 +0100 Subject: [PATCH] Change ToDname/ToRelativeDname to have try_to_*name and to_*name pairs. --- src/base/name/traits.rs | 77 +++++++++++++++++++++++++++---- src/net/client/cache.rs | 11 +---- src/resolv/lookup/srv.rs | 4 +- src/tsig/mod.rs | 2 +- src/zonefile/inplace.rs | 4 +- tests/net/stelline/parse_query.rs | 4 +- 6 files changed, 76 insertions(+), 26 deletions(-) diff --git a/src/base/name/traits.rs b/src/base/name/traits.rs index 5c86493bc..2d7df1276 100644 --- a/src/base/name/traits.rs +++ b/src/base/name/traits.rs @@ -115,9 +115,7 @@ pub trait ToDname: ToLabelIter { /// labels of the name and adds them one by one to [`Dname`]. This will /// work for any name but an optimized implementation can be provided for /// some types of names. - /// - /// [`Dname`]: struct.Dname.html - fn to_dname( + fn try_to_dname( &self, ) -> Result, BuilderAppendError> where @@ -131,8 +129,22 @@ pub trait ToDname: ToLabelIter { Ok(unsafe { Dname::from_octets_unchecked(builder.freeze()) }) } + /// Converts the name into a single, uncompressed name. + /// + /// This is the same as [`try_to_dname`][ToDname::try_to_dname] but for + /// builder types with an unrestricted buffer. + fn to_dname(&self) -> Dname + where + Octets: FromBuilder, + ::Builder: + OctetsBuilder, + ::Builder: EmptyBuilder, + { + infallible(self.try_to_dname()) + } + /// Converts the name into a single name in canonical form. - fn to_canonical_dname( + fn try_to_canonical_dname( &self, ) -> Result, BuilderAppendError> where @@ -146,6 +158,21 @@ pub trait ToDname: ToLabelIter { Ok(unsafe { Dname::from_octets_unchecked(builder.freeze()) }) } + /// Converts the name into a single name in canonical form. + /// + /// This is the same as + /// [`try_to_canonical_dname`][ToDname::try_to_canonical_dname] but for + /// builder types with an unrestricted buffer. + fn to_canonical_dname(&self) -> Dname + where + Octets: FromBuilder, + ::Builder: + OctetsBuilder, + ::Builder: EmptyBuilder, + { + infallible(self.try_to_canonical_dname()) + } + /// Returns an octets slice of the content if possible. /// /// If a value stores the domain name as one single octets sequence, it @@ -202,13 +229,13 @@ pub trait ToDname: ToLabelIter { /// Returns the domain name assembled into a `Vec`. #[cfg(feature = "std")] fn to_vec(&self) -> Dname> { - infallible(self.to_dname()) + self.to_dname() } /// Returns the domain name assembled into a bytes value. #[cfg(feature = "bytes")] fn to_bytes(&self) -> Dname { - infallible(self.to_dname()) + self.to_dname() } /// Tests whether `self` and `other` are equal. @@ -353,7 +380,7 @@ pub trait ToRelativeDname: ToLabelIter { /// some types of names. /// /// [`RelativeDname`]: struct.RelativeDname.html - fn to_relative_dname( + fn try_to_relative_dname( &self, ) -> Result, BuilderAppendError> where @@ -367,8 +394,23 @@ pub trait ToRelativeDname: ToLabelIter { Ok(unsafe { RelativeDname::from_octets_unchecked(builder.freeze()) }) } + /// Converts the name into a single, continous name. + /// + /// This is the same as + /// [`try_to_relative_dname`][ToRelativeDname::try_to_relative_dname] + /// but for builder types with an unrestricted buffer. + fn to_relative_dname(&self) -> RelativeDname + where + Octets: FromBuilder, + ::Builder: + OctetsBuilder, + ::Builder: EmptyBuilder, + { + infallible(self.try_to_relative_dname()) + } + /// Converts the name into a single name in canonical form. - fn to_canonical_relative_dname( + fn try_to_canonical_relative_dname( &self, ) -> Result, BuilderAppendError> where @@ -382,6 +424,21 @@ pub trait ToRelativeDname: ToLabelIter { Ok(unsafe { RelativeDname::from_octets_unchecked(builder.freeze()) }) } + /// Converts the name into a single name in canonical form. + /// + /// This is the same as + /// [`try_to_canonical_relative_dname`][ToRelativeDname::try_to_canonical_relative_dname] + /// but for builder types with an unrestricted buffer. + fn to_canonical_relative_dname(&self) -> RelativeDname + where + Octets: FromBuilder, + ::Builder: + OctetsBuilder, + ::Builder: EmptyBuilder, + { + infallible(self.try_to_canonical_relative_dname()) + } + /// Returns a byte slice of the content if possible. /// /// This method can is used to optimize comparision operations between @@ -434,13 +491,13 @@ pub trait ToRelativeDname: ToLabelIter { /// Returns the domain name assembled into a `Vec`. #[cfg(feature = "std")] fn to_vec(&self) -> RelativeDname> { - infallible(self.to_relative_dname()) + self.to_relative_dname() } /// Returns the domain name assembled into a bytes value. #[cfg(feature = "bytes")] fn to_bytes(&self) -> RelativeDname { - infallible(self.to_relative_dname()) + self.to_relative_dname() } /// Returns whether the name is empty. diff --git a/src/net/client/cache.rs b/src/net/client/cache.rs index 70bb41c4f..474190953 100644 --- a/src/net/client/cache.rs +++ b/src/net/client/cache.rs @@ -35,7 +35,7 @@ use crate::base::{ Dname, Header, Message, MessageBuilder, ParsedDname, StaticCompressor, Ttl, }; -use crate::dep::octseq::{octets::OctetsInto, Octets}; +use crate::dep::octseq::Octets; use crate::net::client::clock::{Clock, Elapsed, SystemClock}; use crate::net::client::request::{ ComposeRequest, Error, GetResponse, SendRequest, @@ -803,15 +803,8 @@ impl Key { where TDN: ToDname, { - let mut qname: Dname> = - qname.to_dname().expect("to_dname should not fail"); - - // Make sure qname is canonical. - qname.make_canonical(); - let qname: Dname = qname.octets_into(); - Self { - qname, + qname: qname.to_canonical_dname(), qclass, qtype, addo: AdDo::new(ad, dnssec_ok), diff --git a/src/resolv/lookup/srv.rs b/src/resolv/lookup/srv.rs index 249b10a6e..d3b26e616 100644 --- a/src/resolv/lookup/srv.rs +++ b/src/resolv/lookup/srv.rs @@ -297,7 +297,7 @@ impl SrvItem { srv.priority(), srv.weight(), srv.port(), - srv.target().to_dname().unwrap(), + srv.target().try_to_dname().unwrap(), ), fallback: false, resolved: None, @@ -306,7 +306,7 @@ impl SrvItem { fn fallback(name: impl ToDname, fallback_port: u16) -> Self { SrvItem { - srv: Srv::new(0, 0, fallback_port, name.to_dname().unwrap()), + srv: Srv::new(0, 0, fallback_port, name.try_to_dname().unwrap()), fallback: true, resolved: None, } diff --git a/src/tsig/mod.rs b/src/tsig/mod.rs index 63f89d862..c2acc8b0f 100644 --- a/src/tsig/mod.rs +++ b/src/tsig/mod.rs @@ -391,7 +391,7 @@ where algorithm: Algorithm, ) -> Option { // XXX This seems a bit wasteful. - let name = name.to_dname().unwrap(); + let name = name.try_to_dname().unwrap(); self.get(&(name, algorithm)).cloned() } } diff --git a/src/zonefile/inplace.rs b/src/zonefile/inplace.rs index cc1d0843e..2a0d61cd6 100644 --- a/src/zonefile/inplace.rs +++ b/src/zonefile/inplace.rs @@ -457,13 +457,13 @@ impl<'a> EntryScanner<'a> { fn scan_control(&mut self) -> Result { let ctrl = self.scan_string()?; if ctrl.eq_ignore_ascii_case("$ORIGIN") { - let origin = self.scan_dname()?.to_dname().unwrap(); + let origin = self.scan_dname()?.to_dname(); self.zonefile.buf.require_line_feed()?; Ok(ScannedEntry::Origin(origin)) } else if ctrl.eq_ignore_ascii_case("$INCLUDE") { let path = self.scan_string()?; let origin = if !self.zonefile.buf.is_line_feed() { - Some(self.scan_dname()?.to_dname().unwrap()) + Some(self.scan_dname()?.to_dname()) } else { None }; diff --git a/tests/net/stelline/parse_query.rs b/tests/net/stelline/parse_query.rs index 6bf22e4f2..399d1f94d 100644 --- a/tests/net/stelline/parse_query.rs +++ b/tests/net/stelline/parse_query.rs @@ -371,13 +371,13 @@ impl<'a> EntryScanner<'a> { fn scan_control(&mut self) -> Result { let ctrl = self.scan_string()?; if ctrl.eq_ignore_ascii_case("$ORIGIN") { - let origin = self.scan_dname()?.to_dname().unwrap(); + let origin = self.scan_dname()?.to_dname(); self.zonefile.buf.require_line_feed()?; Ok(ScannedEntry::Origin(origin)) } else if ctrl.eq_ignore_ascii_case("$INCLUDE") { let path = self.scan_string()?; let origin = if !self.zonefile.buf.is_line_feed() { - Some(self.scan_dname()?.to_dname().unwrap()) + Some(self.scan_dname()?.to_dname()) } else { None };