xref: /webrtc/mdns/src/message/parser.rs (revision ffe74184)
1 use crate::error::*;
2 use crate::message::header::{Header, HeaderInternal, Section};
3 use crate::message::name::Name;
4 use crate::message::question::Question;
5 use crate::message::resource::{unpack_resource_body, Resource, ResourceBody, ResourceHeader};
6 use crate::message::{DnsClass, DnsType};
7 
8 // A Parser allows incrementally parsing a DNS message.
9 //
10 // When parsing is started, the Header is parsed. Next, each question can be
11 // either parsed or skipped. Alternatively, all Questions can be skipped at
12 // once. When all Questions have been parsed, attempting to parse Questions
13 // will return (nil, nil) and attempting to skip Questions will return
14 // (true, nil). After all Questions have been either parsed or skipped, all
15 // Answers, Authorities and Additionals can be either parsed or skipped in the
16 // same way, and each type of Resource must be fully parsed or skipped before
17 // proceeding to the next type of Resource.
18 //
19 // Note that there is no requirement to fully skip or parse the message.
20 #[derive(Default)]
21 pub struct Parser<'a> {
22     pub msg: &'a [u8],
23     pub header: HeaderInternal,
24 
25     pub section: Section,
26     pub off: usize,
27     pub index: usize,
28     pub res_header_valid: bool,
29     pub res_header: ResourceHeader,
30 }
31 
32 impl<'a> Parser<'a> {
33     // start parses the header and enables the parsing of Questions.
start(&mut self, msg: &'a [u8]) -> Result<Header>34     pub fn start(&mut self, msg: &'a [u8]) -> Result<Header> {
35         *self = Parser {
36             msg,
37             ..Default::default()
38         };
39         self.off = self.header.unpack(msg, 0)?;
40         self.section = Section::Questions;
41         Ok(self.header.header())
42     }
43 
check_advance(&mut self, sec: Section) -> Result<()>44     fn check_advance(&mut self, sec: Section) -> Result<()> {
45         if self.section < sec {
46             return Err(Error::ErrNotStarted);
47         }
48         if self.section > sec {
49             return Err(Error::ErrSectionDone);
50         }
51         self.res_header_valid = false;
52         if self.index == self.header.count(sec) as usize {
53             self.index = 0;
54             self.section = Section::from(1 + self.section as u8);
55             return Err(Error::ErrSectionDone);
56         }
57         Ok(())
58     }
59 
resource(&mut self, sec: Section) -> Result<Resource>60     fn resource(&mut self, sec: Section) -> Result<Resource> {
61         let header = self.resource_header(sec)?;
62         self.res_header_valid = false;
63         let (body, off) =
64             unpack_resource_body(header.typ, self.msg, self.off, header.length as usize)?;
65         self.off = off;
66         self.index += 1;
67         Ok(Resource {
68             header,
69             body: Some(body),
70         })
71     }
72 
resource_header(&mut self, sec: Section) -> Result<ResourceHeader>73     fn resource_header(&mut self, sec: Section) -> Result<ResourceHeader> {
74         if self.res_header_valid {
75             return Ok(self.res_header.clone());
76         }
77         self.check_advance(sec)?;
78         let mut hdr = ResourceHeader::default();
79         let off = hdr.unpack(self.msg, self.off, 0)?;
80 
81         self.res_header_valid = true;
82         self.res_header = hdr.clone();
83         self.off = off;
84         Ok(hdr)
85     }
86 
skip_resource(&mut self, sec: Section) -> Result<()>87     fn skip_resource(&mut self, sec: Section) -> Result<()> {
88         if self.res_header_valid {
89             let new_off = self.off + self.res_header.length as usize;
90             if new_off > self.msg.len() {
91                 return Err(Error::ErrResourceLen);
92             }
93             self.off = new_off;
94             self.res_header_valid = false;
95             self.index += 1;
96             return Ok(());
97         }
98         self.check_advance(sec)?;
99 
100         self.off = Resource::skip(self.msg, self.off)?;
101         self.index += 1;
102         Ok(())
103     }
104 
105     // question parses a single question.
question(&mut self) -> Result<Question>106     pub fn question(&mut self) -> Result<Question> {
107         self.check_advance(Section::Questions)?;
108         let mut name = Name::new("")?;
109         let mut off = name.unpack(self.msg, self.off)?;
110         let mut typ = DnsType::Unsupported;
111         off = typ.unpack(self.msg, off)?;
112         let mut class = DnsClass::default();
113         off = class.unpack(self.msg, off)?;
114         self.off = off;
115         self.index += 1;
116         Ok(Question { name, typ, class })
117     }
118 
119     // all_questions parses all Questions.
all_questions(&mut self) -> Result<Vec<Question>>120     pub fn all_questions(&mut self) -> Result<Vec<Question>> {
121         // Multiple questions are valid according to the spec,
122         // but servers don't actually support them. There will
123         // be at most one question here.
124         //
125         // Do not pre-allocate based on info in self.header, since
126         // the data is untrusted.
127         let mut qs = vec![];
128         loop {
129             match self.question() {
130                 Err(err) => {
131                     if Error::ErrSectionDone == err {
132                         return Ok(qs);
133                     } else {
134                         return Err(err);
135                     }
136                 }
137                 Ok(q) => qs.push(q),
138             }
139         }
140     }
141 
142     // skip_question skips a single question.
skip_question(&mut self) -> Result<()>143     pub fn skip_question(&mut self) -> Result<()> {
144         self.check_advance(Section::Questions)?;
145         let mut off = Name::skip(self.msg, self.off)?;
146         off = DnsType::skip(self.msg, off)?;
147         off = DnsClass::skip(self.msg, off)?;
148         self.off = off;
149         self.index += 1;
150         Ok(())
151     }
152 
153     // skip_all_questions skips all Questions.
skip_all_questions(&mut self) -> Result<()>154     pub fn skip_all_questions(&mut self) -> Result<()> {
155         loop {
156             if let Err(err) = self.skip_question() {
157                 if Error::ErrSectionDone == err {
158                     return Ok(());
159                 } else {
160                     return Err(err);
161                 }
162             }
163         }
164     }
165 
166     // answer_header parses a single answer ResourceHeader.
answer_header(&mut self) -> Result<ResourceHeader>167     pub fn answer_header(&mut self) -> Result<ResourceHeader> {
168         self.resource_header(Section::Answers)
169     }
170 
171     // answer parses a single answer Resource.
answer(&mut self) -> Result<Resource>172     pub fn answer(&mut self) -> Result<Resource> {
173         self.resource(Section::Answers)
174     }
175 
176     // all_answers parses all answer Resources.
all_answers(&mut self) -> Result<Vec<Resource>>177     pub fn all_answers(&mut self) -> Result<Vec<Resource>> {
178         // The most common query is for A/AAAA, which usually returns
179         // a handful of IPs.
180         //
181         // Pre-allocate up to a certain limit, since self.header is
182         // untrusted data.
183         let mut n = self.header.answers as usize;
184         if n > 20 {
185             n = 20
186         }
187         let mut a = Vec::with_capacity(n);
188         loop {
189             match self.answer() {
190                 Err(err) => {
191                     if Error::ErrSectionDone == err {
192                         return Ok(a);
193                     } else {
194                         return Err(err);
195                     }
196                 }
197                 Ok(r) => a.push(r),
198             }
199         }
200     }
201 
202     // skip_answer skips a single answer Resource.
skip_answer(&mut self) -> Result<()>203     pub fn skip_answer(&mut self) -> Result<()> {
204         self.skip_resource(Section::Answers)
205     }
206 
207     // skip_all_answers skips all answer Resources.
skip_all_answers(&mut self) -> Result<()>208     pub fn skip_all_answers(&mut self) -> Result<()> {
209         loop {
210             if let Err(err) = self.skip_answer() {
211                 if Error::ErrSectionDone == err {
212                     return Ok(());
213                 } else {
214                     return Err(err);
215                 }
216             }
217         }
218     }
219 
220     // authority_header parses a single authority ResourceHeader.
authority_header(&mut self) -> Result<ResourceHeader>221     pub fn authority_header(&mut self) -> Result<ResourceHeader> {
222         self.resource_header(Section::Authorities)
223     }
224 
225     // authority parses a single authority Resource.
authority(&mut self) -> Result<Resource>226     pub fn authority(&mut self) -> Result<Resource> {
227         self.resource(Section::Authorities)
228     }
229 
230     // all_authorities parses all authority Resources.
all_authorities(&mut self) -> Result<Vec<Resource>>231     pub fn all_authorities(&mut self) -> Result<Vec<Resource>> {
232         // Authorities contains SOA in case of NXDOMAIN and friends,
233         // otherwise it is empty.
234         //
235         // Pre-allocate up to a certain limit, since self.header is
236         // untrusted data.
237         let mut n = self.header.authorities as usize;
238         if n > 10 {
239             n = 10;
240         }
241         let mut a = Vec::with_capacity(n);
242         loop {
243             match self.authority() {
244                 Err(err) => {
245                     if Error::ErrSectionDone == err {
246                         return Ok(a);
247                     } else {
248                         return Err(err);
249                     }
250                 }
251                 Ok(r) => a.push(r),
252             }
253         }
254     }
255 
256     // skip_authority skips a single authority Resource.
skip_authority(&mut self) -> Result<()>257     pub fn skip_authority(&mut self) -> Result<()> {
258         self.skip_resource(Section::Authorities)
259     }
260 
261     // skip_all_authorities skips all authority Resources.
skip_all_authorities(&mut self) -> Result<()>262     pub fn skip_all_authorities(&mut self) -> Result<()> {
263         loop {
264             if let Err(err) = self.skip_authority() {
265                 if Error::ErrSectionDone == err {
266                     return Ok(());
267                 } else {
268                     return Err(err);
269                 }
270             }
271         }
272     }
273 
274     // additional_header parses a single additional ResourceHeader.
additional_header(&mut self) -> Result<ResourceHeader>275     pub fn additional_header(&mut self) -> Result<ResourceHeader> {
276         self.resource_header(Section::Additionals)
277     }
278 
279     // additional parses a single additional Resource.
additional(&mut self) -> Result<Resource>280     pub fn additional(&mut self) -> Result<Resource> {
281         self.resource(Section::Additionals)
282     }
283 
284     // all_additionals parses all additional Resources.
all_additionals(&mut self) -> Result<Vec<Resource>>285     pub fn all_additionals(&mut self) -> Result<Vec<Resource>> {
286         // Additionals usually contain OPT, and sometimes A/AAAA
287         // glue records.
288         //
289         // Pre-allocate up to a certain limit, since self.header is
290         // untrusted data.
291         let mut n = self.header.additionals as usize;
292         if n > 10 {
293             n = 10;
294         }
295         let mut a = Vec::with_capacity(n);
296         loop {
297             match self.additional() {
298                 Err(err) => {
299                     if Error::ErrSectionDone == err {
300                         return Ok(a);
301                     } else {
302                         return Err(err);
303                     }
304                 }
305                 Ok(r) => a.push(r),
306             }
307         }
308     }
309 
310     // skip_additional skips a single additional Resource.
skip_additional(&mut self) -> Result<()>311     pub fn skip_additional(&mut self) -> Result<()> {
312         self.skip_resource(Section::Additionals)
313     }
314 
315     // skip_all_additionals skips all additional Resources.
skip_all_additionals(&mut self) -> Result<()>316     pub fn skip_all_additionals(&mut self) -> Result<()> {
317         loop {
318             if let Err(err) = self.skip_additional() {
319                 if Error::ErrSectionDone == err {
320                     return Ok(());
321                 } else {
322                     return Err(err);
323                 }
324             }
325         }
326     }
327 
328     // resource_body parses a single resource_boy.
329     //
330     // One of the XXXHeader methods must have been called before calling this
331     // method.
resource_body(&mut self) -> Result<Box<dyn ResourceBody>>332     pub fn resource_body(&mut self) -> Result<Box<dyn ResourceBody>> {
333         if !self.res_header_valid {
334             return Err(Error::ErrNotStarted);
335         }
336         let (rb, _off) = unpack_resource_body(
337             self.res_header.typ,
338             self.msg,
339             self.off,
340             self.res_header.length as usize,
341         )?;
342         self.off += self.res_header.length as usize;
343         self.res_header_valid = false;
344         self.index += 1;
345         Ok(rb)
346     }
347 }
348