domain_core/bits/
message.rs

1//! Accessing exisiting DNS messages.
2//!
3//! This module defines a number of types for disecting the content of a
4//! DNS message in wire format. Because many of the components of the message
5//! are of varying length, this can only be done iteratively. You start out
6//! with a value of type [`Message`] that wraps the data of a complete
7//! message and progressively trade it in for values of other types
8//! representing other sections of the message.
9//!
10//! For all details, see the [`Message`] type.
11//!
12//! [`Message`]: struct.Message.html
13
14
15use std::{mem, ops};
16use std::marker::PhantomData;
17use bytes::Bytes;
18use ::iana::{Rcode, Rtype};
19use ::rdata::Cname;
20use super::message_builder::{MessageBuilder, AdditionalBuilder, RecordSectionBuilder};
21use super::header::{Header, HeaderCounts, HeaderSection};
22use super::name::{ParsedDname, ParsedDnameError, ToDname};
23use super::parse::{Parse, Parser, ShortBuf};
24use super::question::Question;
25use super::rdata::{ParseRecordData, RecordData};
26use super::record::{ParsedRecord, Record, RecordParseError};
27
28
29//------------ Message -------------------------------------------------------
30
31/// A DNS message.
32///
33/// This type wraps a bytes value with the wire-format content of a DNS
34/// message and allows parsing the content for further processing.
35///
36/// Typically, you create a message by passing a bytes value with data you
37/// received from the network to the [`from_bytes`] function. This function
38/// does a quick sanity check if the data can be a DNS message at all
39/// before returning a message value. All further parsing happens lazily when
40/// you access more of the message.
41///
42/// Section 4 of [RFC 1035] defines DNS messages as being divded into five
43/// sections named header, question, answer, authority, and additional.
44///
45/// The header section is of a fixed sized and can be accessed at any time
46/// through the methods given under [Header Section]. Most likely, you will
47/// be interested in the first part of the header for which references 
48/// are returned by the [`header`] method.  The second part of the header
49/// section contains the number of entries in the following four sections
50/// and is of less interest as there are more sophisticated ways of accessing
51/// these sections. If you do care, you can get a reference through
52/// [`counts`].
53///
54/// The question section contains what was asked of the DNS by a request.
55/// These questions consist of a domain name, a record type, and class. With
56/// normal queries, a requests asks for all records of the given record type
57/// that are owned by the domain name within the class. There will normally
58/// be exactly one question for normal queries. With other query operations,
59/// the questions may refer to different things.
60///
61/// You can get access to the question section through the [`question`]
62/// method. It returns a [`QuestionSection`] value that is an iterator over
63/// questions. Since a single question is a very common case, there is a 
64/// convenience method [`first_question`] that simple returns the first
65/// question if there is any.
66///
67/// The following three section all contain DNS resource records. In normal
68/// queries, they are empty in a request and may or may not contain records
69/// in a response. The *answer* section contains all the records that answer
70/// the given question. The *authority* section contains records declaring
71/// which name server provided authoritative information for the question,
72/// and the *additional* section can contain records that the name server
73/// thought might be useful for processing the question. For instance, if you
74/// trying to find out the mail server of a domain by asking for MX records,
75/// you likely also want the IP addresses for the server, so the name server
76/// may include these right away and free of charge.
77///
78/// There are functions to access all three sections directly: [`answer`],
79/// [`authority`], and [`additional`]. However, since there are no
80/// pointers to where the later sections start, accessing them directly
81/// means iterating over the previous sections. This is why it is more
82/// efficitent to call [`next_section`] on the returned value and process
83/// them in order. Alternatively, you can use the [`sections`] function
84/// that gives you all four sections at once with the minimal amount of
85/// iterating necessary.
86///
87/// Each record in the record sections is of a specific type. Each type has
88/// its specific record data. Because there are so many types, we decided
89/// against having only one giant enum. Instead, invidual types can either
90/// implement the record data for one single record type or there can be
91/// compound types covering multiple record types. An example of the latter
92/// is [`AllRecordData`] from the [rdata] module that does indeed provide
93/// this one giant enum if you insist on using it.
94/// 
95/// Consequently, the typ representing a record section of a message,
96/// somewhat obviously named [`RecordSection`], iterates over a stand-in type,
97/// [`ParseRecord`], that gives you access to all information of the record
98/// except for its data.
99///
100/// There are two ways to convert that value into a [`Record`] with actual
101/// data. [`ParseRecord::into_record`] takes a record data type as a type
102/// argument—turbo-fish style—and tries to reparse the record as a record
103/// with that data. Alternatively, you can switch the entire record section
104/// to inly iterate over such records via the [`limit_to`] method.
105///
106/// So, if you want to iterate over the MX records in the answer section, you
107/// would do something like this:
108///
109/// ```
110/// # use domain_core::bits::message::Message;
111/// use domain_core::rdata::parsed::Mx;
112///
113/// # let bytes = vec![0; 12].into();
114/// let msg = Message::from_bytes(bytes).unwrap();
115/// for record in msg.answer().unwrap().limit_to::<Mx>() {
116///     if let Ok(record) = record {
117///         // Do something with the record ...
118///     }
119/// }
120/// ```
121///
122/// The code inside the for loop deals with the fact that iterator actually
123/// returns a `Result<T, E>`. An error signals that something went wrong while
124/// parsing. If only the record data is broken, the message remains useful and
125/// parsing can continue with the next record. If the message is fully
126/// broken, the next iteration will return `None` to signal that.
127///
128/// [`additional`]: #method.additional
129/// [`answer`]: #method.answer
130/// [`authority`]: #method.authority
131/// [`counts`]: #method.counts
132/// [`first_question`]: #method.first_question
133/// [`from_bytes`]: #method.from_bytes
134/// [`header`]: #method.header
135/// [`limit_to`]: ../struct.RecordSection.html#method.limit_to
136/// [`next_section`]: ../struct.RecordSection.html#method.next_section
137/// [`question`]: #method.question
138/// [`sections`]: #method.sections
139/// [`AllRecordData`]: ../../rdata/enum.AllRecordData.html
140/// [`QuestionSection`]: struct.QuestionSection.html
141/// [`ParseRecord`]: ../record/struct.ParseRecord.html
142/// [`ParseRecord::into_record`]: ../record/struct.ParseRecord.html#method.into_record
143/// [`RecordSection`]: struct.RecordSection.html
144/// [Header Section]: #header-section
145/// [rdata]: ../../rdata/index.html
146/// [RFC 1035]: https://tools.ietf.org/html/rfc1035
147#[derive(Clone, Debug)]
148pub struct Message {
149    bytes:Bytes,
150}
151
152/// # Creation and Conversion
153///
154impl Message {
155    /// Creates a message from a bytes value.
156    ///
157    /// This fails if the slice is too short to even contain a complete
158    /// header section.  No further checks are done, though, so if this
159    /// function returns `Ok`, the message may still be broken with other
160    /// methods returning `Err(_)`.
161    pub fn from_bytes(bytes: Bytes) -> Result<Self, ShortBuf> {
162        if bytes.len() < mem::size_of::<HeaderSection>() {
163            Err(ShortBuf)
164        }
165        else {
166            Ok(Message { bytes })
167        }
168    }
169
170    /// Creates a message from a bytes value without checking.
171    pub(super) unsafe fn from_bytes_unchecked(bytes: Bytes) -> Self {
172        Message { bytes }
173    }
174
175    /// Returns a reference to the underlying bytes value.
176    pub fn as_bytes(&self) -> &Bytes {
177        &self.bytes
178    }
179
180    /// Returns a reference to the underlying byte slice.
181    pub fn as_slice(&self) -> &[u8] {
182        self.bytes.as_ref()
183    }
184}
185
186
187/// # Header Section
188///
189impl Message {
190    /// Returns a reference to the message header.
191    pub fn header(&self) -> &Header {
192        Header::for_message_slice(self.as_slice())
193    }
194
195    /// Returns a refernce the header counts of the message.
196    pub fn header_counts(&self) -> &HeaderCounts {
197        HeaderCounts::for_message_slice(self.as_slice())
198    }
199
200    /// Returns whether the rcode is NoError.
201    pub fn no_error(&self) -> bool {
202        self.header().rcode() == Rcode::NoError
203    }
204
205    /// Returns whether the rcode is one of the error values.
206    pub fn is_error(&self) -> bool {
207        self.header().rcode() != Rcode::NoError
208    }
209}
210
211
212/// # Sections
213///
214impl Message {
215    /// Returns the question section.
216    pub fn question(&self) -> QuestionSection {
217        QuestionSection::new(self.bytes.clone())
218    }
219
220    /// Returns the zone section of an UPDATE message.
221    ///
222    /// This is identical to `self.question()`.
223    pub fn zone(&self) -> QuestionSection { self.question() }
224
225    /// Returns the answer section.
226    pub fn answer(&self) -> Result<RecordSection, ParsedDnameError> {
227        Ok(self.question().next_section()?)
228    }
229
230    /// Returns the prerequisite section of an UPDATE message.
231    ///
232    /// This is identical to `self.answer()`.
233    pub fn prerequisite(&self) -> Result<RecordSection, ParsedDnameError> {
234        self.answer()
235    }
236
237    /// Returns the authority section.
238    pub fn authority(&self) -> Result<RecordSection, ParsedDnameError> {
239        Ok(self.answer()?.next_section()?.unwrap())
240    }
241
242    /// Returns the update section of an UPDATE message.
243    ///
244    /// This is identical to `self.authority()`.
245    pub fn update(&self) -> Result<RecordSection, ParsedDnameError> {
246        self.authority()
247    }
248
249    /// Returns the additional section.
250    pub fn additional(&self) -> Result<RecordSection, ParsedDnameError> {
251        Ok(self.authority()?.next_section()?.unwrap())
252    }
253
254    /// Returns all four sections in one fell swoop.
255    pub fn sections(&self) -> Result<(QuestionSection, RecordSection,
256                                      RecordSection, RecordSection),
257                                     ParsedDnameError> {
258        let question = self.question();
259        let answer = question.clone().next_section()?;
260        let authority = answer.clone().next_section()?.unwrap();
261        let additional = authority.clone().next_section()?.unwrap();
262        Ok((question, answer, authority, additional))
263    }
264
265    /// Returns record iterator for all sections
266    pub fn iter(&self) -> MessageIterator {
267        match self.answer() {
268            Ok(section) => MessageIterator { inner: Some(section) },
269            Err(_) => MessageIterator { inner: None },
270        }
271    }
272
273    /// Copy records from message into the target message builder.
274    ///
275    /// The method uses `op` to process records from all packet sections before inserting,
276    /// caller can use this closure to filter or manipulate records before inserting.
277    pub fn copy_records<N, D, R, F>(&self, target: MessageBuilder, op: F) -> Result<AdditionalBuilder, ParsedDnameError>
278    where N: ToDname, D: RecordData, R: Into<Record<N, D>>, F: FnMut(Result<ParsedRecord, ParsedDnameError>) -> Option<R> + Copy
279    {
280        // Copy answer, authority, and additional records.
281        let mut target = target.answer();
282        self.answer()?.filter_map(op).for_each(|rr| target.push(rr).unwrap());
283
284        let mut target = target.authority();
285        self.authority()?.filter_map(op).for_each(|rr| target.push(rr).unwrap());
286
287        let mut target = target.additional();
288        self.additional()?.filter_map(op).for_each(|rr| target.push(rr).unwrap());
289
290        Ok(target)
291    }
292}
293
294
295/// # Helpers for Common Tasks
296///
297impl Message {
298    /// Returns whether this is the answer to some other message.
299    ///
300    /// The method checks whether the ID fields of the headers are the same,
301    /// whether the QR flag is set in this message, and whether the questions
302    /// are the same.
303    pub fn is_answer(&self, query: &Message) -> bool {
304        if !self.header().qr()
305                || self.header().id() != query.header().id()
306                || self.header_counts().qdcount()
307                        != query.header_counts().qdcount() {
308            false
309        }
310        else { self.question().eq(query.question()) }
311    }
312
313    /// Returns the first question, if there is any.
314    ///
315    /// The method will return `None` both if there are no questions or if
316    /// parsing fails.
317    pub fn first_question(&self) -> Option<Question<ParsedDname>> {
318        match self.question().next() {
319            None | Some(Err(..)) => None,
320            Some(Ok(question)) => Some(question)
321        }
322    }
323
324    /// Returns the query type of the first question, if any.
325    pub fn qtype(&self) -> Option<Rtype> {
326        self.first_question().map(|x| x.qtype())
327    }
328
329    /// Returns whether the message contains answers of a given type.
330    pub fn contains_answer<D: ParseRecordData>(&self) -> bool {
331        let answer = match self.answer() {
332            Ok(answer) => answer,
333            Err(..) => return false
334        };
335        answer.limit_to::<D>().next().is_some()
336    }
337
338    /// Resolves the canonical name of the answer.
339    ///
340    /// Returns `None` if either the message doesn’t have a question or there
341    /// was a parse error. Otherwise starts with the question’s name,
342    /// follows any CNAME trail and returns the name answers should be for.
343    pub fn canonical_name(&self) -> Option<ParsedDname> {
344        let question = match self.first_question() {
345            None => return None,
346            Some(question) => question
347        };
348        let mut name = question.qname().clone();
349        let answer = match self.answer() {
350            Ok(answer) => answer.limit_to::<Cname<ParsedDname>>(),
351            Err(_) => return None,
352        };
353
354        loop {
355            let mut found = false;
356            for record in answer.clone() {
357                let record = match record {
358                    Ok(record) => record,
359                    Err(_) => continue,
360                };
361                if *record.owner() == name {
362                    name = record.data().cname().clone();
363                    found = true;
364                    break;
365                }
366            }
367            if !found {
368                break
369            }
370        }
371        
372        Some(name)
373    }
374}
375
376
377//--- Deref and AsRef
378
379impl ops::Deref for Message {
380    type Target = Bytes;
381
382    fn deref(&self) -> &Self::Target {
383        self.as_bytes()
384    }
385}
386
387impl AsRef<Message> for Message {
388    fn as_ref(&self) -> &Message {
389        self
390    }
391}
392
393impl AsRef<Bytes> for Message {
394    fn as_ref(&self) -> &Bytes {
395        self.as_bytes()
396    }
397}
398
399impl AsRef<[u8]> for Message {
400    fn as_ref(&self) -> &[u8] {
401        self.as_slice()
402    }
403}
404
405//--- Iterator
406
407pub struct MessageIterator {
408    inner: Option<RecordSection>,
409}
410
411impl Iterator for MessageIterator {
412    type Item = (Result<ParsedRecord, ParsedDnameError>, Section);
413
414    fn next(&mut self) -> Option<Self::Item> {
415        // Try to get next record from current section
416        match self.inner {
417            Some(ref mut inner) => {
418                let item = inner.next();
419                if let Some(item) = item {
420                    return Some((item, inner.section));
421                }
422            },
423            None => return None,
424        }
425
426        // Advance to next section if possible, and retry
427        self.inner = match self.inner.clone().unwrap().next_section() {
428            Ok(section) => section,
429            Err(_) => None,
430        };
431
432        self.next()
433    }
434}
435
436//------------ QuestionSection ----------------------------------------------
437
438/// An iterator over the question section of a DNS message.
439///
440/// The iterator’s item is the result of trying to parse the questions. In
441/// case of a parse error, `next()` will return an error once and
442/// `None` after that.
443///
444/// You can create a value of this type through the [`Message::section`]
445/// method. Use the [`answer`] or [`next_section`] methods to proceed
446/// to an iterator over the answer section.
447///
448/// [`Message::section`]: struct.Message.html#method.section
449/// [`answer`]: #method.answer
450/// [`next_section`]: #method.next_section
451#[derive(Clone, Debug)]
452pub struct QuestionSection {
453    /// The parser for generating the questions.
454    parser: Parser,
455
456    /// The remaining number of questions.
457    ///
458    /// The `Result` is here to monitor an error during iteration.
459    /// It is used to fuse the iterator after an error and is also returned
460    /// by `answer()` should that be called after an error.
461    count: Result<u16, ParsedDnameError>
462}
463
464impl QuestionSection {
465    /// Creates a new question section from a bytes value.
466    fn new(bytes: Bytes) -> Self {
467        let mut parser = Parser::from_bytes(bytes);
468        parser.advance(mem::size_of::<HeaderSection>()).unwrap();
469        QuestionSection {
470            count: Ok(HeaderCounts::for_message_slice(
471                parser.as_slice()).qdcount()
472            ),
473            parser,
474        }
475    }
476
477    /// Proceeds to the answer section.
478    ///
479    /// Skips over any remaining questions and then converts itself into
480    /// the first [`RecordSection`].
481    ///
482    /// [`RecordSection`]: struct.RecordSection.html
483    pub fn answer(mut self) -> Result<RecordSection, ParsedDnameError> {
484        // XXX Use Parser::skip here.
485        for question in &mut self {
486            let _ = question?;
487        }
488        match self.count {
489            Ok(..) => Ok(RecordSection::new(self.parser, Section::first())),
490            Err(err) => Err(err)
491        }
492    }
493
494    /// Proceeds to the answer section.
495    ///
496    /// This is an alias for the [`answer`] method.
497    ///
498    /// [`answer`]: #method.answer
499    pub fn next_section(self) -> Result<RecordSection, ParsedDnameError> {
500        self.answer()
501    }
502}
503
504
505//--- Iterator
506
507impl Iterator for QuestionSection {
508    type Item = Result<Question<ParsedDname>, ParsedDnameError>;
509
510    fn next(&mut self) -> Option<Self::Item> {
511        match self.count {
512            Ok(count) if count > 0 => {
513                match Question::parse(&mut self.parser) {
514                    Ok(question) => {
515                        self.count = Ok(count - 1);
516                        Some(Ok(question))
517                    }
518                    Err(err) => {
519                        self.count = Err(err);
520                        Some(Err(err))
521                    }
522                }
523            }
524            _ => None
525        }
526    }
527}
528
529
530//------------ Section -------------------------------------------------------
531
532/// A helper type enumerating which section a `RecordSection` is currently in.
533#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd)]
534pub enum Section {
535    Answer,
536    Authority,
537    Additional
538}
539
540
541impl Section {
542    /// Returns the first section.
543    pub fn first() -> Self { Section::Answer }
544
545    /// Returns the correct record count for this section.
546    fn count(self, counts: HeaderCounts) -> u16 {
547        match self {
548            Section::Answer => counts.ancount(),
549            Section::Authority => counts.nscount(),
550            Section::Additional => counts.arcount()
551        }
552    }
553
554    /// Returns the value for the following section or `None` if this is last.
555    fn next_section(self) -> Option<Self> {
556        match self {
557            Section::Answer => Some(Section::Authority),
558            Section::Authority => Some(Section::Additional),
559            Section::Additional => None
560        }
561    }
562}
563
564
565//------------ RecordSection -----------------------------------------------
566
567/// An iterator over one of the three record sections of a DNS message.
568/// 
569/// The iterator’s item is the result of parsing a raw record represented by
570/// [`ParsedRecord`]. This type will allow access to a record’s header
571/// only. It can, however, be converted into a concrete [`Record`] via its
572/// [`into_record`] method. If parsing the raw record fails, the iterator
573/// will return an error once and `None` after that.
574///
575/// Alternatively, you can trade in a value of this type into a
576/// [`RecordIter`] that iterates over [`Record`]s of a specific type by
577/// calling the [`limit_to`] method. In particular, you can use this together
578/// with [`AllRecordData`] to acquire an iterator that parses all known
579/// record types. If you are only interested in a subset of records, it may
580/// be more efficient to create a similar enum with only the types you need.
581///
582/// `RecordSection` values cannot be created directly. You can get one either
583/// by calling the method for the section in question of a [`Message`] value
584/// or by proceeding from another section via its `next_section` method.
585///
586/// [`limit_to`]: #method.limit_to
587/// [`AllRecordData`]: ../../rdata/enum.AllRecordData.html
588/// [`Message`]: struct.Message.html
589/// [`ParseRecord`]: ../record/struct.ParsedRecord.html
590/// [`Record`]: ../record/struct.Record.html
591/// [`RecordIter`]: struct.RecordIter.html
592/// [`into_record`]: ../record/struct.ParsedRecord.html#method.into_record
593#[derive(Clone, Debug)]
594pub struct RecordSection {
595    /// The parser for generating the records.
596    parser: Parser,
597
598    /// Which section are we, really?
599    section: Section,
600
601    /// The remaining number of records.
602    ///
603    /// The `Result` is here to monitor an error during iteration.
604    /// It is used to fuse the iterator after an error and is also returned
605    /// by `answer()` should that be called after an error.
606    count: Result<u16, ParsedDnameError>
607}
608
609
610impl RecordSection {
611    /// Creates a new section from a parser.
612    ///
613    /// The parser must only wrap the bytes of the message and it must be
614    /// positioned at the beginning of the section.
615    fn new(parser: Parser, section: Section) ->  Self {
616        RecordSection {
617            count: Ok(section.count(
618                *HeaderCounts::for_message_slice(parser.as_slice())
619            )),
620            section,
621            parser,
622        }
623    }
624
625    /// Trades `self` in for an iterator limited to a concrete record type.
626    ///
627    /// The record type is given through its record data type. Since the data
628    /// is being parsed, this type must implement [`ParseRecordData`]. For
629    /// record data types that are generic over domain name types, this is
630    /// normally achieved by giving them a [`ParsedDname`]. As a convenience,
631    /// type aliases for all the fundamental record data types exist in the
632    /// [domain::rdata::parsed] module.
633    ///
634    /// The returned limited iterator will continue at the current position
635    /// of `self`. It will *not* start from the beginning of the section.
636    ///
637    /// [`ParseRecordData`]: ../rdata/trait.ParseRecordData.html
638    /// [`ParsedDname`]: ../name/struct.ParsedDname.html
639    /// [domain::rdata::parsed]: ../../rdata/parsed/index.html
640    pub fn limit_to<D: ParseRecordData>(self) -> RecordIter<D> {
641        RecordIter::new(self)
642    }
643
644    /// Proceeds to the next section if there is one.
645    ///
646    /// Returns an error if parsing has failed and the message is unsable
647    /// now.
648    pub fn next_section(mut self)
649                        -> Result<Option<Self>, ParsedDnameError> {
650        let section = match self.section.next_section() {
651            Some(section) => section,
652            None => return Ok(None)
653        };
654        // XXX Use Parser::skip here.
655        for record in &mut self {
656            let _ = try!(record);
657        }
658        match self.count {
659            Ok(..) => Ok(Some(RecordSection::new(self.parser, section))),
660            Err(err) => Err(err)
661        }
662    }
663}
664
665
666//--- Iterator
667
668impl Iterator for RecordSection {
669    type Item = Result<ParsedRecord, ParsedDnameError>;
670
671    fn next(&mut self) -> Option<Self::Item> {
672        match self.count {
673            Ok(count) if count > 0 => {
674                match ParsedRecord::parse(&mut self.parser) {
675                    Ok(record) => {
676                        self.count = Ok(count - 1);
677                        Some(Ok(record))
678                    }
679                    Err(err) => {
680                        self.count = Err(err);
681                        Some(Err(err))
682                    }
683                }
684            }
685            _ => None
686        }
687    }
688}
689
690
691//------------ RecordIter ----------------------------------------------------
692
693/// An iterator over specific records of a record section of a DNS message.
694///
695/// The iterator’s item type is the result of trying to parse a record.
696/// It silently skips over all records that `D` cannot or does not want to
697/// parse. If parsing the record data fails, the iterator will return an
698/// error but can continue with the next record. If parsing the entire record
699/// fails (and the message thus becoming unusable) or if the end of the
700/// section is reached, the iterator produces `None`. The latter case can be
701/// distinguished by [`next_section`] returning an error.
702///
703/// You can create a value of this type through the
704/// [`RecordSection::limit_to`] method.
705///
706/// [`next_section`]: #method.next_section
707/// [`RecordSection::limit_to`]: struct.RecordSection.html#method.limit_to
708#[derive(Clone, Debug)]
709pub struct RecordIter<D: ParseRecordData> {
710    section: RecordSection,
711    marker: PhantomData<D>
712}
713
714impl<D: ParseRecordData> RecordIter<D> {
715    /// Creates a new limited record iterator from the given section.
716    fn new(section: RecordSection) -> Self {
717        RecordIter { section, marker: PhantomData }
718    }
719
720    /// Trades in the limited iterator for the complete iterator.
721    ///
722    /// The complete iterator will continue right after the last record
723    /// returned by `self`. It will *not* restart from the beginning of the
724    /// section.
725    pub fn unwrap(self) -> RecordSection {
726        self.section
727    }
728
729    /// Proceeds to the next section if there is one.
730    ///
731    /// Returns an error if parsing has failed and the message is unusable
732    /// now.
733    pub fn next_section(self)
734                        -> Result<Option<RecordSection>, ParsedDnameError> {
735        self.section.next_section()
736    }
737}
738
739
740//--- Iterator
741
742impl<D: ParseRecordData> Iterator for RecordIter<D> {
743    type Item = Result<Record<ParsedDname, D>,
744                       RecordParseError<ParsedDnameError, D::Err>>;
745
746    fn next(&mut self) -> Option<Self::Item> {
747        loop {
748            let record = match self.section.next() {
749                Some(Ok(record)) => record,
750                Some(Err(err)) => {
751                    return Some(Err(RecordParseError::Name(err)))
752                }
753                None => return None,
754            };
755            match record.into_record() {
756                Ok(Some(record)) => return Some(Ok(record)),
757                Err(err) => return Some(Err(err)),
758                Ok(None) => { }
759            }
760        }
761    }
762}
763
764
765//============ Testing ======================================================
766
767#[cfg(test)]
768mod test {
769    use std::str::FromStr;
770    use super::*;
771    use bits::name::*;
772    use bits::message_builder::*;
773    use rdata::Ns;
774    use bits::rdata::UnknownRecordData;
775
776    // Helper for test cases
777    fn get_test_message() -> Message {
778        let msg = MessageBuilder::with_capacity(512);
779        let mut msg = msg.answer();
780        msg.push((Dname::from_str("foo.example.com.").unwrap(), 86000,
781                     Cname::new(Dname::from_str("baz.example.com.")
782                                         .unwrap()))).unwrap();
783        let mut msg = msg.authority();
784        msg.push((Dname::from_str("bar.example.com.").unwrap(), 86000,
785                     Ns::new(Dname::from_str("baz.example.com.")
786                                         .unwrap()))).unwrap();
787
788        Message::from_bytes(msg.finish().into()).unwrap()
789    }
790
791    #[test]
792    fn short_message() {
793        assert!(Message::from_bytes(Bytes::from_static(&[0u8; 11])).is_err());
794        assert!(Message::from_bytes(Bytes::from_static(&[0u8; 12])).is_ok());
795    }
796
797        /*
798    use std::str::FromStr;
799    use bits::message_builder::MessageBuilder;
800    use bits::name::Dname;
801    use bits::question::Question;
802    use iana::Rtype;
803    use rdata::Cname;
804
805    #[test]
806    fn canonical_name() {
807        // Message without CNAMEs.
808        let mut msg = MessageBuilder::new_udp();
809        msg.push(&Question::new_in(Dname::from_str("example.com.").unwrap(),
810                                   Rtype::A)).unwrap();
811        let msg = Message::from_bytes(msg.freeze()).unwrap();
812        println!("{:?}", msg);
813        assert_eq!(Dname::from_str("example.com.").unwrap(),
814                   msg.canonical_name().unwrap());
815        // Message with CNAMEs.
816        let mut msg = MessageBuilder::new(ComposeMode::Unlimited,
817                                          true).unwrap();
818        msg.push((DNameBuf::from_str("example.com.").unwrap(),
819                  Rtype::A)).unwrap();
820        let mut answer = msg.answer();
821        answer.push((DNameBuf::from_str("bar.example.com.").unwrap(), 86000,
822                     Cname::new(DNameBuf::from_str("baz.example.com.")
823                                         .unwrap())))
824              .unwrap();
825        answer.push((DNameBuf::from_str("example.com.").unwrap(), 86000,
826                     Cname::new(DNameBuf::from_str("foo.example.com.")
827                                         .unwrap())))
828              .unwrap();
829        answer.push((DNameBuf::from_str("foo.example.com.").unwrap(), 86000,
830                     Cname::new(DNameBuf::from_str("bar.example.com.")
831                                         .unwrap())))
832              .unwrap();
833        let msg = MessageBuf::from_vec(answer.finish()).unwrap();
834        assert_eq!(DNameBuf::from_str("baz.example.com.").unwrap(),
835                   msg.canonical_name().unwrap());
836    }
837        */
838
839    #[test]
840    fn message_iterator() {
841        let msg = get_test_message();
842
843        // Check that it returns a record from first section
844        let mut iter = msg.iter();
845        let mut value = iter.next();
846        assert_eq!(true, value.is_some());
847        let (rr, section) = value.unwrap();
848        assert_eq!(Section::Answer, section);
849        assert!(rr.is_ok());
850
851        // Check that it advances to next section
852        value = iter.next();
853        assert_eq!(true, value.is_some());
854        let (rr, section) = value.unwrap();
855        assert_eq!(Section::Authority, section);
856        assert!(rr.is_ok());
857    }
858
859    #[test]
860    fn copy_records() {
861        let msg = get_test_message();
862        let target = MessageBuilder::with_capacity(512);
863        let res = msg.copy_records(target, |rec| {
864            if let Ok(rr) = rec {
865                if let Ok(Some(rr)) = rr.into_record::<UnknownRecordData>() {
866                    if rr.rtype() == Rtype::Cname {
867                        return Some(rr);
868                    }
869                }
870            }
871            return None;
872        });
873
874        assert!(res.is_ok());
875        if let Ok(target) = res {
876            let msg = target.freeze();
877            assert_eq!(1, msg.header_counts().ancount());
878            assert_eq!(0, msg.header_counts().arcount());
879        }
880    }
881}