1use std::char;
11use std::cmp::{Ordering, PartialEq};
12use std::fmt::{self, Write};
13use std::hash::{Hash, Hasher};
14use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
15use std::str::FromStr;
16
17use crate::error::*;
18use crate::rr::domain::label::{CaseInsensitive, CaseSensitive, IntoLabel, Label, LabelCmp};
19use crate::rr::domain::usage::LOCALHOST as LOCALHOST_usage;
20use crate::serialize::binary::*;
21use ipnet::{IpNet, Ipv4Net, Ipv6Net};
22#[cfg(feature = "serde-config")]
23use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
24use tinyvec::TinyVec;
25
26#[derive(Clone, Default, Eq)]
28pub struct Name {
29 is_fqdn: bool,
30 label_data: TinyVec<[u8; 32]>,
31 label_ends: TinyVec<[u8; 24]>,
34}
35
36impl Name {
37 pub fn new() -> Self {
39 Self::default()
40 }
41
42 pub fn root() -> Self {
44 let mut this = Self::new();
45 this.is_fqdn = true;
46 this
47 }
48
49 fn extend_name(&mut self, label: &[u8]) -> Result<(), ProtoError> {
51 self.label_data.extend_from_slice(label);
52 self.label_ends.push(self.label_data.len() as u8);
53 if self.len() > 255 {
54 return Err(ProtoErrorKind::DomainNameTooLong(self.len()).into());
55 };
56 Ok(())
57 }
58
59 pub fn is_root(&self) -> bool {
72 self.label_ends.is_empty() && self.is_fqdn()
73 }
74
75 pub fn is_fqdn(&self) -> bool {
98 self.is_fqdn
99 }
100
101 pub fn set_fqdn(&mut self, val: bool) {
105 self.is_fqdn = val
106 }
107
108 pub fn iter(&self) -> LabelIter<'_> {
110 LabelIter {
111 name: self,
112 start: 0,
113 end: self.label_ends.len() as u8,
114 }
115 }
116
117 pub fn append_label<L: IntoLabel>(mut self, label: L) -> ProtoResult<Self> {
130 self.extend_name(label.into_label()?.as_bytes())?;
131 Ok(self)
132 }
133
134 pub fn from_labels<I, L>(labels: I) -> ProtoResult<Self>
158 where
159 I: IntoIterator<Item = L>,
160 L: IntoLabel,
161 {
162 let (labels, errors): (Vec<_>, Vec<_>) = labels
163 .into_iter()
164 .map(IntoLabel::into_label)
165 .partition(Result::is_ok);
166 let labels: Vec<_> = labels.into_iter().map(Result::unwrap).collect();
167 let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect();
168
169 if labels.len() > 255 {
170 return Err(ProtoErrorKind::DomainNameTooLong(labels.len()).into());
171 };
172 if !errors.is_empty() {
173 return Err(format!("error converting some labels: {errors:?}").into());
174 };
175
176 let mut name = Self {
177 is_fqdn: true,
178 ..Self::default()
179 };
180 for label in labels {
181 name = name.append_label(label)?;
182 }
183
184 Ok(name)
185 }
186
187 pub fn append_name(mut self, other: &Self) -> Result<Self, ProtoError> {
213 for label in other.iter() {
214 self.extend_name(label)?;
215 }
216
217 self.is_fqdn = other.is_fqdn;
218 Ok(self)
219 }
220
221 pub fn append_domain(self, domain: &Self) -> Result<Self, ProtoError> {
239 let mut this = self.append_name(domain)?;
240 this.set_fqdn(true);
241 Ok(this)
242 }
243
244 pub fn to_lowercase(&self) -> Self {
259 let new_label_data = self
260 .label_data
261 .iter()
262 .map(|c| c.to_ascii_lowercase())
263 .collect();
264 Self {
265 is_fqdn: self.is_fqdn,
266 label_data: new_label_data,
267 label_ends: self.label_ends.clone(),
268 }
269 }
270
271 pub fn base_name(&self) -> Self {
285 let length = self.label_ends.len();
286 if length > 0 {
287 return self.trim_to(length - 1);
288 }
289 self.clone()
290 }
291
292 pub fn trim_to(&self, num_labels: usize) -> Self {
307 if num_labels > self.label_ends.len() {
308 self.clone()
309 } else {
310 Self::from_labels(self.iter().skip(self.label_ends.len() - num_labels)).unwrap()
311 }
312 }
313
314 pub fn zone_of_case(&self, name: &Self) -> bool {
316 let self_len = self.label_ends.len();
317 let name_len = name.label_ends.len();
318 if self_len == 0 {
319 return true;
320 }
321 if name_len == 0 {
322 return false;
324 }
325 if self_len > name_len {
326 return false;
327 }
328
329 let self_iter = self.iter().rev();
330 let name_iter = name.iter().rev();
331
332 let zip_iter = self_iter.zip(name_iter);
333
334 for (self_label, name_label) in zip_iter {
335 if self_label != name_label {
336 return false;
337 }
338 }
339
340 true
341 }
342
343 pub fn zone_of(&self, name: &Self) -> bool {
360 let self_lower = self.to_lowercase();
361 let name_lower = name.to_lowercase();
362
363 self_lower.zone_of_case(&name_lower)
364 }
365
366 pub fn num_labels(&self) -> u8 {
384 let num = self.label_ends.len() as u8;
387
388 self.iter()
389 .next()
390 .map(|l| if l == b"*" { num - 1 } else { num })
391 .unwrap_or(num)
392 }
393
394 pub fn len(&self) -> usize {
410 let dots = if !self.label_ends.is_empty() {
411 self.label_ends.len()
412 } else {
413 1
414 };
415 dots + self.label_data.len()
416 }
417
418 pub fn is_empty(&self) -> bool {
421 false
422 }
423
424 pub fn parse(local: &str, origin: Option<&Self>) -> ProtoResult<Self> {
437 Self::from_encoded_str::<LabelEncUtf8>(local, origin)
438 }
439
440 pub fn from_ascii<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
468 Self::from_encoded_str::<LabelEncAscii>(name.as_ref(), None)
469 }
470
471 pub fn from_utf8<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
492 Self::from_encoded_str::<LabelEncUtf8>(name.as_ref(), None)
493 }
494
495 pub fn from_str_relaxed<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
514 let name = name.as_ref();
515 Self::from_utf8(name).or_else(|_| Self::from_ascii(name))
516 }
517
518 fn from_encoded_str<E: LabelEnc>(local: &str, origin: Option<&Self>) -> ProtoResult<Self> {
519 let mut name = Self::new();
520 let mut label = String::new();
521
522 let mut state = ParseState::Label;
523
524 if local == "." {
526 name.set_fqdn(true);
527 return Ok(name);
528 }
529
530 for ch in local.chars() {
533 match state {
534 ParseState::Label => match ch {
535 '.' => {
536 name = name.append_label(E::to_label(&label)?)?;
537 label.clear();
538 }
539 '\\' => state = ParseState::Escape1,
540 ch if !ch.is_control() && !ch.is_whitespace() => label.push(ch),
541 _ => return Err(format!("unrecognized char: {ch}").into()),
542 },
543 ParseState::Escape1 => {
544 if ch.is_numeric() {
545 state = ParseState::Escape2(
546 ch.to_digit(8)
547 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?,
548 );
549 } else {
550 label.push(ch);
552 state = ParseState::Label;
553 }
554 }
555 ParseState::Escape2(i) => {
556 if ch.is_numeric() {
557 state = ParseState::Escape3(
558 i,
559 ch.to_digit(8)
560 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?,
561 );
562 } else {
563 return Err(ProtoError::from(format!("unrecognized char: {ch}")));
564 }
565 }
566 ParseState::Escape3(i, ii) => {
567 if ch.is_numeric() {
568 let val: u32 = (i * 8 * 8)
570 + (ii * 8)
571 + ch.to_digit(8)
572 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?;
573 let new: char = char::from_u32(val)
574 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?;
575 label.push(new);
576 state = ParseState::Label;
577 } else {
578 return Err(format!("unrecognized char: {ch}").into());
579 }
580 }
581 }
582 }
583
584 if !label.is_empty() {
585 name = name.append_label(E::to_label(&label)?)?;
586 }
587
588 if local.ends_with('.') {
589 name.set_fqdn(true);
590 } else if let Some(other) = origin {
591 return name.append_domain(other);
592 }
593
594 Ok(name)
595 }
596
597 pub fn emit_as_canonical(
601 &self,
602 encoder: &mut BinEncoder<'_>,
603 canonical: bool,
604 ) -> ProtoResult<()> {
605 let buf_len = encoder.len(); let labels = self.iter();
609
610 let mut labels_written = Vec::with_capacity(self.label_ends.len());
612 for label in labels {
615 if label.len() > 63 {
616 return Err(ProtoErrorKind::LabelBytesTooLong(label.len()).into());
617 }
618
619 labels_written.push(encoder.offset());
620 encoder.emit_character_data(label)?;
621 }
622 let last_index = encoder.offset();
623 for label_idx in &labels_written {
626 match encoder.get_label_pointer(*label_idx, last_index) {
627 Some(_) if canonical => continue,
629 Some(loc) if !canonical => {
630 encoder.set_offset(*label_idx);
632 encoder.trim();
633
634 encoder.emit_u16(0xC000u16 | (loc & 0x3FFFu16))?;
637
638 return Ok(());
640 }
641 _ => {
642 encoder.store_label_pointer(*label_idx, last_index);
644 }
645 }
646 }
647
648 encoder.emit(0)?;
651
652 let length = encoder.len() - buf_len;
654 if length > 255 {
655 return Err(ProtoErrorKind::DomainNameTooLong(length).into());
656 }
657
658 Ok(())
659 }
660
661 pub fn emit_with_lowercase(
668 &self,
669 encoder: &mut BinEncoder<'_>,
670 lowercase: bool,
671 ) -> ProtoResult<()> {
672 let is_canonical_names = encoder.is_canonical_names();
673 if lowercase {
674 self.to_lowercase()
675 .emit_as_canonical(encoder, is_canonical_names)
676 } else {
677 self.emit_as_canonical(encoder, is_canonical_names)
678 }
679 }
680
681 fn cmp_with_f<F: LabelCmp>(&self, other: &Self) -> Ordering {
683 if self.label_ends.is_empty() && other.label_ends.is_empty() {
684 return Ordering::Equal;
685 }
686
687 let self_labels = self.iter().rev();
689 let other_labels = other.iter().rev();
690
691 for (l, r) in self_labels.zip(other_labels) {
692 let l = Label::from_raw_bytes(l).unwrap();
693 let r = Label::from_raw_bytes(r).unwrap();
694 match l.cmp_with_f::<F>(&r) {
695 Ordering::Equal => continue,
696 not_eq => return not_eq,
697 }
698 }
699
700 self.label_ends.len().cmp(&other.label_ends.len())
701 }
702
703 pub fn cmp_case(&self, other: &Self) -> Ordering {
705 self.cmp_with_f::<CaseSensitive>(other)
706 }
707
708 pub fn eq_case(&self, other: &Self) -> bool {
710 self.cmp_with_f::<CaseSensitive>(other) == Ordering::Equal
711 }
712
713 pub fn to_ascii(&self) -> String {
718 let mut s = String::with_capacity(self.len());
719 self.write_labels::<String, LabelEncAscii>(&mut s)
720 .expect("string conversion of name should not fail");
721 s
722 }
723
724 pub fn to_utf8(&self) -> String {
730 format!("{self}")
731 }
732
733 pub fn parse_arpa_name(&self) -> Result<IpNet, ProtoError> {
735 if !self.is_fqdn() {
736 return Err("PQDN cannot be valid arpa name".into());
737 }
738 let mut iter = self.iter().rev();
739 let first = iter
740 .next()
741 .ok_or_else(|| ProtoError::from("not an arpa address"))?;
742 if !"arpa".eq_ignore_ascii_case(std::str::from_utf8(first)?) {
743 return Err("not an arpa address".into());
744 }
745 let second = iter
746 .next()
747 .ok_or_else(|| ProtoError::from("invalid arpa address"))?;
748 let mut prefix_len: u8 = 0;
749 match &std::str::from_utf8(second)?.to_ascii_lowercase()[..] {
750 "in-addr" => {
751 let mut octets: [u8; 4] = [0; 4];
752 for octet in octets.iter_mut() {
753 match iter.next() {
754 Some(label) => *octet = std::str::from_utf8(label)?.parse()?,
755 None => break,
756 }
757 prefix_len += 8;
758 }
759 if iter.next().is_some() {
760 return Err("unrecognized in-addr.arpa.".into());
761 }
762 Ok(IpNet::V4(
763 Ipv4Net::new(octets.into(), prefix_len).expect("Ipv4Net::new"),
764 ))
765 }
766 "ip6" => {
767 let mut address: u128 = 0;
768 while prefix_len < 128 {
769 match iter.next() {
770 Some(label) => {
771 if label.len() == 1 {
772 prefix_len += 4;
773 let hex = u8::from_str_radix(std::str::from_utf8(label)?, 16)?;
774 address |= u128::from(hex) << (128 - prefix_len);
775 } else {
776 return Err("invalid label length for ip6.arpa".into());
777 }
778 }
779 None => break,
780 }
781 }
782 if iter.next().is_some() {
783 return Err("unrecognized ip6.arpa.".into());
784 }
785 Ok(IpNet::V6(
786 Ipv6Net::new(address.into(), prefix_len).expect("Ipv6Net::new"),
787 ))
788 }
789 _ => Err("unrecognized arpa address".into()),
790 }
791 }
792
793 fn write_labels<W: Write, E: LabelEnc>(&self, f: &mut W) -> Result<(), fmt::Error> {
794 let mut iter = self.iter().map(|b| Label::from_raw_bytes(b).unwrap());
795 if let Some(label) = iter.next() {
796 E::write_label(f, &label)?;
797 }
798
799 for label in iter {
800 write!(f, ".")?;
801 E::write_label(f, &label)?;
802 }
803
804 if self.is_root() || self.is_fqdn() {
806 write!(f, ".")?;
807 }
808 Ok(())
809 }
810
811 pub fn is_localhost(&self) -> bool {
829 LOCALHOST_usage.zone_of(self)
830 }
831
832 pub fn is_wildcard(&self) -> bool {
850 self.iter().next().is_some_and(|l| l == b"*")
851 }
852
853 pub fn into_wildcard(self) -> Self {
869 if self.label_ends.is_empty() {
870 return Self::root();
871 }
872 let mut label_data = TinyVec::new();
873 label_data.push(b'*');
874 let mut label_ends = TinyVec::new();
875 label_ends.push(1);
876
877 for label in self.iter().skip(1) {
879 label_data.extend_from_slice(label);
880 label_ends.push(label_data.len() as u8);
881 }
882 Self {
883 label_data,
884 label_ends,
885 is_fqdn: self.is_fqdn,
886 }
887 }
888}
889
890impl std::fmt::Debug for Name {
891 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
892 f.write_str("Name(\"")?;
893 self.write_labels::<_, LabelEncUtf8>(f)?;
894 f.write_str("\")")
895 }
896}
897
898trait LabelEnc {
899 #[allow(clippy::wrong_self_convention)]
900 fn to_label(name: &str) -> ProtoResult<Label>;
901 fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error>;
902}
903
904struct LabelEncAscii;
905impl LabelEnc for LabelEncAscii {
906 #[allow(clippy::wrong_self_convention)]
907 fn to_label(name: &str) -> ProtoResult<Label> {
908 Label::from_ascii(name)
909 }
910
911 fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error> {
912 label.write_ascii(f)
913 }
914}
915
916struct LabelEncUtf8;
917impl LabelEnc for LabelEncUtf8 {
918 #[allow(clippy::wrong_self_convention)]
919 fn to_label(name: &str) -> ProtoResult<Label> {
920 Label::from_utf8(name)
921 }
922
923 fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error> {
924 write!(f, "{label}")
925 }
926}
927
928pub struct LabelIter<'a> {
930 name: &'a Name,
931 start: u8,
932 end: u8,
933}
934
935impl<'a> Iterator for LabelIter<'a> {
936 type Item = &'a [u8];
937
938 fn next(&mut self) -> Option<Self::Item> {
939 if self.start >= self.end {
940 return None;
941 }
942
943 let end = *self.name.label_ends.get(self.start as usize)?;
944 let start = match self.start {
945 0 => 0,
946 _ => self.name.label_ends[(self.start - 1) as usize],
947 };
948 self.start += 1;
949 Some(&self.name.label_data[start as usize..end as usize])
950 }
951
952 fn size_hint(&self) -> (usize, Option<usize>) {
953 let len = self.end.saturating_sub(self.start) as usize;
954 (len, Some(len))
955 }
956}
957
958impl ExactSizeIterator for LabelIter<'_> {}
959
960impl DoubleEndedIterator for LabelIter<'_> {
961 fn next_back(&mut self) -> Option<Self::Item> {
962 if self.end <= self.start {
963 return None;
964 }
965
966 self.end -= 1;
967
968 let end = *self.name.label_ends.get(self.end as usize)?;
969 let start = match self.end {
970 0 => 0,
971 _ => self.name.label_ends[(self.end - 1) as usize],
972 };
973
974 Some(&self.name.label_data[start as usize..end as usize])
975 }
976}
977
978impl<'a> IntoIterator for &'a Name {
979 type Item = &'a [u8];
980 type IntoIter = LabelIter<'a>;
981
982 fn into_iter(self) -> Self::IntoIter {
983 self.iter()
984 }
985}
986
987impl From<IpAddr> for Name {
988 fn from(addr: IpAddr) -> Self {
989 match addr {
990 IpAddr::V4(ip) => ip.into(),
991 IpAddr::V6(ip) => ip.into(),
992 }
993 }
994}
995
996impl From<Ipv4Addr> for Name {
997 fn from(addr: Ipv4Addr) -> Self {
998 let octets = addr.octets();
999
1000 let mut labels =
1001 octets
1002 .iter()
1003 .rev()
1004 .fold(Vec::<Label>::with_capacity(6), |mut labels, o| {
1005 let label: Label = format!("{o}")
1006 .as_bytes()
1007 .into_label()
1008 .expect("IP octet to label should never fail");
1009 labels.push(label);
1010 labels
1011 });
1012
1013 labels.push(
1014 b"in-addr"
1015 .into_label()
1016 .expect("simple name should never fail"),
1017 );
1018 labels.push(b"arpa".into_label().expect("simple name should never fail"));
1019
1020 Self::from_labels(labels).expect("a translation of Ipv4Addr should never fail")
1021 }
1022}
1023
1024impl From<Ipv6Addr> for Name {
1025 fn from(addr: Ipv6Addr) -> Self {
1026 let segments = addr.segments();
1027
1028 let mut labels =
1029 segments
1030 .iter()
1031 .rev()
1032 .fold(Vec::<Label>::with_capacity(34), |mut labels, o| {
1033 labels.push(
1034 format!("{:x}", (*o & 0x000F) as u8)
1035 .as_bytes()
1036 .into_label()
1037 .expect("IP octet to label should never fail"),
1038 );
1039 labels.push(
1040 format!("{:x}", (*o >> 4 & 0x000F) as u8)
1041 .as_bytes()
1042 .into_label()
1043 .expect("IP octet to label should never fail"),
1044 );
1045 labels.push(
1046 format!("{:x}", (*o >> 8 & 0x000F) as u8)
1047 .as_bytes()
1048 .into_label()
1049 .expect("IP octet to label should never fail"),
1050 );
1051 labels.push(
1052 format!("{:x}", (*o >> 12 & 0x000F) as u8)
1053 .as_bytes()
1054 .into_label()
1055 .expect("IP octet to label should never fail"),
1056 );
1057 labels
1058 });
1059
1060 labels.push(b"ip6".into_label().expect("simple name should never fail"));
1061 labels.push(b"arpa".into_label().expect("simple name should never fail"));
1062
1063 Self::from_labels(labels).expect("a translation of Ipv6Addr should never fail")
1064 }
1065}
1066
1067impl PartialEq<Self> for Name {
1068 fn eq(&self, other: &Self) -> bool {
1069 self.cmp_with_f::<CaseInsensitive>(other) == Ordering::Equal
1070 }
1071}
1072
1073impl Hash for Name {
1074 fn hash<H: Hasher>(&self, state: &mut H) {
1075 self.is_fqdn.hash(state);
1076
1077 for l in self
1079 .iter()
1080 .map(|l| Label::from_raw_bytes(l).unwrap().to_lowercase())
1081 {
1082 l.hash(state);
1083 }
1084 }
1085}
1086
1087enum ParseState {
1088 Label,
1089 Escape1,
1090 Escape2(u32),
1091 Escape3(u32, u32),
1092}
1093
1094impl BinEncodable for Name {
1095 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
1096 let is_canonical_names = encoder.is_canonical_names();
1097 self.emit_as_canonical(encoder, is_canonical_names)
1098 }
1099}
1100
1101impl<'r> BinDecodable<'r> for Name {
1102 fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
1107 let mut name = Self::root(); read_inner(decoder, &mut name, None)?;
1110 Ok(name)
1111 }
1112}
1113
1114fn read_inner(
1115 decoder: &mut BinDecoder<'_>,
1116 name: &mut Name,
1117 max_idx: Option<usize>,
1118) -> Result<(), DecodeError> {
1119 let mut state: LabelParseState = LabelParseState::LabelLengthOrPointer;
1120 let name_start = decoder.index();
1121
1122 loop {
1128 if let Some(max_idx) = max_idx {
1130 if decoder.index() >= max_idx {
1131 return Err(DecodeError::LabelOverlapsWithOther {
1132 label: name_start,
1133 other: max_idx,
1134 });
1135 }
1136 }
1137
1138 state = match state {
1139 LabelParseState::LabelLengthOrPointer => {
1140 match decoder
1142 .peek()
1143 .map(Restrict::unverified )
1144 {
1145 Some(0) | None => LabelParseState::Root,
1146 Some(byte) if byte & 0b1100_0000 == 0b1100_0000 => LabelParseState::Pointer,
1147 Some(byte) if byte & 0b1100_0000 == 0b0000_0000 => LabelParseState::Label,
1148 Some(byte) => return Err(DecodeError::UnrecognizedLabelCode(byte)),
1149 }
1150 }
1151 LabelParseState::Label => {
1153 let label = decoder
1154 .read_character_data()?
1155 .verify_unwrap(|l| l.len() <= 63)
1156 .map_err(|l| DecodeError::LabelBytesTooLong(l.len()))?;
1157
1158 name.extend_name(label)
1159 .map_err(|_| DecodeError::DomainNameTooLong(label.len()))?;
1160
1161 LabelParseState::LabelLengthOrPointer
1163 }
1164 LabelParseState::Pointer => {
1186 let pointer_location = decoder.index();
1187 let location = decoder
1188 .read_u16()?
1189 .map(|u| {
1190 u & 0x3FFF
1192 })
1193 .verify_unwrap(|ptr| {
1194 (*ptr as usize) < name_start
1196 })
1197 .map_err(|e| DecodeError::PointerNotPriorToLabel {
1198 idx: pointer_location,
1199 ptr: e,
1200 })?;
1201
1202 let mut pointer = decoder.clone(location);
1203 read_inner(&mut pointer, name, Some(name_start))?;
1204
1205 break;
1207 }
1208 LabelParseState::Root => {
1209 decoder.pop()?;
1211 break;
1212 }
1213 }
1214 }
1215
1216 let len = name.len();
1218 if len >= 255 {
1219 return Err(DecodeError::DomainNameTooLong(len));
1220 }
1221
1222 Ok(())
1223}
1224
1225impl fmt::Display for Name {
1226 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1227 self.write_labels::<fmt::Formatter<'_>, LabelEncUtf8>(f)
1228 }
1229}
1230
1231impl PartialOrd<Self> for Name {
1232 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1233 Some(self.cmp(other))
1234 }
1235}
1236
1237impl Ord for Name {
1238 fn cmp(&self, other: &Self) -> Ordering {
1274 self.cmp_with_f::<CaseInsensitive>(other)
1275 }
1276}
1277
1278enum LabelParseState {
1280 LabelLengthOrPointer, Label, Pointer, Root, }
1285
1286impl FromStr for Name {
1287 type Err = ProtoError;
1288
1289 fn from_str(s: &str) -> Result<Self, Self::Err> {
1291 Self::from_str_relaxed(s)
1292 }
1293}
1294
1295pub trait IntoName: Sized {
1297 fn into_name(self) -> ProtoResult<Name>;
1299}
1300
1301impl IntoName for &str {
1302 fn into_name(self) -> ProtoResult<Name> {
1304 Name::from_utf8(self)
1305 }
1306}
1307
1308impl IntoName for String {
1309 fn into_name(self) -> ProtoResult<Name> {
1311 Name::from_utf8(self)
1312 }
1313}
1314
1315impl IntoName for &String {
1316 fn into_name(self) -> ProtoResult<Name> {
1318 Name::from_utf8(self)
1319 }
1320}
1321
1322impl<T> IntoName for T
1323where
1324 T: Into<Name>,
1325{
1326 fn into_name(self) -> ProtoResult<Name> {
1327 Ok(self.into())
1328 }
1329}
1330
1331#[cfg(feature = "serde-config")]
1332impl Serialize for Name {
1333 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1334 where
1335 S: Serializer,
1336 {
1337 serializer.serialize_str(&self.to_string())
1338 }
1339}
1340
1341#[cfg(feature = "serde-config")]
1342impl<'de> Deserialize<'de> for Name {
1343 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1344 where
1345 D: Deserializer<'de>,
1346 {
1347 let s = String::deserialize(deserializer)?;
1348 FromStr::from_str(&s).map_err(de::Error::custom)
1349 }
1350}
1351
1352#[cfg(test)]
1353mod tests {
1354 #![allow(clippy::dbg_macro, clippy::print_stdout)]
1355
1356 use std::cmp::Ordering;
1357 use std::iter;
1358 use std::str::FromStr;
1359
1360 use super::*;
1361
1362 use crate::serialize::binary::bin_tests::{test_emit_data_set, test_read_data_set};
1363 #[allow(clippy::useless_attribute)]
1364 #[allow(unused)]
1365 use crate::serialize::binary::*;
1366
1367 fn get_data() -> Vec<(Name, Vec<u8>)> {
1368 vec![
1369 (Name::new(), vec![0]), (Name::from_str("a").unwrap(), vec![1, b'a', 0]), (
1372 Name::from_str("a.bc").unwrap(),
1373 vec![1, b'a', 2, b'b', b'c', 0],
1374 ), (
1376 Name::from_str("a.♥").unwrap(),
1377 vec![1, b'a', 7, b'x', b'n', b'-', b'-', b'g', b'6', b'h', 0],
1378 ), ]
1380 }
1381
1382 #[test]
1383 fn test_num_labels() {
1384 assert_eq!(Name::from_str("*").unwrap().num_labels(), 0);
1385 assert_eq!(Name::from_str("a").unwrap().num_labels(), 1);
1386 assert_eq!(Name::from_str("*.b").unwrap().num_labels(), 1);
1387 assert_eq!(Name::from_str("a.b").unwrap().num_labels(), 2);
1388 assert_eq!(Name::from_str("*.b.c").unwrap().num_labels(), 2);
1389 assert_eq!(Name::from_str("a.b.c").unwrap().num_labels(), 3);
1390 }
1391
1392 #[test]
1393 fn test_read() {
1394 test_read_data_set(get_data(), |ref mut d| Name::read(d));
1395 }
1396
1397 #[test]
1398 fn test_write_to() {
1399 test_emit_data_set(get_data(), |e, n| n.emit(e));
1400 }
1401
1402 #[test]
1403 fn test_pointer() {
1404 let mut bytes: Vec<u8> = Vec::with_capacity(512);
1405
1406 let first = Name::from_str("ra.rb.rc").unwrap();
1407 let second = Name::from_str("rb.rc").unwrap();
1408 let third = Name::from_str("rc").unwrap();
1409 let fourth = Name::from_str("z.ra.rb.rc").unwrap();
1410
1411 {
1412 let mut e = BinEncoder::new(&mut bytes);
1413
1414 first.emit(&mut e).unwrap();
1415 assert_eq!(e.len(), 10); second.emit(&mut e).unwrap();
1418 assert_eq!(e.len(), 12);
1420
1421 third.emit(&mut e).unwrap();
1422 assert_eq!(e.len(), 14);
1423
1424 fourth.emit(&mut e).unwrap();
1425 assert_eq!(e.len(), 18);
1426 }
1427
1428 let mut d = BinDecoder::new(&bytes);
1430
1431 let r_test = Name::read(&mut d).unwrap();
1432 assert_eq!(first, r_test);
1433
1434 let r_test = Name::read(&mut d).unwrap();
1435 assert_eq!(second, r_test);
1436
1437 let r_test = Name::read(&mut d).unwrap();
1438 assert_eq!(third, r_test);
1439
1440 let r_test = Name::read(&mut d).unwrap();
1441 assert_eq!(fourth, r_test);
1442 }
1443
1444 #[test]
1445 fn test_pointer_with_pointer_ending_labels() {
1446 let mut bytes: Vec<u8> = Vec::with_capacity(512);
1447
1448 let first = Name::from_str("ra.rb.rc").unwrap();
1449 let second = Name::from_str("ra.rc").unwrap();
1450 let third = Name::from_str("ra.rc").unwrap();
1451
1452 {
1453 let mut e = BinEncoder::new(&mut bytes);
1454
1455 first.emit(&mut e).unwrap();
1456 assert_eq!(e.len(), 10);
1457
1458 second.emit(&mut e).unwrap();
1459 assert_eq!(e.len(), 15);
1461
1462 third.emit(&mut e).unwrap();
1464 assert_eq!(e.len(), 17);
1465 }
1466
1467 let mut d = BinDecoder::new(&bytes);
1469
1470 let r_test = Name::read(&mut d).unwrap();
1471 assert_eq!(first, r_test);
1472
1473 let r_test = Name::read(&mut d).unwrap();
1474 assert_eq!(second, r_test);
1475
1476 let r_test = Name::read(&mut d).unwrap();
1477 assert_eq!(third, r_test);
1478 }
1479
1480 #[test]
1481 fn test_recursive_pointer() {
1482 let bytes = vec![0xC0, 0x01];
1484 let mut d = BinDecoder::new(&bytes);
1485
1486 assert!(Name::read(&mut d).is_err());
1487
1488 let bytes = vec![0xC0, 0x00];
1490 let mut d = BinDecoder::new(&bytes);
1491
1492 assert!(Name::read(&mut d).is_err());
1493
1494 let bytes = vec![0x01, 0x41, 0xC0, 0x00];
1496 let mut d = BinDecoder::new(&bytes);
1497
1498 assert!(Name::read(&mut d).is_err());
1499
1500 let bytes = vec![0xC0, 0x02, 0xC0, 0x00];
1503 let mut d = BinDecoder::new(&bytes);
1504
1505 assert!(Name::read(&mut d).is_err());
1506 }
1507
1508 #[test]
1509 fn test_bin_overlap_enforced() {
1510 let mut bytes: Vec<u8> = Vec::with_capacity(512);
1511 let n: u8 = 31;
1512 for _ in 0..=5 {
1513 bytes.extend(iter::repeat(n).take(n as usize));
1514 }
1515 bytes.push(n + 1);
1516 for b in 0..n {
1517 bytes.push(1 + n + b);
1518 }
1519 bytes.extend_from_slice(&[1, 0]);
1520 for b in 0..n {
1521 bytes.extend_from_slice(&[0xC0, b]);
1522 }
1523 let mut d = BinDecoder::new(&bytes);
1524 d.read_slice(n as usize).unwrap();
1525 assert!(Name::read(&mut d).is_err());
1526 }
1527
1528 #[test]
1529 fn test_bin_max_octets() {
1530 let mut bytes = Vec::with_capacity(512);
1531 for _ in 0..256 {
1532 bytes.extend_from_slice(&[1, b'a']);
1533 }
1534 bytes.push(0);
1535
1536 let mut d = BinDecoder::new(&bytes);
1537 assert!(Name::read(&mut d).is_err());
1538 }
1539
1540 #[test]
1541 fn test_base_name() {
1542 let zone = Name::from_str("example.com.").unwrap();
1543
1544 assert_eq!(zone.base_name(), Name::from_str("com").unwrap());
1545 assert!(zone.base_name().base_name().is_root());
1546 assert!(zone.base_name().base_name().base_name().is_root());
1547 }
1548
1549 #[test]
1550 fn test_zone_of() {
1551 let zone = Name::from_str("example.com").unwrap();
1552 let www = Name::from_str("www.example.com").unwrap();
1553 let none = Name::from_str("none.com").unwrap();
1554 let root = Name::root();
1555
1556 assert!(zone.zone_of(&zone));
1557 assert!(zone.zone_of(&www));
1558 assert!(!zone.zone_of(&none));
1559 assert!(root.zone_of(&zone));
1560 assert!(!zone.zone_of(&root));
1561 }
1562
1563 #[test]
1564 fn test_zone_of_case() {
1565 let zone = Name::from_ascii("examplE.cOm").unwrap();
1566 let www = Name::from_str("www.example.com").unwrap();
1567 let none = Name::from_str("none.com").unwrap();
1568
1569 assert!(zone.zone_of(&zone));
1570 assert!(zone.zone_of(&www));
1571 assert!(!zone.zone_of(&none))
1572 }
1573
1574 #[test]
1575 fn test_partial_cmp_eq() {
1576 let root = Some(Name::from_labels(Vec::<&str>::new()).unwrap());
1577 let comparisons: Vec<(Name, Name)> = vec![
1578 (root.clone().unwrap(), root.clone().unwrap()),
1579 (
1580 Name::parse("example.", root.as_ref()).unwrap(),
1581 Name::parse("example", root.as_ref()).unwrap(),
1582 ),
1583 ];
1584
1585 for (left, right) in comparisons {
1586 println!("left: {left}, right: {right}");
1587 assert_eq!(left.partial_cmp(&right), Some(Ordering::Equal));
1588 }
1589 }
1590
1591 #[test]
1592 fn test_partial_cmp() {
1593 let comparisons: Vec<(Name, Name)> = vec![
1594 (
1595 Name::from_str("example.").unwrap(),
1596 Name::from_str("a.example.").unwrap(),
1597 ),
1598 (
1599 Name::from_str("a.example.").unwrap(),
1600 Name::from_str("yljkjljk.a.example.").unwrap(),
1601 ),
1602 (
1603 Name::from_str("yljkjljk.a.example.").unwrap(),
1604 Name::from_ascii("Z.a.example.").unwrap(),
1605 ),
1606 (
1607 Name::from_ascii("Z.a.example.").unwrap(),
1608 Name::from_ascii("zABC.a.EXAMPLE").unwrap(),
1609 ),
1610 (
1611 Name::from_ascii("zABC.a.EXAMPLE.").unwrap(),
1612 Name::from_str("z.example.").unwrap(),
1613 ),
1614 (
1615 Name::from_str("z.example.").unwrap(),
1616 Name::from_labels(vec![&[1u8] as &[u8], b"z", b"example"]).unwrap(),
1617 ),
1618 (
1619 Name::from_labels(vec![&[1u8] as &[u8], b"z", b"example"]).unwrap(),
1620 Name::from_str("*.z.example.").unwrap(),
1621 ),
1622 (
1623 Name::from_str("*.z.example.").unwrap(),
1624 Name::from_labels(vec![&[200u8] as &[u8], b"z", b"example"]).unwrap(),
1625 ),
1626 ];
1627
1628 for (left, right) in comparisons {
1629 println!("left: {left}, right: {right}");
1630 assert_eq!(left.cmp(&right), Ordering::Less);
1631 }
1632 }
1633
1634 #[test]
1635 fn test_cmp_ignore_case() {
1636 let comparisons: Vec<(Name, Name)> = vec![
1637 (
1638 Name::from_ascii("ExAmPle.").unwrap(),
1639 Name::from_ascii("example.").unwrap(),
1640 ),
1641 (
1642 Name::from_ascii("A.example.").unwrap(),
1643 Name::from_ascii("a.example.").unwrap(),
1644 ),
1645 ];
1646
1647 for (left, right) in comparisons {
1648 println!("left: {left}, right: {right}");
1649 assert_eq!(left, right);
1650 }
1651 }
1652
1653 #[test]
1654 fn test_from_ipv4() {
1655 let ip = IpAddr::V4(Ipv4Addr::new(26, 3, 0, 103));
1656 let name = Name::from_str("103.0.3.26.in-addr.arpa").unwrap();
1657
1658 assert_eq!(Into::<Name>::into(ip), name);
1659 }
1660
1661 #[test]
1662 fn test_from_ipv6() {
1663 let ip = IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x1));
1664 let name = Name::from_str(
1665 "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",
1666 )
1667 .unwrap();
1668
1669 assert_eq!(Into::<Name>::into(ip), name);
1670 }
1671
1672 #[test]
1673 fn test_from_str() {
1674 assert_eq!(
1675 Name::from_str("www.example.com.").unwrap(),
1676 Name::from_labels(vec![b"www" as &[u8], b"example", b"com"]).unwrap()
1677 );
1678 assert_eq!(
1679 Name::from_str(".").unwrap(),
1680 Name::from_labels(Vec::<&str>::new()).unwrap()
1681 );
1682 }
1683
1684 #[test]
1685 fn test_fqdn() {
1686 assert!(Name::root().is_fqdn());
1687 assert!(Name::from_str(".").unwrap().is_fqdn());
1688 assert!(Name::from_str("www.example.com.").unwrap().is_fqdn());
1689 assert!(Name::from_labels(vec![b"www" as &[u8], b"example", b"com"])
1690 .unwrap()
1691 .is_fqdn());
1692
1693 assert!(!Name::new().is_fqdn());
1694 assert!(!Name::from_str("www.example.com").unwrap().is_fqdn());
1695 assert!(!Name::from_str("www.example").unwrap().is_fqdn());
1696 assert!(!Name::from_str("www").unwrap().is_fqdn());
1697 }
1698
1699 #[test]
1700 fn test_to_string() {
1701 assert_eq!(
1702 Name::from_str("www.example.com.").unwrap().to_string(),
1703 "www.example.com."
1704 );
1705 assert_eq!(
1706 Name::from_str("www.example.com").unwrap().to_string(),
1707 "www.example.com"
1708 );
1709 }
1710
1711 #[test]
1712 fn test_from_ascii() {
1713 let bytes_name = Name::from_labels(vec![b"WWW" as &[u8], b"example", b"COM"]).unwrap();
1714 let ascii_name = Name::from_ascii("WWW.example.COM.").unwrap();
1715 let lower_name = Name::from_ascii("www.example.com.").unwrap();
1716
1717 assert!(bytes_name.eq_case(&ascii_name));
1718 assert!(!lower_name.eq_case(&ascii_name));
1719 }
1720
1721 #[test]
1722 fn test_from_utf8() {
1723 let bytes_name = Name::from_labels(vec![b"WWW" as &[u8], b"example", b"COM"]).unwrap();
1724 let utf8_name = Name::from_utf8("WWW.example.COM.").unwrap();
1725 let lower_name = Name::from_utf8("www.example.com.").unwrap();
1726
1727 assert!(!bytes_name.eq_case(&utf8_name));
1728 assert!(lower_name.eq_case(&utf8_name));
1729 }
1730
1731 #[test]
1732 fn test_into_name() {
1733 let name = Name::from_utf8("www.example.com").unwrap();
1734 assert_eq!(Name::from_utf8("www.example.com").unwrap(), name);
1735 assert_eq!(
1736 Name::from_utf8("www.example.com").unwrap(),
1737 Name::from_utf8("www.example.com")
1738 .unwrap()
1739 .into_name()
1740 .unwrap()
1741 );
1742 assert_eq!(
1743 Name::from_utf8("www.example.com").unwrap(),
1744 "www.example.com".into_name().unwrap()
1745 );
1746 assert_eq!(
1747 Name::from_utf8("www.example.com").unwrap(),
1748 "www.example.com".to_string().into_name().unwrap()
1749 );
1750 }
1751
1752 #[test]
1753 fn test_encoding() {
1754 assert_eq!(
1755 Name::from_ascii("WWW.example.COM.").unwrap().to_ascii(),
1756 "WWW.example.COM."
1757 );
1758 assert_eq!(
1759 Name::from_utf8("WWW.example.COM.").unwrap().to_ascii(),
1760 "www.example.com."
1761 );
1762 assert_eq!(
1763 Name::from_ascii("WWW.example.COM.").unwrap().to_utf8(),
1764 "WWW.example.COM."
1765 );
1766 }
1767
1768 #[test]
1769 fn test_excessive_encoding_len() {
1770 use crate::error::ProtoErrorKind;
1771
1772 let mut buf = Vec::with_capacity(u16::MAX as usize);
1774 let mut encoder = BinEncoder::new(&mut buf);
1775
1776 let mut result = Ok(());
1777 for i in 0..10000 {
1778 let name = Name::from_ascii(format!("name{i}.example.com.")).unwrap();
1779 result = name.emit(&mut encoder);
1780 if result.is_err() {
1781 break;
1782 }
1783 }
1784
1785 assert!(result.is_err());
1786 match *result.unwrap_err().kind() {
1787 ProtoErrorKind::MaxBufferSizeExceeded(_) => (),
1788 _ => panic!(),
1789 }
1790 }
1791
1792 #[test]
1793 fn test_underscore() {
1794 Name::from_str("_begin.example.com").expect("failed at beginning");
1795 Name::from_str_relaxed("mid_dle.example.com").expect("failed in the middle");
1796 Name::from_str_relaxed("end_.example.com").expect("failed at the end");
1797 }
1798
1799 #[test]
1800 fn test_parse_arpa_name() {
1801 assert!(Name::from_ascii("168.192.in-addr.arpa")
1802 .unwrap()
1803 .parse_arpa_name()
1804 .is_err());
1805 assert!(Name::from_ascii("host.example.com.")
1806 .unwrap()
1807 .parse_arpa_name()
1808 .is_err());
1809 assert!(Name::from_ascii("caffee.ip6.arpa.")
1810 .unwrap()
1811 .parse_arpa_name()
1812 .is_err());
1813 assert!(Name::from_ascii(
1814 "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."
1815 )
1816 .unwrap()
1817 .parse_arpa_name()
1818 .is_err());
1819 assert!(Name::from_ascii("caffee.in-addr.arpa.")
1820 .unwrap()
1821 .parse_arpa_name()
1822 .is_err());
1823 assert!(Name::from_ascii("1.2.3.4.5.in-addr.arpa.")
1824 .unwrap()
1825 .parse_arpa_name()
1826 .is_err());
1827 assert!(Name::from_ascii("1.2.3.4.home.arpa.")
1828 .unwrap()
1829 .parse_arpa_name()
1830 .is_err());
1831 assert_eq!(
1832 Name::from_ascii("168.192.in-addr.arpa.")
1833 .unwrap()
1834 .parse_arpa_name()
1835 .unwrap(),
1836 IpNet::V4(Ipv4Net::new("192.168.0.0".parse().unwrap(), 16).unwrap())
1837 );
1838 assert_eq!(
1839 Name::from_ascii("1.0.168.192.in-addr.arpa.")
1840 .unwrap()
1841 .parse_arpa_name()
1842 .unwrap(),
1843 IpNet::V4(Ipv4Net::new("192.168.0.1".parse().unwrap(), 32).unwrap())
1844 );
1845 assert_eq!(
1846 Name::from_ascii("0.1.0.0.2.ip6.arpa.")
1847 .unwrap()
1848 .parse_arpa_name()
1849 .unwrap(),
1850 IpNet::V6(Ipv6Net::new("2001::".parse().unwrap(), 20).unwrap())
1851 );
1852 assert_eq!(
1853 Name::from_ascii("D.0.1.0.0.2.ip6.arpa.")
1854 .unwrap()
1855 .parse_arpa_name()
1856 .unwrap(),
1857 IpNet::V6(Ipv6Net::new("2001:d00::".parse().unwrap(), 24).unwrap())
1858 );
1859 assert_eq!(
1860 Name::from_ascii("B.D.0.1.0.0.2.ip6.arpa.")
1861 .unwrap()
1862 .parse_arpa_name()
1863 .unwrap(),
1864 IpNet::V6(Ipv6Net::new("2001:db0::".parse().unwrap(), 28).unwrap())
1865 );
1866 assert_eq!(
1867 Name::from_ascii("8.B.D.0.1.0.0.2.ip6.arpa.")
1868 .unwrap()
1869 .parse_arpa_name()
1870 .unwrap(),
1871 IpNet::V6(Ipv6Net::new("2001:db8::".parse().unwrap(), 32).unwrap())
1872 );
1873 assert_eq!(
1874 Name::from_ascii(
1875 "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."
1876 )
1877 .unwrap()
1878 .parse_arpa_name()
1879 .unwrap(),
1880 IpNet::V6(
1881 Ipv6Net::new("2001:db8:85a3:8d3:1319:8a2e:370:7334".parse().unwrap(), 128).unwrap()
1882 )
1883 );
1884 }
1885
1886 #[test]
1887 fn test_name_too_long_with_append() {
1888 let n = Name::from_ascii("Llocainvannnnnnaxgtezqzqznnnnnn1na.nnntnninvannnnnnaxgtezqzqznnnnnn1na.nnntnnnnnnnaxgtezqzqznnnnnn1na.nnntnaaaaaaaaaaaaaaaaaaaaaaaaiK.iaaaaaaaaaaaaaaaaaaaaaaaaiKa.innnnnaxgtezqzqznnnnnn1na.nnntnaaaaaaaaaaaaaaaaaaaaaaaaiK.iaaaaaaaaaaaaaaaaaaaaaaaaiKa.in").unwrap();
1890 let sfx = Name::from_ascii("xxxxxxx.yyyyy.zzz").unwrap();
1891
1892 let error = n
1893 .append_domain(&sfx)
1894 .expect_err("should have errored, too long");
1895
1896 match error.kind() {
1897 ProtoErrorKind::DomainNameTooLong(_) => (),
1898 _ => panic!("expected too long message"),
1899 }
1900 }
1901
1902 #[test]
1903 fn test_double_ended_iterator() {
1904 let name = Name::from_ascii("www.example.com").unwrap();
1905 let mut iter = name.iter();
1906
1907 assert_eq!(iter.next().unwrap(), b"www");
1908 assert_eq!(iter.next_back().unwrap(), b"com");
1909 assert_eq!(iter.next().unwrap(), b"example");
1910 assert!(iter.next_back().is_none());
1911 assert!(iter.next().is_none());
1912 }
1913
1914 #[test]
1915 fn test_size_hint() {
1916 let name = Name::from_ascii("www.example.com").unwrap();
1917 let mut iter = name.iter();
1918
1919 assert_eq!(iter.size_hint().0, 3);
1920 assert_eq!(iter.next().unwrap(), b"www");
1921 assert_eq!(iter.size_hint().0, 2);
1922 assert_eq!(iter.next_back().unwrap(), b"com");
1923 assert_eq!(iter.size_hint().0, 1);
1924 assert_eq!(iter.next().unwrap(), b"example");
1925 assert_eq!(iter.size_hint().0, 0);
1926 assert!(iter.next_back().is_none());
1927 assert_eq!(iter.size_hint().0, 0);
1928 assert!(iter.next().is_none());
1929 assert_eq!(iter.size_hint().0, 0);
1930 }
1931}