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