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
18#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
23pub struct Name(String);
24impl Name {
25 pub fn as_str(&self) -> &str { &self.0 }
27 pub fn labels(&self) -> u8 {
29 if self.as_str() == "." {
30 0
31 } else {
32 self.as_str().chars().filter(|c| *c == '.').count() as u8
33 }
34 }
35 pub fn trailing_n_labels(&self, n: u8) -> Option<&str> {
37 let labels = self.labels();
38 if n > labels {
39 None
40 } else if n == labels {
41 Some(self.as_str())
42 } else if n == 0 {
43 Some(".")
44 } else {
45 self.as_str().splitn(labels as usize - n as usize + 1, '.').last()
46 }
47 }
48}
49impl core::ops::Deref for Name {
50 type Target = str;
51 fn deref(&self) -> &str { &self.0 }
52}
53impl fmt::Display for Name {
54 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
55 self.0.fmt(f)
56 }
57}
58impl TryFrom<String> for Name {
59 type Error = ();
60 fn try_from(s: String) -> Result<Name, ()> {
61 if s.is_empty() { return Err(()); }
62 if *s.as_bytes().last().unwrap_or(&0) != b"."[0] { return Err(()); }
63 if s.len() > 255 { return Err(()); }
64 if s.chars().any(|c| !c.is_ascii_graphic() || c == '"') { return Err(()); }
65 for label in s.split('.') {
66 if label.len() > 63 { return Err(()); }
67 }
68
69 Ok(Name(s.to_ascii_lowercase()))
70 }
71}
72impl TryFrom<&str> for Name {
73 type Error = ();
74 fn try_from(s: &str) -> Result<Name, ()> {
75 Self::try_from(s.to_owned())
76 }
77}
78
79#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
80pub enum RR {
85 A(A),
87 AAAA(AAAA),
89 NS(NS),
91 Txt(Txt),
93 TLSA(TLSA),
95 CName(CName),
97 DName(DName),
99 DnsKey(DnsKey),
101 DS(DS),
103 RRSig(RRSig),
105 NSec(NSec),
107 NSec3(NSec3),
109}
110impl RR {
111 pub fn name(&self) -> &Name {
113 match self {
114 RR::A(rr) => &rr.name,
115 RR::AAAA(rr) => &rr.name,
116 RR::NS(rr) => &rr.name,
117 RR::Txt(rr) => &rr.name,
118 RR::CName(rr) => &rr.name,
119 RR::DName(rr) => &rr.name,
120 RR::TLSA(rr) => &rr.name,
121 RR::DnsKey(rr) => &rr.name,
122 RR::DS(rr) => &rr.name,
123 RR::RRSig(rr) => &rr.name,
124 RR::NSec(rr) => &rr.name,
125 RR::NSec3(rr) => &rr.name,
126 }
127 }
128 pub fn json(&self) -> String {
130 match self {
131 RR::A(rr) => StaticRecord::json(rr),
132 RR::AAAA(rr) => StaticRecord::json(rr),
133 RR::NS(rr) => StaticRecord::json(rr),
134 RR::Txt(rr) => StaticRecord::json(rr),
135 RR::CName(rr) => StaticRecord::json(rr),
136 RR::DName(rr) => StaticRecord::json(rr),
137 RR::TLSA(rr) => StaticRecord::json(rr),
138 RR::DnsKey(rr) => StaticRecord::json(rr),
139 RR::DS(rr) => StaticRecord::json(rr),
140 RR::RRSig(rr) => StaticRecord::json(rr),
141 RR::NSec(rr) => StaticRecord::json(rr),
142 RR::NSec3(rr) => StaticRecord::json(rr),
143 }
144 }
145 fn ty(&self) -> u16 {
146 match self {
147 RR::A(_) => A::TYPE,
148 RR::AAAA(_) => AAAA::TYPE,
149 RR::NS(_) => NS::TYPE,
150 RR::Txt(_) => Txt::TYPE,
151 RR::CName(_) => CName::TYPE,
152 RR::DName(_) => DName::TYPE,
153 RR::TLSA(_) => TLSA::TYPE,
154 RR::DnsKey(_) => DnsKey::TYPE,
155 RR::DS(_) => DS::TYPE,
156 RR::RRSig(_) => RRSig::TYPE,
157 RR::NSec(_) => NSec::TYPE,
158 RR::NSec3(_) => NSec3::TYPE,
159 }
160 }
161 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
162 match self {
163 RR::A(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
164 RR::AAAA(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
165 RR::NS(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
166 RR::Txt(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
167 RR::CName(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
168 RR::DName(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
169 RR::TLSA(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
170 RR::DnsKey(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
171 RR::DS(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
172 RR::RRSig(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
173 RR::NSec(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
174 RR::NSec3(rr) => StaticRecord::write_u16_len_prefixed_data(rr, out),
175 }
176 }
177 fn ty_to_rr_name(ty: u16) -> Option<&'static str> {
178 match ty {
179 A::TYPE => Some("A"),
180 AAAA::TYPE => Some("AAAA"),
181 NS::TYPE => Some("NS"),
182 Txt::TYPE => Some("TXT"),
183 CName::TYPE => Some("CNAME"),
184 DName::TYPE => Some("DNAME"),
185 TLSA::TYPE => Some("TLSA"),
186 DnsKey::TYPE => Some("DNSKEY"),
187 DS::TYPE => Some("DS"),
188 RRSig::TYPE => Some("RRSIG"),
189 NSec::TYPE => Some("NSEC"),
190 NSec3::TYPE => Some("NSEC3"),
191 _ => None,
192 }
193 }
194}
195impl From<A> for RR { fn from(a: A) -> RR { RR::A(a) } }
196impl From<AAAA> for RR { fn from(aaaa: AAAA) -> RR { RR::AAAA(aaaa) } }
197impl From<NS> for RR { fn from(ns: NS) -> RR { RR::NS(ns) } }
198impl From<Txt> for RR { fn from(txt: Txt) -> RR { RR::Txt(txt) } }
199impl From<CName> for RR { fn from(cname: CName) -> RR { RR::CName(cname) } }
200impl From<DName> for RR { fn from(cname: DName) -> RR { RR::DName(cname) } }
201impl From<TLSA> for RR { fn from(tlsa: TLSA) -> RR { RR::TLSA(tlsa) } }
202impl From<DnsKey> for RR { fn from(dnskey: DnsKey) -> RR { RR::DnsKey(dnskey) } }
203impl From<DS> for RR { fn from(ds: DS) -> RR { RR::DS(ds) } }
204impl From<RRSig> for RR { fn from(rrsig: RRSig) -> RR { RR::RRSig(rrsig) } }
205impl From<NSec> for RR { fn from(nsec: NSec) -> RR { RR::NSec(nsec) } }
206impl From<NSec3> for RR { fn from(nsec3: NSec3) -> RR { RR::NSec3(nsec3) } }
207
208pub(crate) trait StaticRecord : Ord + Sized {
209 const TYPE: u16;
211 fn name(&self) -> &Name;
212 fn json(&self) -> String;
213 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W);
214 fn read_from_data(name: Name, data: &[u8], wire_packet: &[u8]) -> Result<Self, ()>;
215}
216
217pub(crate) trait WriteableRecord : Record {
219 fn serialize_u16_len_prefixed<W: Writer>(&self, out: &mut W);
220}
221impl<RR: StaticRecord> WriteableRecord for RR {
222 fn serialize_u16_len_prefixed<W: Writer>(&self, out: &mut W) {
223 RR::write_u16_len_prefixed_data(self, out)
224 }
225}
226impl WriteableRecord for RR {
227 fn serialize_u16_len_prefixed<W: Writer>(&self, out: &mut W) {
228 RR::write_u16_len_prefixed_data(self, out)
229 }
230}
231
232pub trait Record : Ord {
234 fn ty(&self) -> u16;
239 fn name(&self) -> &Name;
241 fn json(&self) -> String;
243 fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>);
245}
246impl<RR: StaticRecord> Record for RR {
247 fn ty(&self) -> u16 { RR::TYPE }
248 fn name(&self) -> &Name { RR::name(self) }
249 fn json(&self) -> String { RR::json(self) }
250 fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
251 RR::write_u16_len_prefixed_data(self, out)
252 }
253}
254impl Record for RR {
255 fn ty(&self) -> u16 { self.ty() }
256 fn name(&self) -> &Name { self.name() }
257 fn json(&self) -> String { self.json() }
258 fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
259 self.write_u16_len_prefixed_data(out)
260 }
261}
262
263#[derive(Debug, Clone, Hash, PartialEq, Eq)]
264struct TxtBytePart {
265 bytes: [u8; 255],
269 len: NonZeroU8,
271}
272
273#[derive(Debug, Clone, Hash, PartialEq, Eq)]
279pub struct TxtBytes {
280 chunks: Vec<TxtBytePart>,
282}
283
284impl TxtBytes {
285 pub fn new(bytes: &[u8]) -> Result<TxtBytes, ()> {
289 if bytes.len() > 255*255 + 254 { return Err(()); }
290 let mut chunks = Vec::with_capacity((bytes.len() + 254) / 255);
291 let mut data_write = &bytes[..];
292 while !data_write.is_empty() {
293 let split_pos = core::cmp::min(255, data_write.len());
294 let mut part = TxtBytePart {
295 bytes: [0; 255],
296 len: (split_pos as u8).try_into().expect("Cannot be 0 as data_write is not empty"),
297 };
298 part.bytes[..split_pos].copy_from_slice(&data_write[..split_pos]);
299 chunks.push(part);
300 data_write = &data_write[split_pos..];
301 }
302 debug_assert_eq!(chunks.len(), (bytes.len() + 254) / 255);
303 Ok(TxtBytes { chunks })
304 }
305
306 pub fn len(&self) -> usize {
308 let mut res = 0;
309 for chunk in self.chunks.iter() {
310 res += chunk.len.get() as usize;
311 }
312 res
313 }
314
315 pub fn serialized_len(&self) -> u16 {
317 let mut len = 0u16;
318 for chunk in self.chunks.iter() {
319 len = len.checked_add(1 + chunk.len.get() as u16)
320 .expect("TxtBytes objects must fit in 2^16 - 1 bytes when serialized");
321 }
322 len
323 }
324
325 pub fn as_vec(&self) -> Vec<u8> {
327 let mut res = Vec::with_capacity(self.len());
328 for chunk in self.chunks.iter() {
329 res.extend_from_slice(&chunk.bytes[..chunk.len.get() as usize]);
330 }
331 res
332 }
333
334 pub fn iter<'a>(&'a self) -> TxtBytesIter<'a> {
336 TxtBytesIter {
337 bytes: self,
338 next_part: 0,
339 next_byte: 0,
340 }
341 }
342}
343
344impl TryFrom<&str> for TxtBytes {
345 type Error = ();
346 fn try_from(s: &str) -> Result<TxtBytes, ()> {
347 TxtBytes::new(s.as_bytes())
348 }
349}
350
351impl TryFrom<&[u8]> for TxtBytes {
352 type Error = ();
353 fn try_from(b: &[u8]) -> Result<TxtBytes, ()> {
354 TxtBytes::new(b)
355 }
356}
357
358pub struct TxtBytesIter<'a> {
360 bytes: &'a TxtBytes,
361 next_part: usize,
362 next_byte: u8,
363}
364
365impl<'a> Iterator for TxtBytesIter<'a> {
366 type Item = u8;
367 fn next(&mut self) -> Option<u8> {
368 self.bytes.chunks.get(self.next_part)
369 .and_then(|part| if self.next_byte >= part.len.get() {
370 None
371 } else {
372 let res = Some(part.bytes[self.next_byte as usize]);
373 if self.next_byte == part.len.get() - 1 {
374 self.next_byte = 0;
375 self.next_part += 1;
376 } else {
377 self.next_byte += 1;
378 }
379 res
380 })
381 }
382}
383
384#[derive(Debug, Clone, Hash, PartialEq, Eq)]
385pub struct Txt {
387 pub name: Name,
389 pub data: TxtBytes,
394}
395pub const TXT_TYPE: u16 = 16;
397impl Ord for Txt {
398 fn cmp(&self, o: &Txt) -> Ordering {
399 self.name.cmp(&o.name)
400 .then_with(|| {
401 let mut o_chunks = o.data.chunks.iter();
403 for chunk in self.data.chunks.iter() {
404 if let Some(o_chunk) = o_chunks.next() {
405 let chunk_cmp = chunk.len.cmp(&o_chunk.len)
406 .then_with(||chunk.bytes[..chunk.len.get() as usize]
407 .cmp(&o_chunk.bytes[..o_chunk.len.get() as usize]));
408 if !chunk_cmp.is_eq() { return chunk_cmp; }
409 } else {
410 return Ordering::Greater;
412 }
413 }
414 if o_chunks.next().is_some() {
415 Ordering::Less
416 } else {
417 Ordering::Equal
418 }
419 })
420 }
421}
422impl PartialOrd for Txt {
423 fn partial_cmp(&self, o: &Txt) -> Option<Ordering> { Some(self.cmp(o)) }
424}
425impl StaticRecord for Txt {
426 const TYPE: u16 = TXT_TYPE;
427 fn name(&self) -> &Name { &self.name }
428 fn json(&self) -> String {
429 let mut res = format!("{{\"type\":\"txt\",\"name\":\"{}\",\"contents\":", self.name.0);
430 if self.data.iter().all(|b| b >= 0x20 && b <= 0x7e) {
431 res += "\"";
432 for b in self.data.iter() {
433 res.push(b as char);
434 }
435 res += "\"}";
436 } else {
437 res += "[";
438 let mut first_b = true;
439 for b in self.data.iter() {
440 if !first_b { res += ","; }
441 write!(&mut res, "{}", b).expect("Shouldn't fail to write to a String");
442 first_b = false;
443 }
444 res += "]}";
445 }
446 res
447 }
448 fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
449 let mut parts = TxtBytes {
450 chunks: Vec::with_capacity((data.len() + 255) / 256),
451 };
452 let mut serialized_len = 0;
453 while !data.is_empty() {
454 let len = read_u8(&mut data)?;
455 if data.len() < len as usize { return Err(()); }
456 if len == 0 { return Err(()); }
457 serialized_len += 1 + len as u32;
458 if serialized_len > u16::MAX as u32 {
459 return Err(());
460 }
461 let mut part = TxtBytePart {
462 bytes: [0; 255],
463 len: len.try_into().expect("We already checked 0 above"),
464 };
465 part.bytes[..len as usize].copy_from_slice(&data[..len as usize]);
466 data = &data[len as usize..];
467 parts.chunks.push(part);
468 }
469 debug_assert!(data.is_empty());
470 Ok(Txt { name, data: parts })
471 }
472 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
473 out.write(&self.data.serialized_len().to_be_bytes());
474 for chunk in self.data.chunks.iter() {
475 out.write(&[chunk.len.get()]);
476 out.write(&chunk.bytes[..chunk.len.get() as usize]);
477 }
478 }
479}
480
481#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
482pub struct TLSA {
488 pub name: Name,
490 pub cert_usage: u8,
493 pub selector: u8,
495 pub data_ty: u8,
497 pub data: Vec<u8>,
499}
500pub const TLSA_TYPE: u16 = 52;
502impl StaticRecord for TLSA {
503 const TYPE: u16 = TLSA_TYPE;
504 fn name(&self) -> &Name { &self.name }
505 fn json(&self) -> String {
506 let mut out = String::with_capacity(128+self.data.len()*2);
507 write!(&mut out,
508 "{{\"type\":\"tlsa\",\"name\":\"{}\",\"usage\":{},\"selector\":{},\"data_ty\":{},\"data\":\"",
509 self.name.0, self.cert_usage, self.selector, self.data_ty
510 ).expect("Write to a String shouldn't fail");
511 for c in self.data.iter() {
512 write!(&mut out, "{:02X}", c)
513 .expect("Write to a String shouldn't fail");
514 }
515 out += "\"}";
516 out
517 }
518 fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
519 Ok(TLSA {
520 name, cert_usage: read_u8(&mut data)?, selector: read_u8(&mut data)?,
521 data_ty: read_u8(&mut data)?, data: data.to_vec(),
522 })
523 }
524 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
525 let len = 3 + self.data.len();
526 out.write(&(len as u16).to_be_bytes());
527 out.write(&[self.cert_usage, self.selector, self.data_ty]);
528 out.write(&self.data);
529 }
530}
531
532#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
533pub struct CName {
535 pub name: Name,
537 pub canonical_name: Name,
541}
542impl StaticRecord for CName {
543 const TYPE: u16 = 5;
544 fn name(&self) -> &Name { &self.name }
545 fn json(&self) -> String {
546 format!("{{\"type\":\"cname\",\"name\":\"{}\",\"canonical_name\":\"{}\"}}",
547 self.name.0, self.canonical_name.0)
548 }
549 fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
550 let res = CName { name, canonical_name: read_wire_packet_name(&mut data, wire_packet)? };
551 Ok(res)
552 }
553 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
554 let len: u16 = name_len(&self.canonical_name);
555 out.write(&len.to_be_bytes());
556 write_name(out, &self.canonical_name);
557 }
558}
559
560#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
561pub struct DName {
564 pub name: Name,
566 pub delegation_name: Name,
571}
572impl StaticRecord for DName {
573 const TYPE: u16 = 39;
574 fn name(&self) -> &Name { &self.name }
575 fn json(&self) -> String {
576 format!("{{\"type\":\"dname\",\"name\":\"{}\",\"delegation_name\":\"{}\"}}",
577 self.name.0, self.delegation_name.0)
578 }
579 fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
580 let res = DName { name, delegation_name: read_wire_packet_name(&mut data, wire_packet)? };
581 Ok(res)
582 }
583 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
584 let len: u16 = name_len(&self.delegation_name);
585 out.write(&len.to_be_bytes());
586 write_name(out, &self.delegation_name);
587 }
588}
589
590
591#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
592pub struct DnsKey {
594 pub name: Name,
596 pub flags: u16,
598 pub protocol: u8,
600 pub alg: u8,
602 pub pubkey: Vec<u8>,
604}
605impl StaticRecord for DnsKey {
606 const TYPE: u16 = 48;
607 fn name(&self) -> &Name { &self.name }
608 fn json(&self) -> String {
609 let mut out = String::with_capacity(128+self.pubkey.len()*2);
610 write!(&mut out,
611 "{{\"type\":\"dnskey\",\"name\":\"{}\",\"flags\":{},\"protocol\":{},\"alg\":{},\"pubkey\":\"",
612 self.name.0, self.flags, self.protocol, self.alg
613 ).expect("Write to a String shouldn't fail");
614 for c in self.pubkey.iter() {
615 write!(&mut out, "{:02X}", c)
616 .expect("Write to a String shouldn't fail");
617 }
618 out += "\"}";
619 out
620 }
621 fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
622 Ok(DnsKey {
623 name, flags: read_u16(&mut data)?, protocol: read_u8(&mut data)?,
624 alg: read_u8(&mut data)?, pubkey: data.to_vec(),
625 })
626 }
627 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
628 let len = 2 + 1 + 1 + self.pubkey.len();
629 out.write(&(len as u16).to_be_bytes());
630 out.write(&self.flags.to_be_bytes());
631 out.write(&self.protocol.to_be_bytes());
632 out.write(&self.alg.to_be_bytes());
633 out.write(&self.pubkey);
634 }
635}
636impl DnsKey {
637 pub fn key_tag(&self) -> u16 {
639 let mut res = u32::from(self.flags);
640 res += u32::from(self.protocol) << 8;
641 res += u32::from(self.alg);
642 for (idx, b) in self.pubkey.iter().enumerate() {
643 if idx % 2 == 0 {
644 res += u32::from(*b) << 8;
645 } else {
646 res += u32::from(*b);
647 }
648 }
649 res += (res >> 16) & 0xffff;
650 (res & 0xffff) as u16
651 }
652}
653
654#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
655pub struct DS {
658 pub name: Name,
662 pub key_tag: u16,
667 pub alg: u8,
671 pub digest_type: u8,
673 pub digest: Vec<u8>,
675}
676impl StaticRecord for DS {
677 const TYPE: u16 = 43;
678 fn name(&self) -> &Name { &self.name }
679 fn json(&self) -> String {
680 let mut out = String::with_capacity(128+self.digest.len()*2);
681 write!(&mut out,
682 "{{\"type\":\"ds\",\"name\":\"{}\",\"key_tag\":{},\"alg\":{},\"digest_type\":{},\"digest\":\"",
683 self.name.0, self.key_tag, self.alg, self.digest_type
684 ).expect("Write to a String shouldn't fail");
685 for c in self.digest.iter() {
686 write!(&mut out, "{:02X}", c)
687 .expect("Write to a String shouldn't fail");
688 }
689 out += "\"}";
690 out
691 }
692 fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
693 Ok(DS {
694 name, key_tag: read_u16(&mut data)?, alg: read_u8(&mut data)?,
695 digest_type: read_u8(&mut data)?, digest: data.to_vec(),
696 })
697 }
698 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
699 let len = 2 + 1 + 1 + self.digest.len();
700 out.write(&(len as u16).to_be_bytes());
701 out.write(&self.key_tag.to_be_bytes());
702 out.write(&self.alg.to_be_bytes());
703 out.write(&self.digest_type.to_be_bytes());
704 out.write(&self.digest);
705 }
706}
707
708#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
709pub struct RRSig {
712 pub name: Name,
716 pub ty: u16,
721 pub alg: u8,
725 pub labels: u8,
730 pub orig_ttl: u32,
732 pub expiration: u32,
734 pub inception: u32,
736 pub key_tag: u16,
740 pub key_name: Name,
748 pub signature: Vec<u8>,
750}
751impl StaticRecord for RRSig {
752 const TYPE: u16 = 46;
753 fn name(&self) -> &Name { &self.name }
754 fn json(&self) -> String {
755 let mut out = String::with_capacity(256 + self.signature.len()*2);
756 write!(&mut out,
757 "{{\"type\":\"ds\",\"name\":\"{}\",\"signed_record_type\":{},\"alg\":{},\"signed_labels\":{},\"orig_ttl\":{},\"expiration\"{},\"inception\":{},\"key_tag\":{},\"key_name\":\"{}\",\"signature\":\"",
758 self.name.0, self.ty, self.alg, self.labels, self.orig_ttl, self.expiration, self.inception, self.key_tag, self.key_name.0
759 ).expect("Write to a String shouldn't fail");
760 for c in self.signature.iter() {
761 write!(&mut out, "{:02X}", c)
762 .expect("Write to a String shouldn't fail");
763 }
764 out += "\"}";
765 out
766 }
767 fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
768 Ok(RRSig {
769 name, ty: read_u16(&mut data)?, alg: read_u8(&mut data)?,
770 labels: read_u8(&mut data)?, orig_ttl: read_u32(&mut data)?,
771 expiration: read_u32(&mut data)?, inception: read_u32(&mut data)?,
772 key_tag: read_u16(&mut data)?,
773 key_name: read_wire_packet_name(&mut data, wire_packet)?,
774 signature: data.to_vec(),
775 })
776 }
777 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
778 let len = 2 + 1 + 1 + 4*3 + 2 + name_len(&self.key_name) + self.signature.len() as u16;
779 out.write(&len.to_be_bytes());
780 out.write(&self.ty.to_be_bytes());
781 out.write(&self.alg.to_be_bytes());
782 out.write(&self.labels.to_be_bytes());
783 out.write(&self.orig_ttl.to_be_bytes());
784 out.write(&self.expiration.to_be_bytes());
785 out.write(&self.inception.to_be_bytes());
786 out.write(&self.key_tag.to_be_bytes());
787 write_name(out, &self.key_name);
788 out.write(&self.signature);
789 }
790}
791
792#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
793pub struct NSecTypeMask([u8; 8192]);
796impl NSecTypeMask {
797 pub fn new() -> Self { Self([0; 8192]) }
799 pub fn from_types(types: &[u16]) -> Self {
801 let mut flags = [0; 8192];
802 for t in types {
803 flags[*t as usize >> 3] |= 1 << (7 - (*t as usize % 8));
804 }
805 let res = Self(flags);
806 for t in types {
807 debug_assert!(res.contains_type(*t));
808 }
809 res
810 }
811 pub fn contains_type(&self, ty: u16) -> bool {
814 let f = self.0[(ty >> 3) as usize];
815 f & (1 << (7 - (ty % 8))) != 0
817 }
818 fn write_json(&self, s: &mut String) {
819 *s += "[";
820 write!(s, "{:?}", self).expect("Writes to a string shouldn't fail");
821 *s += "]";
822 }
823}
824impl fmt::Debug for NSecTypeMask {
825 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
826 let mut have_written = false;
827 for (idx, mask) in self.0.iter().enumerate() {
828 if *mask == 0 { continue; }
829 for b in 0..8 {
830 if *mask & (1 << b) != 0 {
831 let ty = ((idx as u16) << 3) | (7 - b);
832 match RR::ty_to_rr_name(ty) {
833 Some(name) => write!(f, "{}\"{}\"", if have_written { "," } else { "" }, name)?,
834 _ => write!(f, "{}{}", if have_written { "," } else { "" }, ty)?,
835 }
836 have_written = true;
837 }
838 }
839 }
840 Ok(())
841 }
842}
843
844#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
845pub struct NSec {
848 pub name: Name,
850 pub next_name: Name,
853 pub types: NSecTypeMask,
856}
857impl StaticRecord for NSec {
858 const TYPE: u16 = 47;
859 fn name(&self) -> &Name { &self.name }
860 fn json(&self) -> String {
861 let mut out = String::with_capacity(256 + self.next_name.len());
862 write!(&mut out,
863 "{{\"type\":\"nsec\",\"name\":\"{}\",\"next_name\":\"{}\",\"types\":",
864 self.name.0, self.next_name.0,
865 ).expect("Write to a String shouldn't fail");
866 self.types.write_json(&mut out);
867 out += "}";
868 out
869 }
870 fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
871 let res = NSec {
872 name, next_name: read_wire_packet_name(&mut data, wire_packet)?,
873 types: NSecTypeMask(read_nsec_types_bitmap(&mut data)?),
874 };
875 debug_assert!(data.is_empty());
876 Ok(res)
877 }
878 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
879 let len = name_len(&self.next_name) + nsec_types_bitmap_len(&self.types.0);
880 out.write(&len.to_be_bytes());
881 write_name(out, &self.next_name);
882 write_nsec_types_bitmap(out, &self.types.0);
883 }
884}
885
886#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
887pub struct NSec3 {
890 pub name: Name,
892 pub hash_algo: u8,
895 pub flags: u8,
897 pub hash_iterations: u16,
902 pub salt: Vec<u8>,
906 pub next_name_hash: Vec<u8>,
909 pub types: NSecTypeMask,
912}
913impl StaticRecord for NSec3 {
914 const TYPE: u16 = 50;
915 fn name(&self) -> &Name { &self.name }
916 fn json(&self) -> String {
917 let mut out = String::with_capacity(256);
918 write!(&mut out,
919 "{{\"type\":\"nsec3\",\"name\":\"{}\",\"hash_algo\":{},\"flags\":{},\"hash_iterations\":{},\"salt\":{:?},\"next_name_hash\":{:?},\"types\":",
920 self.name.0, self.hash_algo, self.flags, self.hash_iterations, &self.salt[..], &self.next_name_hash[..]
921 ).expect("Write to a String shouldn't fail");
922 self.types.write_json(&mut out);
923 out += "}";
924 out
925 }
926 fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
927 let res = NSec3 {
928 name, hash_algo: read_u8(&mut data)?, flags: read_u8(&mut data)?,
929 hash_iterations: read_u16(&mut data)?, salt: read_u8_len_prefixed_bytes(&mut data)?,
930 next_name_hash: read_u8_len_prefixed_bytes(&mut data)?,
931 types: NSecTypeMask(read_nsec_types_bitmap(&mut data)?),
932 };
933 debug_assert!(data.is_empty());
934 Ok(res)
935 }
936 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
937 let len = 4 + 2 + self.salt.len() as u16 + self.next_name_hash.len() as u16 +
938 nsec_types_bitmap_len(&self.types.0);
939 out.write(&len.to_be_bytes());
940 out.write(&self.hash_algo.to_be_bytes());
941 out.write(&self.flags.to_be_bytes());
942 out.write(&self.hash_iterations.to_be_bytes());
943 out.write(&(self.salt.len() as u8).to_be_bytes());
944 out.write(&self.salt);
945 out.write(&(self.next_name_hash.len() as u8).to_be_bytes());
946 out.write(&self.next_name_hash);
947 write_nsec_types_bitmap(out, &self.types.0);
948 }
949}
950
951#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
952pub struct A {
954 pub name: Name,
956 pub address: [u8; 4],
958}
959pub const A_TYPE: u16 = 1;
961impl StaticRecord for A {
962 const TYPE: u16 = A_TYPE;
963 fn name(&self) -> &Name { &self.name }
964 fn json(&self) -> String {
965 format!("{{\"type\":\"a\",\"name\":\"{}\",\"address\":{:?}}}", self.name.0, self.address)
966 }
967 fn read_from_data(name: Name, data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
968 if data.len() != 4 { return Err(()); }
969 let mut address = [0; 4];
970 address.copy_from_slice(data);
971 Ok(A { name, address })
972 }
973 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
974 out.write(&4u16.to_be_bytes());
975 out.write(&self.address);
976 }
977}
978
979#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
980pub struct AAAA {
982 pub name: Name,
984 pub address: [u8; 16],
986}
987pub const AAAA_TYPE: u16 = 28;
989impl StaticRecord for AAAA {
990 const TYPE: u16 = AAAA_TYPE;
991 fn name(&self) -> &Name { &self.name }
992 fn json(&self) -> String {
993 format!("{{\"type\":\"aaaa\",\"name\":\"{}\",\"address\":{:?}}}", self.name.0, self.address)
994 }
995 fn read_from_data(name: Name, data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
996 if data.len() != 16 { return Err(()); }
997 let mut address = [0; 16];
998 address.copy_from_slice(data);
999 Ok(AAAA { name, address })
1000 }
1001 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
1002 out.write(&16u16.to_be_bytes());
1003 out.write(&self.address);
1004 }
1005}
1006
1007#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
1008pub struct NS {
1011 pub name: Name,
1016 pub name_server: Name,
1019}
1020impl StaticRecord for NS {
1021 const TYPE: u16 = 2;
1022 fn name(&self) -> &Name { &self.name }
1023 fn json(&self) -> String {
1024 format!("{{\"type\":\"ns\",\"name\":\"{}\",\"ns\":\"{}\"}}", self.name.0, self.name_server.0)
1025 }
1026 fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
1027 let res = NS { name, name_server: read_wire_packet_name(&mut data, wire_packet)? };
1028 Ok(res)
1029 }
1030 fn write_u16_len_prefixed_data<W: Writer>(&self, out: &mut W) {
1031 out.write(&name_len(&self.name_server).to_be_bytes());
1032 write_name(out, &self.name_server);
1033 }
1034}