domain/base/
message.rs

1//! Accessing existing DNS messages.
2//!
3//! This module defines a number of types for processing the content of a DNS
4//! message in wire format. Because many components of the message are of
5//! varying length, this can only be done iteratively. The type [`Message`]
6//! wraps an octets sequence containing a complete message. It provides access
7//! to the four sections of the message via additional types.
8//!
9//! For details, see the [`Message`] type.
10//!
11//! [`Message`]: struct.Message.html
12
13use super::header::{Header, HeaderCounts, HeaderSection};
14use super::iana::{Class, Rcode, Rtype};
15use super::message_builder::{AdditionalBuilder, AnswerBuilder, PushError};
16use super::name::ParsedDname;
17use super::opt::{Opt, OptRecord};
18use super::question::Question;
19use super::rdata::ParseRecordData;
20use super::record::{ComposeRecord, ParsedRecord, Record};
21use super::wire::{Composer, ParseError};
22use crate::rdata::rfc1035::Cname;
23use core::marker::PhantomData;
24use core::{fmt, mem};
25use octseq::{Octets, OctetsFrom, Parser};
26
27//------------ Message -------------------------------------------------------
28
29/// A DNS message.
30///
31/// This type wraps an octets sequence containing the complete wire-format DNS
32/// message and allows access to the various components of the message.
33///
34/// You create a message by passing an octets sequence to the [`from_octets`]
35/// associate function which does some basic sanity checks and, if they
36/// succeed, returns a message for the sequence. All further parsing happens
37/// lazily when you access more of the message. This means that a message is
38/// not necessarily well-formatted and further parsing may fail later on.
39///
40/// Section 4 of [RFC 1035] defines DNS messages as being divded into five
41/// sections named header, question, answer, authority, and additional.
42///
43/// The header section is of a fixed sized and can be accessed at any time
44/// through the methods given under [Header Section]. Most likely, you will
45/// be interested in the first part of the header which is
46/// returned by the [`header`] method.  The second part of the header
47/// section contains the number of entries in the following four sections
48/// and is of less interest as there are more sophisticated ways of accessing
49/// these sections. If you do care, you can get access through
50/// [`header_counts`].
51///
52/// The meaning of the next four sections depends on the type of message as
53/// described by the [opcode] field of the header. Since the most common
54/// type is a query, the sections are named after their function in this type
55/// and the following description will focus on it.
56///
57/// The question section contains what was asked of the DNS by a query. It
58/// contains a number of questions that consist of a domain name, a record
59/// type, and class. A query asks for all records of the given record type
60/// that are owned by the domain name within the class. In queries, there will
61/// be exactly one question. With other opcodes, there may be multiple
62/// questions.
63///
64/// You can acquire an iterator over the questions through the [`question`]
65/// method. It returns a [`QuestionSection`] value that is an iterator over
66/// questions. Since a single question is such a common case, there is a
67/// convenience method [`first_question`] that returns the first question
68/// only.
69///
70/// The following three section all contain DNS resource records. In
71/// queries, they are empty in a request and may or may not contain records
72/// in a response. The *answer* section contains all the records that answer
73/// the given question. The *authority* section contains records declaring
74/// which name server provided authoritative information for the question,
75/// and the *additional* section can contain records that the name server
76/// thought might be useful for processing the question. For instance, if you
77/// trying to find out the mail server of a domain by asking for MX records,
78/// you likely also want the IP addresses for the server, so the name server
79/// may include these right away and free of charge.
80///
81/// There are functions to access all three sections directly: [`answer`],
82/// [`authority`], and [`additional`]. Each method returns a value of type
83/// [RecordSection] which acts as an iterator over the records in the
84/// section. Since there are no pointers to where the later sections start,
85/// accessing them directly means iterating over the previous sections. This
86/// is why it is more efficitent to call [`RecordSection::next_section`] to
87/// progress to a later section. Alternatively, you can use the message’s
88/// [`sections`] method that gives you all four sections at once with the
89/// minimal amount of iterating necessary.
90///
91/// When iterating over the record section, you will receive values of type
92/// [`ParsedRecord`], an intermediary type that only parsed the parts common
93/// to all records. In order to access the data of the record, you will want
94/// to convert it into a [`Record`] which is generic over the actual record
95/// type data. This can be done via [`ParsedRecord::into_record`].
96///
97/// Alternatively, you can trade the record section for one that only returns
98/// the types you are interested in via the [`RecordSection::limit_to`]
99/// method. The iterator returned by that method will quietly skip over all
100/// records that aren’t of the type you are interested in.
101///
102/// So, if you want to iterate over the MX records in the answer section, you
103/// would do something like this:
104///
105/// ```
106/// use domain::base::Message;
107/// use domain::rdata::Mx;
108///
109/// # let octets = vec![0; 12];
110/// let msg = Message::from_octets(octets).unwrap();
111/// for record in msg.answer().unwrap().limit_to::<Mx<_>>() {
112///     if let Ok(record) = record {
113///         // Do something with the record ...
114///     }
115/// }
116/// ```
117///
118/// The `limit_to` method takes the record type as a type argument. Many
119/// record types, like [`Mx`], are generic over octet sequences but the
120/// compiler generally can figure out the concrete type itself, so in most
121/// cases you get away with the underscore there.
122///
123/// Note how the iterator doesn’t actually return records but results of
124/// records and parse errors. This is because only now can it check whether
125/// the record is actually properly formatted. An error signals that something
126/// went wrong while parsing. If only the record data is broken, the message
127/// remains useful and parsing can continue with the next record. If the
128/// message is fully broken, the next iteration will return `None` to signal
129/// that.
130///
131/// [`additional`]: #method.additional
132/// [`answer`]: #method.answer
133/// [`authority`]: #method.authority
134/// [`first_question`]: #method.first_question
135/// [`from_octets`]: #method.from_octets
136/// [`header`]: #method.header
137/// [`header_counts`]: #method.header_counts
138/// [`question`]: #method.question
139/// [`sections`]: #method.sections
140/// [`Mx`]: ../../rdata/rfc1035/struct.Mx.html
141/// [`ParsedRecord`]: ../record/struct.ParsedRecord.html
142/// [`ParsedRecord::into_record`]: ../record/struct.ParsedRecord.html#method.into_record
143/// [`QuestionSection`]: struct.QuestionSection.html
144/// [`Record`]: ../record/struct.Record.html
145/// [`RecordSection`]: struct.RecordSection.html
146/// [`RecordSection::limit_to`]: ../struct.RecordSection.html#method.limit_to
147/// [`RecordSection::next_section`]: ../struct.RecordSection.html#method.next_section
148/// [Header Section]: #header-section
149/// [rdata]: ../../rdata/index.html
150/// [opcode]: ../iana/opcode/enum.Opcode.html
151/// [RFC 1035]: https://tools.ietf.org/html/rfc1035
152#[derive(Clone, Copy)]
153pub struct Message<Octs: ?Sized> {
154    octets: Octs,
155}
156
157/// # Creation and Conversion
158///
159impl<Octs> Message<Octs> {
160    /// Creates a message from an octets sequence.
161    ///
162    /// This fails if the slice is too short to even contain a complete
163    /// header section.  No further checks are done, though, so if this
164    /// function returns ok, the message may still be broken with other
165    /// methods returning errors later one.
166    pub fn from_octets(octets: Octs) -> Result<Self, ShortMessage>
167    where
168        Octs: AsRef<[u8]>,
169    {
170        Message::check_slice(octets.as_ref())?;
171        Ok(unsafe { Self::from_octets_unchecked(octets) })
172    }
173
174    /// Creates a message from a bytes value without checking.
175    ///
176    /// # Safety
177    ///
178    /// The methods for header access rely on the octets being at least as
179    /// long as a header. If the sequence is shorter, the behavior is
180    /// undefined.
181    pub(super) unsafe fn from_octets_unchecked(octets: Octs) -> Self {
182        Message { octets }
183    }
184}
185
186impl Message<[u8]> {
187    /// Creates a message from an octets slice.
188    ///
189    /// This fails if the slice is too short to even contain a complete
190    /// header section.  No further checks are done, though, so if this
191    /// function returns ok, the message may still be broken with other
192    /// methods returning errors later one.
193    pub fn from_slice(slice: &[u8]) -> Result<&Self, ShortMessage> {
194        Message::check_slice(slice)?;
195        Ok(unsafe { Self::from_slice_unchecked(slice) })
196    }
197
198    /// Creates a message from a bytes value without checking.
199    ///
200    /// # Safety
201    ///
202    /// The methods for header access rely on the octets being at least as
203    /// long as a header. If the sequence is shorter, the behavior is
204    /// undefined.
205    unsafe fn from_slice_unchecked(slice: &[u8]) -> &Self {
206        &*(slice as *const [u8] as *const Self)
207    }
208
209    /// Checks that the slice can be used for a message.
210    fn check_slice(slice: &[u8]) -> Result<(), ShortMessage> {
211        if slice.len() < mem::size_of::<HeaderSection>() {
212            Err(ShortMessage(()))
213        } else {
214            Ok(())
215        }
216    }
217}
218
219impl<Octs: ?Sized> Message<Octs> {
220    /// Returns a reference to the underlying octets sequence.
221    pub fn as_octets(&self) -> &Octs {
222        &self.octets
223    }
224
225    /// Converts the message into the underlying octets sequence.
226    pub fn into_octets(self) -> Octs
227    where
228        Octs: Sized,
229    {
230        self.octets
231    }
232
233    /// Returns a slice to the underlying octets sequence.
234    pub fn as_slice(&self) -> &[u8]
235    where
236        Octs: AsRef<[u8]>,
237    {
238        self.octets.as_ref()
239    }
240
241    /// Returns a mutable slice to the underlying octets sequence.
242    ///
243    /// Because it is possible to utterly break the message using this slice,
244    /// the method is private.
245    fn as_slice_mut(&mut self) -> &mut [u8]
246    where
247        Octs: AsMut<[u8]>,
248    {
249        self.octets.as_mut()
250    }
251
252    /// Returns a message for a slice of the octets sequence.
253    pub fn for_slice(&self) -> &Message<[u8]>
254    where
255        Octs: AsRef<[u8]>,
256    {
257        unsafe { Message::from_slice_unchecked(self.octets.as_ref()) }
258    }
259}
260
261/// # Header Section
262///
263impl<Octs: AsRef<[u8]> + ?Sized> Message<Octs> {
264    /// Returns the message header.
265    pub fn header(&self) -> Header {
266        *Header::for_message_slice(self.as_slice())
267    }
268
269    /// Returns a mutable reference to the message header.
270    pub fn header_mut(&mut self) -> &mut Header
271    where
272        Octs: AsMut<[u8]>,
273    {
274        Header::for_message_slice_mut(self.as_slice_mut())
275    }
276
277    /// Returns the header counts of the message.
278    pub fn header_counts(&self) -> HeaderCounts {
279        *HeaderCounts::for_message_slice(self.as_slice())
280    }
281
282    /// Returns the entire header section.
283    pub fn header_section(&self) -> HeaderSection {
284        *HeaderSection::for_message_slice(self.as_slice())
285    }
286
287    /// Returns whether the rcode of the header is NoError.
288    pub fn no_error(&self) -> bool {
289        self.header().rcode() == Rcode::NoError
290    }
291
292    /// Returns whether the rcode of the header is one of the error values.
293    pub fn is_error(&self) -> bool {
294        self.header().rcode() != Rcode::NoError
295    }
296}
297
298/// # Access to Sections
299///
300impl<Octs: Octets + ?Sized> Message<Octs> {
301    /// Returns the question section.
302    pub fn question(&self) -> QuestionSection<'_, Octs> {
303        QuestionSection::new(&self.octets)
304    }
305
306    /// Returns the zone section of an UPDATE message.
307    ///
308    /// This is identical to `self.question()`.
309    pub fn zone(&self) -> QuestionSection<'_, Octs> {
310        self.question()
311    }
312
313    /// Returns the answer section.
314    ///
315    /// Iterates over the question section in order to access the answer
316    /// section. If you are accessing the question section anyway, using
317    /// its [`next_section`] method may be more efficient.
318    ///
319    /// [`next_section`]: ../struct.QuestionSection.html#method.next_section
320    pub fn answer(&self) -> Result<RecordSection<'_, Octs>, ParseError> {
321        self.question().next_section()
322    }
323
324    /// Returns the prerequisite section of an UPDATE message.
325    ///
326    /// This is identical to `self.answer()`.
327    pub fn prerequisite(
328        &self,
329    ) -> Result<RecordSection<'_, Octs>, ParseError> {
330        self.answer()
331    }
332
333    /// Returns the authority section.
334    ///
335    /// Iterates over both the question and the answer sections to determine
336    /// the start of the authority section. If you are already accessing the
337    /// answer section, using [`next_section`] on it is more efficient.
338    ///
339    /// [`next_section`]: ../struct.RecordSection.html#method.next_section
340    pub fn authority(&self) -> Result<RecordSection<'_, Octs>, ParseError> {
341        Ok(self.answer()?.next_section()?.unwrap())
342    }
343
344    /// Returns the update section of an UPDATE message.
345    ///
346    /// This is identical to `self.authority()`.
347    pub fn update(&self) -> Result<RecordSection<'_, Octs>, ParseError> {
348        self.authority()
349    }
350
351    /// Returns the additional section.
352    ///
353    /// Iterates over all three previous sections to determine the start of
354    /// the additional section. If you are already accessing the
355    /// authority section, using [`next_section`] on it is more efficient.
356    ///
357    /// [`next_section`]: ../struct.RecordSection.html#method.next_section
358    pub fn additional(&self) -> Result<RecordSection<'_, Octs>, ParseError> {
359        Ok(self.authority()?.next_section()?.unwrap())
360    }
361
362    /// Returns all four sections in one fell swoop.
363    #[allow(clippy::type_complexity)]
364    pub fn sections(
365        &self,
366    ) -> Result<
367        (
368            QuestionSection<'_, Octs>,
369            RecordSection<'_, Octs>,
370            RecordSection<'_, Octs>,
371            RecordSection<'_, Octs>,
372        ),
373        ParseError,
374    > {
375        let question = self.question();
376        let answer = question.next_section()?;
377        let authority = answer.next_section()?.unwrap();
378        let additional = authority.next_section()?.unwrap();
379        Ok((question, answer, authority, additional))
380    }
381
382    /// Returns an iterator over the records in the message.
383    ///
384    /// The iterator’s item is a pair of a [`ParsedRecord`] and the
385    /// [`Section`] it was found in.
386    ///
387    /// As is customary, this iterator is also accessible via the
388    /// `IntoIterator` trait on a reference to the message.
389    ///
390    /// [`ParsedRecord`]: ../record/struct.ParsedRecord.html
391    /// [`Section`]: enum.Section.html
392    pub fn iter(&self) -> MessageIter<'_, Octs> {
393        self.into_iter()
394    }
395}
396
397/// # Helpers for Common Tasks
398///
399impl<Octs: Octets + ?Sized> Message<Octs> {
400    /// Returns whether this is the answer to some other message.
401    ///
402    /// The method checks whether the ID fields of the headers are the same,
403    /// whether the QR flag is set in this message, and whether the questions
404    /// are the same.
405    pub fn is_answer<Other: Octets>(&self, query: &Message<Other>) -> bool {
406        if !self.header().qr()
407            || self.header().id() != query.header().id()
408            || self.header_counts().qdcount()
409                != query.header_counts().qdcount()
410        {
411            false
412        } else {
413            self.question() == query.question()
414        }
415    }
416
417    /// Returns the first question, if there is any.
418    ///
419    /// The method will return `None` both if there are no questions or if
420    /// parsing fails.
421    pub fn first_question(
422        &self,
423    ) -> Option<Question<ParsedDname<Octs::Range<'_>>>> {
424        match self.question().next() {
425            None | Some(Err(..)) => None,
426            Some(Ok(question)) => Some(question),
427        }
428    }
429
430    /// Returns the sole question of the message.
431    ///
432    /// This is like [`first_question`] but returns an error if there isn’t
433    /// exactly one question or there is a parse error.
434    ///
435    /// [`first_question`]: #method.first_question
436    pub fn sole_question(
437        &self,
438    ) -> Result<Question<ParsedDname<Octs::Range<'_>>>, ParseError> {
439        match self.header_counts().qdcount() {
440            0 => return Err(ParseError::form_error("no question")),
441            1 => {}
442            _ => return Err(ParseError::form_error("multiple questions")),
443        }
444        self.question().next().unwrap()
445    }
446
447    /// Returns the query type of the first question, if any.
448    pub fn qtype(&self) -> Option<Rtype> {
449        self.first_question().map(|x| x.qtype())
450    }
451
452    /// Returns whether the message contains answers of a given type.
453    pub fn contains_answer<'s, Data>(&'s self) -> bool
454    where
455        Data: ParseRecordData<'s, Octs>,
456    {
457        let answer = match self.answer() {
458            Ok(answer) => answer,
459            Err(..) => return false,
460        };
461        answer.limit_to::<Data>().next().is_some()
462    }
463
464    /// Resolves the canonical name of the answer.
465    ///
466    /// The CNAME record allows a domain name to be an alias for a different
467    /// name. Aliases may be chained. The ‘canonical name’ referred to be the
468    /// method’s name is the last name in this chain. A recursive resolver
469    /// will support a stub resolver in figuring out this canonical name by
470    /// including all necessary CNAME records in its answer. This method can
471    /// be used on such an answer to determine the canonical name. As such,
472    /// it will only consider CNAMEs present in the message’s answer section.
473    ///
474    /// It starts with the question name and follows CNAME records until there
475    /// is no next CNAME in the chain and then returns the last CNAME.
476    ///
477    /// If the message doesn’t have a question, if there is a parse error, or
478    /// if there is a CNAME loop the method returns `None`.
479    //
480    //  Loop detection is done by breaking off after ANCOUNT + 1 steps -- if
481    //  there is more steps then there is records in the answer section we
482    //  must have a loop. While the ANCOUNT could be unreasonably large, the
483    //  iterator would break off in this case and we break out with a None
484    //  right away.
485    pub fn canonical_name(&self) -> Option<ParsedDname<Octs::Range<'_>>> {
486        let question = match self.first_question() {
487            None => return None,
488            Some(question) => question,
489        };
490        let mut name = question.into_qname();
491        let answer = match self.answer() {
492            Ok(answer) => answer.limit_to::<Cname<_>>(),
493            Err(_) => return None,
494        };
495
496        for _ in 0..self.header_counts().ancount() + 1 {
497            let mut found = false;
498            for record in answer.clone() {
499                let record = match record {
500                    Ok(record) => record,
501                    Err(_) => continue,
502                };
503                if *record.owner() == name {
504                    name = record.into_data().into_cname();
505                    found = true;
506                    break;
507                }
508            }
509            if !found {
510                return Some(name);
511            }
512        }
513
514        None
515    }
516
517    /// Returns the OPT record from the message, if there is one.
518    pub fn opt(&self) -> Option<OptRecord<Octs::Range<'_>>> {
519        match self.additional() {
520            Ok(section) => match section.limit_to::<Opt<_>>().next() {
521                Some(Ok(rr)) => Some(OptRecord::from(rr)),
522                _ => None,
523            },
524            Err(_) => None,
525        }
526    }
527
528    /// Returns the last additional record from the message.
529    ///
530    /// The method tries to parse the last record of the additional section
531    /// as the provided record type. If that succeeds, it returns that
532    /// parsed record.
533    ///
534    /// If the last record is of the wrong type or parsing fails, returns
535    /// `None`.
536    pub fn get_last_additional<'s, Data: ParseRecordData<'s, Octs>>(
537        &'s self,
538    ) -> Option<Record<ParsedDname<Octs::Range<'s>>, Data>> {
539        let mut section = match self.additional() {
540            Ok(section) => section,
541            Err(_) => return None,
542        };
543        loop {
544            match section.count {
545                Err(_) => return None,
546                Ok(0) => return None,
547                Ok(1) => break,
548                _ => {}
549            }
550            let _ = section.next();
551        }
552        let record = match ParsedRecord::parse(&mut section.parser) {
553            Ok(record) => record,
554            Err(_) => return None,
555        };
556        let record = match record.into_record() {
557            Ok(Some(record)) => record,
558            _ => return None,
559        };
560        Some(record)
561    }
562
563    /// Drops the last additional record from the message.
564    ///
565    /// Does so by decreasing the ’arcount.’ Does, however, not change the
566    /// underlying octet sequence.
567    ///
568    /// # Panics
569    ///
570    /// The method panics if the additional section is empty.
571    pub fn remove_last_additional(&mut self)
572    where
573        Octs: AsMut<[u8]>,
574    {
575        HeaderCounts::for_message_slice_mut(self.octets.as_mut())
576            .dec_arcount();
577    }
578
579    /// Copy records from a message into the target message builder.
580    ///
581    /// The method uses `op` to process records from all record sections
582    /// before inserting, caller can use this closure to filter or manipulate
583    /// records before inserting.
584    pub fn copy_records<'s, R, F, T, O>(
585        &'s self,
586        target: T,
587        mut op: F,
588    ) -> Result<AdditionalBuilder<O>, CopyRecordsError>
589    where
590        Octs: Octets,
591        R: ComposeRecord + 's,
592        F: FnMut(ParsedRecord<'s, Octs>) -> Option<R>,
593        T: Into<AnswerBuilder<O>>,
594        O: Composer,
595    {
596        let mut source = self.answer()?;
597        let mut target = target.into();
598        for rr in &mut source {
599            let rr = rr?;
600            if let Some(rr) = op(rr) {
601                target.push(rr).map_err(CopyRecordsError::Push)?;
602            }
603        }
604
605        let mut source = source.next_section()?.unwrap();
606        let mut target = target.authority();
607        for rr in &mut source {
608            let rr = rr?;
609            if let Some(rr) = op(rr) {
610                target.push(rr).map_err(CopyRecordsError::Push)?;
611            }
612        }
613
614        let source = source.next_section()?.unwrap();
615        let mut target = target.additional();
616        for rr in source {
617            let rr = rr?;
618            if let Some(rr) = op(rr) {
619                target.push(rr).map_err(CopyRecordsError::Push)?;
620            }
621        }
622
623        Ok(target)
624    }
625}
626
627//--- AsRef
628
629// Octs here can’t be ?Sized or it’ll conflict with AsRef<[u8]> below.
630// But [u8] is covered by that impl anyway, so no harm done.
631//
632impl<Octs> AsRef<Octs> for Message<Octs> {
633    fn as_ref(&self) -> &Octs {
634        &self.octets
635    }
636}
637
638impl<Octs: AsRef<[u8]> + ?Sized> AsRef<[u8]> for Message<Octs> {
639    fn as_ref(&self) -> &[u8] {
640        self.octets.as_ref()
641    }
642}
643
644impl<Octs: AsRef<[u8]> + ?Sized> AsRef<Message<[u8]>> for Message<Octs> {
645    fn as_ref(&self) -> &Message<[u8]> {
646        unsafe { Message::from_slice_unchecked(self.octets.as_ref()) }
647    }
648}
649
650//--- OctetsFrom
651
652impl<Octs, SrcOcts> OctetsFrom<Message<SrcOcts>> for Message<Octs>
653where
654    Octs: OctetsFrom<SrcOcts>,
655{
656    type Error = Octs::Error;
657
658    fn try_octets_from(
659        source: Message<SrcOcts>,
660    ) -> Result<Self, Self::Error> {
661        Octs::try_octets_from(source.octets)
662            .map(|octets| unsafe { Self::from_octets_unchecked(octets) })
663    }
664}
665
666//--- IntoIterator
667
668impl<'a, Octs: Octets + ?Sized> IntoIterator for &'a Message<Octs> {
669    type Item = Result<(ParsedRecord<'a, Octs>, Section), ParseError>;
670    type IntoIter = MessageIter<'a, Octs>;
671
672    fn into_iter(self) -> Self::IntoIter {
673        MessageIter {
674            inner: self.answer().ok(),
675        }
676    }
677}
678
679//--- Debug
680
681impl<Octs: AsRef<[u8]> + ?Sized> fmt::Debug for Message<Octs> {
682    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
683        f.debug_struct("Message")
684            .field("id", &self.header().id())
685            .field("qr", &self.header().qr())
686            .field("opcode", &self.header().opcode())
687            .field("flags", &self.header().flags())
688            .field("rcode", &self.header().rcode())
689            .field("qdcount", &self.header_counts().qdcount())
690            .field("ancount", &self.header_counts().ancount())
691            .field("nscount", &self.header_counts().nscount())
692            .field("arcount", &self.header_counts().arcount())
693            .finish()
694    }
695}
696
697//------------ QuestionSection ----------------------------------------------
698
699/// An iterator over the question section of a DNS message.
700///
701/// The iterator’s item is the result of trying to parse the question. In case
702/// of a parse error, `next` will return an error once and `None` after that.
703///
704/// You can create a value of this type through [`Message::question`]. Use the
705/// [`answer`] or [`next_section`] methods on a question section to proceed
706/// to an iterator over the answer section.
707///
708/// [`Message::question`]: struct.Message.html#method.question
709/// [`answer`]: #method.answer
710/// [`next_section`]: #method.next_section
711#[derive(Debug)]
712pub struct QuestionSection<'a, Octs: ?Sized> {
713    /// The parser for generating the questions.
714    parser: Parser<'a, Octs>,
715
716    /// The remaining number of questions.
717    ///
718    /// The `Result` is here to monitor an error during iteration.
719    /// It is used to fuse the iterator after an error and is also returned
720    /// by `answer()` should that be called after an error.
721    count: Result<u16, ParseError>,
722}
723
724impl<'a, Octs: Octets + ?Sized> QuestionSection<'a, Octs> {
725    /// Creates a new question section from a reference to the message octets.
726    fn new(octets: &'a Octs) -> Self {
727        let mut parser = Parser::from_ref(octets);
728        parser.advance(mem::size_of::<HeaderSection>()).unwrap();
729        QuestionSection {
730            count: Ok(
731                HeaderCounts::for_message_slice(parser.as_slice()).qdcount()
732            ),
733            parser,
734        }
735    }
736
737    /// Returns the current position relative to the beginning of the message.
738    #[must_use]
739    pub fn pos(&self) -> usize {
740        self.parser.pos()
741    }
742
743    /// Proceeds to the answer section.
744    ///
745    /// Skips over any remaining questions and then converts itself into the
746    /// first [`RecordSection`].
747    ///
748    /// [`RecordSection`]: struct.RecordSection.html
749    pub fn answer(mut self) -> Result<RecordSection<'a, Octs>, ParseError> {
750        while self.next().is_some() {}
751        let _ = self.count?;
752        Ok(RecordSection::new(self.parser, Section::first()))
753    }
754
755    /// Proceeds to the answer section.
756    ///
757    /// This is identical to [`answer`][Self::answer] and is here for
758    /// consistency.
759    pub fn next_section(self) -> Result<RecordSection<'a, Octs>, ParseError> {
760        self.answer()
761    }
762}
763
764//--- Clone and Clone
765
766impl<'a, Octs: ?Sized> Clone for QuestionSection<'a, Octs> {
767    fn clone(&self) -> Self {
768        *self
769    }
770}
771
772impl<'a, Octs: ?Sized> Copy for QuestionSection<'a, Octs> {}
773
774//--- Iterator
775
776impl<'a, Octs: Octets + ?Sized> Iterator for QuestionSection<'a, Octs> {
777    type Item = Result<Question<ParsedDname<Octs::Range<'a>>>, ParseError>;
778
779    fn next(&mut self) -> Option<Self::Item> {
780        match self.count {
781            Ok(count) if count > 0 => match Question::parse(&mut self.parser)
782            {
783                Ok(question) => {
784                    self.count = Ok(count - 1);
785                    Some(Ok(question))
786                }
787                Err(err) => {
788                    self.count = Err(err);
789                    Some(Err(err))
790                }
791            },
792            _ => None,
793        }
794    }
795}
796
797//--- PartialEq
798
799impl<'a, 'o, Octs, Other> PartialEq<QuestionSection<'o, Other>>
800    for QuestionSection<'a, Octs>
801where
802    Octs: Octets + ?Sized,
803    Other: Octets + ?Sized,
804{
805    fn eq(&self, other: &QuestionSection<'o, Other>) -> bool {
806        let mut me = *self;
807        let mut other = *other;
808        loop {
809            match (me.next(), other.next()) {
810                (Some(Ok(left)), Some(Ok(right))) => {
811                    if left != right {
812                        return false;
813                    }
814                }
815                (None, None) => return true,
816                _ => return false,
817            }
818        }
819    }
820}
821
822//------------ Section -------------------------------------------------------
823
824/// A helper type enumerating the three kinds of record sections.
825///
826/// See the documentation of [`Message`] for what the three sections are.
827///
828/// [`Message`]: struct.Message.html
829#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd)]
830pub enum Section {
831    Answer,
832    Authority,
833    Additional,
834}
835
836impl Section {
837    /// Returns the first section.
838    #[must_use]
839    pub fn first() -> Self {
840        Section::Answer
841    }
842
843    /// Returns the correct record count for this section.
844    fn count(self, counts: HeaderCounts) -> u16 {
845        match self {
846            Section::Answer => counts.ancount(),
847            Section::Authority => counts.nscount(),
848            Section::Additional => counts.arcount(),
849        }
850    }
851
852    /// Returns the value for the following section or `None` if this is last.
853    pub(crate) fn next_section(self) -> Option<Self> {
854        match self {
855            Section::Answer => Some(Section::Authority),
856            Section::Authority => Some(Section::Additional),
857            Section::Additional => None,
858        }
859    }
860}
861
862//------------ RecordSection -----------------------------------------------
863
864/// An iterator over the records in one of the three record sections.
865///
866/// The iterator’s item is the result of parsing a raw record represented by
867/// [`ParsedRecord`]. This type will allow access to an unparsed record. It
868/// can be converted into a concrete [`Record`] via its [`into_record`]
869/// method. If parsing the raw record fails, the iterator will return an
870/// error once and `None` after that.
871///
872/// Alternatively, you can trade in a value of this type into a
873/// [`RecordIter`] that iterates over [`Record`]s of a specific type by
874/// calling the [`limit_to`] method. In particular, you can use this together
875/// with [`AllRecordData`] to acquire an iterator that parses all known
876/// record types.
877///
878/// `RecordSection` values cannot be created directly. You can get one either
879/// by calling the method for the section in question of a [`Message`] value
880/// or by proceeding from another section via its `next_section` method.
881///
882/// [`limit_to`]: #method.limit_to
883/// [`AllRecordData`]: ../../rdata/enum.AllRecordData.html
884/// [`Message`]: struct.Message.html
885/// [`ParseRecord`]: ../record/struct.ParsedRecord.html
886/// [`Record`]: ../record/struct.Record.html
887/// [`RecordIter`]: struct.RecordIter.html
888/// [`into_record`]: ../record/struct.ParsedRecord.html#method.into_record
889#[derive(Debug)]
890pub struct RecordSection<'a, Octs: ?Sized> {
891    /// The parser for generating the records.
892    parser: Parser<'a, Octs>,
893
894    /// Which section are we, really?
895    section: Section,
896
897    /// The remaining number of records.
898    ///
899    /// The `Result` is here to monitor an error during iteration.
900    /// It is used to fuse the iterator after an error and is also returned
901    /// by `answer()` should that be called after an error.
902    count: Result<u16, ParseError>,
903}
904
905impl<'a, Octs: Octets + ?Sized> RecordSection<'a, Octs> {
906    /// Creates a new section from a parser.
907    ///
908    /// The parser must be positioned at the beginning of this section.
909    fn new(parser: Parser<'a, Octs>, section: Section) -> Self {
910        RecordSection {
911            count: Ok(section
912                .count(*HeaderCounts::for_message_slice(parser.as_slice()))),
913            section,
914            parser,
915        }
916    }
917
918    /// Returns the current position relative to the beginning of the message.
919    #[must_use]
920    pub fn pos(&self) -> usize {
921        self.parser.pos()
922    }
923
924    /// Trades `self` in for an iterator limited to a concrete record type.
925    ///
926    /// The record type is given through its record data type. Since the data
927    /// is being parsed, this type must implement [`ParseRecordData`]. For
928    /// record data types that are generic over domain name types, this is
929    /// normally achieved by giving them a [`ParsedDname`]. As a convenience,
930    /// type aliases for all the fundamental record data types exist in the
931    /// [domain::rdata::parsed] module.
932    ///
933    /// The returned limited iterator will continue at the current position
934    /// of `self`. It will *not* start from the beginning of the section.
935    ///
936    /// [`ParseRecordData`]: ../rdata/trait.ParseRecordData.html
937    /// [`ParsedDname`]: ../name/struct.ParsedDname.html
938    /// [domain::rdata::parsed]: ../../rdata/parsed/index.html
939    #[must_use]
940    pub fn limit_to<Data: ParseRecordData<'a, Octs>>(
941        self,
942    ) -> RecordIter<'a, Octs, Data> {
943        RecordIter::new(self, false)
944    }
945
946    /// Trades `self` in for an iterator limited to a type in IN class.
947    ///
948    /// Behaves exactly like [`limit_to`] but skips over records that are not
949    /// of class IN.
950    ///
951    /// [`limit_to`]: #method.limit_to
952    #[must_use]
953    pub fn limit_to_in<Data: ParseRecordData<'a, Octs>>(
954        self,
955    ) -> RecordIter<'a, Octs, Data> {
956        RecordIter::new(self, true)
957    }
958
959    /// Proceeds to the next section if there is one.
960    ///
961    /// Returns an error if parsing has failed and the message is unusable
962    /// now.
963    pub fn next_section(mut self) -> Result<Option<Self>, ParseError> {
964        let section = match self.section.next_section() {
965            Some(section) => section,
966            None => return Ok(None),
967        };
968        while self.skip_next().is_some() {}
969        let _ = self.count?;
970        Ok(Some(RecordSection::new(self.parser, section)))
971    }
972
973    /// Skip the next record.
974    fn skip_next(&mut self) -> Option<Result<(), ParseError>> {
975        match self.count {
976            Ok(count) if count > 0 => {
977                match ParsedRecord::skip(&mut self.parser) {
978                    Ok(_) => {
979                        self.count = Ok(count - 1);
980                        Some(Ok(()))
981                    }
982                    Err(err) => {
983                        self.count = Err(err);
984                        Some(Err(err))
985                    }
986                }
987            }
988            _ => None,
989        }
990    }
991}
992
993//--- Clone and Copy
994
995impl<'a, Octs: ?Sized> Clone for RecordSection<'a, Octs> {
996    fn clone(&self) -> Self {
997        *self
998    }
999}
1000
1001impl<'a, Octs: ?Sized> Copy for RecordSection<'a, Octs> {}
1002
1003//--- Iterator
1004
1005impl<'a, Octs: Octets + ?Sized> Iterator for RecordSection<'a, Octs> {
1006    type Item = Result<ParsedRecord<'a, Octs>, ParseError>;
1007
1008    fn next(&mut self) -> Option<Self::Item> {
1009        match self.count {
1010            Ok(count) if count > 0 => {
1011                match ParsedRecord::parse(&mut self.parser) {
1012                    Ok(record) => {
1013                        self.count = Ok(count - 1);
1014                        Some(Ok(record))
1015                    }
1016                    Err(err) => {
1017                        self.count = Err(err);
1018                        Some(Err(err))
1019                    }
1020                }
1021            }
1022            _ => None,
1023        }
1024    }
1025}
1026
1027//------------ MessageIter ---------------------------------------------------
1028
1029/// An iterator over the records of a message.
1030pub struct MessageIter<'a, Octs: ?Sized> {
1031    inner: Option<RecordSection<'a, Octs>>,
1032}
1033
1034impl<'a, Octs: Octets + ?Sized> Iterator for MessageIter<'a, Octs> {
1035    type Item = Result<(ParsedRecord<'a, Octs>, Section), ParseError>;
1036
1037    fn next(&mut self) -> Option<Self::Item> {
1038        // Try to get next record from current section
1039        match self.inner {
1040            Some(ref mut inner) => {
1041                let item = inner.next();
1042                if let Some(item) = item {
1043                    return Some(item.map(|item| (item, inner.section)));
1044                }
1045            }
1046            None => return None,
1047        }
1048
1049        // Advance to next section if possible, and retry
1050        let inner = self.inner.take()?;
1051        match inner.next_section() {
1052            Ok(section) => {
1053                self.inner = section;
1054                self.next()
1055            }
1056            Err(err) => Some(Err(err)),
1057        }
1058    }
1059}
1060
1061//------------ RecordIter ----------------------------------------------------
1062
1063/// An iterator over specific records of a record section of a DNS message.
1064///
1065/// The iterator’s item type is the result of trying to parse a record.
1066/// It silently skips over all records that `Data` cannot or does not want to
1067/// parse. If parsing the record data fails, the iterator will return an
1068/// error but can continue with the next record. If parsing the entire record
1069/// fails the item will be an error and subsequent attempts to continue will
1070/// also produce errors. This case can be distinguished from an error while
1071/// parsing the record data by [`next_section`] returning an error, too.
1072///
1073/// You can create a value of this type through the
1074/// [`RecordSection::limit_to`] method.
1075///
1076/// [`next_section`]: #method.next_section
1077/// [`RecordSection::limit_to`]: struct.RecordSection.html#method.limit_to
1078#[derive(Debug)]
1079pub struct RecordIter<'a, Octs: ?Sized, Data> {
1080    section: RecordSection<'a, Octs>,
1081    in_only: bool,
1082    marker: PhantomData<Data>,
1083}
1084
1085impl<'a, Octs, Data> RecordIter<'a, Octs, Data>
1086where
1087    Octs: Octets + ?Sized,
1088    Data: ParseRecordData<'a, Octs>,
1089{
1090    /// Creates a new record iterator.
1091    fn new(section: RecordSection<'a, Octs>, in_only: bool) -> Self {
1092        RecordIter {
1093            section,
1094            in_only,
1095            marker: PhantomData,
1096        }
1097    }
1098
1099    /// Trades the limited iterator for the full iterator.
1100    ///
1101    /// The returned iterator will continue right after the last record
1102    /// previously returned.
1103    #[must_use]
1104    pub fn unwrap(self) -> RecordSection<'a, Octs> {
1105        self.section
1106    }
1107
1108    /// Proceeds to the next section if there is one.
1109    ///
1110    /// Returns an error if parsing the message has failed. Returns
1111    /// `Ok(None)` if this iterator was already on the additional section.
1112    pub fn next_section(
1113        self,
1114    ) -> Result<Option<RecordSection<'a, Octs>>, ParseError> {
1115        self.section.next_section()
1116    }
1117}
1118
1119//--- Clone
1120
1121impl<'a, Octs: ?Sized, Data> Clone for RecordIter<'a, Octs, Data> {
1122    fn clone(&self) -> Self {
1123        RecordIter {
1124            section: self.section,
1125            in_only: self.in_only,
1126            marker: PhantomData,
1127        }
1128    }
1129}
1130
1131//--- Iterator
1132
1133impl<'a, Octs, Data> Iterator for RecordIter<'a, Octs, Data>
1134where
1135    Octs: Octets + ?Sized,
1136    Data: ParseRecordData<'a, Octs>,
1137{
1138    type Item =
1139        Result<Record<ParsedDname<Octs::Range<'a>>, Data>, ParseError>;
1140
1141    fn next(&mut self) -> Option<Self::Item> {
1142        loop {
1143            let record = match self.section.next() {
1144                Some(Ok(record)) => record,
1145                Some(Err(err)) => return Some(Err(err)),
1146                None => return None,
1147            };
1148            if self.in_only && record.class() != Class::In {
1149                continue;
1150            }
1151            match record.into_record() {
1152                Ok(Some(record)) => return Some(Ok(record)),
1153                Err(err) => return Some(Err(err)),
1154                Ok(None) => {}
1155            }
1156        }
1157    }
1158}
1159
1160//============ Error Types ===================================================
1161
1162//------------ ShortMessage --------------------------------------------------
1163
1164/// A message was too short to even contain the header.
1165#[derive(Clone, Copy, Debug)]
1166pub struct ShortMessage(());
1167
1168impl fmt::Display for ShortMessage {
1169    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1170        f.write_str("short message")
1171    }
1172}
1173
1174#[cfg(feature = "std")]
1175impl std::error::Error for ShortMessage {}
1176
1177//------------ CopyRecordsError ----------------------------------------------
1178
1179/// An error occurrd while copying records.
1180#[derive(Clone, Copy, Debug)]
1181pub enum CopyRecordsError {
1182    /// Parsing the source message failed.
1183    Parse(ParseError),
1184
1185    /// Not enough space in the target.
1186    Push(PushError),
1187}
1188
1189//--- From
1190
1191impl From<ParseError> for CopyRecordsError {
1192    fn from(err: ParseError) -> Self {
1193        CopyRecordsError::Parse(err)
1194    }
1195}
1196
1197//--- Display and Error
1198
1199impl fmt::Display for CopyRecordsError {
1200    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1201        match *self {
1202            CopyRecordsError::Parse(ref err) => err.fmt(f),
1203            CopyRecordsError::Push(ref err) => err.fmt(f),
1204        }
1205    }
1206}
1207
1208#[cfg(feature = "std")]
1209impl std::error::Error for CopyRecordsError {}
1210
1211//============ Testing =======================================================
1212
1213#[cfg(test)]
1214mod test {
1215    use super::*;
1216    #[cfg(feature = "std")]
1217    use crate::base::message_builder::MessageBuilder;
1218    #[cfg(feature = "std")]
1219    use crate::base::name::Dname;
1220    #[cfg(feature = "std")]
1221    use crate::rdata::{AllRecordData, Ns};
1222    #[cfg(feature = "std")]
1223    use std::vec::Vec;
1224
1225    // Helper for test cases
1226    #[cfg(feature = "std")]
1227    fn get_test_message() -> Message<Vec<u8>> {
1228        let msg = MessageBuilder::new_vec();
1229        let mut msg = msg.answer();
1230        msg.push((
1231            Dname::vec_from_str("foo.example.com.").unwrap(),
1232            86000,
1233            Cname::new(Dname::vec_from_str("baz.example.com.").unwrap()),
1234        ))
1235        .unwrap();
1236        let mut msg = msg.authority();
1237        msg.push((
1238            Dname::vec_from_str("bar.example.com.").unwrap(),
1239            86000,
1240            Ns::new(Dname::vec_from_str("baz.example.com.").unwrap()),
1241        ))
1242        .unwrap();
1243        msg.into_message()
1244    }
1245
1246    #[test]
1247    fn short_message() {
1248        assert!(Message::from_octets(&[0u8; 11]).is_err());
1249        assert!(Message::from_octets(&[0u8; 12]).is_ok());
1250    }
1251
1252    #[test]
1253    #[cfg(feature = "std")]
1254    fn canonical_name() {
1255        use crate::rdata::A;
1256
1257        // Message without CNAMEs.
1258        let mut msg = MessageBuilder::new_vec().question();
1259        msg.push((Dname::vec_from_str("example.com.").unwrap(), Rtype::A))
1260            .unwrap();
1261        let msg_ref = msg.as_message();
1262        assert_eq!(
1263            Dname::vec_from_str("example.com.").unwrap(),
1264            msg_ref.canonical_name().unwrap()
1265        );
1266
1267        // Message with CNAMEs.
1268        let mut msg = msg.answer();
1269        msg.push((
1270            Dname::vec_from_str("bar.example.com.").unwrap(),
1271            86000,
1272            Cname::new(Dname::vec_from_str("baz.example.com.").unwrap()),
1273        ))
1274        .unwrap();
1275        msg.push((
1276            Dname::vec_from_str("example.com.").unwrap(),
1277            86000,
1278            Cname::new(Dname::vec_from_str("foo.example.com.").unwrap()),
1279        ))
1280        .unwrap();
1281        msg.push((
1282            Dname::vec_from_str("foo.example.com.").unwrap(),
1283            86000,
1284            Cname::new(Dname::vec_from_str("bar.example.com.").unwrap()),
1285        ))
1286        .unwrap();
1287        let msg_ref = msg.as_message();
1288        assert_eq!(
1289            Dname::vec_from_str("baz.example.com.").unwrap(),
1290            msg_ref.canonical_name().unwrap()
1291        );
1292
1293        // CNAME loop.
1294        msg.push((
1295            Dname::vec_from_str("baz.example.com").unwrap(),
1296            86000,
1297            Cname::new(Dname::vec_from_str("foo.example.com").unwrap()),
1298        ))
1299        .unwrap();
1300        assert!(msg.as_message().canonical_name().is_none());
1301        msg.push((
1302            Dname::vec_from_str("baz.example.com").unwrap(),
1303            86000,
1304            A::from_octets(127, 0, 0, 1),
1305        ))
1306        .unwrap();
1307        assert!(msg.as_message().canonical_name().is_none());
1308    }
1309
1310    #[test]
1311    #[cfg(feature = "std")]
1312    fn message_iterator() {
1313        let msg = get_test_message();
1314        let mut iter = msg.iter();
1315
1316        // Check that it returns a record from first section
1317        let (_rr, section) = iter.next().unwrap().unwrap();
1318        assert_eq!(Section::Answer, section);
1319
1320        // Check that it advances to next section
1321        let (_rr, section) = iter.next().unwrap().unwrap();
1322        assert_eq!(Section::Authority, section);
1323    }
1324
1325    #[test]
1326    #[cfg(feature = "std")]
1327    fn copy_records() {
1328        let msg = get_test_message();
1329        let target = MessageBuilder::new_vec().question();
1330        let res = msg.copy_records(target.answer(), |rr| {
1331            if let Ok(Some(rr)) =
1332                rr.into_record::<AllRecordData<_, ParsedDname<_>>>()
1333            {
1334                if rr.rtype() == Rtype::Cname {
1335                    return Some(rr);
1336                }
1337            }
1338            None
1339        });
1340
1341        assert!(res.is_ok());
1342        if let Ok(target) = res {
1343            let msg = target.into_message();
1344            assert_eq!(1, msg.header_counts().ancount());
1345            assert_eq!(0, msg.header_counts().arcount());
1346        }
1347    }
1348}