webrtc_mdns/message/
parser.rs

1use crate::error::*;
2use crate::message::header::{Header, HeaderInternal, Section};
3use crate::message::name::Name;
4use crate::message::question::Question;
5use crate::message::resource::{unpack_resource_body, Resource, ResourceBody, ResourceHeader};
6use 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)]
21pub 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
32impl<'a> Parser<'a> {
33    // start parses the header and enables the parsing of Questions.
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
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
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
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
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.
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.
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.
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.
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.
167    pub fn answer_header(&mut self) -> Result<ResourceHeader> {
168        self.resource_header(Section::Answers)
169    }
170
171    // answer parses a single answer Resource.
172    pub fn answer(&mut self) -> Result<Resource> {
173        self.resource(Section::Answers)
174    }
175
176    // all_answers parses all answer Resources.
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.
203    pub fn skip_answer(&mut self) -> Result<()> {
204        self.skip_resource(Section::Answers)
205    }
206
207    // skip_all_answers skips all answer Resources.
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.
221    pub fn authority_header(&mut self) -> Result<ResourceHeader> {
222        self.resource_header(Section::Authorities)
223    }
224
225    // authority parses a single authority Resource.
226    pub fn authority(&mut self) -> Result<Resource> {
227        self.resource(Section::Authorities)
228    }
229
230    // all_authorities parses all authority Resources.
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.
257    pub fn skip_authority(&mut self) -> Result<()> {
258        self.skip_resource(Section::Authorities)
259    }
260
261    // skip_all_authorities skips all authority Resources.
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.
275    pub fn additional_header(&mut self) -> Result<ResourceHeader> {
276        self.resource_header(Section::Additionals)
277    }
278
279    // additional parses a single additional Resource.
280    pub fn additional(&mut self) -> Result<Resource> {
281        self.resource(Section::Additionals)
282    }
283
284    // all_additionals parses all additional Resources.
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.
311    pub fn skip_additional(&mut self) -> Result<()> {
312        self.skip_resource(Section::Additionals)
313    }
314
315    // skip_all_additionals skips all additional Resources.
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.
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}