1use crate::{Buffer, DnsMessage, DnsMessageError, MutBuffer};
2use crate::name::DnsName;
3use crate::parse::Parse;
4use crate::rdata::{RData, RDataParse};
5use crate::write::WriteBytes;
6
7#[derive(Copy, Clone, Debug, PartialEq)]
11pub struct Soa<'a> {
12 pub mname: DnsName<'a>,
15 pub rname: DnsName<'a>,
18 pub serial: u32,
23 pub refresh: u32,
26 pub retry: u32,
29 pub expire: u32,
33 pub minimum: u32,
36}
37
38impl<'a> RDataParse<'a> for Soa<'a> {
39 #[inline]
40 fn parse(rdata: &RData<'a>, i: &mut usize) -> Result<Self, DnsMessageError> {
41 let mname = DnsName::parse(rdata.buffer, i)?;
42 let rname = DnsName::parse(rdata.buffer, i)?;
43 let serial = u32::parse(rdata.buffer, i)?;
44 let refresh = u32::parse(rdata.buffer, i)?;
45 let retry = u32::parse(rdata.buffer, i)?;
46 let expire = u32::parse(rdata.buffer, i)?;
47 let minimum = u32::parse(rdata.buffer, i)?;
48
49 Ok(Self {
50 mname,
51 rname,
52 serial,
53 refresh,
54 retry,
55 expire,
56 minimum,
57 })
58 }
59}
60
61impl<'a> WriteBytes for Soa<'a> {
62 #[inline]
63 fn write<
64 const PTR_STORAGE: usize,
65 const DNS_SECTION: usize,
66 B: MutBuffer + Buffer,
67 >(&self, message: &mut DnsMessage<PTR_STORAGE, DNS_SECTION, B>) -> Result<usize, DnsMessageError> {
68 let mut bytes = 0;
69
70 bytes += self.mname.write(message)?;
71 bytes += self.rname.write(message)?;
72 bytes += self.serial.write(message)?;
73 bytes += self.refresh.write(message)?;
74 bytes += self.retry.write(message)?;
75 bytes += self.expire.write(message)?;
76 bytes += self.minimum.write(message)?;
77
78 Ok(bytes)
79 }
80}
81
82#[cfg(test)]
83mod test {
84 use crate::rdata::testutils::parse_write_test;
85
86 use super::*;
87
88 parse_write_test!(
89 53,
90 [
91 0x03, b'w', b'w', b'w',
92 0x07, b'e', b'x', b'a', b'm', b'p', b'l', b'e',
93 0x03, b'c', b'o', b'm',
94 0x00, 0x03, b'w', b'w', b'w',
96 0x06, b'g', b'o', b'o', b'g', b'l', b'e',
97 0x03, b'c', b'o', b'm',
98 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, ],
105 Soa {
106 mname: unsafe { DnsName::new_unchecked(b"\x03www\x07example\x03com\x00") },
107 rname: unsafe { DnsName::new_unchecked(b"\x03www\x06google\x03com\x00") },
108 serial: 14,
109 refresh: 15,
110 retry: 16,
111 expire: 17,
112 minimum: 18,
113 },
114 );
115}