1#[cfg(feature = "logging")]
8use crate::log::trace;
9
10use crate::error::{e_fmt, Error, Result};
11
12use std::{
13 any::Any,
14 cmp,
15 collections::HashMap,
16 convert::TryInto,
17 fmt,
18 net::{IpAddr, Ipv4Addr, Ipv6Addr},
19 str,
20 time::SystemTime,
21};
22
23#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord)]
27#[non_exhaustive]
28#[repr(u16)]
29pub enum RRType {
30 A = 1,
32
33 CNAME = 5,
35
36 PTR = 12,
38
39 HINFO = 13,
41
42 TXT = 16,
44
45 AAAA = 28,
47
48 SRV = 33,
50
51 NSEC = 47,
53
54 ANY = 255,
56}
57
58impl RRType {
59 pub const fn from_u16(value: u16) -> Option<RRType> {
61 match value {
62 1 => Some(RRType::A),
63 5 => Some(RRType::CNAME),
64 12 => Some(RRType::PTR),
65 13 => Some(RRType::HINFO),
66 16 => Some(RRType::TXT),
67 28 => Some(RRType::AAAA),
68 33 => Some(RRType::SRV),
69 47 => Some(RRType::NSEC),
70 255 => Some(RRType::ANY),
71 _ => None,
72 }
73 }
74}
75
76impl fmt::Display for RRType {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 match self {
79 RRType::A => write!(f, "TYPE_A"),
80 RRType::CNAME => write!(f, "TYPE_CNAME"),
81 RRType::PTR => write!(f, "TYPE_PTR"),
82 RRType::HINFO => write!(f, "TYPE_HINFO"),
83 RRType::TXT => write!(f, "TYPE_TXT"),
84 RRType::AAAA => write!(f, "TYPE_AAAA"),
85 RRType::SRV => write!(f, "TYPE_SRV"),
86 RRType::NSEC => write!(f, "TYPE_NSEC"),
87 RRType::ANY => write!(f, "TYPE_ANY"),
88 }
89 }
90}
91
92pub const CLASS_IN: u16 = 1;
94pub const CLASS_MASK: u16 = 0x7FFF;
95
96pub const CLASS_CACHE_FLUSH: u16 = 0x8000;
98
99pub const MAX_MSG_ABSOLUTE: usize = 8972;
104
105const MSG_HEADER_LEN: usize = 12;
106
107pub const FLAGS_QR_MASK: u16 = 0x8000; pub const FLAGS_QR_QUERY: u16 = 0x0000;
119
120pub const FLAGS_QR_RESPONSE: u16 = 0x8000;
122
123pub const FLAGS_AA: u16 = 0x0400;
125
126pub const FLAGS_TC: u16 = 0x0200;
137
138pub type DnsRecordBox = Box<dyn DnsRecordExt>;
140
141impl Clone for DnsRecordBox {
142 fn clone(&self) -> Self {
143 self.clone_box()
144 }
145}
146
147const U16_SIZE: usize = 2;
148
149#[inline]
151pub const fn ip_address_rr_type(address: &IpAddr) -> RRType {
152 match address {
153 IpAddr::V4(_) => RRType::A,
154 IpAddr::V6(_) => RRType::AAAA,
155 }
156}
157
158#[derive(Eq, PartialEq, Debug, Clone)]
159pub struct DnsEntry {
160 pub(crate) name: String, pub(crate) ty: RRType,
162 class: u16,
163 cache_flush: bool,
164}
165
166impl DnsEntry {
167 const fn new(name: String, ty: RRType, class: u16) -> Self {
168 Self {
169 name,
170 ty,
171 class: class & CLASS_MASK,
172 cache_flush: (class & CLASS_CACHE_FLUSH) != 0,
173 }
174 }
175}
176
177pub trait DnsEntryExt: fmt::Debug {
179 fn entry_name(&self) -> &str;
180
181 fn entry_type(&self) -> RRType;
182}
183
184#[derive(Debug)]
186pub struct DnsQuestion {
187 pub(crate) entry: DnsEntry,
188}
189
190impl DnsEntryExt for DnsQuestion {
191 fn entry_name(&self) -> &str {
192 &self.entry.name
193 }
194
195 fn entry_type(&self) -> RRType {
196 self.entry.ty
197 }
198}
199
200#[derive(Debug, Clone)]
204pub struct DnsRecord {
205 pub(crate) entry: DnsEntry,
206 ttl: u32, created: u64, expires: u64, refresh: u64, new_name: Option<String>,
216}
217
218impl DnsRecord {
219 fn new(name: &str, ty: RRType, class: u16, ttl: u32) -> Self {
220 let created = current_time_millis();
221
222 let refresh = get_expiration_time(created, ttl, 80);
226
227 let expires = get_expiration_time(created, ttl, 100);
228
229 Self {
230 entry: DnsEntry::new(name.to_string(), ty, class),
231 ttl,
232 created,
233 expires,
234 refresh,
235 new_name: None,
236 }
237 }
238
239 pub const fn get_ttl(&self) -> u32 {
240 self.ttl
241 }
242
243 pub const fn get_expire_time(&self) -> u64 {
244 self.expires
245 }
246
247 pub const fn get_refresh_time(&self) -> u64 {
248 self.refresh
249 }
250
251 pub const fn is_expired(&self, now: u64) -> bool {
252 now >= self.expires
253 }
254
255 pub const fn refresh_due(&self, now: u64) -> bool {
256 now >= self.refresh
257 }
258
259 pub fn halflife_passed(&self, now: u64) -> bool {
261 let halflife = get_expiration_time(self.created, self.ttl, 50);
262 now > halflife
263 }
264
265 pub fn is_unique(&self) -> bool {
266 self.entry.cache_flush
267 }
268
269 pub fn refresh_no_more(&mut self) {
272 self.refresh = get_expiration_time(self.created, self.ttl, 100);
273 }
274
275 pub fn refresh_maybe(&mut self, now: u64) -> bool {
277 if self.is_expired(now) || !self.refresh_due(now) {
278 return false;
279 }
280
281 trace!(
282 "{} qtype {} is due to refresh",
283 &self.entry.name,
284 self.entry.ty
285 );
286
287 if self.refresh == get_expiration_time(self.created, self.ttl, 80) {
294 self.refresh = get_expiration_time(self.created, self.ttl, 85);
295 } else if self.refresh == get_expiration_time(self.created, self.ttl, 85) {
296 self.refresh = get_expiration_time(self.created, self.ttl, 90);
297 } else if self.refresh == get_expiration_time(self.created, self.ttl, 90) {
298 self.refresh = get_expiration_time(self.created, self.ttl, 95);
299 } else {
300 self.refresh_no_more();
301 }
302
303 true
304 }
305
306 fn get_remaining_ttl(&self, now: u64) -> u32 {
308 let remaining_millis = get_expiration_time(self.created, self.ttl, 100) - now;
309 cmp::max(0, remaining_millis / 1000) as u32
310 }
311
312 pub const fn get_created(&self) -> u64 {
314 self.created
315 }
316
317 fn set_expire(&mut self, expire_at: u64) {
319 self.expires = expire_at;
320 }
321
322 fn reset_ttl(&mut self, other: &Self) {
323 self.ttl = other.ttl;
324 self.created = other.created;
325 self.refresh = get_expiration_time(self.created, self.ttl, 80);
326 self.expires = get_expiration_time(self.created, self.ttl, 100);
327 }
328
329 pub fn update_ttl(&mut self, now: u64) {
331 if now > self.created {
332 let elapsed = now - self.created;
333 self.ttl -= (elapsed / 1000) as u32;
334 }
335 }
336
337 pub fn set_new_name(&mut self, new_name: String) {
338 if new_name == self.entry.name {
339 self.new_name = None;
340 } else {
341 self.new_name = Some(new_name);
342 }
343 }
344
345 pub fn get_new_name(&self) -> Option<&str> {
346 self.new_name.as_deref()
347 }
348
349 pub(crate) fn get_name(&self) -> &str {
351 self.new_name.as_deref().unwrap_or(&self.entry.name)
352 }
353
354 pub fn get_original_name(&self) -> &str {
355 &self.entry.name
356 }
357}
358
359impl PartialEq for DnsRecord {
360 fn eq(&self, other: &Self) -> bool {
361 self.entry == other.entry
362 }
363}
364
365pub trait DnsRecordExt: fmt::Debug {
367 fn get_record(&self) -> &DnsRecord;
368 fn get_record_mut(&mut self) -> &mut DnsRecord;
369 fn write(&self, packet: &mut DnsOutPacket);
370 fn any(&self) -> &dyn Any;
371
372 fn matches(&self, other: &dyn DnsRecordExt) -> bool;
374
375 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool;
377
378 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering;
381
382 fn compare(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
384 match self.get_class().cmp(&other.get_class()) {
398 cmp::Ordering::Equal => match self.get_type().cmp(&other.get_type()) {
399 cmp::Ordering::Equal => self.compare_rdata(other),
400 not_equal => not_equal,
401 },
402 not_equal => not_equal,
403 }
404 }
405
406 fn rdata_print(&self) -> String;
408
409 fn get_class(&self) -> u16 {
411 self.get_record().entry.class
412 }
413
414 fn get_cache_flush(&self) -> bool {
415 self.get_record().entry.cache_flush
416 }
417
418 fn get_name(&self) -> &str {
420 self.get_record().get_name()
421 }
422
423 fn get_type(&self) -> RRType {
424 self.get_record().entry.ty
425 }
426
427 fn reset_ttl(&mut self, other: &dyn DnsRecordExt) {
430 self.get_record_mut().reset_ttl(other.get_record());
431 }
432
433 fn get_created(&self) -> u64 {
434 self.get_record().get_created()
435 }
436
437 fn get_expire(&self) -> u64 {
438 self.get_record().get_expire_time()
439 }
440
441 fn set_expire(&mut self, expire_at: u64) {
442 self.get_record_mut().set_expire(expire_at);
443 }
444
445 fn set_expire_sooner(&mut self, expire_at: u64) {
447 if expire_at < self.get_expire() {
448 self.get_record_mut().set_expire(expire_at);
449 }
450 }
451
452 fn updated_refresh_time(&mut self, now: u64) -> Option<u64> {
455 if self.get_record_mut().refresh_maybe(now) {
456 Some(self.get_record().get_refresh_time())
457 } else {
458 None
459 }
460 }
461
462 fn suppressed_by_answer(&self, other: &dyn DnsRecordExt) -> bool {
465 self.matches(other) && (other.get_record().ttl > self.get_record().ttl / 2)
466 }
467
468 fn suppressed_by(&self, msg: &DnsIncoming) -> bool {
470 for answer in msg.answers.iter() {
471 if self.suppressed_by_answer(answer.as_ref()) {
472 return true;
473 }
474 }
475 false
476 }
477
478 fn clone_box(&self) -> DnsRecordBox;
479
480 fn boxed(self) -> DnsRecordBox;
481}
482
483#[derive(Debug, Clone)]
485pub struct DnsAddress {
486 pub(crate) record: DnsRecord,
487 address: IpAddr,
488}
489
490impl DnsAddress {
491 pub fn new(name: &str, ty: RRType, class: u16, ttl: u32, address: IpAddr) -> Self {
492 let record = DnsRecord::new(name, ty, class, ttl);
493 Self { record, address }
494 }
495
496 pub fn address(&self) -> IpAddr {
497 self.address
498 }
499}
500
501impl DnsRecordExt for DnsAddress {
502 fn get_record(&self) -> &DnsRecord {
503 &self.record
504 }
505
506 fn get_record_mut(&mut self) -> &mut DnsRecord {
507 &mut self.record
508 }
509
510 fn write(&self, packet: &mut DnsOutPacket) {
511 match self.address {
512 IpAddr::V4(addr) => packet.write_bytes(addr.octets().as_ref()),
513 IpAddr::V6(addr) => packet.write_bytes(addr.octets().as_ref()),
514 };
515 }
516
517 fn any(&self) -> &dyn Any {
518 self
519 }
520
521 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
522 if let Some(other_a) = other.any().downcast_ref::<Self>() {
523 return self.address == other_a.address && self.record.entry == other_a.record.entry;
524 }
525 false
526 }
527
528 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
529 if let Some(other_a) = other.any().downcast_ref::<Self>() {
530 return self.address == other_a.address;
531 }
532 false
533 }
534
535 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
536 if let Some(other_a) = other.any().downcast_ref::<Self>() {
537 self.address.cmp(&other_a.address)
538 } else {
539 cmp::Ordering::Greater
540 }
541 }
542
543 fn rdata_print(&self) -> String {
544 format!("{}", self.address)
545 }
546
547 fn clone_box(&self) -> DnsRecordBox {
548 Box::new(self.clone())
549 }
550
551 fn boxed(self) -> DnsRecordBox {
552 Box::new(self)
553 }
554}
555
556#[derive(Debug, Clone)]
558pub struct DnsPointer {
559 record: DnsRecord,
560 alias: String, }
562
563impl DnsPointer {
564 pub fn new(name: &str, ty: RRType, class: u16, ttl: u32, alias: String) -> Self {
565 let record = DnsRecord::new(name, ty, class, ttl);
566 Self { record, alias }
567 }
568
569 pub fn alias(&self) -> &str {
570 &self.alias
571 }
572}
573
574impl DnsRecordExt for DnsPointer {
575 fn get_record(&self) -> &DnsRecord {
576 &self.record
577 }
578
579 fn get_record_mut(&mut self) -> &mut DnsRecord {
580 &mut self.record
581 }
582
583 fn write(&self, packet: &mut DnsOutPacket) {
584 packet.write_name(&self.alias);
585 }
586
587 fn any(&self) -> &dyn Any {
588 self
589 }
590
591 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
592 if let Some(other_ptr) = other.any().downcast_ref::<Self>() {
593 return self.alias == other_ptr.alias && self.record.entry == other_ptr.record.entry;
594 }
595 false
596 }
597
598 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
599 if let Some(other_ptr) = other.any().downcast_ref::<Self>() {
600 return self.alias == other_ptr.alias;
601 }
602 false
603 }
604
605 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
606 if let Some(other_ptr) = other.any().downcast_ref::<Self>() {
607 self.alias.cmp(&other_ptr.alias)
608 } else {
609 cmp::Ordering::Greater
610 }
611 }
612
613 fn rdata_print(&self) -> String {
614 self.alias.clone()
615 }
616
617 fn clone_box(&self) -> DnsRecordBox {
618 Box::new(self.clone())
619 }
620
621 fn boxed(self) -> DnsRecordBox {
622 Box::new(self)
623 }
624}
625
626#[derive(Debug, Clone)]
628pub struct DnsSrv {
629 pub(crate) record: DnsRecord,
630 pub(crate) priority: u16, pub(crate) weight: u16, host: String,
633 port: u16,
634}
635
636impl DnsSrv {
637 pub fn new(
638 name: &str,
639 class: u16,
640 ttl: u32,
641 priority: u16,
642 weight: u16,
643 port: u16,
644 host: String,
645 ) -> Self {
646 let record = DnsRecord::new(name, RRType::SRV, class, ttl);
647 Self {
648 record,
649 priority,
650 weight,
651 host,
652 port,
653 }
654 }
655
656 pub fn host(&self) -> &str {
657 &self.host
658 }
659
660 pub fn port(&self) -> u16 {
661 self.port
662 }
663
664 pub fn set_host(&mut self, host: String) {
665 self.host = host;
666 }
667}
668
669impl DnsRecordExt for DnsSrv {
670 fn get_record(&self) -> &DnsRecord {
671 &self.record
672 }
673
674 fn get_record_mut(&mut self) -> &mut DnsRecord {
675 &mut self.record
676 }
677
678 fn write(&self, packet: &mut DnsOutPacket) {
679 packet.write_short(self.priority);
680 packet.write_short(self.weight);
681 packet.write_short(self.port);
682 packet.write_name(&self.host);
683 }
684
685 fn any(&self) -> &dyn Any {
686 self
687 }
688
689 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
690 if let Some(other_svc) = other.any().downcast_ref::<Self>() {
691 return self.host == other_svc.host
692 && self.port == other_svc.port
693 && self.weight == other_svc.weight
694 && self.priority == other_svc.priority
695 && self.record.entry == other_svc.record.entry;
696 }
697 false
698 }
699
700 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
701 if let Some(other_srv) = other.any().downcast_ref::<Self>() {
702 return self.host == other_srv.host
703 && self.port == other_srv.port
704 && self.weight == other_srv.weight
705 && self.priority == other_srv.priority;
706 }
707 false
708 }
709
710 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
711 let Some(other_srv) = other.any().downcast_ref::<Self>() else {
712 return cmp::Ordering::Greater;
713 };
714
715 match self
717 .priority
718 .to_be_bytes()
719 .cmp(&other_srv.priority.to_be_bytes())
720 {
721 cmp::Ordering::Equal => {
722 match self
724 .weight
725 .to_be_bytes()
726 .cmp(&other_srv.weight.to_be_bytes())
727 {
728 cmp::Ordering::Equal => {
729 match self.port.to_be_bytes().cmp(&other_srv.port.to_be_bytes()) {
731 cmp::Ordering::Equal => self.host.cmp(&other_srv.host),
732 not_equal => not_equal,
733 }
734 }
735 not_equal => not_equal,
736 }
737 }
738 not_equal => not_equal,
739 }
740 }
741
742 fn rdata_print(&self) -> String {
743 format!(
744 "priority: {}, weight: {}, port: {}, host: {}",
745 self.priority, self.weight, self.port, self.host
746 )
747 }
748
749 fn clone_box(&self) -> DnsRecordBox {
750 Box::new(self.clone())
751 }
752
753 fn boxed(self) -> DnsRecordBox {
754 Box::new(self)
755 }
756}
757
758#[derive(Clone)]
773pub struct DnsTxt {
774 pub(crate) record: DnsRecord,
775 text: Vec<u8>,
776}
777
778impl DnsTxt {
779 pub fn new(name: &str, class: u16, ttl: u32, text: Vec<u8>) -> Self {
780 let record = DnsRecord::new(name, RRType::TXT, class, ttl);
781 Self { record, text }
782 }
783
784 pub fn text(&self) -> &[u8] {
785 &self.text
786 }
787}
788
789impl DnsRecordExt for DnsTxt {
790 fn get_record(&self) -> &DnsRecord {
791 &self.record
792 }
793
794 fn get_record_mut(&mut self) -> &mut DnsRecord {
795 &mut self.record
796 }
797
798 fn write(&self, packet: &mut DnsOutPacket) {
799 packet.write_bytes(&self.text);
800 }
801
802 fn any(&self) -> &dyn Any {
803 self
804 }
805
806 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
807 if let Some(other_txt) = other.any().downcast_ref::<Self>() {
808 return self.text == other_txt.text && self.record.entry == other_txt.record.entry;
809 }
810 false
811 }
812
813 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
814 if let Some(other_txt) = other.any().downcast_ref::<Self>() {
815 return self.text == other_txt.text;
816 }
817 false
818 }
819
820 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
821 if let Some(other_txt) = other.any().downcast_ref::<Self>() {
822 self.text.cmp(&other_txt.text)
823 } else {
824 cmp::Ordering::Greater
825 }
826 }
827
828 fn rdata_print(&self) -> String {
829 format!("{:?}", decode_txt(&self.text))
830 }
831
832 fn clone_box(&self) -> DnsRecordBox {
833 Box::new(self.clone())
834 }
835
836 fn boxed(self) -> DnsRecordBox {
837 Box::new(self)
838 }
839}
840
841impl fmt::Debug for DnsTxt {
842 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
843 let properties = decode_txt(&self.text);
844 write!(
845 f,
846 "DnsTxt {{ record: {:?}, text: {:?} }}",
847 self.record, properties
848 )
849 }
850}
851
852fn decode_txt(txt: &[u8]) -> Vec<TxtProperty> {
854 let mut properties = Vec::new();
855 let mut offset = 0;
856 while offset < txt.len() {
857 let length = txt[offset] as usize;
858 if length == 0 {
859 break; }
861 offset += 1; let offset_end = offset + length;
864 if offset_end > txt.len() {
865 trace!("ERROR: DNS TXT: size given for property is out of range. (offset={}, length={}, offset_end={}, record length={})", offset, length, offset_end, txt.len());
866 break; }
868 let kv_bytes = &txt[offset..offset_end];
869
870 let (k, v) = kv_bytes.iter().position(|&x| x == b'=').map_or_else(
872 || (kv_bytes.to_vec(), None),
873 |idx| (kv_bytes[..idx].to_vec(), Some(kv_bytes[idx + 1..].to_vec())),
874 );
875
876 match String::from_utf8(k) {
878 Ok(k_string) => {
879 properties.push(TxtProperty {
880 key: k_string,
881 val: v,
882 });
883 }
884 Err(e) => trace!("ERROR: convert to String from key: {}", e),
885 }
886
887 offset += length;
888 }
889
890 properties
891}
892
893#[derive(Clone, PartialEq, Eq)]
895pub struct TxtProperty {
896 key: String,
898
899 val: Option<Vec<u8>>,
903}
904
905impl TxtProperty {
906 pub fn val_str(&self) -> &str {
908 self.val
909 .as_ref()
910 .map_or("", |v| std::str::from_utf8(&v[..]).unwrap_or_default())
911 }
912}
913
914impl<K, V> From<&(K, V)> for TxtProperty
916where
917 K: ToString,
918 V: ToString,
919{
920 fn from(prop: &(K, V)) -> Self {
921 Self {
922 key: prop.0.to_string(),
923 val: Some(prop.1.to_string().into_bytes()),
924 }
925 }
926}
927
928impl<K, V> From<(K, V)> for TxtProperty
929where
930 K: ToString,
931 V: AsRef<[u8]>,
932{
933 fn from(prop: (K, V)) -> Self {
934 Self {
935 key: prop.0.to_string(),
936 val: Some(prop.1.as_ref().into()),
937 }
938 }
939}
940
941impl From<&str> for TxtProperty {
943 fn from(key: &str) -> Self {
944 Self {
945 key: key.to_string(),
946 val: None,
947 }
948 }
949}
950
951impl fmt::Display for TxtProperty {
952 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
953 write!(f, "{}={}", self.key, self.val_str())
954 }
955}
956
957impl fmt::Debug for TxtProperty {
961 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
962 let val_string = self.val.as_ref().map_or_else(
963 || "None".to_string(),
964 |v| {
965 std::str::from_utf8(&v[..]).map_or_else(
966 |_| format!("Some({})", u8_slice_to_hex(&v[..])),
967 |s| format!("Some(\"{}\")", s),
968 )
969 },
970 );
971
972 write!(
973 f,
974 "TxtProperty {{key: \"{}\", val: {}}}",
975 &self.key, &val_string,
976 )
977 }
978}
979
980const HEX_TABLE: [char; 16] = [
981 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
982];
983
984fn u8_slice_to_hex(slice: &[u8]) -> String {
988 let mut hex = String::with_capacity(slice.len() * 2 + 2);
989 hex.push_str("0x");
990 for b in slice {
991 hex.push(HEX_TABLE[(b >> 4) as usize]);
992 hex.push(HEX_TABLE[(b & 0x0F) as usize]);
993 }
994 hex
995}
996
997#[derive(Debug, Clone)]
999struct DnsHostInfo {
1000 record: DnsRecord,
1001 cpu: String,
1002 os: String,
1003}
1004
1005impl DnsHostInfo {
1006 fn new(name: &str, ty: RRType, class: u16, ttl: u32, cpu: String, os: String) -> Self {
1007 let record = DnsRecord::new(name, ty, class, ttl);
1008 Self { record, cpu, os }
1009 }
1010}
1011
1012impl DnsRecordExt for DnsHostInfo {
1013 fn get_record(&self) -> &DnsRecord {
1014 &self.record
1015 }
1016
1017 fn get_record_mut(&mut self) -> &mut DnsRecord {
1018 &mut self.record
1019 }
1020
1021 fn write(&self, packet: &mut DnsOutPacket) {
1022 println!("writing HInfo: cpu {} os {}", &self.cpu, &self.os);
1023 packet.write_bytes(self.cpu.as_bytes());
1024 packet.write_bytes(self.os.as_bytes());
1025 }
1026
1027 fn any(&self) -> &dyn Any {
1028 self
1029 }
1030
1031 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
1032 if let Some(other_hinfo) = other.any().downcast_ref::<Self>() {
1033 return self.cpu == other_hinfo.cpu
1034 && self.os == other_hinfo.os
1035 && self.record.entry == other_hinfo.record.entry;
1036 }
1037 false
1038 }
1039
1040 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
1041 if let Some(other_hinfo) = other.any().downcast_ref::<Self>() {
1042 return self.cpu == other_hinfo.cpu && self.os == other_hinfo.os;
1043 }
1044 false
1045 }
1046
1047 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
1048 if let Some(other_hinfo) = other.any().downcast_ref::<Self>() {
1049 match self.cpu.cmp(&other_hinfo.cpu) {
1050 cmp::Ordering::Equal => self.os.cmp(&other_hinfo.os),
1051 ordering => ordering,
1052 }
1053 } else {
1054 cmp::Ordering::Greater
1055 }
1056 }
1057
1058 fn rdata_print(&self) -> String {
1059 format!("cpu: {}, os: {}", self.cpu, self.os)
1060 }
1061
1062 fn clone_box(&self) -> DnsRecordBox {
1063 Box::new(self.clone())
1064 }
1065
1066 fn boxed(self) -> DnsRecordBox {
1067 Box::new(self)
1068 }
1069}
1070
1071#[derive(Debug, Clone)]
1077pub struct DnsNSec {
1078 record: DnsRecord,
1079 next_domain: String,
1080 type_bitmap: Vec<u8>,
1081}
1082
1083impl DnsNSec {
1084 pub fn new(
1085 name: &str,
1086 class: u16,
1087 ttl: u32,
1088 next_domain: String,
1089 type_bitmap: Vec<u8>,
1090 ) -> Self {
1091 let record = DnsRecord::new(name, RRType::NSEC, class, ttl);
1092 Self {
1093 record,
1094 next_domain,
1095 type_bitmap,
1096 }
1097 }
1098
1099 pub fn _types(&self) -> Vec<u16> {
1101 let mut bit_num = 0;
1110 let mut results = Vec::new();
1111
1112 for byte in self.type_bitmap.iter() {
1113 let mut bit_mask: u8 = 0x80; for _ in 0..8 {
1117 if (byte & bit_mask) != 0 {
1118 results.push(bit_num);
1119 }
1120 bit_num += 1;
1121 bit_mask >>= 1; }
1123 }
1124 results
1125 }
1126}
1127
1128impl DnsRecordExt for DnsNSec {
1129 fn get_record(&self) -> &DnsRecord {
1130 &self.record
1131 }
1132
1133 fn get_record_mut(&mut self) -> &mut DnsRecord {
1134 &mut self.record
1135 }
1136
1137 fn write(&self, packet: &mut DnsOutPacket) {
1138 packet.write_bytes(self.next_domain.as_bytes());
1139 packet.write_bytes(&self.type_bitmap);
1140 }
1141
1142 fn any(&self) -> &dyn Any {
1143 self
1144 }
1145
1146 fn matches(&self, other: &dyn DnsRecordExt) -> bool {
1147 if let Some(other_record) = other.any().downcast_ref::<Self>() {
1148 return self.next_domain == other_record.next_domain
1149 && self.type_bitmap == other_record.type_bitmap
1150 && self.record.entry == other_record.record.entry;
1151 }
1152 false
1153 }
1154
1155 fn rrdata_match(&self, other: &dyn DnsRecordExt) -> bool {
1156 if let Some(other_record) = other.any().downcast_ref::<Self>() {
1157 return self.next_domain == other_record.next_domain
1158 && self.type_bitmap == other_record.type_bitmap;
1159 }
1160 false
1161 }
1162
1163 fn compare_rdata(&self, other: &dyn DnsRecordExt) -> cmp::Ordering {
1164 if let Some(other_nsec) = other.any().downcast_ref::<Self>() {
1165 match self.next_domain.cmp(&other_nsec.next_domain) {
1166 cmp::Ordering::Equal => self.type_bitmap.cmp(&other_nsec.type_bitmap),
1167 ordering => ordering,
1168 }
1169 } else {
1170 cmp::Ordering::Greater
1171 }
1172 }
1173
1174 fn rdata_print(&self) -> String {
1175 format!(
1176 "next_domain: {}, type_bitmap len: {}",
1177 self.next_domain,
1178 self.type_bitmap.len()
1179 )
1180 }
1181
1182 fn clone_box(&self) -> DnsRecordBox {
1183 Box::new(self.clone())
1184 }
1185
1186 fn boxed(self) -> DnsRecordBox {
1187 Box::new(self)
1188 }
1189}
1190
1191#[derive(PartialEq)]
1192enum PacketState {
1193 Init = 0,
1194 Finished = 1,
1195}
1196
1197pub struct DnsOutPacket {
1199 data: Vec<Vec<u8>>,
1201
1202 size: usize,
1204
1205 state: PacketState,
1207
1208 names: HashMap<String, u16>,
1210}
1211
1212impl DnsOutPacket {
1213 fn new() -> Self {
1214 Self {
1215 data: Vec::new(),
1216 size: MSG_HEADER_LEN, state: PacketState::Init,
1218 names: HashMap::new(),
1219 }
1220 }
1221
1222 pub fn size(&self) -> usize {
1223 self.size
1224 }
1225
1226 pub fn to_bytes(&self) -> Vec<u8> {
1227 self.data.concat()
1228 }
1229
1230 fn write_question(&mut self, question: &DnsQuestion) {
1231 self.write_name(&question.entry.name);
1232 self.write_short(question.entry.ty as u16);
1233 self.write_short(question.entry.class);
1234 }
1235
1236 fn write_record(&mut self, record_ext: &dyn DnsRecordExt, now: u64) -> bool {
1240 let start_data_length = self.data.len();
1241 let start_size = self.size;
1242
1243 let record = record_ext.get_record();
1244 self.write_name(record.get_name());
1245 self.write_short(record.entry.ty as u16);
1246 if record.entry.cache_flush {
1247 self.write_short(record.entry.class | CLASS_CACHE_FLUSH);
1249 } else {
1250 self.write_short(record.entry.class);
1251 }
1252
1253 if now == 0 {
1254 self.write_u32(record.ttl);
1255 } else {
1256 self.write_u32(record.get_remaining_ttl(now));
1257 }
1258
1259 let index = self.data.len();
1260
1261 self.size += 2;
1263 record_ext.write(self);
1264 self.size -= 2;
1265
1266 let length: usize = self.data[index..].iter().map(|x| x.len()).sum();
1267 self.insert_short(index, length as u16);
1268
1269 if self.size > MAX_MSG_ABSOLUTE {
1270 self.data.truncate(start_data_length);
1271 self.size = start_size;
1272 self.state = PacketState::Finished;
1273 return false;
1274 }
1275
1276 true
1277 }
1278
1279 pub(crate) fn insert_short(&mut self, index: usize, value: u16) {
1280 self.data.insert(index, value.to_be_bytes().to_vec());
1281 self.size += 2;
1282 }
1283
1284 fn write_name(&mut self, name: &str) {
1306 let end = name.len();
1308 let end = if end > 0 && &name[end - 1..] == "." {
1309 end - 1
1310 } else {
1311 end
1312 };
1313
1314 let mut here = 0;
1315 while here < end {
1316 const POINTER_MASK: u16 = 0xC000;
1317 let remaining = &name[here..end];
1318
1319 match self.names.get(remaining) {
1321 Some(offset) => {
1322 let pointer = *offset | POINTER_MASK;
1323 self.write_short(pointer);
1324 break;
1331 }
1332 None => {
1333 self.names.insert(remaining.to_string(), self.size as u16);
1335 let stop = remaining.find('.').map_or(end, |i| here + i);
1339 let label = &name[here..stop];
1340 self.write_utf8(label);
1341
1342 here = stop + 1; }
1344 }
1345
1346 if here >= end {
1347 self.write_byte(0); }
1349 }
1350 }
1351
1352 fn write_utf8(&mut self, utf: &str) {
1353 assert!(utf.len() < 64);
1354 self.write_byte(utf.len() as u8);
1355 self.write_bytes(utf.as_bytes());
1356 }
1357
1358 fn write_bytes(&mut self, s: &[u8]) {
1359 self.data.push(s.to_vec());
1360 self.size += s.len();
1361 }
1362
1363 fn write_u32(&mut self, int: u32) {
1364 self.data.push(int.to_be_bytes().to_vec());
1365 self.size += 4;
1366 }
1367
1368 fn write_short(&mut self, short: u16) {
1369 self.data.push(short.to_be_bytes().to_vec());
1370 self.size += 2;
1371 }
1372
1373 fn write_byte(&mut self, byte: u8) {
1374 self.data.push(vec![byte]);
1375 self.size += 1;
1376 }
1377
1378 fn write_header(
1401 &mut self,
1402 id: u16,
1403 flags: u16,
1404 q_count: u16,
1405 a_count: u16,
1406 auth_count: u16,
1407 addi_count: u16,
1408 ) {
1409 self.insert_short(0, addi_count);
1410 self.insert_short(0, auth_count);
1411 self.insert_short(0, a_count);
1412 self.insert_short(0, q_count);
1413 self.insert_short(0, flags);
1414 self.insert_short(0, id);
1415
1416 self.size -= MSG_HEADER_LEN;
1418
1419 self.state = PacketState::Finished;
1420 }
1421}
1422
1423pub struct DnsOutgoing {
1425 flags: u16,
1426 id: u16,
1427 multicast: bool,
1428 questions: Vec<DnsQuestion>,
1429 answers: Vec<(DnsRecordBox, u64)>,
1430 authorities: Vec<DnsRecordBox>,
1431 additionals: Vec<DnsRecordBox>,
1432 known_answer_count: i64, }
1434
1435impl DnsOutgoing {
1436 pub fn new(flags: u16) -> Self {
1437 Self {
1438 flags,
1439 id: 0,
1440 multicast: true,
1441 questions: Vec::new(),
1442 answers: Vec::new(),
1443 authorities: Vec::new(),
1444 additionals: Vec::new(),
1445 known_answer_count: 0,
1446 }
1447 }
1448
1449 pub fn questions(&self) -> &[DnsQuestion] {
1450 &self.questions
1451 }
1452
1453 pub fn answers_count(&self) -> usize {
1454 self.answers.len()
1455 }
1456
1457 pub fn authorities(&self) -> &[DnsRecordBox] {
1458 &self.authorities
1459 }
1460
1461 pub fn additionals(&self) -> &[DnsRecordBox] {
1462 &self.additionals
1463 }
1464
1465 pub fn known_answer_count(&self) -> i64 {
1466 self.known_answer_count
1467 }
1468
1469 pub fn set_id(&mut self, id: u16) {
1470 self.id = id;
1471 }
1472
1473 pub const fn is_query(&self) -> bool {
1474 (self.flags & FLAGS_QR_MASK) == FLAGS_QR_QUERY
1475 }
1476
1477 const fn is_response(&self) -> bool {
1478 (self.flags & FLAGS_QR_MASK) == FLAGS_QR_RESPONSE
1479 }
1480
1481 pub fn add_additional_answer(&mut self, answer: impl DnsRecordExt + 'static) {
1515 trace!("add_additional_answer: {:?}", &answer);
1516 self.additionals.push(answer.boxed());
1517 }
1518
1519 pub fn add_answer_box(&mut self, answer_box: DnsRecordBox) {
1521 self.answers.push((answer_box, 0));
1522 }
1523
1524 pub fn add_authority(&mut self, record: DnsRecordBox) {
1525 self.authorities.push(record);
1526 }
1527
1528 pub fn add_answer(
1531 &mut self,
1532 msg: &DnsIncoming,
1533 answer: impl DnsRecordExt + Send + 'static,
1534 ) -> bool {
1535 trace!("Check for add_answer");
1536 if answer.suppressed_by(msg) {
1537 trace!("my answer is suppressed by incoming msg");
1538 self.known_answer_count += 1;
1539 return false;
1540 }
1541
1542 self.add_answer_at_time(answer, 0)
1543 }
1544
1545 pub fn add_answer_at_time(
1549 &mut self,
1550 answer: impl DnsRecordExt + Send + 'static,
1551 now: u64,
1552 ) -> bool {
1553 if now == 0 || !answer.get_record().is_expired(now) {
1554 trace!("add_answer push: {:?}", &answer);
1555 self.answers.push((answer.boxed(), now));
1556 return true;
1557 }
1558 false
1559 }
1560
1561 pub fn add_question(&mut self, name: &str, qtype: RRType) {
1562 let q = DnsQuestion {
1563 entry: DnsEntry::new(name.to_string(), qtype, CLASS_IN),
1564 };
1565 self.questions.push(q);
1566 }
1567
1568 pub fn to_data_on_wire(&self) -> Vec<Vec<u8>> {
1570 let packet_list = self.to_packets();
1571 packet_list.iter().map(|p| p.data.concat()).collect()
1572 }
1573
1574 pub fn to_packets(&self) -> Vec<DnsOutPacket> {
1576 let mut packet_list = Vec::new();
1577 let mut packet = DnsOutPacket::new();
1578
1579 let mut question_count = self.questions.len() as u16;
1580 let mut answer_count = 0;
1581 let mut auth_count = 0;
1582 let mut addi_count = 0;
1583 let id = if self.multicast { 0 } else { self.id };
1584
1585 for question in self.questions.iter() {
1586 packet.write_question(question);
1587 }
1588
1589 for (answer, time) in self.answers.iter() {
1590 if packet.write_record(answer.as_ref(), *time) {
1591 answer_count += 1;
1592 }
1593 }
1594
1595 for auth in self.authorities.iter() {
1596 auth_count += u16::from(packet.write_record(auth.as_ref(), 0));
1597 }
1598
1599 for addi in self.additionals.iter() {
1600 if packet.write_record(addi.as_ref(), 0) {
1601 addi_count += 1;
1602 continue;
1603 }
1604
1605 if self.is_response() {
1607 break;
1608 }
1609
1610 packet.write_header(
1615 id,
1616 self.flags | FLAGS_TC,
1617 question_count,
1618 answer_count,
1619 auth_count,
1620 addi_count,
1621 );
1622
1623 packet_list.push(packet);
1624
1625 packet = DnsOutPacket::new();
1627 packet.write_record(addi.as_ref(), 0);
1628
1629 question_count = 0;
1630 answer_count = 0;
1631 auth_count = 0;
1632 addi_count = 1;
1633 }
1634
1635 packet.write_header(
1636 id,
1637 self.flags,
1638 question_count,
1639 answer_count,
1640 auth_count,
1641 addi_count,
1642 );
1643
1644 packet_list.push(packet);
1645 packet_list
1646 }
1647}
1648
1649#[derive(Debug)]
1651pub struct DnsIncoming {
1652 offset: usize,
1653 data: Vec<u8>,
1654 questions: Vec<DnsQuestion>,
1655 answers: Vec<DnsRecordBox>,
1656 authorities: Vec<DnsRecordBox>,
1657 additional: Vec<DnsRecordBox>,
1658 id: u16,
1659 flags: u16,
1660 num_questions: u16,
1661 num_answers: u16,
1662 num_authorities: u16,
1663 num_additionals: u16,
1664}
1665
1666impl DnsIncoming {
1667 pub fn new(data: Vec<u8>) -> Result<Self> {
1668 let mut incoming = Self {
1669 offset: 0,
1670 data,
1671 questions: Vec::new(),
1672 answers: Vec::new(),
1673 authorities: Vec::new(),
1674 additional: Vec::new(),
1675 id: 0,
1676 flags: 0,
1677 num_questions: 0,
1678 num_answers: 0,
1679 num_authorities: 0,
1680 num_additionals: 0,
1681 };
1682
1683 incoming.read_header()?;
1703 incoming.read_questions()?;
1704 incoming.read_answers()?;
1705 incoming.read_authorities()?;
1706 incoming.read_additional()?;
1707
1708 Ok(incoming)
1709 }
1710
1711 pub fn id(&self) -> u16 {
1712 self.id
1713 }
1714
1715 pub fn questions(&self) -> &[DnsQuestion] {
1716 &self.questions
1717 }
1718
1719 pub fn answers(&self) -> &[DnsRecordBox] {
1720 &self.answers
1721 }
1722
1723 pub fn authorities(&self) -> &[DnsRecordBox] {
1724 &self.authorities
1725 }
1726
1727 pub fn additionals(&self) -> &[DnsRecordBox] {
1728 &self.additional
1729 }
1730
1731 pub fn answers_mut(&mut self) -> &mut Vec<DnsRecordBox> {
1732 &mut self.answers
1733 }
1734
1735 pub fn authorities_mut(&mut self) -> &mut Vec<DnsRecordBox> {
1736 &mut self.authorities
1737 }
1738
1739 pub fn additionals_mut(&mut self) -> &mut Vec<DnsRecordBox> {
1740 &mut self.additional
1741 }
1742
1743 pub fn all_records(self) -> impl Iterator<Item = DnsRecordBox> {
1744 self.answers
1745 .into_iter()
1746 .chain(self.authorities)
1747 .chain(self.additional)
1748 }
1749
1750 pub fn num_additionals(&self) -> u16 {
1751 self.num_additionals
1752 }
1753
1754 pub fn num_authorities(&self) -> u16 {
1755 self.num_authorities
1756 }
1757
1758 pub fn num_questions(&self) -> u16 {
1759 self.num_questions
1760 }
1761
1762 pub const fn is_query(&self) -> bool {
1763 (self.flags & FLAGS_QR_MASK) == FLAGS_QR_QUERY
1764 }
1765
1766 pub const fn is_response(&self) -> bool {
1767 (self.flags & FLAGS_QR_MASK) == FLAGS_QR_RESPONSE
1768 }
1769
1770 fn read_header(&mut self) -> Result<()> {
1771 if self.data.len() < MSG_HEADER_LEN {
1772 return Err(e_fmt!(
1773 "DNS incoming: header is too short: {} bytes",
1774 self.data.len()
1775 ));
1776 }
1777
1778 let data = &self.data[0..];
1779 self.id = u16_from_be_slice(&data[..2]);
1780 self.flags = u16_from_be_slice(&data[2..4]);
1781 self.num_questions = u16_from_be_slice(&data[4..6]);
1782 self.num_answers = u16_from_be_slice(&data[6..8]);
1783 self.num_authorities = u16_from_be_slice(&data[8..10]);
1784 self.num_additionals = u16_from_be_slice(&data[10..12]);
1785
1786 self.offset = MSG_HEADER_LEN;
1787
1788 trace!(
1789 "read_header: id {}, {} questions {} answers {} authorities {} additionals",
1790 self.id,
1791 self.num_questions,
1792 self.num_answers,
1793 self.num_authorities,
1794 self.num_additionals
1795 );
1796 Ok(())
1797 }
1798
1799 fn read_questions(&mut self) -> Result<()> {
1800 trace!("read_questions: {}", &self.num_questions);
1801 for i in 0..self.num_questions {
1802 let name = self.read_name()?;
1803
1804 let data = &self.data[self.offset..];
1805 if data.len() < 4 {
1806 return Err(Error::Msg(format!(
1807 "DNS incoming: question idx {} too short: {}",
1808 i,
1809 data.len()
1810 )));
1811 }
1812 let ty = u16_from_be_slice(&data[..2]);
1813 let class = u16_from_be_slice(&data[2..4]);
1814 self.offset += 4;
1815
1816 let Some(rr_type) = RRType::from_u16(ty) else {
1817 return Err(Error::Msg(format!(
1818 "DNS incoming: question idx {} qtype unknown: {}",
1819 i, ty
1820 )));
1821 };
1822
1823 self.questions.push(DnsQuestion {
1824 entry: DnsEntry::new(name, rr_type, class),
1825 });
1826 }
1827 Ok(())
1828 }
1829
1830 fn read_answers(&mut self) -> Result<()> {
1831 self.answers = self.read_rr_records(self.num_answers)?;
1832 Ok(())
1833 }
1834
1835 fn read_authorities(&mut self) -> Result<()> {
1836 self.authorities = self.read_rr_records(self.num_authorities)?;
1837 Ok(())
1838 }
1839
1840 fn read_additional(&mut self) -> Result<()> {
1841 self.additional = self.read_rr_records(self.num_additionals)?;
1842 Ok(())
1843 }
1844
1845 fn read_rr_records(&mut self, count: u16) -> Result<Vec<DnsRecordBox>> {
1847 trace!("read_rr_records: {}", count);
1848 let mut rr_records = Vec::new();
1849
1850 const RR_HEADER_REMAIN: usize = 10;
1876
1877 for _ in 0..count {
1878 let name = self.read_name()?;
1879 let slice = &self.data[self.offset..];
1880
1881 if slice.len() < RR_HEADER_REMAIN {
1882 return Err(Error::Msg(format!(
1883 "read_others: RR '{}' is too short after name: {} bytes",
1884 &name,
1885 slice.len()
1886 )));
1887 }
1888
1889 let ty = u16_from_be_slice(&slice[..2]);
1890 let class = u16_from_be_slice(&slice[2..4]);
1891 let mut ttl = u32_from_be_slice(&slice[4..8]);
1892 if ttl == 0 && self.is_response() {
1893 ttl = 1;
1900 }
1901 let rdata_len = u16_from_be_slice(&slice[8..10]) as usize;
1902 self.offset += RR_HEADER_REMAIN;
1903 let next_offset = self.offset + rdata_len;
1904
1905 if next_offset > self.data.len() {
1907 return Err(Error::Msg(format!(
1908 "RR {name} RDATA length {rdata_len} is invalid: remain data len: {}",
1909 self.data.len() - self.offset
1910 )));
1911 }
1912
1913 let rec: Option<DnsRecordBox> = match RRType::from_u16(ty) {
1915 None => None,
1916
1917 Some(rr_type) => match rr_type {
1918 RRType::CNAME | RRType::PTR => {
1919 Some(DnsPointer::new(&name, rr_type, class, ttl, self.read_name()?).boxed())
1920 }
1921 RRType::TXT => {
1922 Some(DnsTxt::new(&name, class, ttl, self.read_vec(rdata_len)?).boxed())
1923 }
1924 RRType::SRV => Some(
1925 DnsSrv::new(
1926 &name,
1927 class,
1928 ttl,
1929 self.read_u16()?,
1930 self.read_u16()?,
1931 self.read_u16()?,
1932 self.read_name()?,
1933 )
1934 .boxed(),
1935 ),
1936 RRType::HINFO => Some(
1937 DnsHostInfo::new(
1938 &name,
1939 rr_type,
1940 class,
1941 ttl,
1942 self.read_char_string()?,
1943 self.read_char_string()?,
1944 )
1945 .boxed(),
1946 ),
1947 RRType::A => Some(
1948 DnsAddress::new(&name, rr_type, class, ttl, self.read_ipv4()?.into())
1949 .boxed(),
1950 ),
1951 RRType::AAAA => Some(
1952 DnsAddress::new(&name, rr_type, class, ttl, self.read_ipv6()?.into())
1953 .boxed(),
1954 ),
1955 RRType::NSEC => Some(
1956 DnsNSec::new(
1957 &name,
1958 class,
1959 ttl,
1960 self.read_name()?,
1961 self.read_type_bitmap()?,
1962 )
1963 .boxed(),
1964 ),
1965 _ => None,
1966 },
1967 };
1968
1969 if let Some(record) = rec {
1970 trace!("read_rr_records: {:?}", &record);
1971 rr_records.push(record);
1972 } else {
1973 trace!("Unsupported DNS record type: {} name: {}", ty, &name);
1974 self.offset += rdata_len;
1975 }
1976
1977 if self.offset != next_offset {
1979 return Err(Error::Msg(format!(
1980 "read_rr_records: decode offset error for RData type {} offset: {} expected offset: {}",
1981 ty, self.offset, next_offset,
1982 )));
1983 }
1984 }
1985
1986 Ok(rr_records)
1987 }
1988
1989 fn read_char_string(&mut self) -> Result<String> {
1990 let length = self.data[self.offset];
1991 self.offset += 1;
1992 self.read_string(length as usize)
1993 }
1994
1995 fn read_u16(&mut self) -> Result<u16> {
1996 let slice = &self.data[self.offset..];
1997 if slice.len() < U16_SIZE {
1998 return Err(Error::Msg(format!(
1999 "read_u16: slice len is only {}",
2000 slice.len()
2001 )));
2002 }
2003 let num = u16_from_be_slice(&slice[..U16_SIZE]);
2004 self.offset += U16_SIZE;
2005 Ok(num)
2006 }
2007
2008 fn read_type_bitmap(&mut self) -> Result<Vec<u8>> {
2010 if self.data.len() < self.offset + 2 {
2019 return Err(Error::Msg(format!(
2020 "DnsIncoming is too short: {} at NSEC Type Bit Map offset {}",
2021 self.data.len(),
2022 self.offset
2023 )));
2024 }
2025
2026 let block_num = self.data[self.offset];
2027 self.offset += 1;
2028 if block_num != 0 {
2029 return Err(Error::Msg(format!(
2030 "NSEC block number is not 0: {}",
2031 block_num
2032 )));
2033 }
2034
2035 let block_len = self.data[self.offset] as usize;
2036 if !(1..=32).contains(&block_len) {
2037 return Err(Error::Msg(format!(
2038 "NSEC block length must be in the range 1-32: {}",
2039 block_len
2040 )));
2041 }
2042 self.offset += 1;
2043
2044 let end = self.offset + block_len;
2045 if end > self.data.len() {
2046 return Err(Error::Msg(format!(
2047 "NSEC block overflow: {} over RData len {}",
2048 end,
2049 self.data.len()
2050 )));
2051 }
2052 let bitmap = self.data[self.offset..end].to_vec();
2053 self.offset += block_len;
2054
2055 Ok(bitmap)
2056 }
2057
2058 fn read_vec(&mut self, length: usize) -> Result<Vec<u8>> {
2059 if self.data.len() < self.offset + length {
2060 return Err(e_fmt!(
2061 "DNS Incoming: not enough data to read a chunk of data"
2062 ));
2063 }
2064
2065 let v = self.data[self.offset..self.offset + length].to_vec();
2066 self.offset += length;
2067 Ok(v)
2068 }
2069
2070 fn read_ipv4(&mut self) -> Result<Ipv4Addr> {
2071 if self.data.len() < self.offset + 4 {
2072 return Err(e_fmt!("DNS Incoming: not enough data to read an IPV4"));
2073 }
2074
2075 let bytes: [u8; 4] = self.data[self.offset..self.offset + 4]
2076 .try_into()
2077 .map_err(|_| e_fmt!("DNS incoming: Not enough bytes for reading an IPV4"))?;
2078 self.offset += bytes.len();
2079 Ok(Ipv4Addr::from(bytes))
2080 }
2081
2082 fn read_ipv6(&mut self) -> Result<Ipv6Addr> {
2083 if self.data.len() < self.offset + 16 {
2084 return Err(e_fmt!("DNS Incoming: not enough data to read an IPV6"));
2085 }
2086
2087 let bytes: [u8; 16] = self.data[self.offset..self.offset + 16]
2088 .try_into()
2089 .map_err(|_| e_fmt!("DNS incoming: Not enough bytes for reading an IPV6"))?;
2090 self.offset += bytes.len();
2091 Ok(Ipv6Addr::from(bytes))
2092 }
2093
2094 fn read_string(&mut self, length: usize) -> Result<String> {
2095 if self.data.len() < self.offset + length {
2096 return Err(e_fmt!("DNS Incoming: not enough data to read a string"));
2097 }
2098
2099 let s = str::from_utf8(&self.data[self.offset..self.offset + length])
2100 .map_err(|e| Error::Msg(e.to_string()))?;
2101 self.offset += length;
2102 Ok(s.to_string())
2103 }
2104
2105 fn read_name(&mut self) -> Result<String> {
2110 let data = &self.data[..];
2111 let start_offset = self.offset;
2112 let mut offset = start_offset;
2113 let mut name = "".to_string();
2114 let mut at_end = false;
2115
2116 loop {
2127 if offset >= data.len() {
2128 return Err(Error::Msg(format!(
2129 "read_name: offset: {} data len {}. DnsIncoming: {:?}",
2130 offset,
2131 data.len(),
2132 self
2133 )));
2134 }
2135 let length = data[offset];
2136
2137 if length == 0 {
2141 if !at_end {
2142 self.offset = offset + 1;
2143 }
2144 break; }
2146
2147 match length & 0xC0 {
2149 0x00 => {
2150 offset += 1;
2152 let ending = offset + length as usize;
2153
2154 if ending > data.len() {
2156 return Err(Error::Msg(format!(
2157 "read_name: ending {} exceeds data length {}",
2158 ending,
2159 data.len()
2160 )));
2161 }
2162
2163 name += str::from_utf8(&data[offset..ending])
2164 .map_err(|e| Error::Msg(format!("read_name: from_utf8: {}", e)))?;
2165 name += ".";
2166 offset += length as usize;
2167 }
2168 0xC0 => {
2169 let slice = &data[offset..];
2172 if slice.len() < U16_SIZE {
2173 return Err(Error::Msg(format!(
2174 "read_name: u16 slice len is only {}",
2175 slice.len()
2176 )));
2177 }
2178 let pointer = (u16_from_be_slice(slice) ^ 0xC000) as usize;
2179 if pointer >= start_offset {
2180 return Err(Error::Msg(format!(
2182 "Invalid name compression: pointer {} must be less than the start offset {}",
2183 &pointer, &start_offset
2184 )));
2185 }
2186
2187 if !at_end {
2189 self.offset = offset + U16_SIZE;
2190 at_end = true;
2191 }
2192 offset = pointer;
2193 }
2194 _ => {
2195 return Err(Error::Msg(format!(
2196 "Bad name with invalid length: 0x{:x} offset {}, data (so far): {:x?}",
2197 length,
2198 offset,
2199 &data[..offset]
2200 )));
2201 }
2202 };
2203 }
2204
2205 Ok(name)
2206 }
2207}
2208
2209fn current_time_millis() -> u64 {
2211 SystemTime::now()
2212 .duration_since(SystemTime::UNIX_EPOCH)
2213 .expect("failed to get current UNIX time")
2214 .as_millis() as u64
2215}
2216
2217const fn u16_from_be_slice(bytes: &[u8]) -> u16 {
2218 let u8_array: [u8; 2] = [bytes[0], bytes[1]];
2219 u16::from_be_bytes(u8_array)
2220}
2221
2222const fn u32_from_be_slice(s: &[u8]) -> u32 {
2223 let u8_array: [u8; 4] = [s[0], s[1], s[2], s[3]];
2224 u32::from_be_bytes(u8_array)
2225}
2226
2227const fn get_expiration_time(created: u64, ttl: u32, percent: u32) -> u64 {
2230 created + (ttl * percent * 10) as u64
2233}