1use crate::core::MtopError;
2use crate::dns::core::RecordType;
3use crate::dns::name::Name;
4use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
5use std::fmt::{self, Display};
6use std::io::{Read, Seek};
7use std::net::{Ipv4Addr, Ipv6Addr};
8
9#[derive(Debug, Clone, Eq, PartialEq)]
10pub enum RecordData {
11 A(RecordDataA),
12 NS(RecordDataNS),
13 CNAME(RecordDataCNAME),
14 SOA(RecordDataSOA),
15 TXT(RecordDataTXT),
16 AAAA(RecordDataAAAA),
17 SRV(RecordDataSRV),
18 OPT(RecordDataOpt),
19 Unknown(RecordDataUnknown),
20}
21
22impl RecordData {
23 pub fn size(&self) -> usize {
24 match self {
25 Self::A(rd) => rd.size(),
26 Self::NS(rd) => rd.size(),
27 Self::CNAME(rd) => rd.size(),
28 Self::SOA(rd) => rd.size(),
29 Self::TXT(rd) => rd.size(),
30 Self::AAAA(rd) => rd.size(),
31 Self::SRV(rd) => rd.size(),
32 Self::OPT(rd) => rd.size(),
33 Self::Unknown(rd) => rd.size(),
34 }
35 }
36
37 pub fn write_network_bytes<T>(&self, buf: T) -> Result<(), MtopError>
38 where
39 T: WriteBytesExt,
40 {
41 match self {
42 Self::A(rd) => rd.write_network_bytes(buf),
43 Self::NS(rd) => rd.write_network_bytes(buf),
44 Self::CNAME(rd) => rd.write_network_bytes(buf),
45 Self::SOA(rd) => rd.write_network_bytes(buf),
46 Self::TXT(rd) => rd.write_network_bytes(buf),
47 Self::AAAA(rd) => rd.write_network_bytes(buf),
48 Self::SRV(rd) => rd.write_network_bytes(buf),
49 Self::OPT(rd) => rd.write_network_bytes(buf),
50 Self::Unknown(rd) => rd.write_network_bytes(buf),
51 }
52 }
53
54 pub fn read_network_bytes<T>(rtype: RecordType, rdata_len: u16, buf: T) -> Result<Self, MtopError>
55 where
56 T: ReadBytesExt + Seek,
57 {
58 match rtype {
59 RecordType::A => Ok(RecordData::A(RecordDataA::read_network_bytes(buf)?)),
60 RecordType::NS => Ok(RecordData::NS(RecordDataNS::read_network_bytes(buf)?)),
61 RecordType::CNAME => Ok(RecordData::CNAME(RecordDataCNAME::read_network_bytes(buf)?)),
62 RecordType::SOA => Ok(RecordData::SOA(RecordDataSOA::read_network_bytes(buf)?)),
63 RecordType::TXT => Ok(RecordData::TXT(RecordDataTXT::read_network_bytes(rdata_len, buf)?)),
64 RecordType::AAAA => Ok(RecordData::AAAA(RecordDataAAAA::read_network_bytes(buf)?)),
65 RecordType::SRV => Ok(RecordData::SRV(RecordDataSRV::read_network_bytes(buf)?)),
66 RecordType::OPT => Ok(RecordData::OPT(RecordDataOpt::read_network_bytes(rdata_len, buf)?)),
67 RecordType::Unknown(_) => Ok(RecordData::Unknown(RecordDataUnknown::read_network_bytes(
68 rdata_len, buf,
69 )?)),
70 }
71 }
72}
73
74impl Display for RecordData {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 match self {
77 RecordData::A(rd) => Display::fmt(rd, f),
78 RecordData::NS(rd) => Display::fmt(rd, f),
79 RecordData::CNAME(rd) => Display::fmt(rd, f),
80 RecordData::SOA(rd) => Display::fmt(rd, f),
81 RecordData::TXT(rd) => Display::fmt(rd, f),
82 RecordData::AAAA(rd) => Display::fmt(rd, f),
83 RecordData::SRV(rd) => Display::fmt(rd, f),
84 RecordData::OPT(rd) => Display::fmt(rd, f),
85 RecordData::Unknown(rd) => Display::fmt(rd, f),
86 }
87 }
88}
89
90#[derive(Debug, Clone, Eq, PartialEq)]
91pub struct RecordDataA(Ipv4Addr);
92
93impl RecordDataA {
94 pub fn new(addr: Ipv4Addr) -> Self {
95 Self(addr)
96 }
97
98 pub fn addr(&self) -> Ipv4Addr {
99 self.0
100 }
101
102 pub fn size(&self) -> usize {
103 4
104 }
105
106 pub fn write_network_bytes<T>(&self, mut buf: T) -> Result<(), MtopError>
107 where
108 T: WriteBytesExt,
109 {
110 Ok(buf.write_all(&self.0.octets())?)
111 }
112
113 pub fn read_network_bytes<T>(mut buf: T) -> Result<Self, MtopError>
114 where
115 T: ReadBytesExt + Seek,
116 {
117 let mut bytes = [0_u8; 4];
118 buf.read_exact(&mut bytes)?;
119 Ok(RecordDataA::new(Ipv4Addr::from(bytes)))
120 }
121}
122
123impl Display for RecordDataA {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 Display::fmt(&self.0, f)
126 }
127}
128
129#[derive(Debug, Clone, Eq, PartialEq)]
130pub struct RecordDataNS(Name);
131
132impl RecordDataNS {
133 pub fn new(name: Name) -> Self {
134 Self(name)
135 }
136
137 pub fn name(&self) -> &Name {
138 &self.0
139 }
140
141 pub fn size(&self) -> usize {
142 self.0.size()
143 }
144
145 pub fn write_network_bytes<T>(&self, buf: T) -> Result<(), MtopError>
146 where
147 T: WriteBytesExt,
148 {
149 self.0.write_network_bytes(buf)
150 }
151
152 pub fn read_network_bytes<T>(buf: T) -> Result<Self, MtopError>
153 where
154 T: ReadBytesExt + Seek,
155 {
156 Ok(Self::new(Name::read_network_bytes(buf)?))
157 }
158}
159
160impl Display for RecordDataNS {
161 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
162 Display::fmt(&self.0, f)
163 }
164}
165
166#[derive(Debug, Clone, Eq, PartialEq)]
167pub struct RecordDataCNAME(Name);
168
169impl RecordDataCNAME {
170 pub fn new(name: Name) -> Self {
171 Self(name)
172 }
173
174 pub fn name(&self) -> &Name {
175 &self.0
176 }
177
178 pub fn size(&self) -> usize {
179 self.0.size()
180 }
181
182 pub fn write_network_bytes<T>(&self, buf: T) -> Result<(), MtopError>
183 where
184 T: WriteBytesExt,
185 {
186 self.0.write_network_bytes(buf)
187 }
188
189 pub fn read_network_bytes<T>(buf: T) -> Result<Self, MtopError>
190 where
191 T: ReadBytesExt + Seek,
192 {
193 Ok(Self::new(Name::read_network_bytes(buf)?))
194 }
195}
196impl Display for RecordDataCNAME {
197 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
198 Display::fmt(&self.0, f)
199 }
200}
201
202#[derive(Debug, Clone, Eq, PartialEq)]
203pub struct RecordDataSOA {
204 mname: Name,
205 rname: Name,
206 serial: u32,
207 refresh: u32,
208 retry: u32,
209 expire: u32,
210 minimum: u32,
211}
212
213impl RecordDataSOA {
214 pub fn new(mname: Name, rname: Name, serial: u32, refresh: u32, retry: u32, expire: u32, minimum: u32) -> Self {
215 Self {
216 mname,
217 rname,
218 serial,
219 refresh,
220 retry,
221 expire,
222 minimum,
223 }
224 }
225
226 pub fn mname(&self) -> &Name {
227 &self.mname
228 }
229
230 pub fn rname(&self) -> &Name {
231 &self.rname
232 }
233
234 pub fn serial(&self) -> u32 {
235 self.serial
236 }
237
238 pub fn refresh(&self) -> u32 {
239 self.refresh
240 }
241
242 pub fn retry(&self) -> u32 {
243 self.retry
244 }
245
246 pub fn expire(&self) -> u32 {
247 self.expire
248 }
249
250 pub fn minimum(&self) -> u32 {
251 self.minimum
252 }
253
254 pub fn size(&self) -> usize {
255 self.mname.size() + self.rname.size() + (4 * 5)
256 }
257
258 pub fn write_network_bytes<T>(&self, mut buf: T) -> Result<(), MtopError>
259 where
260 T: WriteBytesExt,
261 {
262 self.mname.write_network_bytes(&mut buf)?;
263 self.rname.write_network_bytes(&mut buf)?;
264 buf.write_u32::<NetworkEndian>(self.serial)?;
265 buf.write_u32::<NetworkEndian>(self.refresh)?;
266 buf.write_u32::<NetworkEndian>(self.retry)?;
267 buf.write_u32::<NetworkEndian>(self.expire)?;
268 buf.write_u32::<NetworkEndian>(self.minimum)?;
269 Ok(())
270 }
271
272 pub fn read_network_bytes<T>(mut buf: T) -> Result<Self, MtopError>
273 where
274 T: ReadBytesExt + Seek,
275 {
276 let mname = Name::read_network_bytes(&mut buf)?;
277 let rname = Name::read_network_bytes(&mut buf)?;
278 let serial = buf.read_u32::<NetworkEndian>()?;
279 let refresh = buf.read_u32::<NetworkEndian>()?;
280 let retry = buf.read_u32::<NetworkEndian>()?;
281 let expire = buf.read_u32::<NetworkEndian>()?;
282 let minimum = buf.read_u32::<NetworkEndian>()?;
283
284 Ok(Self::new(mname, rname, serial, refresh, retry, expire, minimum))
285 }
286}
287
288impl Display for RecordDataSOA {
289 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
290 write!(
291 f,
292 "{} {} {} {} {} {} {}",
293 self.mname, self.rname, self.serial, self.refresh, self.retry, self.expire, self.minimum
294 )
295 }
296}
297
298#[derive(Debug, Clone, Eq, PartialEq)]
299pub struct RecordDataTXT(Vec<Vec<u8>>);
300
301impl RecordDataTXT {
302 const MAX_LENGTH: usize = 65535;
303 const MAX_SEGMENT_LENGTH: usize = 255;
304
305 pub fn new<I, B>(items: I) -> Result<Self, MtopError>
306 where
307 I: IntoIterator<Item = B>,
308 B: Into<Vec<u8>>,
309 {
310 let mut segments = Vec::new();
311 let mut total = 0;
312
313 for txt in items {
314 let bytes = txt.into();
315 if bytes.len() > Self::MAX_SEGMENT_LENGTH {
316 return Err(MtopError::runtime(format!(
317 "TXT record segment too long; {} bytes, max {} bytes",
318 bytes.len(),
319 Self::MAX_SEGMENT_LENGTH
320 )));
321 }
322
323 total += 1 + bytes.len();
327 if total > Self::MAX_LENGTH {
328 return Err(MtopError::runtime(format!(
329 "TXT record too long; {} bytes, max {} bytes",
330 total,
331 Self::MAX_LENGTH
332 )));
333 }
334
335 segments.push(bytes);
336 }
337
338 Ok(Self(segments))
339 }
340
341 pub fn bytes(&self) -> &Vec<Vec<u8>> {
342 &self.0
343 }
344
345 pub fn size(&self) -> usize {
346 self.0.iter().map(|v| v.len()).sum::<usize>() + self.0.len()
349 }
350
351 pub fn write_network_bytes<T>(&self, mut buf: T) -> Result<(), MtopError>
352 where
353 T: WriteBytesExt,
354 {
355 for txt in self.0.iter() {
356 buf.write_u8(txt.len() as u8)?;
357 buf.write_all(txt)?;
358 }
359
360 Ok(())
361 }
362
363 pub fn read_network_bytes<T>(rdata_len: u16, mut buf: T) -> Result<Self, MtopError>
364 where
365 T: ReadBytesExt + Seek,
366 {
367 let rdata_len = usize::from(rdata_len);
368 let mut all = Vec::new();
369 let mut consumed = 0;
370
371 while consumed < rdata_len {
372 let len = buf.read_u8()?;
373 if usize::from(len) + consumed > rdata_len {
374 return Err(MtopError::runtime(format!(
375 "text for RecordDataTXT exceeds rdata size; len: {}, consumed: {}, rdata: {}",
376 len, consumed, rdata_len
377 )));
378 }
379
380 let mut txt = Vec::with_capacity(usize::from(len));
381 let mut handle = buf.take(u64::from(len));
382 let n = handle.read_to_end(&mut txt)?;
383 if n != usize::from(len) {
384 return Err(MtopError::runtime(format!(
385 "short read for RecordDataTXT text; expected {}, got {}",
386 len, n
387 )));
388 }
389
390 all.push(txt);
391 consumed += n + 1;
392 buf = handle.into_inner();
393 }
394
395 Self::new(all)
396 }
397}
398
399impl Display for RecordDataTXT {
400 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
401 for txt in self.0.iter() {
402 write!(f, "\"{}\"", String::from_utf8_lossy(txt).replace('\"', "\\\""))?;
407 }
408
409 Ok(())
410 }
411}
412
413#[derive(Debug, Clone, Eq, PartialEq)]
414pub struct RecordDataAAAA(Ipv6Addr);
415
416impl RecordDataAAAA {
417 pub fn new(addr: Ipv6Addr) -> Self {
418 Self(addr)
419 }
420
421 pub fn addr(&self) -> Ipv6Addr {
422 self.0
423 }
424
425 pub fn size(&self) -> usize {
426 16
427 }
428
429 pub fn write_network_bytes<T>(&self, mut buf: T) -> Result<(), MtopError>
430 where
431 T: WriteBytesExt,
432 {
433 Ok(buf.write_all(&self.0.octets())?)
434 }
435
436 pub fn read_network_bytes<T>(mut buf: T) -> Result<Self, MtopError>
437 where
438 T: ReadBytesExt + Seek,
439 {
440 let mut bytes = [0_u8; 16];
441 buf.read_exact(&mut bytes)?;
442 Ok(RecordDataAAAA::new(Ipv6Addr::from(bytes)))
443 }
444}
445
446impl Display for RecordDataAAAA {
447 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
448 Display::fmt(&self.0, f)
449 }
450}
451
452#[derive(Debug, Clone, Eq, PartialEq)]
453pub struct RecordDataSRV {
454 priority: u16,
455 weight: u16,
456 port: u16,
457 target: Name,
458}
459
460impl RecordDataSRV {
461 pub fn new(priority: u16, weight: u16, port: u16, target: Name) -> Self {
462 Self {
463 priority,
464 weight,
465 port,
466 target,
467 }
468 }
469
470 pub fn priority(&self) -> u16 {
471 self.priority
472 }
473
474 pub fn weight(&self) -> u16 {
475 self.weight
476 }
477
478 pub fn port(&self) -> u16 {
479 self.port
480 }
481
482 pub fn target(&self) -> &Name {
483 &self.target
484 }
485
486 pub fn size(&self) -> usize {
487 (2 * 3) + self.target.size()
488 }
489
490 pub fn write_network_bytes<T>(&self, mut buf: T) -> Result<(), MtopError>
491 where
492 T: WriteBytesExt,
493 {
494 buf.write_u16::<NetworkEndian>(self.priority)?;
495 buf.write_u16::<NetworkEndian>(self.weight)?;
496 buf.write_u16::<NetworkEndian>(self.port)?;
497 self.target.write_network_bytes(buf)
498 }
499
500 pub fn read_network_bytes<T>(mut buf: T) -> Result<Self, MtopError>
501 where
502 T: ReadBytesExt + Seek,
503 {
504 let priority = buf.read_u16::<NetworkEndian>()?;
505 let weight = buf.read_u16::<NetworkEndian>()?;
506 let port = buf.read_u16::<NetworkEndian>()?;
507 let target = Name::read_network_bytes(buf)?;
508
509 Ok(Self::new(priority, weight, port, target))
510 }
511}
512
513impl Display for RecordDataSRV {
514 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
515 write!(f, "{} {} {} {}", self.priority, self.weight, self.port, self.target)
516 }
517}
518
519#[derive(Debug, Clone, Eq, PartialEq)]
520pub struct RecordDataOptPair {
521 code: u16,
522 data: Vec<u8>,
523}
524
525impl RecordDataOptPair {
526 const MAX_DATA_LENGTH: usize = 65535;
527
528 pub fn new(code: u16, data: Vec<u8>) -> Result<Self, MtopError> {
529 if data.len() > Self::MAX_DATA_LENGTH {
530 Err(MtopError::runtime(format!(
531 "OPT attribute data too long; {} bytes, max {} bytes",
532 data.len(),
533 Self::MAX_DATA_LENGTH,
534 )))
535 } else {
536 Ok(Self { code, data })
537 }
538 }
539
540 pub fn code(&self) -> u16 {
541 self.code
542 }
543
544 pub fn data(&self) -> &[u8] {
545 &self.data
546 }
547
548 fn size(&self) -> usize {
549 2 + 2 + self.data.len() }
551
552 fn write_network_bytes<T>(&self, mut buf: T) -> Result<(), MtopError>
553 where
554 T: WriteBytesExt,
555 {
556 buf.write_u16::<NetworkEndian>(self.code)?;
557 buf.write_u16::<NetworkEndian>(self.data.len() as u16)?;
558 Ok(buf.write_all(&self.data)?)
559 }
560
561 fn read_network_bytes<T>(mut buf: T) -> Result<Self, MtopError>
562 where
563 T: ReadBytesExt + Seek,
564 {
565 let code = buf.read_u16::<NetworkEndian>()?;
566 let data_len = buf.read_u16::<NetworkEndian>()?;
567 let mut data = Vec::with_capacity(usize::from(data_len));
568 buf.take(u64::from(data_len)).read_to_end(&mut data)?;
569 Ok(Self { code, data })
570 }
571}
572
573impl Display for RecordDataOptPair {
574 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
575 write!(f, "{}: {}", self.code, String::from_utf8_lossy(&self.data))
576 }
577}
578
579#[derive(Debug, Clone, Eq, PartialEq)]
580pub struct RecordDataOpt {
581 options: Vec<RecordDataOptPair>,
582}
583
584impl RecordDataOpt {
585 const MAX_LENGTH: usize = 65535;
586
587 pub fn new(options: Vec<RecordDataOptPair>) -> Result<Self, MtopError> {
588 let size = Self::options_size(&options);
589 if size > Self::MAX_LENGTH {
590 Err(MtopError::runtime(format!(
591 "OPT record data too long; {} bytes, max {} bytes",
592 size,
593 Self::MAX_LENGTH,
594 )))
595 } else {
596 Ok(Self { options })
597 }
598 }
599
600 fn options_size(opts: &[RecordDataOptPair]) -> usize {
601 opts.iter().map(|o| o.size()).sum()
602 }
603
604 pub fn options(&self) -> &[RecordDataOptPair] {
605 &self.options
606 }
607
608 pub fn size(&self) -> usize {
609 Self::options_size(&self.options)
610 }
611
612 pub fn write_network_bytes<T>(&self, mut buf: T) -> Result<(), MtopError>
613 where
614 T: WriteBytesExt,
615 {
616 for opt in self.options.iter() {
617 opt.write_network_bytes(&mut buf)?;
618 }
619
620 Ok(())
621 }
622
623 pub fn read_network_bytes<T>(rdata_len: u16, mut buf: T) -> Result<Self, MtopError>
624 where
625 T: ReadBytesExt + Seek,
626 {
627 let rdata_len = usize::from(rdata_len);
628 let mut options = Vec::new();
629 let mut consumed = 0;
630
631 while consumed < rdata_len {
632 let opt = RecordDataOptPair::read_network_bytes(&mut buf)?;
633 consumed += opt.size();
634 options.push(opt);
635 }
636
637 Ok(Self { options })
638 }
639}
640
641impl Display for RecordDataOpt {
642 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
643 for opt in self.options.iter() {
644 write!(f, "{}", opt)?;
645 }
646
647 Ok(())
648 }
649}
650
651#[derive(Debug, Clone, Eq, PartialEq)]
652pub struct RecordDataUnknown(Vec<u8>);
653
654impl RecordDataUnknown {
655 const MAX_LENGTH: usize = 65535;
656
657 pub fn new(bytes: Vec<u8>) -> Result<Self, MtopError> {
658 if bytes.len() > Self::MAX_LENGTH {
659 Err(MtopError::runtime(format!(
660 "record data too long; {} bytes, max {} bytes",
661 bytes.len(),
662 Self::MAX_LENGTH
663 )))
664 } else {
665 Ok(Self(bytes))
666 }
667 }
668
669 pub fn size(&self) -> usize {
670 self.0.len()
671 }
672
673 pub fn write_network_bytes<T>(&self, mut buf: T) -> Result<(), MtopError>
674 where
675 T: WriteBytesExt,
676 {
677 buf.write_all(&self.0)?;
678 Ok(())
679 }
680
681 pub fn read_network_bytes<T>(rdata_len: u16, buf: T) -> Result<Self, MtopError>
682 where
683 T: ReadBytesExt + Seek,
684 {
685 let mut bytes = Vec::with_capacity(usize::from(rdata_len));
686 let n = buf.take(u64::from(rdata_len)).read_to_end(&mut bytes)?;
687 if n != usize::from(rdata_len) {
688 Err(MtopError::runtime(format!(
689 "short read for RecordDataUnknown; expected {} got {}",
690 rdata_len, n
691 )))
692 } else {
693 Self::new(bytes)
694 }
695 }
696}
697
698impl Display for RecordDataUnknown {
699 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
700 write!(f, "[unknown]")
701 }
702}
703
704#[cfg(test)]
705mod test {
706 use super::{
707 RecordDataA, RecordDataAAAA, RecordDataCNAME, RecordDataNS, RecordDataOptPair, RecordDataSOA, RecordDataSRV,
708 RecordDataTXT,
709 };
710 use crate::dns::RecordDataOpt;
711 use crate::dns::name::Name;
712 use std::io::Cursor;
713 use std::net::{Ipv4Addr, Ipv6Addr};
714 use std::str::FromStr;
715
716 #[test]
717 fn test_record_data_a_write_network_bytes() {
718 let rdata = RecordDataA::new(Ipv4Addr::new(127, 0, 0, 1));
719
720 let mut cur = Cursor::new(Vec::new());
721 rdata.write_network_bytes(&mut cur).unwrap();
722 let buf = cur.into_inner();
723
724 assert_eq!(vec![127, 0, 0, 1], buf);
725 }
726 #[test]
727 fn test_record_data_a_read_network_bytes() {
728 let cur = Cursor::new(vec![127, 0, 0, 53]);
729 let rdata = RecordDataA::read_network_bytes(cur).unwrap();
730
731 assert_eq!(Ipv4Addr::new(127, 0, 0, 53), rdata.addr());
732 }
733
734 #[rustfmt::skip]
735 #[test]
736 fn test_record_data_ns_write_network_bytes() {
737 let name = Name::from_str("ns.example.com.").unwrap();
738 let ns = RecordDataNS::new(name);
739
740 let mut cur = Cursor::new(Vec::new());
741 ns.write_network_bytes(&mut cur).unwrap();
742 let buf = cur.into_inner();
743
744 assert_eq!(
745 vec![
746 2, 110, 115, 7, 101, 120, 97, 109, 112, 108, 101, 3, 99, 111, 109, 0, ],
754 buf,
755 );
756 }
757
758 #[rustfmt::skip]
759 #[test]
760 fn test_record_data_ns_read_network_bytes() {
761 let cur = Cursor::new(vec![
762 2, 110, 115, 7, 101, 120, 97, 109, 112, 108, 101, 3, 99, 111, 109, 0, ]);
770
771 let rdata = RecordDataNS::read_network_bytes(cur).unwrap();
772 assert_eq!("ns.example.com.", rdata.name().to_string());
773 }
774
775 #[rustfmt::skip]
776 #[test]
777 fn test_record_data_cname_write_network_bytes() {
778 let name = Name::from_str("www.example.com.").unwrap();
779 let ns = RecordDataCNAME::new(name);
780
781 let mut cur = Cursor::new(Vec::new());
782 ns.write_network_bytes(&mut cur).unwrap();
783 let buf = cur.into_inner();
784
785 assert_eq!(
786 vec![
787 3, 119, 119, 119, 7, 101, 120, 97, 109, 112, 108, 101, 3, 99, 111, 109, 0, ],
795 buf,
796 );
797 }
798
799 #[rustfmt::skip]
800 #[test]
801 fn test_record_data_cname_read_network_bytes() {
802 let cur = Cursor::new(vec![
803 3, 119, 119, 119, 7, 101, 120, 97, 109, 112, 108, 101, 3, 99, 111, 109, 0, ]);
811
812 let rdata = RecordDataCNAME::read_network_bytes(cur).unwrap();
813 assert_eq!("www.example.com.", rdata.name().to_string());
814 }
815
816 #[rustfmt::skip]
817 #[test]
818 fn test_record_data_soa_write_network_bytes() {
819 let mname = Name::from_str("m.example.com.").unwrap();
820 let rname = Name::from_str("r.example.com.").unwrap();
821 let serial = 123456790;
822 let refresh = 3000;
823 let retry = 300;
824 let expire = 3600;
825 let minimum = 600;
826
827 let soa = RecordDataSOA::new(mname, rname, serial, refresh, retry, expire, minimum);
828 let mut cur = Cursor::new(Vec::new());
829 soa.write_network_bytes(&mut cur).unwrap();
830 let buf = cur.into_inner();
831
832 assert_eq!(
833 vec![
834 1, 109, 7, 101, 120, 97, 109, 112, 108, 101, 3, 99, 111, 109, 0, 1, 114, 7, 101, 120, 97, 109, 112, 108, 101, 3, 99, 111, 109, 0, 7, 91, 205, 22, 0, 0, 11, 184, 0, 0, 1, 44, 0, 0, 14, 16, 0, 0, 2, 88 ],
854 buf,
855 );
856 }
857
858 #[rustfmt::skip]
859 #[test]
860 fn test_record_data_soa_read_network_bytes() {
861 let cur = Cursor::new(vec![
862 1, 109, 7, 101, 120, 97, 109, 112, 108, 101, 3, 99, 111, 109, 0, 1, 114, 7, 101, 120, 97, 109, 112, 108, 101, 3, 99, 111, 109, 0, 7, 91, 205, 22, 0, 0, 11, 184, 0, 0, 1, 44, 0, 0, 14, 16, 0, 0, 2, 88 ]);
882
883 let rdata = RecordDataSOA::read_network_bytes(cur).unwrap();
884 assert_eq!("m.example.com.", rdata.mname().to_string());
885 assert_eq!("r.example.com.", rdata.rname().to_string());
886 assert_eq!(123456790, rdata.serial());
887 assert_eq!(3000, rdata.refresh());
888 assert_eq!(300, rdata.retry());
889 assert_eq!(3600, rdata.expire());
890 assert_eq!(600, rdata.minimum());
891 }
892
893 #[test]
894 fn test_record_data_txt_new_exceeds_max_size() {
895 let segment = "a".repeat(255);
900 let data: Vec<String> = (0..256).map(|_| segment.clone()).collect();
901 let res = RecordDataTXT::new(data);
902
903 assert!(res.is_err());
904 }
905
906 #[test]
907 fn test_record_data_txt_new_success() {
908 let segment = "a".repeat(255);
909 let data: Vec<String> = (0..255).map(|_| segment.clone()).collect();
910 let txt = RecordDataTXT::new(data).unwrap();
911
912 assert_eq!(65280, txt.size());
913 }
914
915 #[test]
916 fn test_record_data_txt_size() {
917 let txt = RecordDataTXT::new(vec!["id=hello", "user=world"]).unwrap();
918 assert_eq!(20, txt.size());
919 }
920
921 #[rustfmt::skip]
922 #[test]
923 fn test_record_data_txt_write_network_bytes() {
924 let txt = RecordDataTXT::new(vec!["id=hello", "user=world"]).unwrap();
925 let mut cur = Cursor::new(Vec::new());
926 txt.write_network_bytes(&mut cur).unwrap();
927 let buf = cur.into_inner();
928
929 assert_eq!(
930 vec![
931 8, 105, 100, 61, 104, 101, 108, 108, 111, 10, 117, 115, 101, 114, 61, 119, 111, 114, 108, 100, ],
936 buf,
937 )
938 }
939
940 #[rustfmt::skip]
941 #[test]
942 fn test_record_data_txt_read_network_bytes() {
943 let bytes = vec![
944 8, 105, 100, 61, 104, 101, 108, 108, 111, 10, 117, 115, 101, 114, 61, 119, 111, 114, 108, 100, ];
949 let bytes_len = bytes.len() as u16;
950 let cur = Cursor::new(bytes);
951
952 let rdata = RecordDataTXT::read_network_bytes(bytes_len, cur).unwrap();
953 let contents = rdata.bytes();
954 assert_eq!("id=hello".as_bytes(), contents[0]);
955 assert_eq!("user=world".as_bytes(), contents[1]);
956 }
957
958 #[test]
959 fn test_record_data_aaaa_write_network_bytes() {
960 let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
961 let rdata = RecordDataAAAA::new(addr);
962
963 let mut cur = Cursor::new(Vec::new());
964 rdata.write_network_bytes(&mut cur).unwrap();
965 let buf = cur.into_inner();
966
967 assert_eq!(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], buf);
968 }
969
970 #[test]
971 fn test_record_data_aaaa_read_network_bytes() {
972 let cur = Cursor::new(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
973 let rdata = RecordDataAAAA::read_network_bytes(cur).unwrap();
974
975 assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), rdata.addr());
976 }
977
978 #[rustfmt::skip]
979 #[test]
980 fn test_record_data_srv_write_network_bytes() {
981 let srv = RecordDataSRV::new(100, 20, 11211, Name::from_str("_cache.example.com.").unwrap());
982 let mut cur = Cursor::new(Vec::new());
983 srv.write_network_bytes(&mut cur).unwrap();
984 let buf = cur.into_inner();
985
986 assert_eq!(
987 vec![
988 0, 100, 0, 20, 43, 203, 6, 95, 99, 97, 99, 104, 101, 7, 101, 120, 97, 109, 112, 108, 101, 3, 99, 111, 109, 0, ],
999 buf,
1000 )
1001 }
1002
1003 #[rustfmt::skip]
1004 #[test]
1005 fn test_record_data_srv_read_network_bytes() {
1006 let cur = Cursor::new(vec![
1007 0, 100, 0, 20, 43, 203, 6, 95, 99, 97, 99, 104, 101, 7, 101, 120, 97, 109, 112, 108, 101, 3, 99, 111, 109, 0, ]);
1018
1019 let rdata = RecordDataSRV::read_network_bytes(cur).unwrap();
1020 assert_eq!(100, rdata.priority());
1021 assert_eq!(20, rdata.weight());
1022 assert_eq!(11211, rdata.port());
1023 assert_eq!("_cache.example.com.", rdata.target().to_string());
1024 }
1025
1026 #[test]
1027 fn test_record_data_opt_pair_new_exceeds_max_size() {
1028 let res = RecordDataOptPair::new(0, "a".repeat(65536).into_bytes());
1029 assert!(res.is_err());
1030 }
1031
1032 #[test]
1033 fn test_record_data_opt_pair_new_success() {
1034 let opt = RecordDataOptPair::new(0, "a".repeat(100).into_bytes()).unwrap();
1035 assert_eq!(0, opt.code());
1036 assert_eq!(2 + 2 + 100, opt.size());
1037 }
1038
1039 #[test]
1040 fn test_record_data_opt_new_exceeds_max_size() {
1041 let opts = vec![
1042 RecordDataOptPair::new(0, "a".repeat(65535).into_bytes()).unwrap(),
1043 RecordDataOptPair::new(1, "a".repeat(65535).into_bytes()).unwrap(),
1044 ];
1045
1046 let res = RecordDataOpt::new(opts);
1047 assert!(res.is_err());
1048 }
1049
1050 #[test]
1051 fn test_record_data_opt_new_success() {
1052 let opts = vec![
1053 RecordDataOptPair::new(0, "a".repeat(100).into_bytes()).unwrap(),
1054 RecordDataOptPair::new(1, "a".repeat(100).into_bytes()).unwrap(),
1055 ];
1056
1057 let res = RecordDataOpt::new(opts).unwrap();
1058 assert_eq!(2 * (2 + 2 + 100), res.size());
1059 }
1060
1061 #[rustfmt::skip]
1062 #[test]
1063 fn test_record_data_opt_write_network_bytes() {
1064 let opt = RecordDataOpt::new(vec![RecordDataOptPair::new(1, "abc".as_bytes().to_vec()).unwrap()]).unwrap();
1065 let mut cur = Cursor::new(Vec::new());
1066 opt.write_network_bytes(&mut cur).unwrap();
1067 let buf = cur.into_inner();
1068
1069 assert_eq!(
1070 vec![
1071 0, 1, 0, 3, 97, 98, 99, ],
1075 buf,
1076 )
1077 }
1078
1079 #[rustfmt::skip]
1080 #[test]
1081 fn test_record_data_opt_read_network_bytes() {
1082 let cur = Cursor::new(vec![
1083 0, 1, 0, 3, 97, 98, 99, ]);
1087
1088 let rdata = RecordDataOpt::read_network_bytes(7, cur).unwrap();
1089 let options = rdata.options();
1090
1091 assert_eq!(
1092 RecordDataOptPair::new(1, "abc".as_bytes().to_vec()).unwrap(),
1093 options[0]
1094 );
1095 }
1096}