1use crate::{Buffer, DnsMessage, DnsMessageError, MutBuffer};
2use crate::answer::DnsAClass;
3use crate::name::DnsName;
4use crate::parse::{Parse, ParseBytes};
5use crate::question::DnsQType;
6use crate::rdata::{DnsAType, RData};
7use crate::write::WriteBytes;
8
9pub struct DnsNameServers<
11 const PTR_STORAGE: usize,
12 B: Buffer,
13> {
14 message: DnsMessage<PTR_STORAGE, 2, B>,
15 remaining: usize,
16}
17
18impl<
19 const PTR_STORAGE: usize,
20 B: Buffer,
21> DnsNameServers<PTR_STORAGE, B> {
22 #[inline(always)]
23 pub(crate) fn new(message: DnsMessage<PTR_STORAGE, 2, B>) -> Self {
24 let remaining = message.header().unwrap().answer_count() as usize;
25 Self {
26 message,
27 remaining,
28 }
29 }
30
31 #[inline(always)]
33 pub fn iter(&mut self) -> Result<DnsNameServersIterator, DnsMessageError> {
34 let (bytes, position) = self.message.bytes_and_position();
35
36 Ok(DnsNameServersIterator {
37 buffer: bytes,
38 current_position: position,
39 remaining: &mut self.remaining,
40 })
41 }
42
43 #[inline(always)]
46 pub fn complete(mut self) -> Result<DnsMessage<PTR_STORAGE, 3, B>, DnsMessageError> {
47 if self.remaining != 0 {
48 for x in self.iter()? { x?; }
49 }
50
51 Ok(DnsMessage {
52 buffer: self.message.buffer,
53 position: self.message.position,
54 ptr_storage: self.message.ptr_storage,
55 ptr_len: self.message.ptr_len,
56 })
57 }
58}
59
60impl<
61 const PTR_STORAGE: usize,
62 B: MutBuffer + Buffer,
63> DnsNameServers<PTR_STORAGE, B> {
64 pub fn append(&mut self, answer: NameServer<DnsAType>) -> Result<(), DnsMessageError> {
67 self.message.truncate()?;
69 answer.write(&mut self.message)?;
70 let answer_count = self.message.header().unwrap().answer_count();
72 let answer_count = answer_count + 1 - self.remaining as u16;
73 self.message.header_mut()?.set_answer_count(answer_count);
74 self.message.header_mut()?.set_name_server_count(0);
75 self.message.header_mut()?.set_additional_records_count(0);
76 self.remaining = 0;
77
78 Ok(())
79 }
80}
81
82pub struct DnsNameServersIterator<'a> {
84 buffer: &'a [u8],
85 current_position: &'a mut usize,
86 remaining: &'a mut usize,
87}
88
89impl<'a> Iterator for DnsNameServersIterator<'a> {
90 type Item = Result<NameServer<'a, RData<'a>>, DnsMessageError>;
91
92 #[inline]
93 fn next(&mut self) -> Option<Self::Item> {
94 if *self.remaining == 0 {
95 return None;
96 }
97
98 let name_server = NameServer::parse(
99 self.buffer, self.current_position
100 );
101 *self.remaining -= 1;
102
103 Some(name_server)
104 }
105}
106
107#[derive(Debug, PartialEq)]
109pub struct NameServer<'a, D> {
110 pub name: DnsName<'a>,
112 pub rdata: D,
114 pub cache_flush: bool,
116 pub aclass: DnsAClass,
118 pub ttl: u32,
120}
121
122impl<'a> NameServer<'a, RData<'a>> {
123 #[inline(always)]
125 pub fn into_parsed(self) -> Result<NameServer<'a, DnsAType<'a>>, DnsMessageError> {
126 Ok(NameServer {
127 name: self.name,
128 rdata: self.rdata.into_parsed()?,
129 cache_flush: self.cache_flush,
130 aclass: self.aclass,
131 ttl: self.ttl,
132 })
133 }
134}
135
136impl<'a> ParseBytes<'a> for NameServer<'a, RData<'a>> {
137 fn parse_bytes(bytes: &'a [u8], i: &mut usize) -> Result<Self, DnsMessageError> {
138 let name = DnsName::parse(bytes, i)?;
139 let atype_id = u16::parse(bytes, i)?;
140 let atype = DnsQType::from_id(atype_id);
141 let cache_flush = atype_id & 0b1000_0000_0000_0000 != 0;
142 let aclass = DnsAClass::from_id(u16::parse(bytes, i)?);
143 let ttl = u32::parse(bytes, i)?;
144 let rdata = RData::parse(bytes, i, atype)?;
145
146 Ok(Self {
147 name,
148 rdata,
149 cache_flush,
150 aclass,
151 ttl,
152 })
153 }
154}
155
156impl<'a> WriteBytes for NameServer<'a, DnsAType<'a>> {
157 fn write<
158 const PTR_STORAGE: usize,
159 const DNS_SECTION: usize,
160 B: MutBuffer + Buffer,
161 >(&self, message: &mut DnsMessage<PTR_STORAGE, DNS_SECTION, B>) -> Result<usize, DnsMessageError> {
162 let mut bytes = 0;
163 bytes += self.name.write(message)?;
165 bytes += self.rdata.id().write(message)?;
167 let mut aclass = self.aclass.id();
168 if self.cache_flush {
169 aclass |= 0b1000_0000;
170 }
171 bytes += aclass.write(message)?;
172 bytes += self.ttl.write(message)?;
174 let rdata_len_placeholder = message.write_placeholder::<2>()?;
175 let rdata_len = self.rdata.write(message)?;
177 bytes += rdata_len;
178 bytes += rdata_len_placeholder(message, (rdata_len as u16).to_be_bytes());
179
180 Ok(bytes)
181 }
182}