1use alloc::vec::Vec;
7use alloc::string::String;
8use alloc::borrow::ToOwned;
9use alloc::format;
10
11use core::cmp::Ordering;
12use core::fmt;
13use core::fmt::Write;
14use core::num::NonZeroU8;
15
16use crate::ser::*;
17
18pub(crate) fn name_ends_with_labels(name: &[u8], suffix: &str) -> bool {
19 if name.len() < suffix.len() { return false; }
20 if name.ends_with(b".") && suffix == "." { return true; }
21
22 let suffix_lowercase_bytes = suffix.bytes().map(|b| b.to_ascii_lowercase());
23 let name_suffix_lowercase =
24 name.iter().skip(name.len() - suffix.len()).map(|b| b.to_ascii_lowercase());
25 if !name_suffix_lowercase.eq(suffix_lowercase_bytes) {
26 return false;
27 }
28 if name.len() == suffix.len() {
29 return true;
30 }
31 name[name.len() - suffix.len() - 1] == b'.'
32}
33
34#[derive(Debug, Clone, Hash, PartialEq, Eq)]
42pub struct Name(String);
43impl Name {
44 pub fn as_str(&self) -> &str { &self.0 }
46 pub fn labels(&self) -> u8 {
48 if self.as_str() == "." {
49 0
50 } else {
51 self.as_str().chars().filter(|c| *c == '.').count() as u8
52 }
53 }
54 pub fn trailing_n_labels(&self, n: u8) -> Option<&str> {
56 let labels = self.labels();
57 if n > labels {
58 None
59 } else if n == labels {
60 Some(self.as_str())
61 } else if n == 0 {
62 Some(".")
63 } else {
64 self.as_str().splitn(labels as usize - n as usize + 1, '.').last()
65 }
66 }
67 pub fn ends_with_labels<N: core::ops::Deref<Target = str>>(&self, suffix: N) -> bool {
72 name_ends_with_labels(self.0.as_bytes(), &*suffix)
73 }
74}
75impl Ord for Name {
76 fn cmp(&self, o: &Name) -> Ordering {
77 let mut self_iter = self.0.split('.');
82 let mut o_iter = o.0.split('.');
83 loop {
84 match (self_iter.next(), o_iter.next()) {
85 (None, None) => return Ordering::Equal,
86 (Some(_), None) => return Ordering::Greater,
87 (None, Some(_)) => return Ordering::Less,
88 (Some(a_label), Some(b_label)) => {
89 let label_ord = a_label.len().cmp(&b_label.len())
90 .then_with(|| a_label.cmp(&b_label));
91 if label_ord != Ordering::Equal { return label_ord; }
92 },
93 }
94 }
95 }
96}
97impl PartialOrd for Name {
98 fn partial_cmp(&self, o: &Name) -> Option<Ordering> { Some(self.cmp(o)) }
99}
100impl core::ops::Deref for Name {
101 type Target = str;
102 fn deref(&self) -> &str { &self.0 }
103}
104impl fmt::Display for Name {
105 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
106 self.0.fmt(f)
107 }
108}
109impl TryFrom<String> for Name {
110 type Error = ();
111 fn try_from(s: String) -> Result<Name, ()> {
112 if s.is_empty() { return Err(()); }
113 if *s.as_bytes().last().unwrap_or(&0) != b"."[0] { return Err(()); }
114 if s.len() > 255 { return Err(()); }
115 if s.chars().any(|c| !['-', '.', '_', '*'].contains(&c) && (c < '0' || c > '9') && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z')) {
116 return Err(());
117 }
118 for label in s.split('.') {
119 if label.len() > 63 { return Err(()); }
120 }
121
122 Ok(Name(s.to_ascii_lowercase()))
123 }
124}
125impl TryFrom<&str> for Name {
126 type Error = ();
127 fn try_from(s: &str) -> Result<Name, ()> {
128 Self::try_from(s.to_owned())
129 }
130}
131
132#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
133pub enum RR {
138 A(A),
140 AAAA(AAAA),
142 NS(NS),
144 Txt(Txt),
146 TLSA(TLSA),
148 CName(CName),
150 DName(DName),
152 DnsKey(DnsKey),
154 DS(DS),
156 RRSig(RRSig),
158 NSec(NSec),
160 NSec3(NSec3),
162}
163impl RR {
164 pub fn name(&self) -> &Name {
166 match self {
167 RR::A(rr) => &rr.name,
168 RR::AAAA(rr) => &rr.name,
169 RR::NS(rr) => &rr.name,
170 RR::Txt(rr) => &rr.name,
171 RR::CName(rr) => &rr.name,
172 RR::DName(rr) => &rr.name,
173 RR::TLSA(rr) => &rr.name,
174 RR::DnsKey(rr) => &rr.name,
175 RR::DS(rr) => &rr.name,
176 RR::RRSig(rr) => &rr.name,
177 RR::NSec(rr) => &rr.name,
178 RR::NSec3(rr) => &rr.name,
179 }
180 }
181 pub fn json(&self) -> String {
183 match self {
184 RR::A(rr) => StaticRecord::json(rr),
185 RR::AAAA(rr) => StaticRecord::json(rr),
186 RR::NS(rr) => StaticRecord::json(rr),
187 RR::Txt(rr) => StaticRecord::json(rr),
188 RR::CName(rr) => StaticRecord::json(rr),
189 RR::DName(rr) => StaticRecord::json(rr),
190 RR::TLSA(rr) => StaticRecord::json(rr),
191 RR::DnsKey(rr) => StaticRecord::json(rr),
192 RR::DS(rr) => StaticRecord::json(rr),
193 RR::RRSig(rr) => StaticRecord::json(rr),
194 RR::NSec(rr) => StaticRecord::json(rr),
195 RR::NSec3(rr) => StaticRecord::json(rr),
196 }
197 }
198 fn ty(&self) -> u16 {
199 match self {
200 RR::A(_) => A::TYPE,
201 RR::AAAA(_) => AAAA::TYPE,
202 RR::NS(_) => NS::TYPE,
203 RR::Txt(_) => Txt::TYPE,
204 RR::CName(_) => CName::TYPE,
205 RR::DName(_) => DName::TYPE,
206 RR::TLSA(_) => TLSA::TYPE,
207 RR::DnsKey(_) => DnsKey::TYPE,
208 RR::DS(_) => DS::TYPE,
209 RR::RRSig(_) => RRSig::TYPE,
210 RR::NSec(_) => NSec::TYPE,
211 RR::NSec3(_) => NSec3::TYPE,
212 }
213 }
214 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
215 match self {
216 RR::A(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
217 RR::AAAA(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
218 RR::NS(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
219 RR::Txt(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
220 RR::CName(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
221 RR::DName(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
222 RR::TLSA(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
223 RR::DnsKey(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
224 RR::DS(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
225 RR::RRSig(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
226 RR::NSec(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
227 RR::NSec3(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
228 }
229 }
230 fn ty_to_rr_name(ty: u16) -> Option<&'static str> {
231 match ty {
232 A::TYPE => Some("A"),
233 AAAA::TYPE => Some("AAAA"),
234 NS::TYPE => Some("NS"),
235 Txt::TYPE => Some("TXT"),
236 CName::TYPE => Some("CNAME"),
237 DName::TYPE => Some("DNAME"),
238 TLSA::TYPE => Some("TLSA"),
239 DnsKey::TYPE => Some("DNSKEY"),
240 DS::TYPE => Some("DS"),
241 RRSig::TYPE => Some("RRSIG"),
242 NSec::TYPE => Some("NSEC"),
243 NSec3::TYPE => Some("NSEC3"),
244 _ => None,
245 }
246 }
247}
248impl From<A> for RR { fn from(a: A) -> RR { RR::A(a) } }
249impl From<AAAA> for RR { fn from(aaaa: AAAA) -> RR { RR::AAAA(aaaa) } }
250impl From<NS> for RR { fn from(ns: NS) -> RR { RR::NS(ns) } }
251impl From<Txt> for RR { fn from(txt: Txt) -> RR { RR::Txt(txt) } }
252impl From<CName> for RR { fn from(cname: CName) -> RR { RR::CName(cname) } }
253impl From<DName> for RR { fn from(cname: DName) -> RR { RR::DName(cname) } }
254impl From<TLSA> for RR { fn from(tlsa: TLSA) -> RR { RR::TLSA(tlsa) } }
255impl From<DnsKey> for RR { fn from(dnskey: DnsKey) -> RR { RR::DnsKey(dnskey) } }
256impl From<DS> for RR { fn from(ds: DS) -> RR { RR::DS(ds) } }
257impl From<RRSig> for RR { fn from(rrsig: RRSig) -> RR { RR::RRSig(rrsig) } }
258impl From<NSec> for RR { fn from(nsec: NSec) -> RR { RR::NSec(nsec) } }
259impl From<NSec3> for RR { fn from(nsec3: NSec3) -> RR { RR::NSec3(nsec3) } }
260
261pub(crate) trait StaticRecord : Ord + Sized {
262 const TYPE: u16;
264 fn name(&self) -> &Name;
265 fn json(&self) -> String;
266 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W);
267 fn read_from_data(name: Name, data: &[u8], wire_packet: &[u8]) -> Result<Self, ()>;
268}
269
270pub(crate) trait WriteableRecord : Record {
272 fn serialize_u16_len_prefixed<W: Writer>(&self, out: &mut W);
273}
274impl<RR: StaticRecord> WriteableRecord for RR {
275 fn serialize_u16_len_prefixed<W: Writer>(&self, out: &mut W) {
276 RR::write_u16_len_prefixed_data(self, out)
277 }
278}
279impl WriteableRecord for RR {
280 fn serialize_u16_len_prefixed<W: Writer>(&self, out: &mut W) {
281 RR::write_u16_len_prefixed_data(self, out)
282 }
283}
284
285pub trait Record : Ord {
287 fn ty(&self) -> u16;
292 fn name(&self) -> &Name;
294 fn json(&self) -> String;
296 fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>);
298}
299impl<RR: StaticRecord> Record for RR {
300 fn ty(&self) -> u16 { RR::TYPE }
301 fn name(&self) -> &Name { RR::name(self) }
302 fn json(&self) -> String { RR::json(self) }
303 fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
304 RR::write_u16_len_prefixed_data(self, out)
305 }
306}
307impl Record for RR {
308 fn ty(&self) -> u16 { self.ty() }
309 fn name(&self) -> &Name { self.name() }
310 fn json(&self) -> String { self.json() }
311 fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
312 self.write_u16_len_prefixed_data(out)
313 }
314}
315
316#[derive(Debug, Clone, Hash, PartialEq, Eq)]
317struct TxtBytePart {
318 bytes: [u8; 255],
322 len: NonZeroU8,
324}
325
326#[derive(Debug, Clone, Hash, PartialEq, Eq)]
332pub struct TxtBytes {
333 chunks: Vec<TxtBytePart>,
335}
336
337impl TxtBytes {
338 pub fn new(bytes: &[u8]) -> Result<TxtBytes, ()> {
342 if bytes.len() > 255*255 + 254 { return Err(()); }
343 let mut chunks = Vec::with_capacity((bytes.len() + 254) / 255);
344 let mut data_write = &bytes[..];
345 while !data_write.is_empty() {
346 let split_pos = core::cmp::min(255, data_write.len());
347 let mut part = TxtBytePart {
348 bytes: [0; 255],
349 len: (split_pos as u8).try_into().expect("Cannot be 0 as data_write is not empty"),
350 };
351 part.bytes[..split_pos].copy_from_slice(&data_write[..split_pos]);
352 chunks.push(part);
353 data_write = &data_write[split_pos..];
354 }
355 debug_assert_eq!(chunks.len(), (bytes.len() + 254) / 255);
356 Ok(TxtBytes { chunks })
357 }
358
359 pub fn len(&self) -> usize {
361 let mut res = 0;
362 for chunk in self.chunks.iter() {
363 res += chunk.len.get() as usize;
364 }
365 res
366 }
367
368 pub fn serialized_len(&self) -> u16 {
370 let mut len = 0u16;
371 for chunk in self.chunks.iter() {
372 len = len.checked_add(1 + chunk.len.get() as u16)
373 .expect("TxtBytes objects must fit in 2^16 - 1 bytes when serialized");
374 }
375 len
376 }
377
378 pub fn as_vec(&self) -> Vec<u8> {
380 let mut res = Vec::with_capacity(self.len());
381 for chunk in self.chunks.iter() {
382 res.extend_from_slice(&chunk.bytes[..chunk.len.get() as usize]);
383 }
384 res
385 }
386
387 pub fn iter<'a>(&'a self) -> TxtBytesIter<'a> {
389 TxtBytesIter {
390 bytes: self,
391 next_part: 0,
392 next_byte: 0,
393 }
394 }
395}
396
397impl TryFrom<&str> for TxtBytes {
398 type Error = ();
399 fn try_from(s: &str) -> Result<TxtBytes, ()> {
400 TxtBytes::new(s.as_bytes())
401 }
402}
403
404impl TryFrom<&[u8]> for TxtBytes {
405 type Error = ();
406 fn try_from(b: &[u8]) -> Result<TxtBytes, ()> {
407 TxtBytes::new(b)
408 }
409}
410
411pub struct TxtBytesIter<'a> {
413 bytes: &'a TxtBytes,
414 next_part: usize,
415 next_byte: u8,
416}
417
418impl<'a> Iterator for TxtBytesIter<'a> {
419 type Item = u8;
420 fn next(&mut self) -> Option<u8> {
421 self.bytes.chunks.get(self.next_part)
422 .and_then(|part| if self.next_byte >= part.len.get() {
423 None
424 } else {
425 let res = Some(part.bytes[self.next_byte as usize]);
426 if self.next_byte == part.len.get() - 1 {
427 self.next_byte = 0;
428 self.next_part += 1;
429 } else {
430 self.next_byte += 1;
431 }
432 res
433 })
434 }
435}
436
437#[derive(Debug, Clone, Hash, PartialEq, Eq)]
438pub struct Txt {
440 pub name: Name,
442 pub data: TxtBytes,
447}
448pub const TXT_TYPE: u16 = 16;
450impl Ord for Txt {
451 fn cmp(&self, o: &Txt) -> Ordering {
452 self.name.cmp(&o.name)
453 .then_with(|| {
454 let mut o_chunks = o.data.chunks.iter();
456 for chunk in self.data.chunks.iter() {
457 if let Some(o_chunk) = o_chunks.next() {
458 let chunk_cmp = chunk.len.cmp(&o_chunk.len)
459 .then_with(||chunk.bytes[..chunk.len.get() as usize]
460 .cmp(&o_chunk.bytes[..o_chunk.len.get() as usize]));
461 if !chunk_cmp.is_eq() { return chunk_cmp; }
462 } else {
463 return Ordering::Greater;
465 }
466 }
467 if o_chunks.next().is_some() {
468 Ordering::Less
469 } else {
470 Ordering::Equal
471 }
472 })
473 }
474}
475impl PartialOrd for Txt {
476 fn partial_cmp(&self, o: &Txt) -> Option<Ordering> { Some(self.cmp(o)) }
477}
478impl StaticRecord for Txt {
479 const TYPE: u16 = TXT_TYPE;
480 fn name(&self) -> &Name { &self.name }
481 fn json(&self) -> String {
482 let mut res = format!("{{\"type\":\"txt\",\"name\":\"{}\",\"contents\":", self.name.0);
483 if self.data.iter().all(|b| b >= 0x20 && b <= 0x7e) {
484 res += "\"";
485 for b in self.data.iter() {
486 if b == b'"' || b == b'\\' {
487 res.push('\\');
488 }
489 res.push(b as char);
490 }
491 res += "\"}";
492 } else {
493 res += "[";
494 let mut first_b = true;
495 for b in self.data.iter() {
496 if !first_b { res += ","; }
497 write!(&mut res, "{}", b).expect("Shouldn't fail to write to a String");
498 first_b = false;
499 }
500 res += "]}";
501 }
502 res
503 }
504 fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
505 let mut parts = TxtBytes {
506 chunks: Vec::with_capacity((data.len() + 255) / 256),
507 };
508 let mut serialized_len = 0;
509 while !data.is_empty() {
510 let len = read_u8(&mut data)?;
511 if data.len() < len as usize { return Err(()); }
512 if len == 0 { return Err(()); }
513 serialized_len += 1 + len as u32;
514 if serialized_len > u16::MAX as u32 {
515 return Err(());
516 }
517 let mut part = TxtBytePart {
518 bytes: [0; 255],
519 len: len.try_into().expect("We already checked 0 above"),
520 };
521 part.bytes[..len as usize].copy_from_slice(&data[..len as usize]);
522 data = &data[len as usize..];
523 parts.chunks.push(part);
524 }
525 debug_assert!(data.is_empty());
526 Ok(Txt { name, data: parts })
527 }
528 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
529 out.write(&self.data.serialized_len().to_be_bytes());
530 for chunk in self.data.chunks.iter() {
531 out.write(&[chunk.len.get()]);
532 out.write(&chunk.bytes[..chunk.len.get() as usize]);
533 }
534 }
535}
536
537#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
538pub struct TLSA {
544 pub name: Name,
546 pub cert_usage: u8,
549 pub selector: u8,
551 pub data_ty: u8,
553 pub data: Vec<u8>,
555}
556pub const TLSA_TYPE: u16 = 52;
558impl StaticRecord for TLSA {
559 const TYPE: u16 = TLSA_TYPE;
560 fn name(&self) -> &Name { &self.name }
561 fn json(&self) -> String {
562 let mut out = String::with_capacity(128+self.data.len()*2);
563 write!(&mut out,
564 "{{\"type\":\"tlsa\",\"name\":\"{}\",\"usage\":{},\"selector\":{},\"data_ty\":{},\"data\":\"",
565 self.name.0, self.cert_usage, self.selector, self.data_ty
566 ).expect("Write to a String shouldn't fail");
567 for c in self.data.iter() {
568 write!(&mut out, "{:02X}", c)
569 .expect("Write to a String shouldn't fail");
570 }
571 out += "\"}";
572 out
573 }
574 fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
575 Ok(TLSA {
576 name, cert_usage: read_u8(&mut data)?, selector: read_u8(&mut data)?,
577 data_ty: read_u8(&mut data)?, data: data.to_vec(),
578 })
579 }
580 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
581 let len = 3 + self.data.len();
582 out.write(&(len as u16).to_be_bytes());
583 out.write(&[self.cert_usage, self.selector, self.data_ty]);
584 out.write(&self.data);
585 }
586}
587
588#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
589pub struct CName {
591 pub name: Name,
593 pub canonical_name: Name,
597}
598impl StaticRecord for CName {
599 const TYPE: u16 = 5;
600 fn name(&self) -> &Name { &self.name }
601 fn json(&self) -> String {
602 format!("{{\"type\":\"cname\",\"name\":\"{}\",\"canonical_name\":\"{}\"}}",
603 self.name.0, self.canonical_name.0)
604 }
605 fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
606 let res = CName { name, canonical_name: read_wire_packet_name(&mut data, wire_packet)? };
607 Ok(res)
608 }
609 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
610 let len: u16 = name_len(&self.canonical_name);
611 out.write(&len.to_be_bytes());
612 write_name(out, &self.canonical_name);
613 }
614}
615
616#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
617pub struct DName {
620 pub name: Name,
622 pub delegation_name: Name,
627}
628impl StaticRecord for DName {
629 const TYPE: u16 = 39;
630 fn name(&self) -> &Name { &self.name }
631 fn json(&self) -> String {
632 format!("{{\"type\":\"dname\",\"name\":\"{}\",\"delegation_name\":\"{}\"}}",
633 self.name.0, self.delegation_name.0)
634 }
635 fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
636 let res = DName { name, delegation_name: read_wire_packet_name(&mut data, wire_packet)? };
637 Ok(res)
638 }
639 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
640 let len: u16 = name_len(&self.delegation_name);
641 out.write(&len.to_be_bytes());
642 write_name(out, &self.delegation_name);
643 }
644}
645
646
647#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
648pub struct DnsKey {
650 pub name: Name,
652 pub flags: u16,
654 pub protocol: u8,
656 pub alg: u8,
658 pub pubkey: Vec<u8>,
660}
661impl StaticRecord for DnsKey {
662 const TYPE: u16 = 48;
663 fn name(&self) -> &Name { &self.name }
664 fn json(&self) -> String {
665 let mut out = String::with_capacity(128+self.pubkey.len()*2);
666 write!(&mut out,
667 "{{\"type\":\"dnskey\",\"name\":\"{}\",\"flags\":{},\"protocol\":{},\"alg\":{},\"pubkey\":\"",
668 self.name.0, self.flags, self.protocol, self.alg
669 ).expect("Write to a String shouldn't fail");
670 for c in self.pubkey.iter() {
671 write!(&mut out, "{:02X}", c)
672 .expect("Write to a String shouldn't fail");
673 }
674 out += "\"}";
675 out
676 }
677 fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
678 Ok(DnsKey {
679 name, flags: read_u16(&mut data)?, protocol: read_u8(&mut data)?,
680 alg: read_u8(&mut data)?, pubkey: data.to_vec(),
681 })
682 }
683 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
684 let len = 2 + 1 + 1 + self.pubkey.len();
685 out.write(&(len as u16).to_be_bytes());
686 out.write(&self.flags.to_be_bytes());
687 out.write(&self.protocol.to_be_bytes());
688 out.write(&self.alg.to_be_bytes());
689 out.write(&self.pubkey);
690 }
691}
692impl DnsKey {
693 pub fn key_tag(&self) -> u16 {
695 let mut res = u32::from(self.flags);
696 res += u32::from(self.protocol) << 8;
697 res += u32::from(self.alg);
698 for (idx, b) in self.pubkey.iter().enumerate() {
699 if idx % 2 == 0 {
700 res += u32::from(*b) << 8;
701 } else {
702 res += u32::from(*b);
703 }
704 }
705 res += (res >> 16) & 0xffff;
706 (res & 0xffff) as u16
707 }
708}
709
710#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
711pub struct DS {
714 pub name: Name,
718 pub key_tag: u16,
723 pub alg: u8,
727 pub digest_type: u8,
729 pub digest: Vec<u8>,
731}
732impl StaticRecord for DS {
733 const TYPE: u16 = 43;
734 fn name(&self) -> &Name { &self.name }
735 fn json(&self) -> String {
736 let mut out = String::with_capacity(128+self.digest.len()*2);
737 write!(&mut out,
738 "{{\"type\":\"ds\",\"name\":\"{}\",\"key_tag\":{},\"alg\":{},\"digest_type\":{},\"digest\":\"",
739 self.name.0, self.key_tag, self.alg, self.digest_type
740 ).expect("Write to a String shouldn't fail");
741 for c in self.digest.iter() {
742 write!(&mut out, "{:02X}", c)
743 .expect("Write to a String shouldn't fail");
744 }
745 out += "\"}";
746 out
747 }
748 fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
749 Ok(DS {
750 name, key_tag: read_u16(&mut data)?, alg: read_u8(&mut data)?,
751 digest_type: read_u8(&mut data)?, digest: data.to_vec(),
752 })
753 }
754 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
755 let len = 2 + 1 + 1 + self.digest.len();
756 out.write(&(len as u16).to_be_bytes());
757 out.write(&self.key_tag.to_be_bytes());
758 out.write(&self.alg.to_be_bytes());
759 out.write(&self.digest_type.to_be_bytes());
760 out.write(&self.digest);
761 }
762}
763
764#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
765pub struct RRSig {
768 pub name: Name,
772 pub ty: u16,
777 pub alg: u8,
781 pub labels: u8,
786 pub orig_ttl: u32,
788 pub expiration: u32,
790 pub inception: u32,
792 pub key_tag: u16,
796 pub key_name: Name,
804 pub signature: Vec<u8>,
806}
807impl StaticRecord for RRSig {
808 const TYPE: u16 = 46;
809 fn name(&self) -> &Name { &self.name }
810 fn json(&self) -> String {
811 let mut out = String::with_capacity(256 + self.signature.len()*2);
812 write!(&mut out,
813 "{{\"type\":\"ds\",\"name\":\"{}\",\"signed_record_type\":{},\"alg\":{},\"signed_labels\":{},\"orig_ttl\":{},\"expiration\":{},\"inception\":{},\"key_tag\":{},\"key_name\":\"{}\",\"signature\":\"",
814 self.name.0, self.ty, self.alg, self.labels, self.orig_ttl, self.expiration, self.inception, self.key_tag, self.key_name.0
815 ).expect("Write to a String shouldn't fail");
816 for c in self.signature.iter() {
817 write!(&mut out, "{:02X}", c)
818 .expect("Write to a String shouldn't fail");
819 }
820 out += "\"}";
821 out
822 }
823 fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
824 Ok(RRSig {
825 name, ty: read_u16(&mut data)?, alg: read_u8(&mut data)?,
826 labels: read_u8(&mut data)?, orig_ttl: read_u32(&mut data)?,
827 expiration: read_u32(&mut data)?, inception: read_u32(&mut data)?,
828 key_tag: read_u16(&mut data)?,
829 key_name: read_wire_packet_name(&mut data, wire_packet)?,
830 signature: data.to_vec(),
831 })
832 }
833 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
834 let len = 2 + 1 + 1 + 4*3 + 2 + name_len(&self.key_name) + self.signature.len() as u16;
835 out.write(&len.to_be_bytes());
836 out.write(&self.ty.to_be_bytes());
837 out.write(&self.alg.to_be_bytes());
838 out.write(&self.labels.to_be_bytes());
839 out.write(&self.orig_ttl.to_be_bytes());
840 out.write(&self.expiration.to_be_bytes());
841 out.write(&self.inception.to_be_bytes());
842 out.write(&self.key_tag.to_be_bytes());
843 write_name(out, &self.key_name);
844 out.write(&self.signature);
845 }
846}
847
848const NSEC_MASK_INLINE_LEN: usize = 15;
850
851#[derive(Clone)]
852pub(super) enum NSecTypeMaskBytes {
853 Heap(Vec<u8>),
854 Inline {
855 bytes: [u8; NSEC_MASK_INLINE_LEN],
856 len: u8,
857 },
858}
859impl NSecTypeMaskBytes {
860 pub fn new() -> Self { Self::Inline { bytes: [0; NSEC_MASK_INLINE_LEN], len: 0 } }
861 pub fn len(&self) -> usize {
862 match self {
863 Self::Heap(bitmap) => bitmap.len(),
864 Self::Inline { len, .. } => *len as usize,
865 }
866 }
867 pub fn resize(&mut self, new_len: usize) {
868 match self {
869 Self::Heap(bitmap) => bitmap.resize(new_len, 0),
870 Self::Inline { bytes, len } if new_len <= NSEC_MASK_INLINE_LEN => {
871 bytes[core::cmp::min(*len as usize, new_len)..].fill(0);
872 *len = new_len as u8;
873 },
874 Self::Inline { bytes, len } => {
875 let mut bitmap = Vec::with_capacity(new_len);
876 bitmap.extend_from_slice(&bytes[..*len as usize]);
877 bitmap.resize(new_len, 0);
878 *self = Self::Heap(bitmap);
879 },
880 }
881 }
882 fn wire_blocks(&self) -> impl Iterator<Item = (u8, &[u8])> {
883 self.chunks(32).enumerate().filter_map(|(idx, flags)| {
884 let last_nonzero_idx = flags.iter().rposition(|flag| *flag != 0)?;
885 debug_assert!(idx <= u8::MAX as usize);
887 Some((idx as u8, &flags[..last_nonzero_idx + 1]))
888 })
889 }
890 fn wire_bytes(&self) -> impl Iterator<Item = u8> + '_ {
891 self.wire_blocks().flat_map(|(block, flags)| {
892 [block, flags.len() as u8].into_iter().chain(flags.iter().copied())
893 })
894 }
895 fn write<W: Writer>(&self, out: &mut W) {
896 for byte in self.wire_bytes() {
897 out.write(&byte.to_be_bytes());
898 }
899 }
900}
901impl core::ops::Deref for NSecTypeMaskBytes {
902 type Target = [u8];
903 fn deref(&self) -> &[u8] {
904 match self {
905 Self::Heap(bitmap) => &bitmap[..],
906 Self::Inline { bytes, len } => &bytes[..*len as usize],
907 }
908 }
909}
910impl core::ops::DerefMut for NSecTypeMaskBytes {
911 fn deref_mut(&mut self) -> &mut [u8] {
912 match self {
913 Self::Heap(bitmap) => &mut bitmap[..],
914 Self::Inline { bytes, len } => &mut bytes[..*len as usize],
915 }
916 }
917}
918impl PartialEq for NSecTypeMaskBytes {
919 fn eq(&self, o: &Self) -> bool { self.wire_bytes().eq(o.wire_bytes()) }
920}
921impl Eq for NSecTypeMaskBytes {}
922impl Ord for NSecTypeMaskBytes {
923 fn cmp(&self, o: &Self) -> Ordering { self.wire_bytes().cmp(o.wire_bytes()) }
924}
925impl PartialOrd for NSecTypeMaskBytes {
926 fn partial_cmp(&self, o: &Self) -> Option<Ordering> { Some(self.cmp(o)) }
927}
928impl core::hash::Hash for NSecTypeMaskBytes {
929 fn hash<H: core::hash::Hasher>(&self, hasher: &mut H) {
930 for byte in self.wire_bytes() {
931 hasher.write_u8(byte);
932 }
933 }
934}
935
936#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
937pub struct NSecTypeMask(NSecTypeMaskBytes);
940impl NSecTypeMask {
941 pub fn new() -> Self { Self(NSecTypeMaskBytes::new()) }
943 pub fn from_types(types: &[u16]) -> Self {
945 let mut flags = NSecTypeMaskBytes::new();
946 if let Some(max_type) = types.iter().max() {
947 flags.resize((*max_type as usize >> 3) + 1);
948 }
949 for t in types {
950 flags[*t as usize >> 3] |= 1 << (7 - (*t as usize % 8));
951 }
952 let res = Self(flags);
953 for t in types {
954 debug_assert!(res.contains_type(*t));
955 }
956 res
957 }
958 pub fn contains_type(&self, ty: u16) -> bool {
961 match self.0.get((ty >> 3) as usize) {
962 Some(f) => f & (1 << (7 - (ty % 8))) != 0,
964 None => false,
965 }
966 }
967 fn write_json(&self, s: &mut String) {
968 *s += "[";
969 write!(s, "{:?}", self).expect("Writes to a string shouldn't fail");
970 *s += "]";
971 }
972}
973impl fmt::Debug for NSecTypeMask {
974 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
975 let mut have_written = false;
976 for (idx, mask) in self.0.iter().enumerate() {
977 if *mask == 0 { continue; }
978 for b in 0..8 {
979 if *mask & (1 << b) != 0 {
980 let ty = ((idx as u16) << 3) | (7 - b);
981 match RR::ty_to_rr_name(ty) {
982 Some(name) => write!(f, "{}\"{}\"", if have_written { "," } else { "" }, name)?,
983 _ => write!(f, "{}{}", if have_written { "," } else { "" }, ty)?,
984 }
985 have_written = true;
986 }
987 }
988 }
989 Ok(())
990 }
991}
992
993#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
994pub struct NSec {
997 pub name: Name,
999 pub next_name: Vec<u8>,
1005 pub types: NSecTypeMask,
1008}
1009impl StaticRecord for NSec {
1010 const TYPE: u16 = 47;
1011 fn name(&self) -> &Name { &self.name }
1012 fn json(&self) -> String {
1013 let mut out = String::with_capacity(256 + self.next_name.len());
1014 write!(&mut out, "{{\"type\":\"nsec\",\"name\":\"{}\",\"next_name\":\"", self.name.0)
1015 .expect("Write to a String shouldn't fail");
1016 for c in self.next_name.iter() {
1017 if *c >= 0x20 && *c <= 0x7e {
1018 if *c == b'"' || *c == b'\\' {
1019 out.push('\\');
1020 }
1021 out.push(char::from_u32((*c).into()).unwrap());
1022 } else {
1023 out += "\\u";
1024 write!(&mut out, "00{:02x}", *c).expect("Write to a String shouldn't fail");
1025 }
1026 }
1027 out += "\",\"types\":";
1028 self.types.write_json(&mut out);
1029 out += "}";
1030 out
1031 }
1032 fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
1033 let res = NSec {
1034 name, next_name: read_wire_packet_name_bytes(&mut data, wire_packet)?,
1035 types: NSecTypeMask(read_nsec_types_bitmap(&mut data)?),
1036 };
1037 debug_assert!(data.is_empty());
1038 Ok(res)
1039 }
1040 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
1041 let len = name_bytes_len(&self.next_name) + self.types.0.wire_bytes().count() as u16;
1042 out.write(&len.to_be_bytes());
1043 write_name_without_case_modification(out, &self.next_name);
1045 self.types.0.write(out);
1046 }
1047}
1048
1049#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
1050pub struct NSec3 {
1053 pub name: Name,
1055 pub hash_algo: u8,
1058 pub flags: u8,
1060 pub hash_iterations: u16,
1065 pub salt: Vec<u8>,
1069 pub next_name_hash: Vec<u8>,
1072 pub types: NSecTypeMask,
1075}
1076impl StaticRecord for NSec3 {
1077 const TYPE: u16 = 50;
1078 fn name(&self) -> &Name { &self.name }
1079 fn json(&self) -> String {
1080 let mut out = String::with_capacity(256);
1081 write!(&mut out,
1082 "{{\"type\":\"nsec3\",\"name\":\"{}\",\"hash_algo\":{},\"flags\":{},\"hash_iterations\":{},\"salt\":{:?},\"next_name_hash\":{:?},\"types\":",
1083 self.name.0, self.hash_algo, self.flags, self.hash_iterations, &self.salt[..], &self.next_name_hash[..]
1084 ).expect("Write to a String shouldn't fail");
1085 self.types.write_json(&mut out);
1086 out += "}";
1087 out
1088 }
1089 fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
1090 let res = NSec3 {
1091 name, hash_algo: read_u8(&mut data)?, flags: read_u8(&mut data)?,
1092 hash_iterations: read_u16(&mut data)?, salt: read_u8_len_prefixed_bytes(&mut data)?,
1093 next_name_hash: read_u8_len_prefixed_bytes(&mut data)?,
1094 types: NSecTypeMask(read_nsec_types_bitmap(&mut data)?),
1095 };
1096 debug_assert!(data.is_empty());
1097 Ok(res)
1098 }
1099 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
1100 let len = 4 + 2 + self.salt.len() as u16 + self.next_name_hash.len() as u16 +
1101 self.types.0.wire_bytes().count() as u16;
1102 out.write(&len.to_be_bytes());
1103 out.write(&self.hash_algo.to_be_bytes());
1104 out.write(&self.flags.to_be_bytes());
1105 out.write(&self.hash_iterations.to_be_bytes());
1106 out.write(&(self.salt.len() as u8).to_be_bytes());
1107 out.write(&self.salt);
1108 out.write(&(self.next_name_hash.len() as u8).to_be_bytes());
1109 out.write(&self.next_name_hash);
1110 self.types.0.write(out);
1111 }
1112}
1113
1114#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
1115pub struct A {
1117 pub name: Name,
1119 pub address: [u8; 4],
1121}
1122pub const A_TYPE: u16 = 1;
1124impl StaticRecord for A {
1125 const TYPE: u16 = A_TYPE;
1126 fn name(&self) -> &Name { &self.name }
1127 fn json(&self) -> String {
1128 format!("{{\"type\":\"a\",\"name\":\"{}\",\"address\":{:?}}}", self.name.0, self.address)
1129 }
1130 fn read_from_data(name: Name, data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
1131 if data.len() != 4 { return Err(()); }
1132 let mut address = [0; 4];
1133 address.copy_from_slice(data);
1134 Ok(A { name, address })
1135 }
1136 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
1137 out.write(&4u16.to_be_bytes());
1138 out.write(&self.address);
1139 }
1140}
1141
1142#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
1143pub struct AAAA {
1145 pub name: Name,
1147 pub address: [u8; 16],
1149}
1150pub const AAAA_TYPE: u16 = 28;
1152impl StaticRecord for AAAA {
1153 const TYPE: u16 = AAAA_TYPE;
1154 fn name(&self) -> &Name { &self.name }
1155 fn json(&self) -> String {
1156 format!("{{\"type\":\"aaaa\",\"name\":\"{}\",\"address\":{:?}}}", self.name.0, self.address)
1157 }
1158 fn read_from_data(name: Name, data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
1159 if data.len() != 16 { return Err(()); }
1160 let mut address = [0; 16];
1161 address.copy_from_slice(data);
1162 Ok(AAAA { name, address })
1163 }
1164 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
1165 out.write(&16u16.to_be_bytes());
1166 out.write(&self.address);
1167 }
1168}
1169
1170#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
1171pub struct NS {
1174 pub name: Name,
1179 pub name_server: Name,
1182}
1183impl StaticRecord for NS {
1184 const TYPE: u16 = 2;
1185 fn name(&self) -> &Name { &self.name }
1186 fn json(&self) -> String {
1187 format!("{{\"type\":\"ns\",\"name\":\"{}\",\"ns\":\"{}\"}}", self.name.0, self.name_server.0)
1188 }
1189 fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
1190 let res = NS { name, name_server: read_wire_packet_name(&mut data, wire_packet)? };
1191 Ok(res)
1192 }
1193 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
1194 out.write(&name_len(&self.name_server).to_be_bytes());
1195 write_name(out, &self.name_server);
1196 }
1197}
1198
1199#[cfg(test)]
1200mod tests {
1201 use super::*;
1202
1203 const NAMES: [&str; 14] = [
1204 ".",
1205 "*.example.com.",
1206 "a.example.com.",
1207 "z.",
1208 "z.a.example.",
1209 "aa.",
1210 "com.",
1211 "ns2.exampl.com.",
1212 "ns2.example.com.",
1213 "sub.example.com.",
1214 "ns10.example.com.",
1215 "ns20.example.com.",
1216 "example.com.",
1217 "xn--e1afmkfd.com.",
1218 ];
1219
1220 fn wire_encoding(name: &Name) -> Vec<u8> {
1221 let mut res = Vec::new();
1222 write_name(&mut res, name);
1223 res
1224 }
1225
1226 #[test]
1227 fn name_ord_matches_wire_encoding() {
1228 for a in NAMES.iter() {
1229 for b in NAMES.iter() {
1230 let a_name: Name = (*a).try_into().unwrap();
1231 let b_name: Name = (*b).try_into().unwrap();
1232 let wire_ord = wire_encoding(&a_name).cmp(&wire_encoding(&b_name));
1233 assert_eq!(a_name.cmp(&b_name), wire_ord);
1234 let a_ns = NS { name: ".".try_into().unwrap(), name_server: a_name};
1235 let b_ns = NS { name: ".".try_into().unwrap(), name_server: b_name};
1236 assert_eq!(a_ns.cmp(&b_ns), wire_ord);
1237 }
1238 }
1239 }
1240}