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}