1 // Copyright 2015-2017 Benjamin Fry <benjaminfry@me.com>
2 //
3 // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4 // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5 // http://opensource.org/licenses/MIT>, at your option. This file may not be
6 // copied, modified, or distributed except according to those terms.
7 
8 //! domain name, aka labels, implementation
9 
10 use std::char;
11 use std::cmp::{Ordering, PartialEq};
12 use std::fmt::{self, Write};
13 use std::hash::{Hash, Hasher};
14 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
15 use std::str::FromStr;
16 
17 use crate::error::*;
18 use crate::rr::domain::label::{CaseInsensitive, CaseSensitive, IntoLabel, Label, LabelCmp};
19 use crate::rr::domain::usage::LOCALHOST as LOCALHOST_usage;
20 use crate::serialize::binary::*;
21 use ipnet::{IpNet, Ipv4Net, Ipv6Net};
22 #[cfg(feature = "serde-config")]
23 use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
24 use tinyvec::TinyVec;
25 
26 /// A domain name
27 #[derive(Clone, Default, Debug, Eq)]
28 pub struct Name {
29     is_fqdn: bool,
30     label_data: TinyVec<[u8; 32]>,
31     // This 24 is chosen because TinyVec accomodates an inline buffer up to 24 bytes without
32     // increasing its stack footprint
33     label_ends: TinyVec<[u8; 24]>,
34 }
35 
36 impl Name {
37     /// Create a new domain::Name, i.e. label
new() -> Self38     pub fn new() -> Self {
39         Default::default()
40     }
41 
42     /// Returns the root label, i.e. no labels, can probably make this better in the future.
root() -> Self43     pub fn root() -> Self {
44         let mut this = Self::new();
45         this.is_fqdn = true;
46         this
47     }
48 
49     /// Returns true if there are no labels, i.e. it's empty.
50     ///
51     /// In DNS the root is represented by `.`
52     ///
53     /// # Examples
54     ///
55     /// ```
56     /// use trust_dns_proto::rr::domain::Name;
57     ///
58     /// let root = Name::root();
59     /// assert_eq!(&root.to_string(), ".");
60     /// ```
is_root(&self) -> bool61     pub fn is_root(&self) -> bool {
62         self.label_ends.is_empty() && self.is_fqdn()
63     }
64 
65     /// Returns true if the name is a fully qualified domain name.
66     ///
67     /// If this is true, it has effects like only querying for this single name, as opposed to building
68     ///  up a search list in resolvers.
69     ///
70     /// *warning: this interface is unstable and may change in the future*
71     ///
72     /// # Examples
73     ///
74     /// ```
75     /// use std::str::FromStr;
76     /// use trust_dns_proto::rr::domain::Name;
77     ///
78     /// let name = Name::from_str("www").unwrap();
79     /// assert!(!name.is_fqdn());
80     ///
81     /// let name = Name::from_str("www.example.com").unwrap();
82     /// assert!(!name.is_fqdn());
83     ///
84     /// let name = Name::from_str("www.example.com.").unwrap();
85     /// assert!(name.is_fqdn());
86     /// ```
is_fqdn(&self) -> bool87     pub fn is_fqdn(&self) -> bool {
88         self.is_fqdn
89     }
90 
91     /// Specifies this name is a fully qualified domain name
92     ///
93     /// *warning: this interface is unstable and may change in the future*
set_fqdn(&mut self, val: bool)94     pub fn set_fqdn(&mut self, val: bool) {
95         self.is_fqdn = val
96     }
97 
98     /// Returns an iterator over the labels
iter(&self) -> LabelIter<'_>99     pub fn iter(&self) -> LabelIter<'_> {
100         LabelIter {
101             name: self,
102             index: 0,
103             started: false,
104             finished: false,
105         }
106     }
107 
108     /// Appends the label to the end of this name
109     ///
110     /// # Example
111     ///
112     /// ```rust
113     /// use std::str::FromStr;
114     /// use trust_dns_proto::rr::domain::Name;
115     ///
116     /// let name = Name::from_str("www.example").unwrap();
117     /// let name = name.append_label("com").unwrap();
118     /// assert_eq!(name, Name::from_str("www.example.com").unwrap());
119     /// ```
append_label<L: IntoLabel>(mut self, label: L) -> ProtoResult<Self>120     pub fn append_label<L: IntoLabel>(mut self, label: L) -> ProtoResult<Self> {
121         self.label_data
122             .extend_from_slice(label.into_label()?.as_bytes());
123         self.label_ends.push(self.label_data.len() as u8);
124         if self.len() > 255 {
125             return Err("labels exceed maximum length of 255".into());
126         };
127         Ok(self)
128     }
129 
130     /// Creates a new Name from the specified labels
131     ///
132     /// # Arguments
133     ///
134     /// * `labels` - vector of items which will be stored as Strings.
135     ///
136     /// # Examples
137     ///
138     /// ```rust
139     /// use std::str::FromStr;
140     /// use trust_dns_proto::rr::domain::Name;
141     ///
142     /// // From strings, uses utf8 conversion
143     /// let from_labels = Name::from_labels(vec!["www", "example", "com"]).unwrap();
144     /// assert_eq!(from_labels, Name::from_str("www.example.com").unwrap());
145     ///
146     /// // Force a set of bytes into labels (this is none-standard and potentially dangerous)
147     /// let from_labels = Name::from_labels(vec!["bad chars".as_bytes(), "example".as_bytes(), "com".as_bytes()]).unwrap();
148     /// assert_eq!(from_labels.iter().next(), Some(&b"bad chars"[..]));
149     ///
150     /// let root = Name::from_labels(Vec::<&str>::new()).unwrap();
151     /// assert!(root.is_root());
152     /// ```
from_labels<I, L>(labels: I) -> ProtoResult<Self> where I: IntoIterator<Item = L>, L: IntoLabel,153     pub fn from_labels<I, L>(labels: I) -> ProtoResult<Self>
154     where
155         I: IntoIterator<Item = L>,
156         L: IntoLabel,
157     {
158         let (labels, errors): (Vec<_>, Vec<_>) = labels
159             .into_iter()
160             .map(IntoLabel::into_label)
161             .partition(Result::is_ok);
162         let labels: Vec<_> = labels.into_iter().map(Result::unwrap).collect();
163         let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect();
164 
165         if labels.len() > 255 {
166             return Err("labels exceed maximum length of 255".into());
167         };
168         if !errors.is_empty() {
169             return Err(format!("error converting some labels: {:?}", errors).into());
170         };
171 
172         let mut name = Name {
173             is_fqdn: true,
174             ..Default::default()
175         };
176         for label in labels {
177             name = name.append_label(label)?;
178         }
179 
180         Ok(name)
181     }
182 
183     /// Appends `other` to `self`, returning a new `Name`
184     ///
185     /// Carries forward `is_fqdn` from `other`.
186     ///
187     /// # Examples
188     ///
189     /// ```rust
190     /// use std::str::FromStr;
191     /// use trust_dns_proto::rr::domain::Name;
192     ///
193     /// let local = Name::from_str("www").unwrap();
194     /// let domain = Name::from_str("example.com").unwrap();
195     /// assert!(!domain.is_fqdn());
196     ///
197     /// let name = local.clone().append_name(&domain);
198     /// assert_eq!(name, Name::from_str("www.example.com").unwrap());
199     /// assert!(!name.is_fqdn());
200     ///
201     /// // see also `Name::append_domain`
202     /// let domain = Name::from_str("example.com.").unwrap();
203     /// assert!(domain.is_fqdn());
204     /// let name = local.append_name(&domain);
205     /// assert_eq!(name, Name::from_str("www.example.com.").unwrap());
206     /// assert!(name.is_fqdn());
207     /// ```
append_name(mut self, other: &Self) -> Self208     pub fn append_name(mut self, other: &Self) -> Self {
209         for label in other.iter() {
210             self.label_data.extend_from_slice(label);
211             self.label_ends.push(self.label_data.len() as u8);
212         }
213 
214         self.is_fqdn = other.is_fqdn;
215         self
216     }
217 
218     /// Appends the `domain` to `self`, making the new `Name` an FQDN
219     ///
220     /// This is an alias for `append_name` with the added effect of marking the new `Name` as
221     /// a fully-qualified-domain-name.
222     ///
223     /// # Examples
224     ///
225     /// ```rust
226     /// use std::str::FromStr;
227     /// use trust_dns_proto::rr::domain::Name;
228     ///
229     /// let local = Name::from_str("www").unwrap();
230     /// let domain = Name::from_str("example.com").unwrap();
231     /// let name = local.append_domain(&domain);
232     /// assert_eq!(name, Name::from_str("www.example.com").unwrap());
233     /// assert!(name.is_fqdn())
234     /// ```
append_domain(self, domain: &Self) -> Self235     pub fn append_domain(self, domain: &Self) -> Self {
236         let mut this = self.append_name(domain);
237         this.set_fqdn(true);
238         this
239     }
240 
241     /// Creates a new Name with all labels lowercased
242     ///
243     /// # Examples
244     ///
245     /// ```
246     /// use std::cmp::Ordering;
247     /// use std::str::FromStr;
248     ///
249     /// use trust_dns_proto::rr::domain::{Label, Name};
250     ///
251     /// let example_com = Name::from_ascii("Example.Com").unwrap();
252     /// assert_eq!(example_com.cmp_case(&Name::from_str("example.com").unwrap()), Ordering::Less);
253     /// assert!(example_com.to_lowercase().eq_case(&Name::from_str("example.com").unwrap()));
254     /// ```
to_lowercase(&self) -> Self255     pub fn to_lowercase(&self) -> Self {
256         let new_label_data = self
257             .label_data
258             .iter()
259             .map(|c| c.to_ascii_lowercase())
260             .collect();
261         Name {
262             is_fqdn: self.is_fqdn,
263             label_data: new_label_data,
264             label_ends: self.label_ends.clone(),
265         }
266     }
267 
268     /// Trims off the first part of the name, to help with searching for the domain piece
269     ///
270     /// # Examples
271     ///
272     /// ```
273     /// use std::str::FromStr;
274     /// use trust_dns_proto::rr::domain::Name;
275     ///
276     /// let example_com = Name::from_str("example.com.").unwrap();
277     /// assert_eq!(example_com.base_name(), Name::from_str("com.").unwrap());
278     /// assert_eq!(Name::from_str("com.").unwrap().base_name(), Name::root());
279     /// assert_eq!(Name::root().base_name(), Name::root());
280     /// ```
base_name(&self) -> Name281     pub fn base_name(&self) -> Name {
282         let length = self.label_ends.len();
283         if length > 0 {
284             return self.trim_to(length - 1);
285         }
286         self.clone()
287     }
288 
289     /// Trims to the number of labels specified
290     ///
291     /// # Examples
292     ///
293     /// ```
294     /// use std::str::FromStr;
295     /// use trust_dns_proto::rr::domain::Name;
296     ///
297     /// let example_com = Name::from_str("example.com.").unwrap();
298     /// assert_eq!(example_com.trim_to(2), Name::from_str("example.com.").unwrap());
299     /// assert_eq!(example_com.trim_to(1), Name::from_str("com.").unwrap());
300     /// assert_eq!(example_com.trim_to(0), Name::root());
301     /// assert_eq!(example_com.trim_to(3), Name::from_str("example.com.").unwrap());
302     /// ```
trim_to(&self, num_labels: usize) -> Name303     pub fn trim_to(&self, num_labels: usize) -> Name {
304         if num_labels > self.label_ends.len() {
305             self.clone()
306         } else {
307             Name::from_labels(self.iter().skip(self.label_ends.len() - num_labels)).unwrap()
308         }
309     }
310 
311     /// same as `zone_of` allows for case sensitive call
zone_of_case(&self, name: &Self) -> bool312     pub fn zone_of_case(&self, name: &Self) -> bool {
313         let self_len = self.label_ends.len();
314         let name_len = name.label_ends.len();
315         if self_len == 0 {
316             return true;
317         }
318         if name_len == 0 {
319             // self_len != 0
320             return false;
321         }
322         if self_len > name_len {
323             return false;
324         }
325 
326         let self_iter = self.iter().rev();
327         let name_iter = name.iter().rev();
328 
329         let zip_iter = self_iter.zip(name_iter);
330 
331         for (self_label, name_label) in zip_iter {
332             if self_label != name_label {
333                 return false;
334             }
335         }
336 
337         true
338     }
339 
340     /// returns true if the name components of self are all present at the end of name
341     ///
342     /// # Example
343     ///
344     /// ```rust
345     /// use std::str::FromStr;
346     /// use trust_dns_proto::rr::domain::Name;
347     ///
348     /// let name = Name::from_str("www.example.com").unwrap();
349     /// let name = Name::from_str("www.example.com").unwrap();
350     /// let zone = Name::from_str("example.com").unwrap();
351     /// let another = Name::from_str("example.net").unwrap();
352     /// assert!(zone.zone_of(&name));
353     /// assert!(!name.zone_of(&zone));
354     /// assert!(!another.zone_of(&name));
355     /// ```
zone_of(&self, name: &Self) -> bool356     pub fn zone_of(&self, name: &Self) -> bool {
357         let self_lower = self.to_lowercase();
358         let name_lower = name.to_lowercase();
359 
360         self_lower.zone_of_case(&name_lower)
361     }
362 
363     /// Returns the number of labels in the name, discounting `*`.
364     ///
365     /// # Examples
366     ///
367     /// ```
368     /// use std::str::FromStr;
369     /// use trust_dns_proto::rr::domain::Name;
370     ///
371     /// let root = Name::root();
372     /// assert_eq!(root.num_labels(), 0);
373     ///
374     /// let example_com = Name::from_str("example.com").unwrap();
375     /// assert_eq!(example_com.num_labels(), 2);
376     ///
377     /// let star_example_com = Name::from_str("*.example.com.").unwrap();
378     /// assert_eq!(star_example_com.num_labels(), 2);
379     /// ```
num_labels(&self) -> u8380     pub fn num_labels(&self) -> u8 {
381         // it is illegal to have more than 256 labels.
382 
383         let num = self.label_ends.len() as u8;
384 
385         self.iter()
386             .next()
387             .map(|l| if l == b"*" { num - 1 } else { num })
388             .unwrap_or(num)
389     }
390 
391     /// returns the length in bytes of the labels. '.' counts as 1
392     ///
393     /// This can be used as an estimate, when serializing labels, they will often be compressed
394     /// and/or escaped causing the exact length to be different.
395     ///
396     /// # Examples
397     ///
398     /// ```
399     /// use std::str::FromStr;
400     /// use trust_dns_proto::rr::domain::Name;
401     ///
402     /// assert_eq!(Name::from_str("www.example.com.").unwrap().len(), 16);
403     /// assert_eq!(Name::from_str(".").unwrap().len(), 1);
404     /// assert_eq!(Name::root().len(), 1);
405     /// ```
len(&self) -> usize406     pub fn len(&self) -> usize {
407         let dots = if !self.label_ends.is_empty() {
408             self.label_ends.len()
409         } else {
410             1
411         };
412         dots + self.label_data.len()
413     }
414 
415     /// Returns whether the length of the labels, in bytes is 0. In practice, since '.' counts as
416     /// 1, this is never the case so the method returns false.
is_empty(&self) -> bool417     pub fn is_empty(&self) -> bool {
418         false
419     }
420 
421     /// attempts to parse a name such as `"example.com."` or `"subdomain.example.com."`
422     ///
423     /// # Examples
424     ///
425     /// ```rust
426     /// use std::str::FromStr;
427     /// use trust_dns_proto::rr::domain::Name;
428     ///
429     /// let name = Name::from_str("example.com.").unwrap();
430     /// assert_eq!(name.base_name(), Name::from_str("com.").unwrap());
431     /// assert_eq!(name.iter().next(), Some(&b"example"[..]));
432     /// ```
parse(local: &str, origin: Option<&Self>) -> ProtoResult<Self>433     pub fn parse(local: &str, origin: Option<&Self>) -> ProtoResult<Self> {
434         Self::from_encoded_str::<LabelEncUtf8>(local, origin)
435     }
436 
437     /// Will convert the string to a name only allowing ascii as valid input
438     ///
439     /// This method will also preserve the case of the name where that's desirable
440     ///
441     /// # Examples
442     ///
443     /// ```
444     /// use trust_dns_proto::rr::Name;
445     ///
446     /// let bytes_name = Name::from_labels(vec!["WWW".as_bytes(), "example".as_bytes(), "COM".as_bytes()]).unwrap();
447     /// let ascii_name = Name::from_ascii("WWW.example.COM.").unwrap();
448     /// let lower_name = Name::from_ascii("www.example.com.").unwrap();
449     ///
450     /// assert!(bytes_name.eq_case(&ascii_name));
451     /// assert!(!lower_name.eq_case(&ascii_name));
452     ///
453     /// // escaped values
454     /// let bytes_name = Name::from_labels(vec!["email.name".as_bytes(), "example".as_bytes(), "com".as_bytes()]).unwrap();
455     /// let name = Name::from_ascii("email\\.name.example.com.").unwrap();
456     ///
457     /// assert_eq!(bytes_name, name);
458     ///
459     /// let bytes_name = Name::from_labels(vec!["bad.char".as_bytes(), "example".as_bytes(), "com".as_bytes()]).unwrap();
460     /// let name = Name::from_ascii("bad\\056char.example.com.").unwrap();
461     ///
462     /// assert_eq!(bytes_name, name);
463     /// ```
from_ascii<S: AsRef<str>>(name: S) -> ProtoResult<Self>464     pub fn from_ascii<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
465         Self::from_encoded_str::<LabelEncAscii>(name.as_ref(), None)
466     }
467 
468     // TODO: currently reserved to be private to the crate, due to confusion of IDNA vs. utf8 in https://tools.ietf.org/html/rfc6762#appendix-F
469     /// Will convert the string to a name using IDNA, punycode, to encode the UTF8 as necessary
470     ///
471     /// When making names IDNA compatible, there is a side-effect of lowercasing the name.
472     ///
473     /// # Examples
474     ///
475     /// ```
476     /// use std::str::FromStr;
477     /// use trust_dns_proto::rr::Name;
478     ///
479     /// let bytes_name = Name::from_labels(vec!["WWW".as_bytes(), "example".as_bytes(), "COM".as_bytes()]).unwrap();
480     ///
481     /// // from_str calls through to from_utf8
482     /// let utf8_name = Name::from_str("WWW.example.COM.").unwrap();
483     /// let lower_name = Name::from_str("www.example.com.").unwrap();
484     ///
485     /// assert!(!bytes_name.eq_case(&utf8_name));
486     /// assert!(lower_name.eq_case(&utf8_name));
487     /// ```
from_utf8<S: AsRef<str>>(name: S) -> ProtoResult<Self>488     pub fn from_utf8<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
489         Self::from_encoded_str::<LabelEncUtf8>(name.as_ref(), None)
490     }
491 
492     /// First attempts to decode via `from_utf8`, if that fails IDNA checks, then falls back to
493     /// ascii decoding.
494     ///
495     /// # Examples
496     ///
497     /// ```
498     /// use std::str::FromStr;
499     /// use trust_dns_proto::rr::Name;
500     ///
501     /// // Ok, underscore in the beginning of a name
502     /// assert!(Name::from_utf8("_allows.example.com.").is_ok());
503     ///
504     /// // Error, underscore in the end
505     /// assert!(Name::from_utf8("dis_allowed.example.com.").is_err());
506     ///
507     /// // Ok, relaxed mode
508     /// assert!(Name::from_str_relaxed("allow_in_.example.com.").is_ok());
509     /// ```
from_str_relaxed<S: AsRef<str>>(name: S) -> ProtoResult<Self>510     pub fn from_str_relaxed<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
511         let name = name.as_ref();
512         Self::from_utf8(name).or_else(|_| Self::from_ascii(name))
513     }
514 
from_encoded_str<E: LabelEnc>(local: &str, origin: Option<&Self>) -> ProtoResult<Self>515     fn from_encoded_str<E: LabelEnc>(local: &str, origin: Option<&Self>) -> ProtoResult<Self> {
516         let mut name = Name::new();
517         let mut label = String::new();
518 
519         let mut state = ParseState::Label;
520 
521         // short circuit root parse
522         if local == "." {
523             name.set_fqdn(true);
524             return Ok(name);
525         }
526 
527         // TODO: it would be nice to relocate this to Label, but that is hard because the label boundary can only be detected after processing escapes...
528         // evaluate all characters
529         for ch in local.chars() {
530             match state {
531                 ParseState::Label => match ch {
532                     '.' => {
533                         name = name.append_label(E::to_label(&label)?)?;
534                         label.clear();
535                     }
536                     '\\' => state = ParseState::Escape1,
537                     ch if !ch.is_control() && !ch.is_whitespace() => label.push(ch),
538                     _ => return Err(format!("unrecognized char: {}", ch).into()),
539                 },
540                 ParseState::Escape1 => {
541                     if ch.is_numeric() {
542                         state =
543                             ParseState::Escape2(ch.to_digit(8).ok_or_else(|| {
544                                 ProtoError::from(format!("illegal char: {}", ch))
545                             })?);
546                     } else {
547                         // it's a single escaped char
548                         label.push(ch);
549                         state = ParseState::Label;
550                     }
551                 }
552                 ParseState::Escape2(i) => {
553                     if ch.is_numeric() {
554                         state = ParseState::Escape3(
555                             i,
556                             ch.to_digit(8)
557                                 .ok_or_else(|| ProtoError::from(format!("illegal char: {}", ch)))?,
558                         );
559                     } else {
560                         return Err(ProtoError::from(format!("unrecognized char: {}", ch)));
561                     }
562                 }
563                 ParseState::Escape3(i, ii) => {
564                     if ch.is_numeric() {
565                         // octal conversion
566                         let val: u32 = (i * 8 * 8)
567                             + (ii * 8)
568                             + ch.to_digit(8)
569                                 .ok_or_else(|| ProtoError::from(format!("illegal char: {}", ch)))?;
570                         let new: char = char::from_u32(val)
571                             .ok_or_else(|| ProtoError::from(format!("illegal char: {}", ch)))?;
572                         label.push(new);
573                         state = ParseState::Label;
574                     } else {
575                         return Err(format!("unrecognized char: {}", ch).into());
576                     }
577                 }
578             }
579         }
580 
581         if !label.is_empty() {
582             name = name.append_label(E::to_label(&label)?)?;
583         }
584 
585         if local.ends_with('.') {
586             name.set_fqdn(true);
587         } else if let Some(other) = origin {
588             return Ok(name.append_domain(other));
589         }
590 
591         Ok(name)
592     }
593 
594     /// Emits the canonical version of the name to the encoder.
595     ///
596     /// In canonical form, there will be no pointers written to the encoder (i.e. no compression).
emit_as_canonical( &self, encoder: &mut BinEncoder<'_>, canonical: bool, ) -> ProtoResult<()>597     pub fn emit_as_canonical(
598         &self,
599         encoder: &mut BinEncoder<'_>,
600         canonical: bool,
601     ) -> ProtoResult<()> {
602         let buf_len = encoder.len(); // lazily assert the size is less than 255...
603                                      // lookup the label in the BinEncoder
604                                      // if it exists, write the Pointer
605         let labels = self.iter();
606 
607         // start index of each label
608         let mut labels_written: Vec<usize> = Vec::with_capacity(self.label_ends.len());
609 
610         if canonical {
611             for label in labels {
612                 encoder.emit_character_data(label)?;
613             }
614         } else {
615             // we're going to write out each label, tracking the indexes of the start to each label
616             //   then we'll look to see if we can remove them and recapture the capacity in the buffer...
617             for label in labels {
618                 if label.len() > 63 {
619                     return Err(ProtoErrorKind::LabelBytesTooLong(label.len()).into());
620                 }
621 
622                 labels_written.push(encoder.offset());
623                 encoder.emit_character_data(label)?;
624             }
625 
626             // we've written all the labels to the buf, the current offset is the end
627             let last_index = encoder.offset();
628 
629             // now search for other labels already stored matching from the beginning label, strip then to the end
630             //   if it's not found, then store this as a new label
631             for label_idx in &labels_written {
632                 let label_ptr: Option<u16> = encoder.get_label_pointer(*label_idx, last_index);
633 
634                 // before we write the label, let's look for the current set of labels.
635                 if let Some(loc) = label_ptr {
636                     // reset back to the beginning of this label, and then write the pointer...
637                     encoder.set_offset(*label_idx);
638                     encoder.trim();
639 
640                     // write out the pointer marker
641                     //  or'd with the location which shouldn't be larger than this 2^14 or 16k
642                     encoder.emit_u16(0xC000u16 | (loc & 0x3FFFu16))?;
643 
644                     // we found a pointer don't write more, break
645                     return Ok(());
646                 } else {
647                     // no existing label exists, store this new one.
648                     encoder.store_label_pointer(*label_idx, last_index);
649                 }
650             }
651         }
652 
653         // if we're getting here, then we didn't write out a pointer and are ending the name
654         // the end of the list of names
655         encoder.emit(0)?;
656 
657         // the entire name needs to be less than 256.
658         let length = encoder.len() - buf_len;
659         if length > 255 {
660             return Err(ProtoErrorKind::DomainNameTooLong(length).into());
661         }
662 
663         Ok(())
664     }
665 
666     /// Writes the labels, as lower case, to the encoder
667     ///
668     /// # Arguments
669     ///
670     /// * `encoder` - encoder for writing this name
671     /// * `lowercase` - if true the name will be lowercased, otherwise it will not be changed when writing
emit_with_lowercase( &self, encoder: &mut BinEncoder<'_>, lowercase: bool, ) -> ProtoResult<()>672     pub fn emit_with_lowercase(
673         &self,
674         encoder: &mut BinEncoder<'_>,
675         lowercase: bool,
676     ) -> ProtoResult<()> {
677         let is_canonical_names = encoder.is_canonical_names();
678         if lowercase {
679             self.to_lowercase()
680                 .emit_as_canonical(encoder, is_canonical_names)
681         } else {
682             self.emit_as_canonical(encoder, is_canonical_names)
683         }
684     }
685 
686     /// compares with the other label, ignoring case
cmp_with_f<F: LabelCmp>(&self, other: &Self) -> Ordering687     fn cmp_with_f<F: LabelCmp>(&self, other: &Self) -> Ordering {
688         if self.label_ends.is_empty() && other.label_ends.is_empty() {
689             return Ordering::Equal;
690         }
691 
692         // we reverse the iters so that we are comparing from the root/domain to the local...
693         let self_labels = self.iter().rev();
694         let other_labels = other.iter().rev();
695 
696         for (l, r) in self_labels.zip(other_labels) {
697             let l = Label::from_raw_bytes(l).unwrap();
698             let r = Label::from_raw_bytes(r).unwrap();
699             match l.cmp_with_f::<F>(&r) {
700                 Ordering::Equal => continue,
701                 not_eq => return not_eq,
702             }
703         }
704 
705         self.label_ends.len().cmp(&other.label_ends.len())
706     }
707 
708     /// Case sensitive comparison
cmp_case(&self, other: &Self) -> Ordering709     pub fn cmp_case(&self, other: &Self) -> Ordering {
710         self.cmp_with_f::<CaseSensitive>(other)
711     }
712 
713     /// Compares the Names, in a case sensitive manner
eq_case(&self, other: &Self) -> bool714     pub fn eq_case(&self, other: &Self) -> bool {
715         self.cmp_with_f::<CaseSensitive>(other) == Ordering::Equal
716     }
717 
718     /// Converts this name into an ascii safe string.
719     ///
720     /// If the name is an IDNA name, then the name labels will be returned with the `xn--` prefix.
721     ///  see `to_utf8` or the `Display` impl for methods which convert labels to utf8.
to_ascii(&self) -> String722     pub fn to_ascii(&self) -> String {
723         let mut s = String::with_capacity(self.len());
724         self.write_labels::<String, LabelEncAscii>(&mut s)
725             .expect("string conversion of name should not fail");
726         s
727     }
728 
729     /// Converts the Name labels to the utf8 String form.
730     ///
731     /// This converts the name to an unescaped format, that could be used with parse. If, the name is
732     ///  is followed by the final `.`, e.g. as in `www.example.com.`, which represents a fully
733     ///  qualified Name.
to_utf8(&self) -> String734     pub fn to_utf8(&self) -> String {
735         format!("{}", self)
736     }
737 
738     /// Converts a *.arpa Name in a PTR record back into an IpNet if possible.
parse_arpa_name(&self) -> Result<IpNet, ProtoError>739     pub fn parse_arpa_name(&self) -> Result<IpNet, ProtoError> {
740         if !self.is_fqdn() {
741             return Err("PQDN cannot be valid arpa name".into());
742         }
743         let mut iter = self.iter().rev();
744         let first = iter
745             .next()
746             .ok_or_else(|| ProtoError::from("not an arpa address"))?;
747         if !"arpa".eq_ignore_ascii_case(std::str::from_utf8(first)?) {
748             return Err("not an arpa address".into());
749         }
750         let second = iter
751             .next()
752             .ok_or_else(|| ProtoError::from("invalid arpa address"))?;
753         let mut prefix_len: u8 = 0;
754         match &std::str::from_utf8(second)?.to_ascii_lowercase()[..] {
755             "in-addr" => {
756                 let mut octets: [u8; 4] = [0; 4];
757                 for octet in octets.iter_mut() {
758                     match iter.next() {
759                         Some(label) => *octet = std::str::from_utf8(label)?.parse()?,
760                         None => break,
761                     }
762                     prefix_len += 8;
763                 }
764                 if iter.next().is_some() {
765                     return Err("unrecognized in-addr.arpa.".into());
766                 }
767                 Ok(IpNet::V4(
768                     Ipv4Net::new(octets.into(), prefix_len).expect("Ipv4Net::new"),
769                 ))
770             }
771             "ip6" => {
772                 let mut address: u128 = 0;
773                 while prefix_len < 128 {
774                     match iter.next() {
775                         Some(label) => {
776                             if label.len() == 1 {
777                                 prefix_len += 4;
778                                 let hex = u8::from_str_radix(std::str::from_utf8(label)?, 16)?;
779                                 address |= u128::from(hex) << (128 - prefix_len);
780                             } else {
781                                 return Err("invalid label length for ip6.arpa".into());
782                             }
783                         }
784                         None => break,
785                     }
786                 }
787                 if iter.next().is_some() {
788                     return Err("unrecognized ip6.arpa.".into());
789                 }
790                 Ok(IpNet::V6(
791                     Ipv6Net::new(address.into(), prefix_len).expect("Ipv6Net::new"),
792                 ))
793             }
794             _ => Err("unrecognized arpa address".into()),
795         }
796     }
797 
write_labels<W: Write, E: LabelEnc>(&self, f: &mut W) -> Result<(), fmt::Error>798     fn write_labels<W: Write, E: LabelEnc>(&self, f: &mut W) -> Result<(), fmt::Error> {
799         let mut iter = self.iter().map(|b| Label::from_raw_bytes(b).unwrap());
800         if let Some(label) = iter.next() {
801             E::write_label(f, &label)?;
802         }
803 
804         for label in iter {
805             write!(f, ".")?;
806             E::write_label(f, &label)?;
807         }
808 
809         // if it was the root name
810         if self.is_root() || self.is_fqdn() {
811             write!(f, ".")?;
812         }
813         Ok(())
814     }
815 
816     /// Returns true if the `Name` is either localhost or in the localhost zone.
817     ///
818     /// # Example
819     ///
820     /// ```
821     /// use std::str::FromStr;
822     /// use trust_dns_proto::rr::Name;
823     ///
824     /// let name = Name::from_str("localhost").unwrap();
825     /// assert!(name.is_localhost());
826     ///
827     /// let name = Name::from_str("localhost.").unwrap();
828     /// assert!(name.is_localhost());
829     ///
830     /// let name = Name::from_str("my.localhost.").unwrap();
831     /// assert!(name.is_localhost());
832     /// ```
is_localhost(&self) -> bool833     pub fn is_localhost(&self) -> bool {
834         LOCALHOST_usage.zone_of(self)
835     }
836 
837     /// True if the first label of this name is the wildcard, i.e. '*'
838     ///
839     /// # Example
840     ///
841     /// ```
842     /// use std::str::FromStr;
843     /// use trust_dns_proto::rr::Name;
844     ///
845     /// let name = Name::from_str("www.example.com").unwrap();
846     /// assert!(!name.is_wildcard());
847     ///
848     /// let name = Name::from_str("*.example.com").unwrap();
849     /// assert!(name.is_wildcard());
850     ///
851     /// let name = Name::root();
852     /// assert!(!name.is_wildcard());
853     /// ```
is_wildcard(&self) -> bool854     pub fn is_wildcard(&self) -> bool {
855         self.iter().next().map_or(false, |l| l == b"*")
856     }
857 
858     /// Converts a name to a wildcard, by replacing the first label with `*`
859     ///
860     /// # Example
861     ///
862     /// ```
863     /// use std::str::FromStr;
864     /// use trust_dns_proto::rr::Name;
865     ///
866     /// let name = Name::from_str("www.example.com").unwrap().into_wildcard();
867     /// assert_eq!(name, Name::from_str("*.example.com.").unwrap());
868     ///
869     /// // does nothing if the root
870     /// let name = Name::root().into_wildcard();
871     /// assert_eq!(name, Name::root());
872     /// ```
into_wildcard(self) -> Self873     pub fn into_wildcard(self) -> Self {
874         if self.label_ends.is_empty() {
875             return Name::root();
876         }
877         let mut label_data = TinyVec::new();
878         label_data.push(b'*');
879         let mut label_ends = TinyVec::new();
880         label_ends.push(1);
881         for label in self.iter().skip(1) {
882             label_data.extend_from_slice(label);
883             label_ends.push(label_data.len() as u8);
884         }
885         Name {
886             label_data,
887             label_ends,
888             is_fqdn: self.is_fqdn,
889         }
890     }
891 }
892 
893 trait LabelEnc {
894     #[allow(clippy::wrong_self_convention)]
to_label(name: &str) -> ProtoResult<Label>895     fn to_label(name: &str) -> ProtoResult<Label>;
write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error>896     fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error>;
897 }
898 
899 struct LabelEncAscii;
900 impl LabelEnc for LabelEncAscii {
901     #[allow(clippy::wrong_self_convention)]
to_label(name: &str) -> ProtoResult<Label>902     fn to_label(name: &str) -> ProtoResult<Label> {
903         Label::from_ascii(name)
904     }
905 
write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error>906     fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error> {
907         label.write_ascii(f)
908     }
909 }
910 
911 struct LabelEncUtf8;
912 impl LabelEnc for LabelEncUtf8 {
913     #[allow(clippy::wrong_self_convention)]
to_label(name: &str) -> ProtoResult<Label>914     fn to_label(name: &str) -> ProtoResult<Label> {
915         Label::from_utf8(name)
916     }
917 
write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error>918     fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error> {
919         write!(f, "{}", label)
920     }
921 }
922 
923 /// An iterator over labels in a name
924 pub struct LabelIter<'a> {
925     name: &'a Name,
926     index: usize,
927     started: bool,
928     finished: bool,
929 }
930 
931 impl<'a> Iterator for LabelIter<'a> {
932     type Item = &'a [u8];
933 
next(&mut self) -> Option<Self::Item>934     fn next(&mut self) -> Option<Self::Item> {
935         if self.finished {
936             return None;
937         }
938         self.started = true;
939         let end = *self.name.label_ends.get(self.index)?;
940         let start = match self.index {
941             0 => 0,
942             _ => self.name.label_ends[self.index - 1],
943         };
944         self.index += 1;
945         if self.index == self.name.label_ends.len() {
946             self.finished = true;
947         }
948         Some(&self.name.label_data[start as usize..end as usize])
949     }
950 
size_hint(&self) -> (usize, Option<usize>)951     fn size_hint(&self) -> (usize, Option<usize>) {
952         let len = self.name.label_ends.len() - self.index;
953         (len, Some(len))
954     }
955 }
956 
957 impl<'a> ExactSizeIterator for LabelIter<'a> {}
958 
959 impl<'a> DoubleEndedIterator for LabelIter<'a> {
next_back(&mut self) -> Option<Self::Item>960     fn next_back(&mut self) -> Option<Self::Item> {
961         if self.finished {
962             return None;
963         }
964         if !self.started {
965             self.index = self.name.label_ends.len().checked_sub(1)?;
966         }
967         self.started = true;
968         let end = *self.name.label_ends.get(self.index)?;
969         let start = match self.index {
970             0 => 0,
971             _ => self.name.label_ends[self.index - 1],
972         };
973         if self.index == 0 {
974             self.finished = true;
975         } else {
976             self.index -= 1;
977         }
978         Some(&self.name.label_data[start as usize..end as usize])
979     }
980 }
981 
982 impl<'a> IntoIterator for &'a Name {
983     type Item = &'a [u8];
984     type IntoIter = LabelIter<'a>;
985 
into_iter(self) -> Self::IntoIter986     fn into_iter(self) -> Self::IntoIter {
987         self.iter()
988     }
989 }
990 
991 impl From<IpAddr> for Name {
from(addr: IpAddr) -> Name992     fn from(addr: IpAddr) -> Name {
993         match addr {
994             IpAddr::V4(ip) => ip.into(),
995             IpAddr::V6(ip) => ip.into(),
996         }
997     }
998 }
999 
1000 impl From<Ipv4Addr> for Name {
from(addr: Ipv4Addr) -> Name1001     fn from(addr: Ipv4Addr) -> Name {
1002         let octets = addr.octets();
1003 
1004         let mut labels =
1005             octets
1006                 .iter()
1007                 .rev()
1008                 .fold(Vec::<Label>::with_capacity(6), |mut labels, o| {
1009                     let label: Label = format!("{}", o)
1010                         .as_bytes()
1011                         .into_label()
1012                         .expect("IP octet to label should never fail");
1013                     labels.push(label);
1014                     labels
1015                 });
1016 
1017         labels.push(
1018             b"in-addr"
1019                 .into_label()
1020                 .expect("simple name should never fail"),
1021         );
1022         labels.push(b"arpa".into_label().expect("simple name should never fail"));
1023 
1024         Self::from_labels(labels).expect("a translation of Ipv4Addr should never fail")
1025     }
1026 }
1027 
1028 impl From<Ipv6Addr> for Name {
from(addr: Ipv6Addr) -> Name1029     fn from(addr: Ipv6Addr) -> Name {
1030         let segments = addr.segments();
1031 
1032         let mut labels =
1033             segments
1034                 .iter()
1035                 .rev()
1036                 .fold(Vec::<Label>::with_capacity(34), |mut labels, o| {
1037                     labels.push(
1038                         format!("{:x}", (*o & 0x000F) as u8)
1039                             .as_bytes()
1040                             .into_label()
1041                             .expect("IP octet to label should never fail"),
1042                     );
1043                     labels.push(
1044                         format!("{:x}", (*o >> 4 & 0x000F) as u8)
1045                             .as_bytes()
1046                             .into_label()
1047                             .expect("IP octet to label should never fail"),
1048                     );
1049                     labels.push(
1050                         format!("{:x}", (*o >> 8 & 0x000F) as u8)
1051                             .as_bytes()
1052                             .into_label()
1053                             .expect("IP octet to label should never fail"),
1054                     );
1055                     labels.push(
1056                         format!("{:x}", (*o >> 12 & 0x000F) as u8)
1057                             .as_bytes()
1058                             .into_label()
1059                             .expect("IP octet to label should never fail"),
1060                     );
1061                     labels
1062                 });
1063 
1064         labels.push(b"ip6".into_label().expect("simple name should never fail"));
1065         labels.push(b"arpa".into_label().expect("simple name should never fail"));
1066 
1067         Self::from_labels(labels).expect("a translation of Ipv6Addr should never fail")
1068     }
1069 }
1070 
1071 impl PartialEq<Name> for Name {
eq(&self, other: &Self) -> bool1072     fn eq(&self, other: &Self) -> bool {
1073         self.cmp_with_f::<CaseInsensitive>(other) == Ordering::Equal
1074     }
1075 }
1076 
1077 impl Hash for Name {
hash<H: Hasher>(&self, state: &mut H)1078     fn hash<H: Hasher>(&self, state: &mut H) {
1079         self.is_fqdn.hash(state);
1080 
1081         // this needs to be CaseInsensitive like PartialEq
1082         for l in self
1083             .iter()
1084             .map(|l| Label::from_raw_bytes(l).unwrap().to_lowercase())
1085         {
1086             l.hash(state);
1087         }
1088     }
1089 }
1090 
1091 enum ParseState {
1092     Label,
1093     Escape1,
1094     Escape2(u32),
1095     Escape3(u32, u32),
1096 }
1097 
1098 impl BinEncodable for Name {
emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()>1099     fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
1100         let is_canonical_names = encoder.is_canonical_names();
1101         self.emit_as_canonical(encoder, is_canonical_names)
1102     }
1103 }
1104 
1105 impl<'r> BinDecodable<'r> for Name {
1106     /// parses the chain of labels
1107     ///  this has a max of 255 octets, with each label being less than 63.
1108     ///  all names will be stored lowercase internally.
1109     /// This will consume the portions of the `Vec` which it is reading...
read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Name>1110     fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Name> {
1111         let mut label_data = TinyVec::new();
1112         let mut label_ends = TinyVec::new();
1113         read_inner(decoder, &mut label_data, &mut label_ends, None)?;
1114         Ok(Name {
1115             is_fqdn: true,
1116             label_data,
1117             label_ends,
1118         })
1119     }
1120 }
1121 
read_inner( decoder: &mut BinDecoder<'_>, label_data: &mut TinyVec<[u8; 32]>, label_ends: &mut TinyVec<[u8; 24]>, max_idx: Option<usize>, ) -> Result<(), DecodeError>1122 fn read_inner(
1123     decoder: &mut BinDecoder<'_>,
1124     label_data: &mut TinyVec<[u8; 32]>,
1125     label_ends: &mut TinyVec<[u8; 24]>,
1126     max_idx: Option<usize>,
1127 ) -> Result<(), DecodeError> {
1128     let mut state: LabelParseState = LabelParseState::LabelLengthOrPointer;
1129     let name_start = decoder.index();
1130 
1131     // assume all chars are utf-8. We're doing byte-by-byte operations, no endianess issues...
1132     // reserved: (1000 0000 aka 0800) && (0100 0000 aka 0400)
1133     // pointer: (slice == 1100 0000 aka C0) & C0 == true, then 03FF & slice = offset
1134     // label: 03FF & slice = length; slice.next(length) = label
1135     // root: 0000
1136     loop {
1137         // this protects against overlapping labels
1138         if let Some(max_idx) = max_idx {
1139             if decoder.index() >= max_idx {
1140                 return Err(DecodeError::LabelOverlapsWithOther {
1141                     label: name_start,
1142                     other: max_idx,
1143                 });
1144             }
1145         }
1146 
1147         // enforce max length of name
1148         let cur_len = label_data.len() + label_ends.len();
1149         if cur_len > 255 {
1150             return Err(DecodeError::DomainNameTooLong(cur_len));
1151         }
1152 
1153         state = match state {
1154             LabelParseState::LabelLengthOrPointer => {
1155                 // determine what the next label is
1156                 match decoder
1157                     .peek()
1158                     .map(Restrict::unverified /*verified in this usage*/)
1159                 {
1160                     Some(0) | None => LabelParseState::Root,
1161                     Some(byte) if byte & 0b1100_0000 == 0b1100_0000 => LabelParseState::Pointer,
1162                     Some(byte) if byte & 0b1100_0000 == 0b0000_0000 => LabelParseState::Label,
1163                     Some(byte) => return Err(DecodeError::UnrecognizedLabelCode(byte)),
1164                 }
1165             }
1166             // labels must have a maximum length of 63
1167             LabelParseState::Label => {
1168                 let label = decoder
1169                     .read_character_data()?
1170                     .verify_unwrap(|l| l.len() <= 63)
1171                     .map_err(|l| DecodeError::LabelBytesTooLong(l.len()))?;
1172 
1173                 label_data.extend_from_slice(label);
1174                 label_ends.push(label_data.len() as u8);
1175 
1176                 // reset to collect more data
1177                 LabelParseState::LabelLengthOrPointer
1178             }
1179             //         4.1.4. Message compression
1180             //
1181             // In order to reduce the size of messages, the domain system utilizes a
1182             // compression scheme which eliminates the repetition of domain names in a
1183             // message.  In this scheme, an entire domain name or a list of labels at
1184             // the end of a domain name is replaced with a pointer to a prior occurrence
1185             // of the same name.
1186             //
1187             // The pointer takes the form of a two octet sequence:
1188             //
1189             //     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1190             //     | 1  1|                OFFSET                   |
1191             //     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1192             //
1193             // The first two bits are ones.  This allows a pointer to be distinguished
1194             // from a label, since the label must begin with two zero bits because
1195             // labels are restricted to 63 octets or less.  (The 10 and 01 combinations
1196             // are reserved for future use.)  The OFFSET field specifies an offset from
1197             // the start of the message (i.e., the first octet of the ID field in the
1198             // domain header).  A zero offset specifies the first byte of the ID field,
1199             // etc.
1200             LabelParseState::Pointer => {
1201                 let pointer_location = decoder.index();
1202                 let location = decoder
1203                     .read_u16()?
1204                     .map(|u| {
1205                         // get rid of the two high order bits, they are markers for length or pointers
1206                         u & 0x3FFF
1207                     })
1208                     .verify_unwrap(|ptr| {
1209                         // all labels must appear "prior" to this Name
1210                         (*ptr as usize) < name_start
1211                     })
1212                     .map_err(|e| DecodeError::PointerNotPriorToLabel {
1213                         idx: pointer_location,
1214                         ptr: e,
1215                     })?;
1216 
1217                 let mut pointer = decoder.clone(location);
1218                 read_inner(&mut pointer, label_data, label_ends, Some(name_start))?;
1219 
1220                 // Pointers always finish the name, break like Root.
1221                 break;
1222             }
1223             LabelParseState::Root => {
1224                 // need to pop() the 0 off the stack...
1225                 decoder.pop()?;
1226                 break;
1227             }
1228         }
1229     }
1230 
1231     Ok(())
1232 }
1233 
1234 impl fmt::Display for Name {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1235     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1236         self.write_labels::<fmt::Formatter<'_>, LabelEncUtf8>(f)
1237     }
1238 }
1239 
1240 impl PartialOrd<Name> for Name {
partial_cmp(&self, other: &Name) -> Option<Ordering>1241     fn partial_cmp(&self, other: &Name) -> Option<Ordering> {
1242         Some(self.cmp(other))
1243     }
1244 }
1245 
1246 impl Ord for Name {
1247     /// Case insensitive comparison, see [`Name::cmp_case`] for case sensitive comparisons
1248     ///
1249     /// RFC 4034                DNSSEC Resource Records               March 2005
1250     ///
1251     /// ```text
1252     /// 6.1.  Canonical DNS Name Order
1253     ///
1254     ///  For the purposes of DNS security, owner names are ordered by treating
1255     ///  individual labels as unsigned left-justified octet strings.  The
1256     ///  absence of a octet sorts before a zero value octet, and uppercase
1257     ///  US-ASCII letters are treated as if they were lowercase US-ASCII
1258     ///  letters.
1259     ///
1260     ///  To compute the canonical ordering of a set of DNS names, start by
1261     ///  sorting the names according to their most significant (rightmost)
1262     ///  labels.  For names in which the most significant label is identical,
1263     ///  continue sorting according to their next most significant label, and
1264     ///  so forth.
1265     ///
1266     ///  For example, the following names are sorted in canonical DNS name
1267     ///  order.  The most significant label is "example".  At this level,
1268     ///  "example" sorts first, followed by names ending in "a.example", then
1269     ///  by names ending "z.example".  The names within each level are sorted
1270     ///  in the same way.
1271     ///
1272     ///            example
1273     ///            a.example
1274     ///            yljkjljk.a.example
1275     ///            Z.a.example
1276     ///            zABC.a.EXAMPLE
1277     ///            z.example
1278     ///            \001.z.example
1279     ///            *.z.example
1280     ///            \200.z.example
1281     /// ```
cmp(&self, other: &Self) -> Ordering1282     fn cmp(&self, other: &Self) -> Ordering {
1283         self.cmp_with_f::<CaseInsensitive>(other)
1284     }
1285 }
1286 
1287 /// This is the list of states for the label parsing state machine
1288 enum LabelParseState {
1289     LabelLengthOrPointer, // basically the start of the FSM
1290     Label,                // storing length of the label, must be < 63
1291     Pointer,              // location of pointer in slice,
1292     Root,                 // root is the end of the labels list, aka null
1293 }
1294 
1295 impl FromStr for Name {
1296     type Err = ProtoError;
1297 
1298     /// Uses the Name::from_utf8 conversion on this string, see [`from_ascii`] for ascii only, or for preserving case
from_str(s: &str) -> Result<Self, Self::Err>1299     fn from_str(s: &str) -> Result<Self, Self::Err> {
1300         Name::from_str_relaxed(s)
1301     }
1302 }
1303 
1304 /// Conversion into a Name
1305 pub trait IntoName: Sized {
1306     /// Convert this into Name
into_name(self) -> ProtoResult<Name>1307     fn into_name(self) -> ProtoResult<Name>;
1308 }
1309 
1310 impl<'a> IntoName for &'a str {
1311     /// Performs a utf8, IDNA or punycode, translation of the `str` into `Name`
into_name(self) -> ProtoResult<Name>1312     fn into_name(self) -> ProtoResult<Name> {
1313         Name::from_utf8(self)
1314     }
1315 }
1316 
1317 impl IntoName for String {
1318     /// Performs a utf8, IDNA or punycode, translation of the `String` into `Name`
into_name(self) -> ProtoResult<Name>1319     fn into_name(self) -> ProtoResult<Name> {
1320         Name::from_utf8(self)
1321     }
1322 }
1323 
1324 impl<T> IntoName for T
1325 where
1326     T: Into<Name>,
1327 {
into_name(self) -> ProtoResult<Name>1328     fn into_name(self) -> ProtoResult<Name> {
1329         Ok(self.into())
1330     }
1331 }
1332 
1333 #[cfg(feature = "serde-config")]
1334 impl Serialize for Name {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,1335     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1336     where
1337         S: Serializer,
1338     {
1339         serializer.serialize_str(&self.to_string())
1340     }
1341 }
1342 
1343 #[cfg(feature = "serde-config")]
1344 impl<'de> Deserialize<'de> for Name {
deserialize<D>(deserializer: D) -> Result<Name, D::Error> where D: Deserializer<'de>,1345     fn deserialize<D>(deserializer: D) -> Result<Name, D::Error>
1346     where
1347         D: Deserializer<'de>,
1348     {
1349         let s = String::deserialize(deserializer)?;
1350         FromStr::from_str(&s).map_err(de::Error::custom)
1351     }
1352 }
1353 
1354 #[cfg(test)]
1355 mod tests {
1356     #![allow(clippy::dbg_macro, clippy::print_stdout)]
1357 
1358     use std::cmp::Ordering;
1359     use std::iter;
1360     use std::str::FromStr;
1361 
1362     use super::*;
1363 
1364     use crate::serialize::binary::bin_tests::{test_emit_data_set, test_read_data_set};
1365     #[allow(clippy::useless_attribute)]
1366     #[allow(unused)]
1367     use crate::serialize::binary::*;
1368 
get_data() -> Vec<(Name, Vec<u8>)>1369     fn get_data() -> Vec<(Name, Vec<u8>)> {
1370         vec![
1371             (Name::new(), vec![0]),                           // base case, only the root
1372             (Name::from_str("a").unwrap(), vec![1, b'a', 0]), // a single 'a' label
1373             (
1374                 Name::from_str("a.bc").unwrap(),
1375                 vec![1, b'a', 2, b'b', b'c', 0],
1376             ), // two labels, 'a.bc'
1377             (
1378                 Name::from_str("a.♥").unwrap(),
1379                 vec![1, b'a', 7, b'x', b'n', b'-', b'-', b'g', b'6', b'h', 0],
1380             ), // two labels utf8, 'a.♥'
1381         ]
1382     }
1383 
1384     #[test]
test_num_labels()1385     fn test_num_labels() {
1386         assert_eq!(Name::from_str("*").unwrap().num_labels(), 0);
1387         assert_eq!(Name::from_str("a").unwrap().num_labels(), 1);
1388         assert_eq!(Name::from_str("*.b").unwrap().num_labels(), 1);
1389         assert_eq!(Name::from_str("a.b").unwrap().num_labels(), 2);
1390         assert_eq!(Name::from_str("*.b.c").unwrap().num_labels(), 2);
1391         assert_eq!(Name::from_str("a.b.c").unwrap().num_labels(), 3);
1392     }
1393 
1394     #[test]
test_read()1395     fn test_read() {
1396         test_read_data_set(get_data(), |ref mut d| Name::read(d));
1397     }
1398 
1399     #[test]
test_write_to()1400     fn test_write_to() {
1401         test_emit_data_set(get_data(), |e, n| n.emit(e));
1402     }
1403 
1404     #[test]
test_pointer()1405     fn test_pointer() {
1406         let mut bytes: Vec<u8> = Vec::with_capacity(512);
1407 
1408         let first = Name::from_str("ra.rb.rc").unwrap();
1409         let second = Name::from_str("rb.rc").unwrap();
1410         let third = Name::from_str("rc").unwrap();
1411         let fourth = Name::from_str("z.ra.rb.rc").unwrap();
1412 
1413         {
1414             let mut e = BinEncoder::new(&mut bytes);
1415 
1416             first.emit(&mut e).unwrap();
1417             assert_eq!(e.len(), 10); // should be 7 u8s...
1418 
1419             second.emit(&mut e).unwrap();
1420             // if this wrote the entire thing, then it would be +5... but a pointer should be +2
1421             assert_eq!(e.len(), 12);
1422 
1423             third.emit(&mut e).unwrap();
1424             assert_eq!(e.len(), 14);
1425 
1426             fourth.emit(&mut e).unwrap();
1427             assert_eq!(e.len(), 18);
1428         }
1429 
1430         // now read them back
1431         let mut d = BinDecoder::new(&bytes);
1432 
1433         let r_test = Name::read(&mut d).unwrap();
1434         assert_eq!(first, r_test);
1435 
1436         let r_test = Name::read(&mut d).unwrap();
1437         assert_eq!(second, r_test);
1438 
1439         let r_test = Name::read(&mut d).unwrap();
1440         assert_eq!(third, r_test);
1441 
1442         let r_test = Name::read(&mut d).unwrap();
1443         assert_eq!(fourth, r_test);
1444     }
1445 
1446     #[test]
test_pointer_with_pointer_ending_labels()1447     fn test_pointer_with_pointer_ending_labels() {
1448         let mut bytes: Vec<u8> = Vec::with_capacity(512);
1449 
1450         let first = Name::from_str("ra.rb.rc").unwrap();
1451         let second = Name::from_str("ra.rc").unwrap();
1452         let third = Name::from_str("ra.rc").unwrap();
1453 
1454         {
1455             let mut e = BinEncoder::new(&mut bytes);
1456 
1457             first.emit(&mut e).unwrap();
1458             assert_eq!(e.len(), 10);
1459 
1460             second.emit(&mut e).unwrap();
1461             // +5 with the first +3 being the text form of "ra" and +2 for the pointer to "rc".
1462             assert_eq!(e.len(), 15);
1463 
1464             // +2 with the pointer to "ra.rc" as previously seen.
1465             third.emit(&mut e).unwrap();
1466             assert_eq!(e.len(), 17);
1467         }
1468 
1469         // now read them back
1470         let mut d = BinDecoder::new(&bytes);
1471 
1472         let r_test = Name::read(&mut d).unwrap();
1473         assert_eq!(first, r_test);
1474 
1475         let r_test = Name::read(&mut d).unwrap();
1476         assert_eq!(second, r_test);
1477 
1478         let r_test = Name::read(&mut d).unwrap();
1479         assert_eq!(third, r_test);
1480     }
1481 
1482     #[test]
test_recursive_pointer()1483     fn test_recursive_pointer() {
1484         // points to an invalid beginning label marker
1485         let bytes = vec![0xC0, 0x01];
1486         let mut d = BinDecoder::new(&bytes);
1487 
1488         assert!(Name::read(&mut d).is_err());
1489 
1490         // formerly a stack overflow, recursing back on itself
1491         let bytes = vec![0xC0, 0x00];
1492         let mut d = BinDecoder::new(&bytes);
1493 
1494         assert!(Name::read(&mut d).is_err());
1495 
1496         // formerly a stack overflow, recursing back on itself
1497         let bytes = vec![0x01, 0x41, 0xC0, 0x00];
1498         let mut d = BinDecoder::new(&bytes);
1499 
1500         assert!(Name::read(&mut d).is_err());
1501 
1502         // formerly a stack overflow, recursing by going past the end, then back to the beginning.
1503         //   this is disallowed based on the rule that all labels must be "prior" to the current label.
1504         let bytes = vec![0xC0, 0x02, 0xC0, 0x00];
1505         let mut d = BinDecoder::new(&bytes);
1506 
1507         assert!(Name::read(&mut d).is_err());
1508     }
1509 
1510     #[test]
test_bin_overlap_enforced()1511     fn test_bin_overlap_enforced() {
1512         let mut bytes: Vec<u8> = Vec::with_capacity(512);
1513         let n: u8 = 31;
1514         for _ in 0..=5 {
1515             bytes.extend(iter::repeat(n).take(n as usize));
1516         }
1517         bytes.push(n + 1);
1518         for b in 0..n {
1519             bytes.push(1 + n + b);
1520         }
1521         bytes.extend_from_slice(&[1, 0]);
1522         for b in 0..n {
1523             bytes.extend_from_slice(&[0xC0, b]);
1524         }
1525         let mut d = BinDecoder::new(&bytes);
1526         d.read_slice(n as usize).unwrap();
1527         assert!(Name::read(&mut d).is_err());
1528     }
1529 
1530     #[test]
test_bin_max_octets()1531     fn test_bin_max_octets() {
1532         let mut bytes = Vec::with_capacity(512);
1533         for _ in 0..256 {
1534             bytes.extend_from_slice(&[1, b'a']);
1535         }
1536         bytes.push(0);
1537 
1538         let mut d = BinDecoder::new(&bytes);
1539         assert!(Name::read(&mut d).is_err());
1540     }
1541 
1542     #[test]
test_base_name()1543     fn test_base_name() {
1544         let zone = Name::from_str("example.com.").unwrap();
1545 
1546         assert_eq!(zone.base_name(), Name::from_str("com").unwrap());
1547         assert!(zone.base_name().base_name().is_root());
1548         assert!(zone.base_name().base_name().base_name().is_root());
1549     }
1550 
1551     #[test]
test_zone_of()1552     fn test_zone_of() {
1553         let zone = Name::from_str("example.com").unwrap();
1554         let www = Name::from_str("www.example.com").unwrap();
1555         let none = Name::from_str("none.com").unwrap();
1556         let root = Name::root();
1557 
1558         assert!(zone.zone_of(&zone));
1559         assert!(zone.zone_of(&www));
1560         assert!(!zone.zone_of(&none));
1561         assert!(root.zone_of(&zone));
1562         assert!(!zone.zone_of(&root));
1563     }
1564 
1565     #[test]
test_zone_of_case()1566     fn test_zone_of_case() {
1567         let zone = Name::from_ascii("examplE.cOm").unwrap();
1568         let www = Name::from_str("www.example.com").unwrap();
1569         let none = Name::from_str("none.com").unwrap();
1570 
1571         assert!(zone.zone_of(&zone));
1572         assert!(zone.zone_of(&www));
1573         assert!(!zone.zone_of(&none))
1574     }
1575 
1576     #[test]
test_partial_cmp_eq()1577     fn test_partial_cmp_eq() {
1578         let root = Some(Name::from_labels(Vec::<&str>::new()).unwrap());
1579         let comparisons: Vec<(Name, Name)> = vec![
1580             (root.clone().unwrap(), root.clone().unwrap()),
1581             (
1582                 Name::parse("example.", root.as_ref()).unwrap(),
1583                 Name::parse("example", root.as_ref()).unwrap(),
1584             ),
1585         ];
1586 
1587         for (left, right) in comparisons {
1588             println!("left: {}, right: {}", left, right);
1589             assert_eq!(left.partial_cmp(&right), Some(Ordering::Equal));
1590         }
1591     }
1592 
1593     #[test]
test_partial_cmp()1594     fn test_partial_cmp() {
1595         let comparisons: Vec<(Name, Name)> = vec![
1596             (
1597                 Name::from_str("example.").unwrap(),
1598                 Name::from_str("a.example.").unwrap(),
1599             ),
1600             (
1601                 Name::from_str("a.example.").unwrap(),
1602                 Name::from_str("yljkjljk.a.example.").unwrap(),
1603             ),
1604             (
1605                 Name::from_str("yljkjljk.a.example.").unwrap(),
1606                 Name::from_ascii("Z.a.example.").unwrap(),
1607             ),
1608             (
1609                 Name::from_ascii("Z.a.example.").unwrap(),
1610                 Name::from_ascii("zABC.a.EXAMPLE").unwrap(),
1611             ),
1612             (
1613                 Name::from_ascii("zABC.a.EXAMPLE.").unwrap(),
1614                 Name::from_str("z.example.").unwrap(),
1615             ),
1616             (
1617                 Name::from_str("z.example.").unwrap(),
1618                 Name::from_labels(vec![&[1u8] as &[u8], b"z", b"example"]).unwrap(),
1619             ),
1620             (
1621                 Name::from_labels(vec![&[1u8] as &[u8], b"z", b"example"]).unwrap(),
1622                 Name::from_str("*.z.example.").unwrap(),
1623             ),
1624             (
1625                 Name::from_str("*.z.example.").unwrap(),
1626                 Name::from_labels(vec![&[200u8] as &[u8], b"z", b"example"]).unwrap(),
1627             ),
1628         ];
1629 
1630         for (left, right) in comparisons {
1631             println!("left: {}, right: {}", left, right);
1632             assert_eq!(left.cmp(&right), Ordering::Less);
1633         }
1634     }
1635 
1636     #[test]
test_cmp_ignore_case()1637     fn test_cmp_ignore_case() {
1638         let comparisons: Vec<(Name, Name)> = vec![
1639             (
1640                 Name::from_ascii("ExAmPle.").unwrap(),
1641                 Name::from_ascii("example.").unwrap(),
1642             ),
1643             (
1644                 Name::from_ascii("A.example.").unwrap(),
1645                 Name::from_ascii("a.example.").unwrap(),
1646             ),
1647         ];
1648 
1649         for (left, right) in comparisons {
1650             println!("left: {}, right: {}", left, right);
1651             assert_eq!(left, right);
1652         }
1653     }
1654 
1655     #[test]
test_from_ipv4()1656     fn test_from_ipv4() {
1657         let ip = IpAddr::V4(Ipv4Addr::new(26, 3, 0, 103));
1658         let name = Name::from_str("103.0.3.26.in-addr.arpa").unwrap();
1659 
1660         assert_eq!(Into::<Name>::into(ip), name);
1661     }
1662 
1663     #[test]
test_from_ipv6()1664     fn test_from_ipv6() {
1665         let ip = IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x1));
1666         let name = Name::from_str(
1667             "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa",
1668         )
1669         .unwrap();
1670 
1671         assert_eq!(Into::<Name>::into(ip), name);
1672     }
1673 
1674     #[test]
test_from_str()1675     fn test_from_str() {
1676         assert_eq!(
1677             Name::from_str("www.example.com.").unwrap(),
1678             Name::from_labels(vec![b"www" as &[u8], b"example", b"com"]).unwrap()
1679         );
1680         assert_eq!(
1681             Name::from_str(".").unwrap(),
1682             Name::from_labels(Vec::<&str>::new()).unwrap()
1683         );
1684     }
1685 
1686     #[test]
test_fqdn()1687     fn test_fqdn() {
1688         assert!(Name::root().is_fqdn());
1689         assert!(Name::from_str(".").unwrap().is_fqdn());
1690         assert!(Name::from_str("www.example.com.").unwrap().is_fqdn());
1691         assert!(Name::from_labels(vec![b"www" as &[u8], b"example", b"com"])
1692             .unwrap()
1693             .is_fqdn());
1694 
1695         assert!(!Name::new().is_fqdn());
1696         assert!(!Name::from_str("www.example.com").unwrap().is_fqdn());
1697         assert!(!Name::from_str("www.example").unwrap().is_fqdn());
1698         assert!(!Name::from_str("www").unwrap().is_fqdn());
1699     }
1700 
1701     #[test]
test_to_string()1702     fn test_to_string() {
1703         assert_eq!(
1704             Name::from_str("www.example.com.").unwrap().to_string(),
1705             "www.example.com."
1706         );
1707         assert_eq!(
1708             Name::from_str("www.example.com").unwrap().to_string(),
1709             "www.example.com"
1710         );
1711     }
1712 
1713     #[test]
test_from_ascii()1714     fn test_from_ascii() {
1715         let bytes_name = Name::from_labels(vec![b"WWW" as &[u8], b"example", b"COM"]).unwrap();
1716         let ascii_name = Name::from_ascii("WWW.example.COM.").unwrap();
1717         let lower_name = Name::from_ascii("www.example.com.").unwrap();
1718 
1719         assert!(bytes_name.eq_case(&ascii_name));
1720         assert!(!lower_name.eq_case(&ascii_name));
1721     }
1722 
1723     #[test]
test_from_utf8()1724     fn test_from_utf8() {
1725         let bytes_name = Name::from_labels(vec![b"WWW" as &[u8], b"example", b"COM"]).unwrap();
1726         let utf8_name = Name::from_utf8("WWW.example.COM.").unwrap();
1727         let lower_name = Name::from_utf8("www.example.com.").unwrap();
1728 
1729         assert!(!bytes_name.eq_case(&utf8_name));
1730         assert!(lower_name.eq_case(&utf8_name));
1731     }
1732 
1733     #[test]
test_into_name()1734     fn test_into_name() {
1735         let name = Name::from_utf8("www.example.com").unwrap();
1736         assert_eq!(Name::from_utf8("www.example.com").unwrap(), name);
1737         assert_eq!(
1738             Name::from_utf8("www.example.com").unwrap(),
1739             Name::from_utf8("www.example.com")
1740                 .unwrap()
1741                 .into_name()
1742                 .unwrap()
1743         );
1744         assert_eq!(
1745             Name::from_utf8("www.example.com").unwrap(),
1746             "www.example.com".into_name().unwrap()
1747         );
1748         assert_eq!(
1749             Name::from_utf8("www.example.com").unwrap(),
1750             "www.example.com".to_string().into_name().unwrap()
1751         );
1752     }
1753 
1754     #[test]
test_encoding()1755     fn test_encoding() {
1756         assert_eq!(
1757             Name::from_ascii("WWW.example.COM.").unwrap().to_ascii(),
1758             "WWW.example.COM."
1759         );
1760         assert_eq!(
1761             Name::from_utf8("WWW.example.COM.").unwrap().to_ascii(),
1762             "www.example.com."
1763         );
1764         assert_eq!(
1765             Name::from_ascii("WWW.example.COM.").unwrap().to_utf8(),
1766             "WWW.example.COM."
1767         );
1768     }
1769 
1770     #[test]
test_excessive_encoding_len()1771     fn test_excessive_encoding_len() {
1772         use crate::error::ProtoErrorKind;
1773 
1774         // u16 max value is where issues start being tickled...
1775         let mut buf = Vec::with_capacity(u16::max_value() as usize);
1776         let mut encoder = BinEncoder::new(&mut buf);
1777 
1778         let mut result = Ok(());
1779         for i in 0..10000 {
1780             let name = Name::from_ascii(format!("name{}.example.com.", i)).unwrap();
1781             result = name.emit(&mut encoder);
1782             if let Err(..) = result {
1783                 break;
1784             }
1785         }
1786 
1787         assert!(result.is_err());
1788         match *result.unwrap_err().kind() {
1789             ProtoErrorKind::MaxBufferSizeExceeded(_) => (),
1790             _ => panic!(),
1791         }
1792     }
1793 
1794     #[test]
test_underscore()1795     fn test_underscore() {
1796         Name::from_str("_begin.example.com").expect("failed at beginning");
1797         Name::from_str_relaxed("mid_dle.example.com").expect("failed in the middle");
1798         Name::from_str_relaxed("end_.example.com").expect("failed at the end");
1799     }
1800 
1801     #[test]
test_parse_arpa_name()1802     fn test_parse_arpa_name() {
1803         assert!(Name::from_ascii("168.192.in-addr.arpa")
1804             .unwrap()
1805             .parse_arpa_name()
1806             .is_err());
1807         assert!(Name::from_ascii("host.example.com.")
1808             .unwrap()
1809             .parse_arpa_name()
1810             .is_err());
1811         assert!(Name::from_ascii("caffee.ip6.arpa.")
1812             .unwrap()
1813             .parse_arpa_name()
1814             .is_err());
1815         assert!(Name::from_ascii(
1816             "1.4.3.3.7.0.7.3.0.E.2.A.8.9.1.3.1.3.D.8.0.3.A.5.8.8.B.D.0.1.0.0.2.ip6.arpa."
1817         )
1818         .unwrap()
1819         .parse_arpa_name()
1820         .is_err());
1821         assert!(Name::from_ascii("caffee.in-addr.arpa.")
1822             .unwrap()
1823             .parse_arpa_name()
1824             .is_err());
1825         assert!(Name::from_ascii("1.2.3.4.5.in-addr.arpa.")
1826             .unwrap()
1827             .parse_arpa_name()
1828             .is_err());
1829         assert!(Name::from_ascii("1.2.3.4.home.arpa.")
1830             .unwrap()
1831             .parse_arpa_name()
1832             .is_err());
1833         assert_eq!(
1834             Name::from_ascii("168.192.in-addr.arpa.")
1835                 .unwrap()
1836                 .parse_arpa_name()
1837                 .unwrap(),
1838             IpNet::V4(Ipv4Net::new("192.168.0.0".parse().unwrap(), 16).unwrap())
1839         );
1840         assert_eq!(
1841             Name::from_ascii("1.0.168.192.in-addr.arpa.")
1842                 .unwrap()
1843                 .parse_arpa_name()
1844                 .unwrap(),
1845             IpNet::V4(Ipv4Net::new("192.168.0.1".parse().unwrap(), 32).unwrap())
1846         );
1847         assert_eq!(
1848             Name::from_ascii("0.1.0.0.2.ip6.arpa.")
1849                 .unwrap()
1850                 .parse_arpa_name()
1851                 .unwrap(),
1852             IpNet::V6(Ipv6Net::new("2001::".parse().unwrap(), 20).unwrap())
1853         );
1854         assert_eq!(
1855             Name::from_ascii("D.0.1.0.0.2.ip6.arpa.")
1856                 .unwrap()
1857                 .parse_arpa_name()
1858                 .unwrap(),
1859             IpNet::V6(Ipv6Net::new("2001:d00::".parse().unwrap(), 24).unwrap())
1860         );
1861         assert_eq!(
1862             Name::from_ascii("B.D.0.1.0.0.2.ip6.arpa.")
1863                 .unwrap()
1864                 .parse_arpa_name()
1865                 .unwrap(),
1866             IpNet::V6(Ipv6Net::new("2001:db0::".parse().unwrap(), 28).unwrap())
1867         );
1868         assert_eq!(
1869             Name::from_ascii("8.B.D.0.1.0.0.2.ip6.arpa.")
1870                 .unwrap()
1871                 .parse_arpa_name()
1872                 .unwrap(),
1873             IpNet::V6(Ipv6Net::new("2001:db8::".parse().unwrap(), 32).unwrap())
1874         );
1875         assert_eq!(
1876             Name::from_ascii(
1877                 "4.3.3.7.0.7.3.0.E.2.A.8.9.1.3.1.3.D.8.0.3.A.5.8.8.B.D.0.1.0.0.2.ip6.arpa."
1878             )
1879             .unwrap()
1880             .parse_arpa_name()
1881             .unwrap(),
1882             IpNet::V6(
1883                 Ipv6Net::new("2001:db8:85a3:8d3:1319:8a2e:370:7334".parse().unwrap(), 128).unwrap()
1884             )
1885         );
1886     }
1887 }
1888