1#[cfg(feature = "logging")]
8use crate::log::trace;
9
10use crate::error::{e_fmt, Error, Result};
11
12use if_addrs::Interface;
13
14use std::{
15 any::Any,
16 cmp,
17 collections::HashMap,
18 convert::TryInto,
19 fmt,
20 net::{IpAddr, Ipv4Addr, Ipv6Addr},
21 str,
22 time::SystemTime,
23};
24
25#[derive(Clone, Debug, Eq, Hash, PartialEq)]
27pub struct InterfaceId {
28 name: String,
29 index: u32,
30}
31
32impl InterfaceId {
33 pub fn index(&self) -> u32 {
34 self.index
35 }
36}
37
38impl fmt::Display for InterfaceId {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 write!(f, "{}: {}", self.index, self.name)
41 }
42}
43
44impl From<&Interface> for InterfaceId {
45 fn from(interface: &Interface) -> Self {
46 InterfaceId {
47 name: interface.name.clone(),
48 index: interface.index.unwrap_or_default(),
49 }
50 }
51}
52
53#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord)]
57#[non_exhaustive]
58#[repr(u16)]
59pub enum RRType {
60 A = 1,
62
63 CNAME = 5,
65
66 PTR = 12,
68
69 HINFO = 13,
71
72 TXT = 16,
74
75 AAAA = 28,
77
78 SRV = 33,
80
81 NSEC = 47,
83
84 ANY = 255,
86}
87
88impl RRType {
89 pub const fn from_u16(value: u16) -> Option<RRType> {
91 match value {
92 1 => Some(RRType::A),
93 5 => Some(RRType::CNAME),
94 12 => Some(RRType::PTR),
95 13 => Some(RRType::HINFO),
96 16 => Some(RRType::TXT),
97 28 => Some(RRType::AAAA),
98 33 => Some(RRType::SRV),
99 47 => Some(RRType::NSEC),
100 255 => Some(RRType::ANY),
101 _ => None,
102 }
103 }
104}
105
106impl fmt::Display for RRType {
107 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108 match self {
109 RRType::A => write!(f, "TYPE_A"),
110 RRType::CNAME => write!(f, "TYPE_CNAME"),
111 RRType::PTR => write!(f, "TYPE_PTR"),
112 RRType::HINFO => write!(f, "TYPE_HINFO"),
113 RRType::TXT => write!(f, "TYPE_TXT"),
114 RRType::AAAA => write!(f, "TYPE_AAAA"),
115 RRType::SRV => write!(f, "TYPE_SRV"),
116 RRType::NSEC => write!(f, "TYPE_NSEC"),
117 RRType::ANY => write!(f, "TYPE_ANY"),
118 }
119 }
120}
121
122pub const CLASS_IN: u16 = 1;
124pub const CLASS_MASK: u16 = 0x7FFF;
125
126pub const CLASS_CACHE_FLUSH: u16 = 0x8000;
128
129pub const MAX_MSG_ABSOLUTE: usize = 8972;
134
135const MSG_HEADER_LEN: usize = 12;
136
137pub const FLAGS_QR_MASK: u16 = 0x8000; pub const FLAGS_QR_QUERY: u16 = 0x0000;
149
150pub const FLAGS_QR_RESPONSE: u16 = 0x8000;
152
153pub const FLAGS_AA: u16 = 0x0400;
155
156pub const FLAGS_TC: u16 = 0x0200;
167
168pub type DnsRecordBox = Box<dyn DnsRecordExt>;
170
171impl Clone for DnsRecordBox {
172 fn clone(&self) -> Self {
173 self.clone_box()
174 }
175}
176
177const U16_SIZE: usize = 2;
178
179#[inline]
181pub const fn ip_address_rr_type(address: &IpAddr) -> RRType {
182 match address {
183 IpAddr::V4(_) => RRType::A,
184 IpAddr::V6(_) => RRType::AAAA,
185 }
186}
187
188#[derive(Eq, PartialEq, Debug, Clone)]
189pub struct DnsEntry {
190 pub(crate) name: String, pub(crate) ty: RRType,
192 class: u16,
193 cache_flush: bool,
194}
195
196impl DnsEntry {
197 const fn new(name: String, ty: RRType, class: u16) -> Self {
198 Self {
199 name,
200 ty,
201 class: class & CLASS_MASK,
202 cache_flush: (class & CLASS_CACHE_FLUSH) != 0,
203 }
204 }
205}
206
207pub trait DnsEntryExt: fmt::Debug {
209 fn entry_name(&self) -> &str;
210
211 fn entry_type(&self) -> RRType;
212}
213
214#[derive(Debug)]
216pub struct DnsQuestion {
217 pub(crate) entry: DnsEntry,
218}
219
220impl DnsEntryExt for DnsQuestion {
221 fn entry_name(&self) -> &str {
222 &self.entry.name
223 }
224
225 fn entry_type(&self) -> RRType {
226 self.entry.ty
227 }
228}
229
230#[derive(Debug, Clone)]
234pub struct DnsRecord {
235 pub(crate) entry: DnsEntry,
236 ttl: u32, created: u64, expires: u64, refresh: u64, new_name: Option<String>,
246}
247
248impl DnsRecord {
249 fn new(name: &str, ty: RRType, class: u16, ttl: u32) -> Self {
250 let created = current_time_millis();
251
252 let refresh = get_expiration_time(created, ttl, 80);
256
257 let expires = get_expiration_time(created, ttl, 100);
258
259 Self {
260 entry: DnsEntry::new(name.to_string(), ty, class),
261 ttl,
262 created,
263 expires,
264 refresh,
265 new_name: None,
266 }
267 }
268
269 pub const fn get_ttl(&self) -> u32 {
270 self.ttl
271 }
272
273 pub const fn get_expire_time(&self) -> u64 {
274 self.expires
275 }
276
277 pub const fn get_refresh_time(&self) -> u64 {
278 self.refresh
279 }
280
281 pub const fn is_expired(&self, now: u64) -> bool {
282 now >= self.expires
283 }
284
285 pub const fn refresh_due(&self, now: u64) -> bool {
286 now >= self.refresh
287 }
288
289 pub fn halflife_passed(&self, now: u64) -> bool {
291 let halflife = get_expiration_time(self.created, self.ttl, 50);
292 now > halflife
293 }
294
295 pub fn is_unique(&self) -> bool {
296 self.entry.cache_flush
297 }
298
299 pub fn refresh_no_more(&mut self) {
302 self.refresh = get_expiration_time(self.created, self.ttl, 100);
303 }
304
305 pub fn refresh_maybe(&mut self, now: u64) -> bool {
307 if self.is_expired(now) || !self.refresh_due(now) {
308 return false;
309 }
310
311 trace!(
312 "{} qtype {} is due to refresh",
313 &self.entry.name,
314 self.entry.ty
315 );
316
317 if self.refresh == get_expiration_time(self.created, self.ttl, 80) {
324 self.refresh = get_expiration_time(self.created, self.ttl, 85);
325 } else if self.refresh == get_expiration_time(self.created, self.ttl, 85) {
326 self.refresh = get_expiration_time(self.created, self.ttl, 90);
327 } else if self.refresh == get_expiration_time(self.created, self.ttl, 90) {
328 self.refresh = get_expiration_time(self.created, self.ttl, 95);
329 } else {
330 self.refresh_no_more();
331 }
332
333 true
334 }
335
336 fn get_remaining_ttl(&self, now: u64) -> u32 {
338 let remaining_millis = get_expiration_time(self.created, self.ttl, 100) - now;
339 cmp::max(0, remaining_millis / 1000) as u32
340 }
341
342 pub const fn get_created(&self) -> u64 {
344 self.created
345 }
346
347 fn set_expire(&mut self, expire_at: u64) {
349 self.expires = expire_at;
350 }
351
352 fn reset_ttl(&mut self, other: &Self) {
353 self.ttl = other.ttl;
354 self.created = other.created;
355 self.refresh = get_expiration_time(self.created, self.ttl, 80);
356 self.expires = get_expiration_time(self.created, self.ttl, 100);
357 }
358
359 pub fn update_ttl(&mut self, now: u64) {
361 if now > self.created {
362 let elapsed = now - self.created;
363 self.ttl -= (elapsed / 1000) as u32;
364 }
365 }
366
367 pub fn set_new_name(&mut self, new_name: String) {
368 if new_name == self.entry.name {
369 self.new_name = None;
370 } else {
371 self.new_name = Some(new_name);
372 }
373 }
374
375 pub fn get_new_name(&self) -> Option<&str> {
376 self.new_name.as_deref()
377 }
378
379 pub(crate) fn get_name(&self) -> &str {
381 self.new_name.as_deref().unwrap_or(&self.entry.name)
382 }
383
384 pub fn get_original_name(&self) -> &str {
385 &self.entry.name
386 }
387}
388
389impl PartialEq for DnsRecord {
390 fn eq(&self, other: &Self) -> bool {
391 self.entry == other.entry
392 }
393}
394
395pub trait DnsRecordExt: fmt::Debug {
397 fn get_record(&self) -> &DnsRecord;
398 fn get_record_mut(&mut self) -> &mut DnsRecord;
399 fn write(&self, packet: &mut DnsOutPacket);
400 fn any(&self) -> &dyn Any;
401
402 fn matches(&self, other: &dyn DnsRecordExt) -> bool;
404
405 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool;
407
408 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering;
411
412 fn compare(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
414 match self.get_class().cmp(&other.get_class()) {
428 cmp::Ordering::Equal => match self.get_type().cmp(&other.get_type()) {
429 cmp::Ordering::Equal => self.compare_rdata(other),
430 not_equal => not_equal,
431 },
432 not_equal => not_equal,
433 }
434 }
435
436 fn rdata_print(&self) -> String;
438
439 fn get_class(&self) -> u16 {
441 self.get_record().entry.class
442 }
443
444 fn get_cache_flush(&self) -> bool {
445 self.get_record().entry.cache_flush
446 }
447
448 fn get_name(&self) -> &str {
450 self.get_record().get_name()
451 }
452
453 fn get_type(&self) -> RRType {
454 self.get_record().entry.ty
455 }
456
457 fn reset_ttl(&mut self, other: &dyn DnsRecordExt) {
460 self.get_record_mut().reset_ttl(other.get_record());
461 }
462
463 fn get_created(&self) -> u64 {
464 self.get_record().get_created()
465 }
466
467 fn get_expire(&self) -> u64 {
468 self.get_record().get_expire_time()
469 }
470
471 fn set_expire(&mut self, expire_at: u64) {
472 self.get_record_mut().set_expire(expire_at);
473 }
474
475 fn set_expire_sooner(&mut self, expire_at: u64) {
477 if expire_at < self.get_expire() {
478 self.get_record_mut().set_expire(expire_at);
479 }
480 }
481
482 fn updated_refresh_time(&mut self, now: u64) -> Option<u64> {
485 if self.get_record_mut().refresh_maybe(now) {
486 Some(self.get_record().get_refresh_time())
487 } else {
488 None
489 }
490 }
491
492 fn suppressed_by_answer(&self, other: &dyn DnsRecordExt) -> bool {
495 self.matches(other) && (other.get_record().ttl > self.get_record().ttl / 2)
496 }
497
498 fn suppressed_by(&self, msg: &DnsIncoming) -> bool {
500 for answer in msg.answers.iter() {
501 if self.suppressed_by_answer(answer.as_ref()) {
502 return true;
503 }
504 }
505 false
506 }
507
508 fn clone_box(&self) -> DnsRecordBox;
509
510 fn boxed(self) -> DnsRecordBox;
511}
512
513#[derive(Debug, Clone)]
515pub struct DnsAddress {
516 pub(crate) record: DnsRecord,
517 address: IpAddr,
518 interface_id: InterfaceId,
519}
520
521impl DnsAddress {
522 pub fn new(
523 name: &str,
524 ty: RRType,
525 class: u16,
526 ttl: u32,
527 address: IpAddr,
528 interface_id: InterfaceId,
529 ) -> Self {
530 let record = DnsRecord::new(name, ty, class, ttl);
531 Self {
532 record,
533 address,
534 interface_id,
535 }
536 }
537
538 pub fn address(&self) -> IpAddr {
539 self.address
540 }
541}
542
543impl DnsRecordExt for DnsAddress {
544 fn get_record(&self) -> &DnsRecord {
545 &self.record
546 }
547
548 fn get_record_mut(&mut self) -> &mut DnsRecord {
549 &mut self.record
550 }
551
552 fn write(&self, packet: &mut DnsOutPacket) {
553 match self.address {
554 IpAddr::V4(addr) => packet.write_bytes(addr.octets().as_ref()),
555 IpAddr::V6(addr) => packet.write_bytes(addr.octets().as_ref()),
556 };
557 }
558
559 fn any(&self) -> &dyn Any {
560 self
561 }
562
563 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
564 if let Some(other_a) = other.any().downcast_ref::<Self>() {
565 return self.address == other_a.address
566 && self.record.entry == other_a.record.entry
567 && self.interface_id == other_a.interface_id;
568 }
569 false
570 }
571
572 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
573 if let Some(other_a) = other.any().downcast_ref::<Self>() {
574 return self.address == other_a.address;
575 }
576 false
577 }
578
579 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
580 if let Some(other_a) = other.any().downcast_ref::<Self>() {
581 self.address.cmp(&other_a.address)
582 } else {
583 cmp::Ordering::Greater
584 }
585 }
586
587 fn rdata_print(&self) -> String {
588 format!("{}", self.address)
589 }
590
591 fn clone_box(&self) -> DnsRecordBox {
592 Box::new(self.clone())
593 }
594
595 fn boxed(self) -> DnsRecordBox {
596 Box::new(self)
597 }
598}
599
600#[derive(Debug, Clone)]
602pub struct DnsPointer {
603 record: DnsRecord,
604 alias: String, }
606
607impl DnsPointer {
608 pub fn new(name: &str, ty: RRType, class: u16, ttl: u32, alias: String) -> Self {
609 let record = DnsRecord::new(name, ty, class, ttl);
610 Self { record, alias }
611 }
612
613 pub fn alias(&self) -> &str {
614 &self.alias
615 }
616}
617
618impl DnsRecordExt for DnsPointer {
619 fn get_record(&self) -> &DnsRecord {
620 &self.record
621 }
622
623 fn get_record_mut(&mut self) -> &mut DnsRecord {
624 &mut self.record
625 }
626
627 fn write(&self, packet: &mut DnsOutPacket) {
628 packet.write_name(&self.alias);
629 }
630
631 fn any(&self) -> &dyn Any {
632 self
633 }
634
635 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
636 if let Some(other_ptr) = other.any().downcast_ref::<Self>() {
637 return self.alias == other_ptr.alias && self.record.entry == other_ptr.record.entry;
638 }
639 false
640 }
641
642 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
643 if let Some(other_ptr) = other.any().downcast_ref::<Self>() {
644 return self.alias == other_ptr.alias;
645 }
646 false
647 }
648
649 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
650 if let Some(other_ptr) = other.any().downcast_ref::<Self>() {
651 self.alias.cmp(&other_ptr.alias)
652 } else {
653 cmp::Ordering::Greater
654 }
655 }
656
657 fn rdata_print(&self) -> String {
658 self.alias.clone()
659 }
660
661 fn clone_box(&self) -> DnsRecordBox {
662 Box::new(self.clone())
663 }
664
665 fn boxed(self) -> DnsRecordBox {
666 Box::new(self)
667 }
668}
669
670#[derive(Debug, Clone)]
672pub struct DnsSrv {
673 pub(crate) record: DnsRecord,
674 pub(crate) priority: u16, pub(crate) weight: u16, host: String,
677 port: u16,
678}
679
680impl DnsSrv {
681 pub fn new(
682 name: &str,
683 class: u16,
684 ttl: u32,
685 priority: u16,
686 weight: u16,
687 port: u16,
688 host: String,
689 ) -> Self {
690 let record = DnsRecord::new(name, RRType::SRV, class, ttl);
691 Self {
692 record,
693 priority,
694 weight,
695 host,
696 port,
697 }
698 }
699
700 pub fn host(&self) -> &str {
701 &self.host
702 }
703
704 pub fn port(&self) -> u16 {
705 self.port
706 }
707
708 pub fn set_host(&mut self, host: String) {
709 self.host = host;
710 }
711}
712
713impl DnsRecordExt for DnsSrv {
714 fn get_record(&self) -> &DnsRecord {
715 &self.record
716 }
717
718 fn get_record_mut(&mut self) -> &mut DnsRecord {
719 &mut self.record
720 }
721
722 fn write(&self, packet: &mut DnsOutPacket) {
723 packet.write_short(self.priority);
724 packet.write_short(self.weight);
725 packet.write_short(self.port);
726 packet.write_name(&self.host);
727 }
728
729 fn any(&self) -> &dyn Any {
730 self
731 }
732
733 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
734 if let Some(other_svc) = other.any().downcast_ref::<Self>() {
735 return self.host == other_svc.host
736 && self.port == other_svc.port
737 && self.weight == other_svc.weight
738 && self.priority == other_svc.priority
739 && self.record.entry == other_svc.record.entry;
740 }
741 false
742 }
743
744 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
745 if let Some(other_srv) = other.any().downcast_ref::<Self>() {
746 return self.host == other_srv.host
747 && self.port == other_srv.port
748 && self.weight == other_srv.weight
749 && self.priority == other_srv.priority;
750 }
751 false
752 }
753
754 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
755 let Some(other_srv) = other.any().downcast_ref::<Self>() else {
756 return cmp::Ordering::Greater;
757 };
758
759 match self
761 .priority
762 .to_be_bytes()
763 .cmp(&other_srv.priority.to_be_bytes())
764 {
765 cmp::Ordering::Equal => {
766 match self
768 .weight
769 .to_be_bytes()
770 .cmp(&other_srv.weight.to_be_bytes())
771 {
772 cmp::Ordering::Equal => {
773 match self.port.to_be_bytes().cmp(&other_srv.port.to_be_bytes()) {
775 cmp::Ordering::Equal => self.host.cmp(&other_srv.host),
776 not_equal => not_equal,
777 }
778 }
779 not_equal => not_equal,
780 }
781 }
782 not_equal => not_equal,
783 }
784 }
785
786 fn rdata_print(&self) -> String {
787 format!(
788 "priority: {}, weight: {}, port: {}, host: {}",
789 self.priority, self.weight, self.port, self.host
790 )
791 }
792
793 fn clone_box(&self) -> DnsRecordBox {
794 Box::new(self.clone())
795 }
796
797 fn boxed(self) -> DnsRecordBox {
798 Box::new(self)
799 }
800}
801
802#[derive(Clone)]
817pub struct DnsTxt {
818 pub(crate) record: DnsRecord,
819 text: Vec<u8>,
820}
821
822impl DnsTxt {
823 pub fn new(name: &str, class: u16, ttl: u32, text: Vec<u8>) -> Self {
824 let record = DnsRecord::new(name, RRType::TXT, class, ttl);
825 Self { record, text }
826 }
827
828 pub fn text(&self) -> &[u8] {
829 &self.text
830 }
831}
832
833impl DnsRecordExt for DnsTxt {
834 fn get_record(&self) -> &DnsRecord {
835 &self.record
836 }
837
838 fn get_record_mut(&mut self) -> &mut DnsRecord {
839 &mut self.record
840 }
841
842 fn write(&self, packet: &mut DnsOutPacket) {
843 packet.write_bytes(&self.text);
844 }
845
846 fn any(&self) -> &dyn Any {
847 self
848 }
849
850 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
851 if let Some(other_txt) = other.any().downcast_ref::<Self>() {
852 return self.text == other_txt.text && self.record.entry == other_txt.record.entry;
853 }
854 false
855 }
856
857 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
858 if let Some(other_txt) = other.any().downcast_ref::<Self>() {
859 return self.text == other_txt.text;
860 }
861 false
862 }
863
864 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
865 if let Some(other_txt) = other.any().downcast_ref::<Self>() {
866 self.text.cmp(&other_txt.text)
867 } else {
868 cmp::Ordering::Greater
869 }
870 }
871
872 fn rdata_print(&self) -> String {
873 format!("{:?}", decode_txt(&self.text))
874 }
875
876 fn clone_box(&self) -> DnsRecordBox {
877 Box::new(self.clone())
878 }
879
880 fn boxed(self) -> DnsRecordBox {
881 Box::new(self)
882 }
883}
884
885impl fmt::Debug for DnsTxt {
886 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
887 let properties = decode_txt(&self.text);
888 write!(
889 f,
890 "DnsTxt {{ record: {:?}, text: {:?} }}",
891 self.record, properties
892 )
893 }
894}
895
896fn decode_txt(txt: &[u8]) -> Vec<TxtProperty> {
898 let mut properties = Vec::new();
899 let mut offset = 0;
900 while offset < txt.len() {
901 let length = txt[offset] as usize;
902 if length == 0 {
903 break; }
905 offset += 1; let offset_end = offset + length;
908 if offset_end > txt.len() {
909 trace!("ERROR: DNS TXT: size given for property is out of range. (offset={}, length={}, offset_end={}, record length={})", offset, length, offset_end, txt.len());
910 break; }
912 let kv_bytes = &txt[offset..offset_end];
913
914 let (k, v) = kv_bytes.iter().position(|&x| x == b'=').map_or_else(
916 || (kv_bytes.to_vec(), None),
917 |idx| (kv_bytes[..idx].to_vec(), Some(kv_bytes[idx + 1..].to_vec())),
918 );
919
920 match String::from_utf8(k) {
922 Ok(k_string) => {
923 properties.push(TxtProperty {
924 key: k_string,
925 val: v,
926 });
927 }
928 Err(e) => trace!("ERROR: convert to String from key: {}", e),
929 }
930
931 offset += length;
932 }
933
934 properties
935}
936
937#[derive(Clone, PartialEq, Eq)]
939pub struct TxtProperty {
940 key: String,
942
943 val: Option<Vec<u8>>,
947}
948
949impl TxtProperty {
950 pub fn val_str(&self) -> &str {
952 self.val
953 .as_ref()
954 .map_or("", |v| std::str::from_utf8(&v[..]).unwrap_or_default())
955 }
956}
957
958impl<K, V> From<&(K, V)> for TxtProperty
960where
961 K: ToString,
962 V: ToString,
963{
964 fn from(prop: &(K, V)) -> Self {
965 Self {
966 key: prop.0.to_string(),
967 val: Some(prop.1.to_string().into_bytes()),
968 }
969 }
970}
971
972impl<K, V> From<(K, V)> for TxtProperty
973where
974 K: ToString,
975 V: AsRef<[u8]>,
976{
977 fn from(prop: (K, V)) -> Self {
978 Self {
979 key: prop.0.to_string(),
980 val: Some(prop.1.as_ref().into()),
981 }
982 }
983}
984
985impl From<&str> for TxtProperty {
987 fn from(key: &str) -> Self {
988 Self {
989 key: key.to_string(),
990 val: None,
991 }
992 }
993}
994
995impl fmt::Display for TxtProperty {
996 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
997 write!(f, "{}={}", self.key, self.val_str())
998 }
999}
1000
1001impl fmt::Debug for TxtProperty {
1005 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1006 let val_string = self.val.as_ref().map_or_else(
1007 || "None".to_string(),
1008 |v| {
1009 std::str::from_utf8(&v[..]).map_or_else(
1010 |_| format!("Some({})", u8_slice_to_hex(&v[..])),
1011 |s| format!("Some(\"{}\")", s),
1012 )
1013 },
1014 );
1015
1016 write!(
1017 f,
1018 "TxtProperty {{key: \"{}\", val: {}}}",
1019 &self.key, &val_string,
1020 )
1021 }
1022}
1023
1024const HEX_TABLE: [char; 16] = [
1025 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
1026];
1027
1028fn u8_slice_to_hex(slice: &[u8]) -> String {
1032 let mut hex = String::with_capacity(slice.len() * 2 + 2);
1033 hex.push_str("0x");
1034 for b in slice {
1035 hex.push(HEX_TABLE[(b >> 4) as usize]);
1036 hex.push(HEX_TABLE[(b & 0x0F) as usize]);
1037 }
1038 hex
1039}
1040
1041#[derive(Debug, Clone)]
1043struct DnsHostInfo {
1044 record: DnsRecord,
1045 cpu: String,
1046 os: String,
1047}
1048
1049impl DnsHostInfo {
1050 fn new(name: &str, ty: RRType, class: u16, ttl: u32, cpu: String, os: String) -> Self {
1051 let record = DnsRecord::new(name, ty, class, ttl);
1052 Self { record, cpu, os }
1053 }
1054}
1055
1056impl DnsRecordExt for DnsHostInfo {
1057 fn get_record(&self) -> &DnsRecord {
1058 &self.record
1059 }
1060
1061 fn get_record_mut(&mut self) -> &mut DnsRecord {
1062 &mut self.record
1063 }
1064
1065 fn write(&self, packet: &mut DnsOutPacket) {
1066 println!("writing HInfo: cpu {} os {}", &self.cpu, &self.os);
1067 packet.write_bytes(self.cpu.as_bytes());
1068 packet.write_bytes(self.os.as_bytes());
1069 }
1070
1071 fn any(&self) -> &dyn Any {
1072 self
1073 }
1074
1075 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
1076 if let Some(other_hinfo) = other.any().downcast_ref::<Self>() {
1077 return self.cpu == other_hinfo.cpu
1078 && self.os == other_hinfo.os
1079 && self.record.entry == other_hinfo.record.entry;
1080 }
1081 false
1082 }
1083
1084 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
1085 if let Some(other_hinfo) = other.any().downcast_ref::<Self>() {
1086 return self.cpu == other_hinfo.cpu && self.os == other_hinfo.os;
1087 }
1088 false
1089 }
1090
1091 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
1092 if let Some(other_hinfo) = other.any().downcast_ref::<Self>() {
1093 match self.cpu.cmp(&other_hinfo.cpu) {
1094 cmp::Ordering::Equal => self.os.cmp(&other_hinfo.os),
1095 ordering => ordering,
1096 }
1097 } else {
1098 cmp::Ordering::Greater
1099 }
1100 }
1101
1102 fn rdata_print(&self) -> String {
1103 format!("cpu: {}, os: {}", self.cpu, self.os)
1104 }
1105
1106 fn clone_box(&self) -> DnsRecordBox {
1107 Box::new(self.clone())
1108 }
1109
1110 fn boxed(self) -> DnsRecordBox {
1111 Box::new(self)
1112 }
1113}
1114
1115#[derive(Debug, Clone)]
1121pub struct DnsNSec {
1122 record: DnsRecord,
1123 next_domain: String,
1124 type_bitmap: Vec<u8>,
1125}
1126
1127impl DnsNSec {
1128 pub fn new(
1129 name: &str,
1130 class: u16,
1131 ttl: u32,
1132 next_domain: String,
1133 type_bitmap: Vec<u8>,
1134 ) -> Self {
1135 let record = DnsRecord::new(name, RRType::NSEC, class, ttl);
1136 Self {
1137 record,
1138 next_domain,
1139 type_bitmap,
1140 }
1141 }
1142
1143 pub fn _types(&self) -> Vec<u16> {
1145 let mut bit_num = 0;
1154 let mut results = Vec::new();
1155
1156 for byte in self.type_bitmap.iter() {
1157 let mut bit_mask: u8 = 0x80; for _ in 0..8 {
1161 if (byte & bit_mask) != 0 {
1162 results.push(bit_num);
1163 }
1164 bit_num += 1;
1165 bit_mask >>= 1; }
1167 }
1168 results
1169 }
1170}
1171
1172impl DnsRecordExt for DnsNSec {
1173 fn get_record(&self) -> &DnsRecord {
1174 &self.record
1175 }
1176
1177 fn get_record_mut(&mut self) -> &mut DnsRecord {
1178 &mut self.record
1179 }
1180
1181 fn write(&self, packet: &mut DnsOutPacket) {
1182 packet.write_bytes(self.next_domain.as_bytes());
1183 packet.write_bytes(&self.type_bitmap);
1184 }
1185
1186 fn any(&self) -> &dyn Any {
1187 self
1188 }
1189
1190 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
1191 if let Some(other_record) = other.any().downcast_ref::<Self>() {
1192 return self.next_domain == other_record.next_domain
1193 && self.type_bitmap == other_record.type_bitmap
1194 && self.record.entry == other_record.record.entry;
1195 }
1196 false
1197 }
1198
1199 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
1200 if let Some(other_record) = other.any().downcast_ref::<Self>() {
1201 return self.next_domain == other_record.next_domain
1202 && self.type_bitmap == other_record.type_bitmap;
1203 }
1204 false
1205 }
1206
1207 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
1208 if let Some(other_nsec) = other.any().downcast_ref::<Self>() {
1209 match self.next_domain.cmp(&other_nsec.next_domain) {
1210 cmp::Ordering::Equal => self.type_bitmap.cmp(&other_nsec.type_bitmap),
1211 ordering => ordering,
1212 }
1213 } else {
1214 cmp::Ordering::Greater
1215 }
1216 }
1217
1218 fn rdata_print(&self) -> String {
1219 format!(
1220 "next_domain: {}, type_bitmap len: {}",
1221 self.next_domain,
1222 self.type_bitmap.len()
1223 )
1224 }
1225
1226 fn clone_box(&self) -> DnsRecordBox {
1227 Box::new(self.clone())
1228 }
1229
1230 fn boxed(self) -> DnsRecordBox {
1231 Box::new(self)
1232 }
1233}
1234
1235#[derive(PartialEq)]
1236enum PacketState {
1237 Init = 0,
1238 Finished = 1,
1239}
1240
1241pub struct DnsOutPacket {
1243 data: Vec<Vec<u8>>,
1245
1246 size: usize,
1248
1249 state: PacketState,
1251
1252 names: HashMap<String, u16>,
1254}
1255
1256impl DnsOutPacket {
1257 fn new() -> Self {
1258 Self {
1259 data: Vec::new(),
1260 size: MSG_HEADER_LEN, state: PacketState::Init,
1262 names: HashMap::new(),
1263 }
1264 }
1265
1266 pub fn size(&self) -> usize {
1267 self.size
1268 }
1269
1270 pub fn to_bytes(&self) -> Vec<u8> {
1271 self.data.concat()
1272 }
1273
1274 fn write_question(&mut self, question: &DnsQuestion) {
1275 self.write_name(&question.entry.name);
1276 self.write_short(question.entry.ty as u16);
1277 self.write_short(question.entry.class);
1278 }
1279
1280 fn write_record(&mut self, record_ext: &dyn DnsRecordExt, now: u64) -> bool {
1284 let start_data_length = self.data.len();
1285 let start_size = self.size;
1286
1287 let record = record_ext.get_record();
1288 self.write_name(record.get_name());
1289 self.write_short(record.entry.ty as u16);
1290 if record.entry.cache_flush {
1291 self.write_short(record.entry.class | CLASS_CACHE_FLUSH);
1293 } else {
1294 self.write_short(record.entry.class);
1295 }
1296
1297 if now == 0 {
1298 self.write_u32(record.ttl);
1299 } else {
1300 self.write_u32(record.get_remaining_ttl(now));
1301 }
1302
1303 let index = self.data.len();
1304
1305 self.size += 2;
1307 record_ext.write(self);
1308 self.size -= 2;
1309
1310 let length: usize = self.data[index..].iter().map(|x| x.len()).sum();
1311 self.insert_short(index, length as u16);
1312
1313 if self.size > MAX_MSG_ABSOLUTE {
1314 self.data.truncate(start_data_length);
1315 self.size = start_size;
1316 self.state = PacketState::Finished;
1317 return false;
1318 }
1319
1320 true
1321 }
1322
1323 pub(crate) fn insert_short(&mut self, index: usize, value: u16) {
1324 self.data.insert(index, value.to_be_bytes().to_vec());
1325 self.size += 2;
1326 }
1327
1328 fn write_name(&mut self, name: &str) {
1350 let end = name.len();
1352 let end = if end > 0 && &name[end - 1..] == "." {
1353 end - 1
1354 } else {
1355 end
1356 };
1357
1358 let mut here = 0;
1359 while here < end {
1360 const POINTER_MASK: u16 = 0xC000;
1361 let remaining = &name[here..end];
1362
1363 match self.names.get(remaining) {
1365 Some(offset) => {
1366 let pointer = *offset | POINTER_MASK;
1367 self.write_short(pointer);
1368 break;
1375 }
1376 None => {
1377 self.names.insert(remaining.to_string(), self.size as u16);
1379 let stop = remaining.find('.').map_or(end, |i| here + i);
1383 let label = &name[here..stop];
1384 self.write_utf8(label);
1385
1386 here = stop + 1; }
1388 }
1389
1390 if here >= end {
1391 self.write_byte(0); }
1393 }
1394 }
1395
1396 fn write_utf8(&mut self, utf: &str) {
1397 assert!(utf.len() < 64);
1398 self.write_byte(utf.len() as u8);
1399 self.write_bytes(utf.as_bytes());
1400 }
1401
1402 fn write_bytes(&mut self, s: &[u8]) {
1403 self.data.push(s.to_vec());
1404 self.size += s.len();
1405 }
1406
1407 fn write_u32(&mut self, int: u32) {
1408 self.data.push(int.to_be_bytes().to_vec());
1409 self.size += 4;
1410 }
1411
1412 fn write_short(&mut self, short: u16) {
1413 self.data.push(short.to_be_bytes().to_vec());
1414 self.size += 2;
1415 }
1416
1417 fn write_byte(&mut self, byte: u8) {
1418 self.data.push(vec![byte]);
1419 self.size += 1;
1420 }
1421
1422 fn write_header(
1445 &mut self,
1446 id: u16,
1447 flags: u16,
1448 q_count: u16,
1449 a_count: u16,
1450 auth_count: u16,
1451 addi_count: u16,
1452 ) {
1453 self.insert_short(0, addi_count);
1454 self.insert_short(0, auth_count);
1455 self.insert_short(0, a_count);
1456 self.insert_short(0, q_count);
1457 self.insert_short(0, flags);
1458 self.insert_short(0, id);
1459
1460 self.size -= MSG_HEADER_LEN;
1462
1463 self.state = PacketState::Finished;
1464 }
1465}
1466
1467pub struct DnsOutgoing {
1469 flags: u16,
1470 id: u16,
1471 multicast: bool,
1472 questions: Vec<DnsQuestion>,
1473 answers: Vec<(DnsRecordBox, u64)>,
1474 authorities: Vec<DnsRecordBox>,
1475 additionals: Vec<DnsRecordBox>,
1476 known_answer_count: i64, }
1478
1479impl DnsOutgoing {
1480 pub fn new(flags: u16) -> Self {
1481 Self {
1482 flags,
1483 id: 0,
1484 multicast: true,
1485 questions: Vec::new(),
1486 answers: Vec::new(),
1487 authorities: Vec::new(),
1488 additionals: Vec::new(),
1489 known_answer_count: 0,
1490 }
1491 }
1492
1493 pub fn questions(&self) -> &[DnsQuestion] {
1494 &self.questions
1495 }
1496
1497 pub(crate) fn _answers(&self) -> &[(DnsRecordBox, u64)] {
1499 &self.answers
1500 }
1501
1502 pub fn answers_count(&self) -> usize {
1503 self.answers.len()
1504 }
1505
1506 pub fn authorities(&self) -> &[DnsRecordBox] {
1507 &self.authorities
1508 }
1509
1510 pub fn additionals(&self) -> &[DnsRecordBox] {
1511 &self.additionals
1512 }
1513
1514 pub fn known_answer_count(&self) -> i64 {
1515 self.known_answer_count
1516 }
1517
1518 pub fn set_id(&mut self, id: u16) {
1519 self.id = id;
1520 }
1521
1522 pub const fn is_query(&self) -> bool {
1523 (self.flags & FLAGS_QR_MASK) == FLAGS_QR_QUERY
1524 }
1525
1526 const fn is_response(&self) -> bool {
1527 (self.flags & FLAGS_QR_MASK) == FLAGS_QR_RESPONSE
1528 }
1529
1530 pub fn add_additional_answer(&mut self, answer: impl DnsRecordExt + 'static) {
1564 trace!("add_additional_answer: {:?}", &answer);
1565 self.additionals.push(answer.boxed());
1566 }
1567
1568 pub fn add_answer_box(&mut self, answer_box: DnsRecordBox) {
1570 self.answers.push((answer_box, 0));
1571 }
1572
1573 pub fn add_authority(&mut self, record: DnsRecordBox) {
1574 self.authorities.push(record);
1575 }
1576
1577 pub fn add_answer(
1580 &mut self,
1581 msg: &DnsIncoming,
1582 answer: impl DnsRecordExt + Send + 'static,
1583 ) -> bool {
1584 trace!("Check for add_answer");
1585 if answer.suppressed_by(msg) {
1586 trace!("my answer is suppressed by incoming msg");
1587 self.known_answer_count += 1;
1588 return false;
1589 }
1590
1591 self.add_answer_at_time(answer, 0)
1592 }
1593
1594 pub fn add_answer_at_time(
1598 &mut self,
1599 answer: impl DnsRecordExt + Send + 'static,
1600 now: u64,
1601 ) -> bool {
1602 if now == 0 || !answer.get_record().is_expired(now) {
1603 trace!("add_answer push: {:?}", &answer);
1604 self.answers.push((answer.boxed(), now));
1605 return true;
1606 }
1607 false
1608 }
1609
1610 pub fn add_question(&mut self, name: &str, qtype: RRType) {
1611 let q = DnsQuestion {
1612 entry: DnsEntry::new(name.to_string(), qtype, CLASS_IN),
1613 };
1614 self.questions.push(q);
1615 }
1616
1617 pub fn to_data_on_wire(&self) -> Vec<Vec<u8>> {
1619 let packet_list = self.to_packets();
1620 packet_list.iter().map(|p| p.data.concat()).collect()
1621 }
1622
1623 pub fn to_packets(&self) -> Vec<DnsOutPacket> {
1625 let mut packet_list = Vec::new();
1626 let mut packet = DnsOutPacket::new();
1627
1628 let mut question_count = self.questions.len() as u16;
1629 let mut answer_count = 0;
1630 let mut auth_count = 0;
1631 let mut addi_count = 0;
1632 let id = if self.multicast { 0 } else { self.id };
1633
1634 for question in self.questions.iter() {
1635 packet.write_question(question);
1636 }
1637
1638 for (answer, time) in self.answers.iter() {
1639 if packet.write_record(answer.as_ref(), *time) {
1640 answer_count += 1;
1641 }
1642 }
1643
1644 for auth in self.authorities.iter() {
1645 auth_count += u16::from(packet.write_record(auth.as_ref(), 0));
1646 }
1647
1648 for addi in self.additionals.iter() {
1649 if packet.write_record(addi.as_ref(), 0) {
1650 addi_count += 1;
1651 continue;
1652 }
1653
1654 if self.is_response() {
1656 break;
1657 }
1658
1659 packet.write_header(
1664 id,
1665 self.flags | FLAGS_TC,
1666 question_count,
1667 answer_count,
1668 auth_count,
1669 addi_count,
1670 );
1671
1672 packet_list.push(packet);
1673
1674 packet = DnsOutPacket::new();
1676 packet.write_record(addi.as_ref(), 0);
1677
1678 question_count = 0;
1679 answer_count = 0;
1680 auth_count = 0;
1681 addi_count = 1;
1682 }
1683
1684 packet.write_header(
1685 id,
1686 self.flags,
1687 question_count,
1688 answer_count,
1689 auth_count,
1690 addi_count,
1691 );
1692
1693 packet_list.push(packet);
1694 packet_list
1695 }
1696}
1697
1698#[derive(Debug)]
1700pub struct DnsIncoming {
1701 offset: usize,
1702 data: Vec<u8>,
1703 questions: Vec<DnsQuestion>,
1704 answers: Vec<DnsRecordBox>,
1705 authorities: Vec<DnsRecordBox>,
1706 additional: Vec<DnsRecordBox>,
1707 id: u16,
1708 flags: u16,
1709 num_questions: u16,
1710 num_answers: u16,
1711 num_authorities: u16,
1712 num_additionals: u16,
1713 interface_id: InterfaceId,
1714}
1715
1716impl DnsIncoming {
1717 pub fn new(data: Vec<u8>, interface_id: InterfaceId) -> Result<Self> {
1718 let mut incoming = Self {
1719 offset: 0,
1720 data,
1721 questions: Vec::new(),
1722 answers: Vec::new(),
1723 authorities: Vec::new(),
1724 additional: Vec::new(),
1725 id: 0,
1726 flags: 0,
1727 num_questions: 0,
1728 num_answers: 0,
1729 num_authorities: 0,
1730 num_additionals: 0,
1731 interface_id,
1732 };
1733
1734 incoming.read_header()?;
1754 incoming.read_questions()?;
1755 incoming.read_answers()?;
1756 incoming.read_authorities()?;
1757 incoming.read_additional()?;
1758
1759 Ok(incoming)
1760 }
1761
1762 pub fn id(&self) -> u16 {
1763 self.id
1764 }
1765
1766 pub fn questions(&self) -> &[DnsQuestion] {
1767 &self.questions
1768 }
1769
1770 pub fn answers(&self) -> &[DnsRecordBox] {
1771 &self.answers
1772 }
1773
1774 pub fn authorities(&self) -> &[DnsRecordBox] {
1775 &self.authorities
1776 }
1777
1778 pub fn additionals(&self) -> &[DnsRecordBox] {
1779 &self.additional
1780 }
1781
1782 pub fn answers_mut(&mut self) -> &mut Vec<DnsRecordBox> {
1783 &mut self.answers
1784 }
1785
1786 pub fn authorities_mut(&mut self) -> &mut Vec<DnsRecordBox> {
1787 &mut self.authorities
1788 }
1789
1790 pub fn additionals_mut(&mut self) -> &mut Vec<DnsRecordBox> {
1791 &mut self.additional
1792 }
1793
1794 pub fn all_records(self) -> impl Iterator<Item = DnsRecordBox> {
1795 self.answers
1796 .into_iter()
1797 .chain(self.authorities)
1798 .chain(self.additional)
1799 }
1800
1801 pub fn num_additionals(&self) -> u16 {
1802 self.num_additionals
1803 }
1804
1805 pub fn num_authorities(&self) -> u16 {
1806 self.num_authorities
1807 }
1808
1809 pub fn num_questions(&self) -> u16 {
1810 self.num_questions
1811 }
1812
1813 pub const fn is_query(&self) -> bool {
1814 (self.flags & FLAGS_QR_MASK) == FLAGS_QR_QUERY
1815 }
1816
1817 pub const fn is_response(&self) -> bool {
1818 (self.flags & FLAGS_QR_MASK) == FLAGS_QR_RESPONSE
1819 }
1820
1821 fn read_header(&mut self) -> Result<()> {
1822 if self.data.len() < MSG_HEADER_LEN {
1823 return Err(e_fmt!(
1824 "DNS incoming: header is too short: {} bytes",
1825 self.data.len()
1826 ));
1827 }
1828
1829 let data = &self.data[0..];
1830 self.id = u16_from_be_slice(&data[..2]);
1831 self.flags = u16_from_be_slice(&data[2..4]);
1832 self.num_questions = u16_from_be_slice(&data[4..6]);
1833 self.num_answers = u16_from_be_slice(&data[6..8]);
1834 self.num_authorities = u16_from_be_slice(&data[8..10]);
1835 self.num_additionals = u16_from_be_slice(&data[10..12]);
1836
1837 self.offset = MSG_HEADER_LEN;
1838
1839 trace!(
1840 "read_header: id {}, {} questions {} answers {} authorities {} additionals",
1841 self.id,
1842 self.num_questions,
1843 self.num_answers,
1844 self.num_authorities,
1845 self.num_additionals
1846 );
1847 Ok(())
1848 }
1849
1850 fn read_questions(&mut self) -> Result<()> {
1851 trace!("read_questions: {}", &self.num_questions);
1852 for i in 0..self.num_questions {
1853 let name = self.read_name()?;
1854
1855 let data = &self.data[self.offset..];
1856 if data.len() < 4 {
1857 return Err(Error::Msg(format!(
1858 "DNS incoming: question idx {} too short: {}",
1859 i,
1860 data.len()
1861 )));
1862 }
1863 let ty = u16_from_be_slice(&data[..2]);
1864 let class = u16_from_be_slice(&data[2..4]);
1865 self.offset += 4;
1866
1867 let Some(rr_type) = RRType::from_u16(ty) else {
1868 return Err(Error::Msg(format!(
1869 "DNS incoming: question idx {} qtype unknown: {}",
1870 i, ty
1871 )));
1872 };
1873
1874 self.questions.push(DnsQuestion {
1875 entry: DnsEntry::new(name, rr_type, class),
1876 });
1877 }
1878 Ok(())
1879 }
1880
1881 fn read_answers(&mut self) -> Result<()> {
1882 self.answers = self.read_rr_records(self.num_answers)?;
1883 Ok(())
1884 }
1885
1886 fn read_authorities(&mut self) -> Result<()> {
1887 self.authorities = self.read_rr_records(self.num_authorities)?;
1888 Ok(())
1889 }
1890
1891 fn read_additional(&mut self) -> Result<()> {
1892 self.additional = self.read_rr_records(self.num_additionals)?;
1893 Ok(())
1894 }
1895
1896 fn read_rr_records(&mut self, count: u16) -> Result<Vec<DnsRecordBox>> {
1898 trace!("read_rr_records: {}", count);
1899 let mut rr_records = Vec::new();
1900
1901 const RR_HEADER_REMAIN: usize = 10;
1927
1928 for _ in 0..count {
1929 let name = self.read_name()?;
1930 let slice = &self.data[self.offset..];
1931
1932 if slice.len() < RR_HEADER_REMAIN {
1933 return Err(Error::Msg(format!(
1934 "read_others: RR '{}' is too short after name: {} bytes",
1935 &name,
1936 slice.len()
1937 )));
1938 }
1939
1940 let ty = u16_from_be_slice(&slice[..2]);
1941 let class = u16_from_be_slice(&slice[2..4]);
1942 let mut ttl = u32_from_be_slice(&slice[4..8]);
1943 if ttl == 0 && self.is_response() {
1944 ttl = 1;
1951 }
1952 let rdata_len = u16_from_be_slice(&slice[8..10]) as usize;
1953 self.offset += RR_HEADER_REMAIN;
1954 let next_offset = self.offset + rdata_len;
1955
1956 if next_offset > self.data.len() {
1958 return Err(Error::Msg(format!(
1959 "RR {name} RDATA length {rdata_len} is invalid: remain data len: {}",
1960 self.data.len() - self.offset
1961 )));
1962 }
1963
1964 let rec: Option<DnsRecordBox> = match RRType::from_u16(ty) {
1966 None => None,
1967
1968 Some(rr_type) => match rr_type {
1969 RRType::CNAME | RRType::PTR => {
1970 Some(DnsPointer::new(&name, rr_type, class, ttl, self.read_name()?).boxed())
1971 }
1972 RRType::TXT => {
1973 Some(DnsTxt::new(&name, class, ttl, self.read_vec(rdata_len)?).boxed())
1974 }
1975 RRType::SRV => Some(
1976 DnsSrv::new(
1977 &name,
1978 class,
1979 ttl,
1980 self.read_u16()?,
1981 self.read_u16()?,
1982 self.read_u16()?,
1983 self.read_name()?,
1984 )
1985 .boxed(),
1986 ),
1987 RRType::HINFO => Some(
1988 DnsHostInfo::new(
1989 &name,
1990 rr_type,
1991 class,
1992 ttl,
1993 self.read_char_string()?,
1994 self.read_char_string()?,
1995 )
1996 .boxed(),
1997 ),
1998 RRType::A => Some(
1999 DnsAddress::new(
2000 &name,
2001 rr_type,
2002 class,
2003 ttl,
2004 self.read_ipv4()?.into(),
2005 self.interface_id.clone(),
2006 )
2007 .boxed(),
2008 ),
2009 RRType::AAAA => Some(
2010 DnsAddress::new(
2011 &name,
2012 rr_type,
2013 class,
2014 ttl,
2015 self.read_ipv6()?.into(),
2016 self.interface_id.clone(),
2017 )
2018 .boxed(),
2019 ),
2020 RRType::NSEC => Some(
2021 DnsNSec::new(
2022 &name,
2023 class,
2024 ttl,
2025 self.read_name()?,
2026 self.read_type_bitmap()?,
2027 )
2028 .boxed(),
2029 ),
2030 _ => None,
2031 },
2032 };
2033
2034 if let Some(record) = rec {
2035 trace!("read_rr_records: {:?}", &record);
2036 rr_records.push(record);
2037 } else {
2038 trace!("Unsupported DNS record type: {} name: {}", ty, &name);
2039 self.offset += rdata_len;
2040 }
2041
2042 if self.offset != next_offset {
2044 return Err(Error::Msg(format!(
2045 "read_rr_records: decode offset error for RData type {} offset: {} expected offset: {}",
2046 ty, self.offset, next_offset,
2047 )));
2048 }
2049 }
2050
2051 Ok(rr_records)
2052 }
2053
2054 fn read_char_string(&mut self) -> Result<String> {
2055 let length = self.data[self.offset];
2056 self.offset += 1;
2057 self.read_string(length as usize)
2058 }
2059
2060 fn read_u16(&mut self) -> Result<u16> {
2061 let slice = &self.data[self.offset..];
2062 if slice.len() < U16_SIZE {
2063 return Err(Error::Msg(format!(
2064 "read_u16: slice len is only {}",
2065 slice.len()
2066 )));
2067 }
2068 let num = u16_from_be_slice(&slice[..U16_SIZE]);
2069 self.offset += U16_SIZE;
2070 Ok(num)
2071 }
2072
2073 fn read_type_bitmap(&mut self) -> Result<Vec<u8>> {
2075 if self.data.len() < self.offset + 2 {
2084 return Err(Error::Msg(format!(
2085 "DnsIncoming is too short: {} at NSEC Type Bit Map offset {}",
2086 self.data.len(),
2087 self.offset
2088 )));
2089 }
2090
2091 let block_num = self.data[self.offset];
2092 self.offset += 1;
2093 if block_num != 0 {
2094 return Err(Error::Msg(format!(
2095 "NSEC block number is not 0: {}",
2096 block_num
2097 )));
2098 }
2099
2100 let block_len = self.data[self.offset] as usize;
2101 if !(1..=32).contains(&block_len) {
2102 return Err(Error::Msg(format!(
2103 "NSEC block length must be in the range 1-32: {}",
2104 block_len
2105 )));
2106 }
2107 self.offset += 1;
2108
2109 let end = self.offset + block_len;
2110 if end > self.data.len() {
2111 return Err(Error::Msg(format!(
2112 "NSEC block overflow: {} over RData len {}",
2113 end,
2114 self.data.len()
2115 )));
2116 }
2117 let bitmap = self.data[self.offset..end].to_vec();
2118 self.offset += block_len;
2119
2120 Ok(bitmap)
2121 }
2122
2123 fn read_vec(&mut self, length: usize) -> Result<Vec<u8>> {
2124 if self.data.len() < self.offset + length {
2125 return Err(e_fmt!(
2126 "DNS Incoming: not enough data to read a chunk of data"
2127 ));
2128 }
2129
2130 let v = self.data[self.offset..self.offset + length].to_vec();
2131 self.offset += length;
2132 Ok(v)
2133 }
2134
2135 fn read_ipv4(&mut self) -> Result<Ipv4Addr> {
2136 if self.data.len() < self.offset + 4 {
2137 return Err(e_fmt!("DNS Incoming: not enough data to read an IPV4"));
2138 }
2139
2140 let bytes: [u8; 4] = self.data[self.offset..self.offset + 4]
2141 .try_into()
2142 .map_err(|_| e_fmt!("DNS incoming: Not enough bytes for reading an IPV4"))?;
2143 self.offset += bytes.len();
2144 Ok(Ipv4Addr::from(bytes))
2145 }
2146
2147 fn read_ipv6(&mut self) -> Result<Ipv6Addr> {
2148 if self.data.len() < self.offset + 16 {
2149 return Err(e_fmt!("DNS Incoming: not enough data to read an IPV6"));
2150 }
2151
2152 let bytes: [u8; 16] = self.data[self.offset..self.offset + 16]
2153 .try_into()
2154 .map_err(|_| e_fmt!("DNS incoming: Not enough bytes for reading an IPV6"))?;
2155 self.offset += bytes.len();
2156 Ok(Ipv6Addr::from(bytes))
2157 }
2158
2159 fn read_string(&mut self, length: usize) -> Result<String> {
2160 if self.data.len() < self.offset + length {
2161 return Err(e_fmt!("DNS Incoming: not enough data to read a string"));
2162 }
2163
2164 let s = str::from_utf8(&self.data[self.offset..self.offset + length])
2165 .map_err(|e| Error::Msg(e.to_string()))?;
2166 self.offset += length;
2167 Ok(s.to_string())
2168 }
2169
2170 fn read_name(&mut self) -> Result<String> {
2175 let data = &self.data[..];
2176 let start_offset = self.offset;
2177 let mut offset = start_offset;
2178 let mut name = "".to_string();
2179 let mut at_end = false;
2180
2181 loop {
2192 if offset >= data.len() {
2193 return Err(Error::Msg(format!(
2194 "read_name: offset: {} data len {}. DnsIncoming: {:?}",
2195 offset,
2196 data.len(),
2197 self
2198 )));
2199 }
2200 let length = data[offset];
2201
2202 if length == 0 {
2206 if !at_end {
2207 self.offset = offset + 1;
2208 }
2209 break; }
2211
2212 match length & 0xC0 {
2214 0x00 => {
2215 offset += 1;
2217 let ending = offset + length as usize;
2218
2219 if ending > data.len() {
2221 return Err(Error::Msg(format!(
2222 "read_name: ending {} exceeds data length {}",
2223 ending,
2224 data.len()
2225 )));
2226 }
2227
2228 name += str::from_utf8(&data[offset..ending])
2229 .map_err(|e| Error::Msg(format!("read_name: from_utf8: {}", e)))?;
2230 name += ".";
2231 offset += length as usize;
2232 }
2233 0xC0 => {
2234 let slice = &data[offset..];
2237 if slice.len() < U16_SIZE {
2238 return Err(Error::Msg(format!(
2239 "read_name: u16 slice len is only {}",
2240 slice.len()
2241 )));
2242 }
2243 let pointer = (u16_from_be_slice(slice) ^ 0xC000) as usize;
2244 if pointer >= start_offset {
2245 return Err(Error::Msg(format!(
2247 "Invalid name compression: pointer {} must be less than the start offset {}",
2248 &pointer, &start_offset
2249 )));
2250 }
2251
2252 if !at_end {
2254 self.offset = offset + U16_SIZE;
2255 at_end = true;
2256 }
2257 offset = pointer;
2258 }
2259 _ => {
2260 return Err(Error::Msg(format!(
2261 "Bad name with invalid length: 0x{:x} offset {}, data (so far): {:x?}",
2262 length,
2263 offset,
2264 &data[..offset]
2265 )));
2266 }
2267 };
2268 }
2269
2270 Ok(name)
2271 }
2272}
2273
2274fn current_time_millis() -> u64 {
2276 SystemTime::now()
2277 .duration_since(SystemTime::UNIX_EPOCH)
2278 .expect("failed to get current UNIX time")
2279 .as_millis() as u64
2280}
2281
2282const fn u16_from_be_slice(bytes: &[u8]) -> u16 {
2283 let u8_array: [u8; 2] = [bytes[0], bytes[1]];
2284 u16::from_be_bytes(u8_array)
2285}
2286
2287const fn u32_from_be_slice(s: &[u8]) -> u32 {
2288 let u8_array: [u8; 4] = [s[0], s[1], s[2], s[3]];
2289 u32::from_be_bytes(u8_array)
2290}
2291
2292const fn get_expiration_time(created: u64, ttl: u32, percent: u32) -> u64 {
2295 created + (ttl * percent * 10) as u64
2298}