domain/base/
message_builder.rs

1//! Building a new DNS message.
2//!
3//! The types in this module allow building a DNS message consecutively from
4//! its parts. Since messages consist of five parts, a number of types are
5//! involved. The concept is that you start out with a [`MessageBuilder`] and
6//! work your way step by step through the sections by trading the builder in
7//! for on of another type representing the following section. The sequence
8//! is [`MessageBuilder`], [`QuestionBuilder`], [`AnswerBuilder`],
9//! [`AuthorityBuilder`], and finally [`AdditionalBuilder`].
10//!
11//! You can skip forward over unwanted sections. You can also go backwards,
12//! but then you’ll loose anything you built before. The naming of the
13//! methods that do these things is consistent across types: `builder` takes
14//! you to the message builder. The four methods `question`, `answer`,
15//! `additional`, and `authority` progress or return to the respective
16//! section. Finally, `finish` completes building.
17//!
18//! Each of the section builders offers a `push` method to add elements to
19//! the section. For the question section, the method accepts anything that
20//! resembles a [`Question`] while the three record sections except
21//! something that looks like a [`Record`]. Apart from actual values
22//! of these types, tuples of the components also work, such as a pair of a
23//! domain name and a record type for a question or a triple of the owner
24//! name, TTL, and record data for a record.
25//!
26//! The `push` method of the record
27//! section builders is also available via the [`RecordSectionBuilder`]
28//! trait so you can build code that works with all three record sections.
29//!
30//! The [`AdditionalBuilder`] has a special feature that helps building the
31//! OPT record for EDNS. Its [`opt`][AdditionalBuilder::opt] method allows a
32//! closure to build this record on the fly via the [`OptBuilder`] type.
33//!
34//! Building happens atop any [octets builder], so the type of buffer to use
35//! for building can be chosen. The module also provides a few helper types
36//! that provide optional features for building messages. All of these are
37//! wrappers around an octets builder and are octets builders themselves, so
38//! you can mix and match.
39//!
40//! First, the [`StreamTarget`] builds a message for use with streaming
41//! transport protocols, e.g., TCP, where the actual message is preceded by
42//! a 16 bit length counter. The stream target keeps this counter up-to-date
43//! and makes sure the message doesn’t become longer than what the counter
44//! can provide for.
45//!
46//! There is also support for name compression. This is a mechanism to decrease
47//! the size of a DNS message by avoiding repeating domain names: Instead of
48//! including a domain name or suffix of a domain name that has been mentioned
49//! already, a pointer to the position of the original mention is provided.
50//! Since this process is somewhat expensive as you have to remember which names
51//! have already been used, it isn’t enabled by default and is instead provided
52//! by separate octets builders which we call compressors.
53//!
54//! Currently, there are three different compressors. [`TreeCompressor`] stores
55//! all names it encountered in a binary tree. While it can handle any number
56//! of names, it does require an allocator and therefore cannot be used in a
57//! `no_std` environment. [`HashCompressor`] also requires allocation, but uses
58//! a fast and space efficient hash table (via the `hashbrown` crate) instead.
59//! [`StaticCompressor`], meanwhile, has a static table for up to 24 names. It
60//! is ineffective on large messages with lots of different names, but this is
61//! quite rare anyway.
62//!
63//! # Example
64//!
65//! The following example builds a message with both name compression and
66//! the stream length and simply puts two A records into it.
67//!
68#![cfg_attr(feature = "std", doc = "```")]
69#![cfg_attr(not(feature = "std"), doc = "```ignore")]
70//! use std::str::FromStr;
71//! use domain::base::{
72//!     Name, MessageBuilder, Rtype, StaticCompressor, StreamTarget
73//! };
74//! use domain::rdata::A;
75//!
76//! // Make a domain name we can use later on.
77//! let name = Name::<Vec<u8>>::from_str("example.com").unwrap();
78//!
79//! // Create a message builder wrapping a compressor wrapping a stream
80//! // target.
81//! let mut msg = MessageBuilder::from_target(
82//!     StaticCompressor::new(
83//!         StreamTarget::new_vec()
84//!     )
85//! ).unwrap();
86//!
87//! // Set the RD bit in the header and proceed to the question section.
88//! msg.header_mut().set_rd(true);
89//! let mut msg = msg.question();
90//!
91//! // Add a question and proceed to the answer section.
92//! msg.push((&name, Rtype::A)).unwrap();
93//! let mut msg = msg.answer();
94//!
95//! // Add two answer and proceed to the additional sections
96//! msg.push((&name, 86400, A::from_octets(192, 0, 2, 1))).unwrap();
97//! msg.push((&name, 86400, A::from_octets(192, 0, 2, 2))).unwrap();
98//! let mut msg = msg.additional();
99//!
100//! // Add an OPT record.
101//! msg.opt(|opt| {
102//!     opt.set_udp_payload_size(4096);
103//!     Ok(())
104//! }).unwrap();
105//!
106//! // Convert the builder into the actual message.
107//! let target = msg.finish().into_target();
108//!
109//! // A stream target can provide access to the data with or without the
110//! // length counter:
111//! let _ = target.as_stream_slice(); // With length
112//! let _ = target.as_dgram_slice(); // Without length
113//! ```
114//!
115//! [`MessageBuilder`]: struct.MessageBuilder.html
116//! [`QuestionBuilder`]: struct.QuestionBuilder.html
117//! [`AnswerBuilder`]: struct.AnswerBuilder.html
118//! [`AuthorityBuilder`]: struct.AuthorityBuilder.html
119//! [`AdditionalBuilder`]: struct.AdditionalBuilder.html
120//! [`AdditionalBuilder::opt`]: struct.AdditionalBuilder.html#method.opt
121//! [`OptBuilder`]: struct.OptBuilder.html
122//! [`RecordSectionBuilder`]: trait.RecordSectionBuilder.html
123//! [`StaticCompressor`]: struct.StaticCompressor.html
124//! [`StreamTarget`]: struct.StreamTarget.html
125//! [`TreeCompressor`]: struct.TreeCompressor.html
126//! [`Question`]: ../question/struct.Question.html
127//! [`Record`]: ../question/struct.Record.html
128//! [octets builder]: ../octets/trait.OctetsBuilder.html
129
130use super::header::{CountOverflow, Header, HeaderCounts, HeaderSection};
131#[cfg(feature = "rand")]
132use super::iana::Rtype;
133use super::iana::{OptRcode, OptionCode, Rcode};
134use super::message::Message;
135use super::name::{Label, ToName};
136use super::opt::{ComposeOptData, OptHeader, OptRecord};
137use super::question::ComposeQuestion;
138use super::record::ComposeRecord;
139use super::wire::{Compose, Composer};
140#[cfg(feature = "bytes")]
141use bytes::BytesMut;
142use core::ops::{Deref, DerefMut};
143use core::{fmt, mem};
144#[cfg(feature = "std")]
145use hashbrown::HashTable;
146#[cfg(feature = "std")]
147use octseq::array::Array;
148#[cfg(any(feature = "std", feature = "bytes"))]
149use octseq::builder::infallible;
150use octseq::builder::{FreezeBuilder, OctetsBuilder, ShortBuf, Truncate};
151use octseq::octets::Octets;
152#[cfg(feature = "std")]
153use std::collections::{hash_map::RandomState, HashMap};
154#[cfg(feature = "std")]
155use std::hash::BuildHasher;
156#[cfg(feature = "std")]
157use std::vec::Vec;
158
159//------------ MessageBuilder ------------------------------------------------
160
161/// Starts building a DNS message.
162///
163/// This type wraps an [`OctetsBuilder`] and starts the process of building a
164/// message. It allows access to the header section. The message builder can
165/// be traded in for any section builder or the underlying octets builder.
166///
167/// For more details see the [module documentation].
168///
169/// [module documentation]: index.html
170/// [`OctetsBuilder`]: ../../octets/trait.OctetsBuilder.html
171#[derive(Clone, Debug)]
172pub struct MessageBuilder<Target> {
173    target: Target,
174
175    /// An optional maximum message size.
176    ///
177    /// Defaults to usize::MAX.
178    limit: usize,
179}
180
181/// # Creating Message Builders
182///
183impl<Target: OctetsBuilder + Truncate> MessageBuilder<Target> {
184    /// Creates a new message builder using the given target.
185    ///
186    /// The target must be an [`OctetsBuilder`]. It will be truncated to zero
187    /// size before appending the header section. That is, all data that was
188    /// in the builder before will be lost.
189    ///
190    /// The function will result in an error if the builder doesn’t have
191    /// enough space for the header section.
192    pub fn from_target(
193        mut target: Target,
194    ) -> Result<Self, Target::AppendError> {
195        target.truncate(0);
196        target.append_slice(HeaderSection::new().as_slice())?;
197        Ok(MessageBuilder {
198            target,
199            limit: usize::MAX,
200        })
201    }
202}
203
204#[cfg(feature = "std")]
205impl MessageBuilder<Vec<u8>> {
206    /// Creates a new message builder atop a `Vec<u8>`.
207    #[must_use]
208    pub fn new_vec() -> Self {
209        infallible(Self::from_target(Vec::new()))
210    }
211}
212
213#[cfg(feature = "std")]
214impl MessageBuilder<StreamTarget<Vec<u8>>> {
215    /// Creates a new builder for a streamable message atop a `Vec<u8>`.
216    #[must_use]
217    pub fn new_stream_vec() -> Self {
218        Self::from_target(StreamTarget::new_vec()).unwrap()
219    }
220}
221
222#[cfg(feature = "bytes")]
223impl MessageBuilder<BytesMut> {
224    /// Creates a new message builder atop a bytes value.
225    pub fn new_bytes() -> Self {
226        infallible(Self::from_target(BytesMut::new()))
227    }
228}
229
230#[cfg(feature = "bytes")]
231impl MessageBuilder<StreamTarget<BytesMut>> {
232    /// Creates a new streamable message builder atop a bytes value.
233    pub fn new_stream_bytes() -> Self {
234        Self::from_target(StreamTarget::new_bytes()).unwrap()
235    }
236}
237
238impl<Target: Composer> MessageBuilder<Target> {
239    /// Starts creating an answer for the given message.
240    ///
241    /// Specifically, this sets the ID, QR, OPCODE, RD, and RCODE fields
242    /// in the header and attempts to push the message’s questions to the
243    /// builder.
244    ///
245    /// The method converts the message builder into an answer builder ready
246    /// to receive the answer for the question.
247    pub fn start_answer<Octs: Octets + ?Sized>(
248        mut self,
249        msg: &Message<Octs>,
250        rcode: Rcode,
251    ) -> Result<AnswerBuilder<Target>, PushError> {
252        {
253            let header = self.header_mut();
254            header.set_id(msg.header().id());
255            header.set_qr(true);
256            header.set_opcode(msg.header().opcode());
257            header.set_rd(msg.header().rd());
258            header.set_rcode(rcode);
259        }
260        let mut builder = self.question();
261        for item in msg.question().flatten() {
262            builder.push(item)?;
263        }
264        Ok(builder.answer())
265    }
266
267    /// Starts creating an error for the given message.
268    ///
269    /// Like [`start_answer()`][Self::start_answer] but infallible. Questions
270    /// will be pushed if possible.
271    pub fn start_error<Octs: Octets + ?Sized>(
272        mut self,
273        msg: &Message<Octs>,
274        rcode: Rcode,
275    ) -> AnswerBuilder<Target> {
276        {
277            let header = self.header_mut();
278            header.set_id(msg.header().id());
279            header.set_qr(true);
280            header.set_opcode(msg.header().opcode());
281            header.set_rd(msg.header().rd());
282            header.set_rcode(rcode);
283        }
284
285        let mut builder = self.question();
286        for item in msg.question().flatten() {
287            if builder.push(item).is_err() {
288                builder.header_mut().set_rcode(Rcode::SERVFAIL);
289                break;
290            }
291        }
292
293        builder.answer()
294    }
295
296    /// Creates an AXFR request for the given domain.
297    ///
298    /// Sets a random ID, pushes the domain and the AXFR record type into
299    /// the question section, and converts the builder into an answer builder.
300    #[cfg(feature = "rand")]
301    pub fn request_axfr<N: ToName>(
302        mut self,
303        apex: N,
304    ) -> Result<AnswerBuilder<Target>, PushError> {
305        self.header_mut().set_random_id();
306        let mut builder = self.question();
307        builder.push((apex, Rtype::AXFR))?;
308        Ok(builder.answer())
309    }
310}
311
312/// # Limiting message size
313impl<Target: Composer> MessageBuilder<Target> {
314    /// Limit how much of the underlying buffer may be used.
315    ///
316    /// When a limit is set, calling `push()` on a message section (e.g.
317    /// [`AdditionalBuilder::push()`]) will fail if the limit is exceeded just
318    /// as if the actual end of the underlying buffer had been reached.
319    ///
320    /// Note: Calling this function does NOT truncate the underlying buffer.
321    /// If the new limit is lees than the amount of the buffer that has
322    /// already been used, exisitng content beyond the limit will remain
323    /// untouched, the length will remain larger than the limit, and calls to
324    /// `push()` will fail until the buffer is truncated to a size less than
325    /// the limit.
326    pub fn set_push_limit(&mut self, limit: usize) {
327        self.limit = limit;
328    }
329
330    /// Clear the push limit, if set.
331    ///
332    /// Removes any push limit previously set via `[set_push_limit()`].
333    pub fn clear_push_limit(&mut self) {
334        self.limit = usize::MAX;
335    }
336
337    /// Returns the current push limit, if set.
338    pub fn push_limit(&self) -> Option<usize> {
339        if self.limit == usize::MAX {
340            None
341        } else {
342            Some(self.limit)
343        }
344    }
345}
346
347/// # Access to the Message Header
348///
349impl<Target: OctetsBuilder + AsRef<[u8]>> MessageBuilder<Target> {
350    /// Return the current value of the message header.
351    pub fn header(&self) -> Header {
352        *Header::for_message_slice(self.target.as_ref())
353    }
354
355    /// Return the current value of the message header counts.
356    pub fn counts(&self) -> HeaderCounts {
357        *HeaderCounts::for_message_slice(self.target.as_ref())
358    }
359}
360
361impl<Target: OctetsBuilder + AsMut<[u8]>> MessageBuilder<Target> {
362    /// Returns a mutable reference to the message header for manipulations.
363    pub fn header_mut(&mut self) -> &mut Header {
364        Header::for_message_slice_mut(self.target.as_mut())
365    }
366
367    /// Returns a mutable reference to the message header counts.
368    fn counts_mut(&mut self) -> &mut HeaderCounts {
369        HeaderCounts::for_message_slice_mut(self.target.as_mut())
370    }
371}
372
373/// # Conversions
374///
375impl<Target> MessageBuilder<Target> {
376    /// Converts the message builder into a message builder
377    ///
378    /// This is a no-op.
379    pub fn builder(self) -> MessageBuilder<Target> {
380        self
381    }
382}
383
384impl<Target: Composer> MessageBuilder<Target> {
385    /// Converts the message builder into a question builder.
386    pub fn question(self) -> QuestionBuilder<Target> {
387        QuestionBuilder::new(self)
388    }
389
390    /// Converts the message builder into an answer builder.
391    ///
392    /// This will leave the question section empty.
393    pub fn answer(self) -> AnswerBuilder<Target> {
394        self.question().answer()
395    }
396
397    /// Converts the message builder into an authority builder.
398    ///
399    /// This will leave the question and answer sections empty.
400    pub fn authority(self) -> AuthorityBuilder<Target> {
401        self.question().answer().authority()
402    }
403
404    /// Converts the message builder into an additional builder.
405    ///
406    /// This will leave the question, answer, and authority sections empty.
407    pub fn additional(self) -> AdditionalBuilder<Target> {
408        self.question().answer().authority().additional()
409    }
410
411    /// Converts the message into the underlying octets builder.
412    ///
413    /// This will leave the all sections empty.
414    pub fn finish(self) -> Target {
415        self.target
416    }
417}
418
419impl<Target: FreezeBuilder> MessageBuilder<Target> {
420    /// Converts the builder into a message.
421    ///
422    /// The method will return a message atop whatever octets sequence the
423    /// builder’s octets builder converts into.
424    pub fn into_message(self) -> Message<Target::Octets> {
425        unsafe { Message::from_octets_unchecked(self.target.freeze()) }
426    }
427}
428
429impl<Target> MessageBuilder<Target> {
430    /// Returns a reference to the underlying octets builder.
431    pub fn as_target(&self) -> &Target {
432        &self.target
433    }
434
435    /// Returns a mutable reference to the underlying octets builder.
436    ///
437    /// Since one could entirely mess up the message with this reference, the
438    /// method is private.
439    fn as_target_mut(&mut self) -> &mut Target {
440        &mut self.target
441    }
442
443    /// Returns an octets slice of the octets assembled so far.
444    pub fn as_slice(&self) -> &[u8]
445    where
446        Target: AsRef<[u8]>,
447    {
448        self.as_target().as_ref()
449    }
450
451    /// Returns a message atop for the octets assembled so far.
452    ///
453    /// This message is atop the octets slices derived from the builder, so
454    /// it can be created cheaply.
455    pub fn as_message(&self) -> Message<&[u8]>
456    where
457        Target: AsRef<[u8]>,
458    {
459        unsafe { Message::from_octets_unchecked(self.target.as_ref()) }
460    }
461}
462
463impl<Target: Composer> MessageBuilder<Target> {
464    fn push<Push, Inc>(
465        &mut self,
466        push: Push,
467        inc: Inc,
468    ) -> Result<(), PushError>
469    where
470        Push: FnOnce(&mut Target) -> Result<(), ShortBuf>,
471        Inc: FnOnce(&mut HeaderCounts) -> Result<(), CountOverflow>,
472    {
473        let pos = self.target.as_ref().len();
474        if let Err(err) = push(&mut self.target) {
475            self.target.truncate(pos);
476            return Err(From::from(err));
477        }
478
479        let new_pos = self.target.as_ref().len();
480        if new_pos >= self.limit {
481            self.target.truncate(pos);
482            return Err(PushError::ShortBuf);
483        }
484
485        if inc(self.counts_mut()).is_err() {
486            self.target.truncate(pos);
487            return Err(PushError::CountOverflow);
488        }
489        Ok(())
490    }
491}
492
493//--- From
494
495impl<Target> From<QuestionBuilder<Target>> for MessageBuilder<Target>
496where
497    Target: Composer,
498{
499    fn from(src: QuestionBuilder<Target>) -> Self {
500        src.builder()
501    }
502}
503
504impl<Target> From<AnswerBuilder<Target>> for MessageBuilder<Target>
505where
506    Target: Composer,
507{
508    fn from(src: AnswerBuilder<Target>) -> Self {
509        src.builder()
510    }
511}
512
513impl<Target> From<AuthorityBuilder<Target>> for MessageBuilder<Target>
514where
515    Target: Composer,
516{
517    fn from(src: AuthorityBuilder<Target>) -> Self {
518        src.builder()
519    }
520}
521
522impl<Target> From<AdditionalBuilder<Target>> for MessageBuilder<Target>
523where
524    Target: Composer,
525{
526    fn from(src: AdditionalBuilder<Target>) -> Self {
527        src.builder()
528    }
529}
530
531impl<Target> From<MessageBuilder<Target>> for Message<Target::Octets>
532where
533    Target: FreezeBuilder,
534{
535    fn from(src: MessageBuilder<Target>) -> Self {
536        src.into_message()
537    }
538}
539
540//--- AsRef
541//
542// XXX Should we deref down to target?
543
544impl<Target> AsRef<Target> for MessageBuilder<Target> {
545    fn as_ref(&self) -> &Target {
546        self.as_target()
547    }
548}
549
550impl<Target: AsRef<[u8]>> AsRef<[u8]> for MessageBuilder<Target> {
551    fn as_ref(&self) -> &[u8] {
552        self.as_slice()
553    }
554}
555
556//------------ QuestionBuilder -----------------------------------------------
557
558/// Builds the question section of a DNS message.
559///
560/// A value of this type can be acquired by calling the `question` method on
561/// any other builder type. See the [module documentation] for an overview of
562/// how to build a message.
563///
564/// You can push questions to the end of the question section via the
565/// [`push`] method. It accepts various things that represent a question:
566/// question values and references; tuples of a domain name, record type, and
567/// class; and, using the regular class of IN, a pair of just a domain name
568/// and record type.
569///
570/// Once you are finished building the question section, you can progress to
571/// the answer section via the [`answer`] method or finish the message via
572/// [`finish`]. Additionally, conversions to all other builder types are
573/// available as well.
574///
575/// [`answer`]: #method.answer
576/// [`finish`]: #method.finish
577/// [`push`]: #method.push
578/// [module documentation]: index.html
579#[derive(Clone, Debug)]
580pub struct QuestionBuilder<Target> {
581    builder: MessageBuilder<Target>,
582}
583
584impl<Target: OctetsBuilder> QuestionBuilder<Target> {
585    /// Creates a new question builder from a message builder.
586    fn new(builder: MessageBuilder<Target>) -> Self {
587        Self { builder }
588    }
589}
590
591impl<Target: Composer> QuestionBuilder<Target> {
592    /// Appends a question to the question section.
593    ///
594    /// This method accepts anything that implements the [`ComposeQuestion`]
595    /// trait. Apart from an actual [`Question`][super::question::Question]
596    /// or a reference to it, this can also be a tuple of a domain name,
597    /// record type, and class or, if the class is the usual IN, a pair of
598    /// just the name and type.
599    ///
600    /// In other words, the options are:
601    ///
602    #[cfg_attr(feature = "std", doc = "```")]
603    #[cfg_attr(not(feature = "std"), doc = "```ignore")]
604    /// use domain::base::{Name, MessageBuilder, Question, Rtype};
605    /// use domain::base::iana::Class;
606    ///
607    /// let mut msg = MessageBuilder::new_vec().question();
608    /// msg.push(Question::new_in(Name::root_ref(), Rtype::A)).unwrap();
609    /// msg.push(&Question::new_in(Name::root_ref(), Rtype::A)).unwrap();
610    /// msg.push((Name::root_ref(), Rtype::A, Class::IN)).unwrap();
611    /// msg.push((Name::root_ref(), Rtype::A)).unwrap();
612    /// ```
613    pub fn push(
614        &mut self,
615        question: impl ComposeQuestion,
616    ) -> Result<(), PushError> {
617        self.builder.push(
618            |target| question.compose_question(target).map_err(Into::into),
619            |counts| counts.inc_qdcount(),
620        )
621    }
622}
623
624/// # Conversions
625///
626/// Additional conversion are available via the `Deref` implementation.
627impl<Target: Composer> QuestionBuilder<Target> {
628    /// Rewinds to an empty question section.
629    ///
630    /// All previously added questions will be lost.
631    pub fn rewind(&mut self) {
632        self.as_target_mut()
633            .truncate(mem::size_of::<HeaderSection>());
634        self.counts_mut().set_qdcount(0);
635    }
636
637    /// Converts the question builder into a message builder.
638    ///
639    /// All questions will be dropped and the question section will be empty.
640    pub fn builder(mut self) -> MessageBuilder<Target> {
641        self.rewind();
642        self.builder
643    }
644}
645
646impl<Target> QuestionBuilder<Target> {
647    /// Converts the question builder into a question builder.
648    ///
649    /// In other words, doesn’t do anything.
650    pub fn question(self) -> QuestionBuilder<Target> {
651        self
652    }
653}
654
655impl<Target: Composer> QuestionBuilder<Target> {
656    /// Converts the question builder into an answer builder.
657    pub fn answer(self) -> AnswerBuilder<Target> {
658        AnswerBuilder::new(self.builder)
659    }
660
661    /// Converts the question builder into an authority builder.
662    ///
663    /// This will leave the answer section empty.
664    pub fn authority(self) -> AuthorityBuilder<Target> {
665        self.answer().authority()
666    }
667
668    /// Converts the question builder into an additional builder.
669    ///
670    /// This will leave the answer and authority sections empty.
671    pub fn additional(self) -> AdditionalBuilder<Target> {
672        self.answer().authority().additional()
673    }
674
675    /// Converts the question builder into the underlying octets builder.
676    ///
677    /// This will leave the answer, authority, and additional sections empty.
678    pub fn finish(self) -> Target {
679        self.builder.finish()
680    }
681}
682
683impl<Target: FreezeBuilder> QuestionBuilder<Target> {
684    /// Converts the question builder into the final message.
685    ///
686    /// The method will return a message atop whatever octets sequence the
687    /// builder’s octets builder converts into.
688    pub fn into_message(self) -> Message<Target::Octets> {
689        self.builder.into_message()
690    }
691}
692
693impl<Target> QuestionBuilder<Target> {
694    /// Returns a reference to the underlying message builder.
695    pub fn as_builder(&self) -> &MessageBuilder<Target> {
696        &self.builder
697    }
698
699    /// Returns a mutable reference to the underlying message builder.
700    pub fn as_builder_mut(&mut self) -> &mut MessageBuilder<Target> {
701        &mut self.builder
702    }
703}
704
705//--- From
706
707impl<Target> From<MessageBuilder<Target>> for QuestionBuilder<Target>
708where
709    Target: Composer,
710{
711    fn from(src: MessageBuilder<Target>) -> Self {
712        src.question()
713    }
714}
715
716impl<Target> From<AnswerBuilder<Target>> for QuestionBuilder<Target>
717where
718    Target: Composer,
719{
720    fn from(src: AnswerBuilder<Target>) -> Self {
721        src.question()
722    }
723}
724
725impl<Target> From<AuthorityBuilder<Target>> for QuestionBuilder<Target>
726where
727    Target: Composer,
728{
729    fn from(src: AuthorityBuilder<Target>) -> Self {
730        src.question()
731    }
732}
733
734impl<Target> From<AdditionalBuilder<Target>> for QuestionBuilder<Target>
735where
736    Target: Composer,
737{
738    fn from(src: AdditionalBuilder<Target>) -> Self {
739        src.question()
740    }
741}
742
743impl<Target> From<QuestionBuilder<Target>> for Message<Target::Octets>
744where
745    Target: FreezeBuilder,
746{
747    fn from(src: QuestionBuilder<Target>) -> Self {
748        src.into_message()
749    }
750}
751
752//--- Deref, DerefMut, AsRef, and AsMut
753
754impl<Target> Deref for QuestionBuilder<Target> {
755    type Target = MessageBuilder<Target>;
756
757    fn deref(&self) -> &Self::Target {
758        &self.builder
759    }
760}
761
762impl<Target> DerefMut for QuestionBuilder<Target> {
763    fn deref_mut(&mut self) -> &mut Self::Target {
764        &mut self.builder
765    }
766}
767
768impl<Target> AsRef<MessageBuilder<Target>> for QuestionBuilder<Target> {
769    fn as_ref(&self) -> &MessageBuilder<Target> {
770        self.as_builder()
771    }
772}
773
774impl<Target> AsMut<MessageBuilder<Target>> for QuestionBuilder<Target> {
775    fn as_mut(&mut self) -> &mut MessageBuilder<Target> {
776        self.as_builder_mut()
777    }
778}
779
780impl<Target> AsRef<Target> for QuestionBuilder<Target> {
781    fn as_ref(&self) -> &Target {
782        self.as_target()
783    }
784}
785
786impl<Target: AsRef<[u8]>> AsRef<[u8]> for QuestionBuilder<Target> {
787    fn as_ref(&self) -> &[u8] {
788        self.as_slice()
789    }
790}
791
792//------------ AnswerBuilder -------------------------------------------------
793
794/// Builds the answer section of a DNS message.
795///
796/// A value of this type can be acquired by calling the `answer` method on
797/// any other builder type. See the [module documentation] for an overview of
798/// how to build a message.
799///
800/// You can push records to the end of the answer section via the [`push`]
801/// method. It accepts various things that represent resource records: record
802/// values and references, tuples of an owner domain name, a class, TTL, and
803/// record data, as well as tuples of just the owner, TTL, and data, assuming
804/// the class of IN.
805///
806/// Once you are finished building the answer section, you can progress to
807/// the authority section via the [`authority`] method or finish the message
808/// via [`finish`]. Additionally, conversions to all other builder types are
809/// available as well.
810///
811/// [`authority`]: #method.authority
812/// [`finish`]: #method.finish
813/// [`push`]: #method.push
814/// [module documentation]: index.html
815#[derive(Clone, Debug)]
816pub struct AnswerBuilder<Target> {
817    /// The message builder we work on.
818    builder: MessageBuilder<Target>,
819
820    /// The index in the octets builder where the answer section starts.
821    start: usize,
822}
823
824impl<Target: Composer> AnswerBuilder<Target> {
825    /// Creates a new answer builder from an underlying message builder.
826    ///
827    /// Assumes that all three record sections are empty.
828    #[must_use]
829    fn new(builder: MessageBuilder<Target>) -> Self {
830        AnswerBuilder {
831            start: builder.target.as_ref().len(),
832            builder,
833        }
834    }
835}
836
837impl<Target> AnswerBuilder<Target> {
838    #[must_use]
839    pub fn into_target(self) -> Target {
840        self.builder.target
841    }
842}
843
844impl<Target: Composer> AnswerBuilder<Target> {
845    /// Appends a record to the answer section.
846    ///
847    /// This methods accepts anything that implements the [`ComposeRecord`]
848    /// trait. Apart from record values and references, this are tuples of
849    /// the owner domain name, optionally the class (which is taken to be IN
850    /// if missing), the TTL, and record data.
851    ///
852    /// In other words, you can do the following things:
853    ///
854    #[cfg_attr(feature = "std", doc = "```")]
855    #[cfg_attr(not(feature = "std"), doc = "```ignore")]
856    /// use domain::base::{Name, MessageBuilder, Record, Rtype, Ttl};
857    /// use domain::base::iana::Class;
858    /// use domain::rdata::A;
859    ///
860    /// let mut msg = MessageBuilder::new_vec().answer();
861    /// let record = Record::new(
862    ///     Name::root_ref(), Class::IN, Ttl::from_secs(86400), A::from_octets(192, 0, 2, 1)
863    /// );
864    /// msg.push(&record).unwrap();
865    /// msg.push(record).unwrap();
866    /// msg.push(
867    ///     (Name::root_ref(), Class::IN, 86400, A::from_octets(192, 0, 2, 1))
868    /// ).unwrap();
869    /// msg.push(
870    ///     (Name::root_ref(), 86400, A::from_octets(192, 0, 2, 1))
871    /// ).unwrap();
872    /// ```
873    ///
874    pub fn push(
875        &mut self,
876        record: impl ComposeRecord,
877    ) -> Result<(), PushError> {
878        self.builder.push(
879            |target| record.compose_record(target).map_err(Into::into),
880            |counts| counts.inc_ancount(),
881        )
882    }
883
884    /// Appends a record to the answer section without consuming it.
885    ///
886    /// See [`push`][Self::push].
887    pub fn push_ref(
888        &mut self,
889        record: &impl ComposeRecord,
890    ) -> Result<(), PushError> {
891        self.builder.push(
892            |target| record.compose_record(target).map_err(Into::into),
893            |counts| counts.inc_ancount(),
894        )
895    }
896}
897
898/// # Conversions
899///
900/// Additional conversion are available via the `Deref` implementation.
901impl<Target: Composer> AnswerBuilder<Target> {
902    /// Rewinds to an empty answer section.
903    ///
904    /// All previously added answers will be lost.
905    pub fn rewind(&mut self) {
906        self.builder.target.truncate(self.start);
907        self.counts_mut().set_ancount(0);
908    }
909
910    /// Converts the answer builder into a message builder.
911    ///
912    /// All questions and answers will be dropped and all sections will be
913    /// empty.
914    pub fn builder(self) -> MessageBuilder<Target> {
915        self.question().builder()
916    }
917
918    /// Converts the answer builder into a question builder.
919    ///
920    /// All answers will be dropped. All previously added questions will,
921    /// however, remain.
922    pub fn question(mut self) -> QuestionBuilder<Target> {
923        self.rewind();
924        QuestionBuilder::new(self.builder)
925    }
926}
927
928impl<Target: Composer> AnswerBuilder<Target> {
929    /// Converts the answer builder into an answer builder.
930    ///
931    /// This doesn’t do anything, really.
932    pub fn answer(self) -> AnswerBuilder<Target> {
933        self
934    }
935
936    /// Converts the answer builder into an authority builder.
937    pub fn authority(self) -> AuthorityBuilder<Target> {
938        AuthorityBuilder::new(self)
939    }
940
941    /// Converts the answer builder into an additional builder.
942    ///
943    /// This will leave the authority section empty.
944    pub fn additional(self) -> AdditionalBuilder<Target> {
945        self.authority().additional()
946    }
947
948    /// Converts the answer builder into the underlying octets builder.
949    ///
950    /// This will leave the authority and additional sections empty.
951    pub fn finish(self) -> Target {
952        self.builder.finish()
953    }
954}
955
956impl<Target: FreezeBuilder> AnswerBuilder<Target> {
957    /// Converts the answer builder into the final message.
958    ///
959    /// The method will return a message atop whatever octets sequence the
960    /// builder’s octets builder converts into.
961    pub fn into_message(self) -> Message<Target::Octets> {
962        self.builder.into_message()
963    }
964}
965
966impl<Target> AnswerBuilder<Target> {
967    /// Returns a reference to the underlying message builder.
968    pub fn as_builder(&self) -> &MessageBuilder<Target> {
969        &self.builder
970    }
971
972    /// Returns a mutable reference to the underlying message builder.
973    pub fn as_builder_mut(&mut self) -> &mut MessageBuilder<Target> {
974        &mut self.builder
975    }
976}
977
978//--- From
979
980impl<Target> From<MessageBuilder<Target>> for AnswerBuilder<Target>
981where
982    Target: Composer,
983{
984    fn from(src: MessageBuilder<Target>) -> Self {
985        src.answer()
986    }
987}
988
989impl<Target> From<QuestionBuilder<Target>> for AnswerBuilder<Target>
990where
991    Target: Composer,
992{
993    fn from(src: QuestionBuilder<Target>) -> Self {
994        src.answer()
995    }
996}
997
998impl<Target> From<AuthorityBuilder<Target>> for AnswerBuilder<Target>
999where
1000    Target: Composer,
1001{
1002    fn from(src: AuthorityBuilder<Target>) -> Self {
1003        src.answer()
1004    }
1005}
1006
1007impl<Target> From<AdditionalBuilder<Target>> for AnswerBuilder<Target>
1008where
1009    Target: Composer,
1010{
1011    fn from(src: AdditionalBuilder<Target>) -> Self {
1012        src.answer()
1013    }
1014}
1015
1016impl<Target> From<AnswerBuilder<Target>> for Message<Target::Octets>
1017where
1018    Target: FreezeBuilder,
1019{
1020    fn from(src: AnswerBuilder<Target>) -> Self {
1021        src.into_message()
1022    }
1023}
1024
1025//--- Deref, DerefMut, AsRef, and AsMut
1026
1027impl<Target> Deref for AnswerBuilder<Target> {
1028    type Target = MessageBuilder<Target>;
1029
1030    fn deref(&self) -> &Self::Target {
1031        &self.builder
1032    }
1033}
1034
1035impl<Target> DerefMut for AnswerBuilder<Target> {
1036    fn deref_mut(&mut self) -> &mut Self::Target {
1037        &mut self.builder
1038    }
1039}
1040
1041impl<Target> AsRef<MessageBuilder<Target>> for AnswerBuilder<Target> {
1042    fn as_ref(&self) -> &MessageBuilder<Target> {
1043        self.as_builder()
1044    }
1045}
1046
1047impl<Target> AsMut<MessageBuilder<Target>> for AnswerBuilder<Target> {
1048    fn as_mut(&mut self) -> &mut MessageBuilder<Target> {
1049        self.as_builder_mut()
1050    }
1051}
1052
1053impl<Target> AsRef<Target> for AnswerBuilder<Target> {
1054    fn as_ref(&self) -> &Target {
1055        self.as_target()
1056    }
1057}
1058
1059impl<Target: AsRef<[u8]>> AsRef<[u8]> for AnswerBuilder<Target> {
1060    fn as_ref(&self) -> &[u8] {
1061        self.as_slice()
1062    }
1063}
1064
1065//------------ AuthorityBuilder ----------------------------------------------
1066
1067/// Builds the authority section of a DNS message.
1068///
1069/// A value of this type can be acquired by calling the `authority` method on
1070/// any other builder type. See the [module documentation] for an overview of
1071/// how to build a message.
1072///
1073/// You can push records to the end of the authority section via the [`push`]
1074/// method. It accepts various things that represent resource records: record
1075/// values and references, tuples of an owner domain name, a class, TTL, and
1076/// record data, as well as tuples of just the owner, TTL, and data, assuming
1077/// the class of IN.
1078///
1079/// Once you are finished building the authority section, you can progress to
1080/// the additional section via the [`additional`] method or finish the message
1081/// via [`finish`]. Additionally, conversions to all other builder types are
1082/// available as well.
1083///
1084/// [`additional`]: #method.additional
1085/// [`finish`]: #method.finish
1086/// [`push`]: #method.push
1087/// [module documentation]: index.html
1088#[derive(Clone, Debug)]
1089pub struct AuthorityBuilder<Target> {
1090    /// The message builder we work on.
1091    answer: AnswerBuilder<Target>,
1092
1093    /// The index in the octets builder where the authority section starts.
1094    start: usize,
1095}
1096
1097impl<Target: Composer> AuthorityBuilder<Target> {
1098    /// Creates a new authority builder from an answer builder.
1099    ///
1100    /// Assumes that the authority and additional sections are empty.
1101    fn new(answer: AnswerBuilder<Target>) -> Self {
1102        AuthorityBuilder {
1103            start: answer.as_target().as_ref().len(),
1104            answer,
1105        }
1106    }
1107}
1108
1109impl<Target: Composer> AuthorityBuilder<Target> {
1110    /// Appends a record to the authority section.
1111    ///
1112    /// This methods accepts anything that implements the [`ComposeRecord`] trait.
1113    /// Apart from record values and references, this are tuples of the owner
1114    /// domain name, optionally the class (which is taken to be IN if
1115    /// missing), the TTL, and record data.
1116    ///
1117    /// In other words, you can do the following things:
1118    ///
1119    #[cfg_attr(feature = "std", doc = "```")]
1120    #[cfg_attr(not(feature = "std"), doc = "```ignore")]
1121    /// use domain::base::{Name, MessageBuilder, Record, Rtype, Ttl};
1122    /// use domain::base::iana::Class;
1123    /// use domain::rdata::A;
1124    ///
1125    /// let mut msg = MessageBuilder::new_vec().authority();
1126    /// let record = Record::new(
1127    ///     Name::root_ref(), Class::IN, Ttl::from_secs(86400),
1128    ///     A::from_octets(192, 0, 2, 1)
1129    /// );
1130    /// msg.push(&record).unwrap();
1131    /// msg.push(record).unwrap();
1132    /// msg.push(
1133    ///     (Name::root_ref(), Class::IN, 86400, A::from_octets(192, 0, 2, 1))
1134    /// ).unwrap();
1135    /// msg.push(
1136    ///     (Name::root_ref(), 86400, A::from_octets(192, 0, 2, 1))
1137    /// ).unwrap();
1138    /// ```
1139    pub fn push(
1140        &mut self,
1141        record: impl ComposeRecord,
1142    ) -> Result<(), PushError> {
1143        self.answer.builder.push(
1144            |target| record.compose_record(target).map_err(Into::into),
1145            |counts| counts.inc_nscount(),
1146        )
1147    }
1148}
1149
1150/// # Conversions
1151///
1152/// Additional conversion methods are available via the `Deref`
1153/// implementation.
1154impl<Target: Composer> AuthorityBuilder<Target> {
1155    /// Rewinds to an empty authority section.
1156    ///
1157    /// All previously added authority records will be lost.
1158    pub fn rewind(&mut self) {
1159        self.answer.as_target_mut().truncate(self.start);
1160        self.counts_mut().set_nscount(0);
1161    }
1162
1163    /// Converts the authority builder into a message builder.
1164    ///
1165    /// All questions, answer and authority records will be dropped and all
1166    /// sections will be empty.
1167    pub fn builder(self) -> MessageBuilder<Target> {
1168        self.question().builder()
1169    }
1170
1171    /// Converts the authority builder into a question builder.
1172    ///
1173    /// All authority and answer records will be dropped. All previously added
1174    /// questions will, however, remain.
1175    pub fn question(self) -> QuestionBuilder<Target> {
1176        self.answer().question()
1177    }
1178
1179    /// Converts the authority builder into an answer builder.
1180    ///
1181    /// All authority records will be dropped. All previously added questions
1182    /// and answer records will, however, remain.
1183    pub fn answer(mut self) -> AnswerBuilder<Target> {
1184        self.rewind();
1185        self.answer
1186    }
1187
1188    /// Converts the authority builder into an authority builder.
1189    ///
1190    /// This is identical to the identity function.
1191    pub fn authority(self) -> AuthorityBuilder<Target> {
1192        self
1193    }
1194
1195    /// Converts the authority builder into an additional builder.
1196    pub fn additional(self) -> AdditionalBuilder<Target> {
1197        AdditionalBuilder::new(self)
1198    }
1199
1200    /// Converts the authority builder into the underlying octets builder.
1201    ///
1202    /// This will leave the additional section empty.
1203    pub fn finish(self) -> Target {
1204        self.answer.finish()
1205    }
1206}
1207
1208impl<Target: FreezeBuilder> AuthorityBuilder<Target> {
1209    /// Converts the authority builder into the final message.
1210    ///
1211    /// The method will return a message atop whatever octets sequence the
1212    /// builder’s octets builder converts into.
1213    pub fn into_message(self) -> Message<Target::Octets> {
1214        self.answer.into_message()
1215    }
1216}
1217
1218impl<Target> AuthorityBuilder<Target> {
1219    /// Returns a reference to the underlying message builder.
1220    pub fn as_builder(&self) -> &MessageBuilder<Target> {
1221        self.answer.as_builder()
1222    }
1223
1224    /// Returns a mutable reference to the underlying message builder.
1225    pub fn as_builder_mut(&mut self) -> &mut MessageBuilder<Target> {
1226        self.answer.as_builder_mut()
1227    }
1228}
1229
1230//--- From
1231
1232impl<Target> From<MessageBuilder<Target>> for AuthorityBuilder<Target>
1233where
1234    Target: Composer,
1235{
1236    fn from(src: MessageBuilder<Target>) -> Self {
1237        src.authority()
1238    }
1239}
1240
1241impl<Target> From<QuestionBuilder<Target>> for AuthorityBuilder<Target>
1242where
1243    Target: Composer,
1244{
1245    fn from(src: QuestionBuilder<Target>) -> Self {
1246        src.authority()
1247    }
1248}
1249
1250impl<Target> From<AnswerBuilder<Target>> for AuthorityBuilder<Target>
1251where
1252    Target: Composer,
1253{
1254    fn from(src: AnswerBuilder<Target>) -> Self {
1255        src.authority()
1256    }
1257}
1258
1259impl<Target> From<AdditionalBuilder<Target>> for AuthorityBuilder<Target>
1260where
1261    Target: Composer,
1262{
1263    fn from(src: AdditionalBuilder<Target>) -> Self {
1264        src.authority()
1265    }
1266}
1267
1268impl<Target> From<AuthorityBuilder<Target>> for Message<Target::Octets>
1269where
1270    Target: FreezeBuilder,
1271{
1272    fn from(src: AuthorityBuilder<Target>) -> Self {
1273        src.into_message()
1274    }
1275}
1276
1277//--- Deref, DerefMut, AsRef, and AsMut
1278
1279impl<Target> Deref for AuthorityBuilder<Target> {
1280    type Target = MessageBuilder<Target>;
1281
1282    fn deref(&self) -> &Self::Target {
1283        self.answer.deref()
1284    }
1285}
1286
1287impl<Target> DerefMut for AuthorityBuilder<Target> {
1288    fn deref_mut(&mut self) -> &mut Self::Target {
1289        self.answer.deref_mut()
1290    }
1291}
1292
1293impl<Target> AsRef<MessageBuilder<Target>> for AuthorityBuilder<Target> {
1294    fn as_ref(&self) -> &MessageBuilder<Target> {
1295        self.as_builder()
1296    }
1297}
1298
1299impl<Target> AsMut<MessageBuilder<Target>> for AuthorityBuilder<Target> {
1300    fn as_mut(&mut self) -> &mut MessageBuilder<Target> {
1301        self.as_builder_mut()
1302    }
1303}
1304
1305impl<Target> AsRef<Target> for AuthorityBuilder<Target> {
1306    fn as_ref(&self) -> &Target {
1307        self.as_target()
1308    }
1309}
1310
1311impl<Target: AsRef<[u8]>> AsRef<[u8]> for AuthorityBuilder<Target> {
1312    fn as_ref(&self) -> &[u8] {
1313        self.as_slice()
1314    }
1315}
1316
1317//------------ AdditionalBuilder ---------------------------------------------
1318
1319/// Builds the additional section of a DNS message.
1320///
1321/// A value of this type can be acquired by calling the `additional` method on
1322/// any other builder type. See the [module documentation] for an overview of
1323/// how to build a message.
1324///
1325/// You can push records to the end of the additional section via the [`push`]
1326/// method. It accepts various things that represent resource records: record
1327/// values and references, tuples of an owner domain name, a class, TTL, and
1328/// record data, as well as tuples of just the owner, TTL, and data, assuming
1329/// the class of IN.
1330///
1331/// A special method exists to make adding an OPT record to the section
1332/// easier. The [`opt`] method creates an [`OptBuilder`] and passes it to a
1333/// closure. This way, you can add and remove OPT records from additional
1334/// builders that are part of another type and cannot be traded in easily.
1335///
1336/// Once you are finished building the additional section, you can finish the
1337/// message via [`finish`]. Additionally, conversions to all other builder
1338/// types are available as well.
1339///
1340/// [`finish`]: #method.finish
1341/// [`opt`]: #method.opt
1342/// [`push`]: #method.push
1343/// [`OptBuilder`]: struct.OptBuilder.html
1344/// [module documentation]: index.html
1345#[derive(Clone, Debug)]
1346pub struct AdditionalBuilder<Target> {
1347    /// The message builder we work on.
1348    authority: AuthorityBuilder<Target>,
1349
1350    /// The index in the octets builder where the additional section starts.
1351    start: usize,
1352}
1353
1354impl<Target: Composer> AdditionalBuilder<Target> {
1355    /// Creates a new additional builder from an authority builder.
1356    ///
1357    /// Assumes that the additional section is currently empty.
1358    fn new(authority: AuthorityBuilder<Target>) -> Self {
1359        AdditionalBuilder {
1360            start: authority.as_target().as_ref().len(),
1361            authority,
1362        }
1363    }
1364}
1365
1366impl<Target: Composer> AdditionalBuilder<Target> {
1367    /// Appends a record to the additional section.
1368    ///
1369    /// This methods accepts anything that implements the
1370    /// [`ComposeRecord`] trait.
1371    /// Apart from record values and references, this are tuples of the owner
1372    /// domain name, optionally the class (which is taken to be IN if
1373    /// missing), the TTL, and record data.
1374    ///
1375    /// In other words, you can do the following things:
1376    ///
1377    #[cfg_attr(feature = "std", doc = "```")]
1378    #[cfg_attr(not(feature = "std"), doc = "```ignore")]
1379    /// use domain::base::{Name, MessageBuilder, Record, Rtype, Ttl};
1380    /// use domain::base::iana::Class;
1381    /// use domain::rdata::A;
1382    ///
1383    /// let mut msg = MessageBuilder::new_vec().additional();
1384    /// let record = Record::new(
1385    ///     Name::root_ref(), Class::IN, Ttl::from_secs(86400), A::from_octets(192, 0, 2, 1)
1386    /// );
1387    /// msg.push(&record).unwrap();
1388    /// msg.push(record).unwrap();
1389    /// msg.push(
1390    ///     (Name::root_ref(), Class::IN, 86400, A::from_octets(192, 0, 2, 1))
1391    /// ).unwrap();
1392    /// msg.push(
1393    ///     (Name::root_ref(), 86400, A::from_octets(192, 0, 2, 1))
1394    /// ).unwrap();
1395    /// ```
1396    pub fn push(
1397        &mut self,
1398        record: impl ComposeRecord,
1399    ) -> Result<(), PushError> {
1400        self.authority.answer.builder.push(
1401            |target| record.compose_record(target).map_err(Into::into),
1402            |counts| counts.inc_arcount(),
1403        )
1404    }
1405}
1406
1407impl<Target: Composer> AdditionalBuilder<Target> {
1408    /// Appends and builds an OPT record.
1409    ///
1410    /// The actual building of the record is handled by a closure that
1411    /// receives an [`OptBuilder`] which can both change the header of the
1412    /// record and add options.
1413    ///
1414    /// The method will return whatever the closure returns. In addition, it
1415    /// will return an error if it failed to add the header of the OPT record.
1416    ///
1417    /// [`OptBuilder`]: struct.OptBuilder.html
1418    pub fn opt<F>(&mut self, op: F) -> Result<(), PushError>
1419    where
1420        F: FnOnce(
1421            &mut OptBuilder<'_, Target>,
1422        ) -> Result<(), Target::AppendError>,
1423    {
1424        self.authority.answer.builder.push(
1425            |target| OptBuilder::new(target)?.build(op),
1426            |counts| counts.inc_arcount(),
1427        )
1428    }
1429}
1430
1431/// # Conversions
1432///
1433/// Additional conversion methods are available via the `Deref`
1434/// implementation.
1435impl<Target: Composer> AdditionalBuilder<Target> {
1436    /// Rewinds to an empty additional section.
1437    ///
1438    /// All previously added additional records will be lost.
1439    pub fn rewind(&mut self) {
1440        self.authority.as_target_mut().truncate(self.start);
1441        self.counts_mut().set_arcount(0);
1442    }
1443
1444    /// Converts the additional builder into a message builder.
1445    ///
1446    /// All questions and records will be dropped and all sections will be
1447    /// empty.
1448    pub fn builder(self) -> MessageBuilder<Target> {
1449        self.question().builder()
1450    }
1451
1452    /// Converts the additional builder into a question builder.
1453    ///
1454    /// All answer, authority, and additional records will be dropped. All
1455    /// previously added questions will, however, remain.
1456    pub fn question(self) -> QuestionBuilder<Target> {
1457        self.answer().question()
1458    }
1459
1460    /// Converts the additional builder into an answer builder.
1461    ///
1462    /// All authority and additional records will be dropped. All questions
1463    /// and answer records will remain.
1464    pub fn answer(self) -> AnswerBuilder<Target> {
1465        self.authority().answer()
1466    }
1467
1468    /// Converts the additional builder into an authority builder.
1469    ///
1470    /// All additional records will be dropped. All questions, answer, and
1471    /// authority records will remain.
1472    pub fn authority(mut self) -> AuthorityBuilder<Target> {
1473        self.rewind();
1474        self.authority
1475    }
1476
1477    /// Converts the additional builder into an additional builder.
1478    ///
1479    /// In other words, does absolutely nothing.
1480    pub fn additional(self) -> AdditionalBuilder<Target> {
1481        self
1482    }
1483
1484    /// Converts the additional builder into the underlying octets builder.
1485    pub fn finish(self) -> Target {
1486        self.authority.finish()
1487    }
1488}
1489
1490impl<Target: FreezeBuilder> AdditionalBuilder<Target> {
1491    /// Converts the additional builder into the final message.
1492    ///
1493    /// The method will return a message atop whatever octets sequence the
1494    /// builder’s octets builder converts into.
1495    pub fn into_message(self) -> Message<Target::Octets> {
1496        self.authority.into_message()
1497    }
1498}
1499
1500impl<Target> AdditionalBuilder<Target> {
1501    /// Returns a reference to the underlying message builder.
1502    pub fn as_builder(&self) -> &MessageBuilder<Target> {
1503        self.authority.as_builder()
1504    }
1505
1506    /// Returns a mutable reference to the underlying message builder.
1507    pub fn as_builder_mut(&mut self) -> &mut MessageBuilder<Target> {
1508        self.authority.as_builder_mut()
1509    }
1510}
1511
1512//--- From
1513
1514impl<Target> From<MessageBuilder<Target>> for AdditionalBuilder<Target>
1515where
1516    Target: Composer,
1517{
1518    fn from(src: MessageBuilder<Target>) -> Self {
1519        src.additional()
1520    }
1521}
1522
1523impl<Target> From<QuestionBuilder<Target>> for AdditionalBuilder<Target>
1524where
1525    Target: Composer,
1526{
1527    fn from(src: QuestionBuilder<Target>) -> Self {
1528        src.additional()
1529    }
1530}
1531
1532impl<Target> From<AnswerBuilder<Target>> for AdditionalBuilder<Target>
1533where
1534    Target: Composer,
1535{
1536    fn from(src: AnswerBuilder<Target>) -> Self {
1537        src.additional()
1538    }
1539}
1540
1541impl<Target> From<AuthorityBuilder<Target>> for AdditionalBuilder<Target>
1542where
1543    Target: Composer,
1544{
1545    fn from(src: AuthorityBuilder<Target>) -> Self {
1546        src.additional()
1547    }
1548}
1549
1550impl<Target> From<AdditionalBuilder<Target>> for Message<Target::Octets>
1551where
1552    Target: FreezeBuilder,
1553{
1554    fn from(src: AdditionalBuilder<Target>) -> Self {
1555        src.into_message()
1556    }
1557}
1558
1559//--- Deref, DerefMut, AsRef, and AsMut
1560
1561impl<Target> Deref for AdditionalBuilder<Target> {
1562    type Target = MessageBuilder<Target>;
1563
1564    fn deref(&self) -> &Self::Target {
1565        self.as_builder()
1566    }
1567}
1568
1569impl<Target> DerefMut for AdditionalBuilder<Target> {
1570    fn deref_mut(&mut self) -> &mut Self::Target {
1571        self.as_builder_mut()
1572    }
1573}
1574
1575impl<Target> AsRef<MessageBuilder<Target>> for AdditionalBuilder<Target> {
1576    fn as_ref(&self) -> &MessageBuilder<Target> {
1577        self.as_builder()
1578    }
1579}
1580
1581impl<Target> AsMut<MessageBuilder<Target>> for AdditionalBuilder<Target> {
1582    fn as_mut(&mut self) -> &mut MessageBuilder<Target> {
1583        self.as_builder_mut()
1584    }
1585}
1586
1587impl<Target> AsRef<Target> for AdditionalBuilder<Target> {
1588    fn as_ref(&self) -> &Target {
1589        self.as_target()
1590    }
1591}
1592
1593impl<Target: AsRef<[u8]>> AsRef<[u8]> for AdditionalBuilder<Target> {
1594    fn as_ref(&self) -> &[u8] {
1595        self.as_slice()
1596    }
1597}
1598
1599//------------ RecordSectionBuilder ------------------------------------------
1600
1601/// A section that can have records pushed to it.
1602///
1603/// This trait exists to make it possible to write code that works for all
1604/// three record sections. It basically just duplicates the `push` method of
1605/// these sections.
1606///
1607/// (This method is available on the sections as a method, too, so you don’t
1608/// need to import the `RecordSectionBuilder` all the time.)
1609pub trait RecordSectionBuilder<Target: Composer> {
1610    /// Appends a record to a record section.
1611    ///
1612    /// The methods accepts anything that implements the [`ComposeRecord`] trait.
1613    /// Apart from record values and references, this are tuples of the owner
1614    /// domain name, optionally the class (which is taken to be IN if
1615    /// missing), the TTL, and record data.
1616    fn push(&mut self, record: impl ComposeRecord) -> Result<(), PushError>;
1617}
1618
1619impl<Target> RecordSectionBuilder<Target> for AnswerBuilder<Target>
1620where
1621    Target: Composer,
1622{
1623    fn push(&mut self, record: impl ComposeRecord) -> Result<(), PushError> {
1624        Self::push(self, record)
1625    }
1626}
1627
1628impl<Target: Composer> RecordSectionBuilder<Target>
1629    for AuthorityBuilder<Target>
1630{
1631    fn push(&mut self, record: impl ComposeRecord) -> Result<(), PushError> {
1632        Self::push(self, record)
1633    }
1634}
1635
1636impl<Target> RecordSectionBuilder<Target> for AdditionalBuilder<Target>
1637where
1638    Target: Composer,
1639{
1640    fn push(&mut self, record: impl ComposeRecord) -> Result<(), PushError> {
1641        Self::push(self, record)
1642    }
1643}
1644
1645//------------ OptBuilder ----------------------------------------------------
1646
1647/// Builds an OPT record.
1648///
1649/// A mutable reference of this type is passed to the closure given to
1650/// [`AdditionalBuilder::opt`] allowing this closure to manipulate both the
1651/// header values of the record and push options to the record data.
1652///
1653/// [`AdditionalBuilder::opt`]: struct.AdditonalBuilder.html#method.opt
1654pub struct OptBuilder<'a, Target: ?Sized> {
1655    start: usize,
1656    target: &'a mut Target,
1657}
1658
1659impl<'a, Target: Composer + ?Sized> OptBuilder<'a, Target> {
1660    /// Creates a new opt builder atop an additional builder.
1661    fn new(target: &'a mut Target) -> Result<Self, ShortBuf> {
1662        let start = target.as_ref().len();
1663        OptHeader::default().compose(target).map_err(Into::into)?;
1664        Ok(OptBuilder { start, target })
1665    }
1666
1667    fn build<F>(&mut self, op: F) -> Result<(), ShortBuf>
1668    where
1669        F: FnOnce(&mut Self) -> Result<(), Target::AppendError>,
1670    {
1671        self.target.append_slice(&[0; 2]).map_err(Into::into)?;
1672        let pos = self.target.as_ref().len();
1673        match op(self) {
1674            Ok(_) => match u16::try_from(self.target.as_ref().len() - pos) {
1675                Ok(len) => {
1676                    self.target.as_mut()[pos - 2..pos]
1677                        .copy_from_slice(&(len).to_be_bytes());
1678                    Ok(())
1679                }
1680                Err(_) => {
1681                    self.target.truncate(pos);
1682                    Err(ShortBuf)
1683                }
1684            },
1685            Err(_) => {
1686                self.target.truncate(pos);
1687                Err(ShortBuf)
1688            }
1689        }
1690    }
1691
1692    /// Replaces the contents of this [`OptBuilder`] with the given
1693    /// [`OptRecord`]`.
1694    pub fn clone_from<T: AsRef<[u8]>>(
1695        &mut self,
1696        source: &OptRecord<T>,
1697    ) -> Result<(), Target::AppendError> {
1698        self.target.truncate(self.start);
1699        source.as_record().compose(self.target)
1700    }
1701
1702    /// Appends an option to the OPT record.
1703    pub fn push<Opt: ComposeOptData + ?Sized>(
1704        &mut self,
1705        opt: &Opt,
1706    ) -> Result<(), Target::AppendError> {
1707        self.push_raw_option(opt.code(), opt.compose_len(), |target| {
1708            opt.compose_option(target)
1709        })
1710    }
1711
1712    /// Appends a raw option to the OPT record.
1713    ///
1714    /// The method will append an option with the given option code. The data
1715    /// of the option will be written via the closure `op`.
1716    pub fn push_raw_option<F>(
1717        &mut self,
1718        code: OptionCode,
1719        option_len: u16,
1720        op: F,
1721    ) -> Result<(), Target::AppendError>
1722    where
1723        F: FnOnce(&mut Target) -> Result<(), Target::AppendError>,
1724    {
1725        code.compose(self.target)?;
1726        option_len.compose(self.target)?;
1727        op(self.target)
1728    }
1729
1730    /// Returns the current UDP payload size field of the OPT record.
1731    ///
1732    /// This field contains the largest UDP datagram the sender can accept.
1733    /// This is not the path MTU but really what the sender can work with
1734    /// internally.
1735    #[must_use]
1736    pub fn udp_payload_size(&self) -> u16 {
1737        self.opt_header().udp_payload_size()
1738    }
1739
1740    /// Sets the UDP payload size field of the OPT record.
1741    pub fn set_udp_payload_size(&mut self, value: u16) {
1742        self.opt_header_mut().set_udp_payload_size(value)
1743    }
1744
1745    /// Returns the extended rcode of the message.
1746    ///
1747    /// The method assembles the rcode both from the message header and the
1748    /// OPT header.
1749    #[must_use]
1750    pub fn rcode(&self) -> OptRcode {
1751        self.opt_header()
1752            .rcode(*Header::for_message_slice(self.target.as_ref()))
1753    }
1754
1755    /// Sets the extended rcode of the message.
1756    //
1757    /// The method will update both the message header and the OPT header.
1758    pub fn set_rcode(&mut self, rcode: OptRcode) {
1759        Header::for_message_slice_mut(self.target.as_mut())
1760            .set_rcode(rcode.rcode());
1761        self.opt_header_mut().set_rcode(rcode)
1762    }
1763
1764    /// Returns the EDNS version of the OPT header.
1765    ///
1766    /// Only EDNS version 0 is currently defined.
1767    #[must_use]
1768    pub fn version(&self) -> u8 {
1769        self.opt_header().version()
1770    }
1771
1772    /// Sets the EDNS version of the OPT header.
1773    pub fn set_version(&mut self, version: u8) {
1774        self.opt_header_mut().set_version(version)
1775    }
1776
1777    /// Returns the value of the DNSSEC OK (DO) bit.
1778    ///
1779    /// By setting this bit, a resolver indicates that it is interested in
1780    /// also receiving the DNSSEC-related resource records necessary to
1781    /// validate an answer. The bit and the related procedures are defined in
1782    /// [RFC 3225].
1783    ///
1784    /// [RFC 3225]: https://tools.ietf.org/html/rfc3225
1785    #[must_use]
1786    pub fn dnssec_ok(&self) -> bool {
1787        self.opt_header().dnssec_ok()
1788    }
1789
1790    /// Sets the DNSSEC OK (DO) bit to the given value.
1791    pub fn set_dnssec_ok(&mut self, value: bool) {
1792        self.opt_header_mut().set_dnssec_ok(value)
1793    }
1794
1795    /// Returns a reference to the full OPT header.
1796    fn opt_header(&self) -> &OptHeader {
1797        OptHeader::for_record_slice(&self.target.as_ref()[self.start..])
1798    }
1799
1800    /// Returns a mutual reference to the full OPT header.
1801    fn opt_header_mut(&mut self) -> &mut OptHeader {
1802        let start = self.start;
1803        OptHeader::for_record_slice_mut(&mut self.target.as_mut()[start..])
1804    }
1805
1806    /// Returns a reference to the underlying octets builder.
1807    pub fn as_target(&self) -> &Target {
1808        self.target
1809    }
1810}
1811
1812//------------ StreamTarget --------------------------------------------------
1813
1814/// A builder target for sending messages on stream transports.
1815///
1816/// TODO: Rename this type and adjust the doc comments as it is usable both
1817/// for datagram AND stream transports via [`as_dgram_slice`] and
1818/// [`as_stream_slice`].
1819///
1820/// When messages are sent over stream-oriented transports such as TCP, a DNS
1821/// message is preceded by a 16 bit length value in order to determine the end
1822/// of a message. This type transparently adds this length value as the first
1823/// two octets of an octets builder and itself presents an octets builder
1824/// interface for building the actual message. Whenever data is pushed to that
1825/// builder interface, the type will update the length value.
1826///
1827/// Because the length is 16 bits long, the assembled message can be at most
1828/// 65536 octets long, independently of the maximum length the underlying
1829/// builder allows.
1830///
1831/// [`as_dgram_slice`]: Self::as_dgram_slice
1832/// [`as_stream_slice`]: Self::as_stream_slice
1833#[derive(Clone, Debug, Default)]
1834pub struct StreamTarget<Target> {
1835    /// The underlying octets builder.
1836    target: Target,
1837}
1838
1839impl<Target: Composer> StreamTarget<Target> {
1840    /// Creates a new stream target wrapping an octets builder.
1841    ///
1842    /// The function will truncate the builder back to empty and append the
1843    /// length value. Because of the latter, this can fail if the octets
1844    /// builder doesn’t even have space for that.
1845    pub fn new(mut target: Target) -> Result<Self, Target::AppendError> {
1846        target.truncate(0);
1847        0u16.compose(&mut target)?;
1848        Ok(StreamTarget { target })
1849    }
1850}
1851
1852#[cfg(feature = "std")]
1853impl StreamTarget<Vec<u8>> {
1854    /// Creates a stream target atop an empty `Vec<u8>`.
1855    #[must_use]
1856    pub fn new_vec() -> Self {
1857        infallible(Self::new(Vec::new()))
1858    }
1859}
1860
1861#[cfg(feature = "bytes")]
1862impl StreamTarget<BytesMut> {
1863    /// Creates a stream target atop an empty `Vec<u8>`.
1864    pub fn new_bytes() -> Self {
1865        infallible(Self::new(BytesMut::new()))
1866    }
1867}
1868
1869impl<Target> StreamTarget<Target> {
1870    /// Returns a reference to the underlying octets builder.
1871    pub fn as_target(&self) -> &Target {
1872        &self.target
1873    }
1874
1875    /// Converts the stream target into the underlying octets builder.
1876    ///
1877    /// The returned builder will contain the 16 bit length value with the
1878    /// correct content and the assembled message.
1879    pub fn into_target(self) -> Target {
1880        self.target
1881    }
1882}
1883
1884impl<Target: AsRef<[u8]> + AsMut<[u8]>> StreamTarget<Target> {
1885    /// Updates the length value to the current length of the target.
1886    fn update_shim(&mut self) -> Result<(), ShortBuf> {
1887        match u16::try_from(self.target.as_ref().len() - 2) {
1888            Ok(len) => {
1889                self.target.as_mut()[..2].copy_from_slice(&len.to_be_bytes());
1890                Ok(())
1891            }
1892            Err(_) => Err(ShortBuf),
1893        }
1894    }
1895}
1896
1897impl<Target: AsRef<[u8]>> StreamTarget<Target> {
1898    /// Returns an octets slice of the message for stream transports.
1899    ///
1900    /// The slice will start with the length octets and can be send as is
1901    /// through a stream transport such as TCP.
1902    pub fn as_stream_slice(&self) -> &[u8] {
1903        self.target.as_ref()
1904    }
1905
1906    /// Returns an octets slice of the message for datagram transports.
1907    ///
1908    /// The slice will not contain the length octets but only the actual
1909    /// message itself. This slice can be used for sending via datagram
1910    /// transports such as UDP.
1911    pub fn as_dgram_slice(&self) -> &[u8] {
1912        &self.target.as_ref()[2..]
1913    }
1914}
1915
1916//--- AsRef, AsMut
1917
1918impl<Target: AsRef<[u8]>> AsRef<[u8]> for StreamTarget<Target> {
1919    fn as_ref(&self) -> &[u8] {
1920        &self.target.as_ref()[2..]
1921    }
1922}
1923
1924impl<Target: AsMut<[u8]>> AsMut<[u8]> for StreamTarget<Target> {
1925    fn as_mut(&mut self) -> &mut [u8] {
1926        &mut self.target.as_mut()[2..]
1927    }
1928}
1929
1930//--- OctetsBuilder, Truncate, Composer
1931
1932impl<Target> OctetsBuilder for StreamTarget<Target>
1933where
1934    Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>,
1935    Target::AppendError: Into<ShortBuf>,
1936{
1937    type AppendError = ShortBuf;
1938
1939    fn append_slice(
1940        &mut self,
1941        slice: &[u8],
1942    ) -> Result<(), Self::AppendError> {
1943        self.target.append_slice(slice).map_err(Into::into)?;
1944        self.update_shim()
1945    }
1946}
1947
1948impl<Target: Composer> Truncate for StreamTarget<Target> {
1949    fn truncate(&mut self, len: usize) {
1950        self.target
1951            .truncate(len.checked_add(2).expect("long truncate"));
1952        self.update_shim().expect("truncate grew buffer???")
1953    }
1954}
1955
1956impl<Target> Composer for StreamTarget<Target>
1957where
1958    Target: Composer,
1959    Target::AppendError: Into<ShortBuf>,
1960{
1961    fn append_compressed_name<N: ToName + ?Sized>(
1962        &mut self,
1963        name: &N,
1964    ) -> Result<(), Self::AppendError> {
1965        self.target
1966            .append_compressed_name(name)
1967            .map_err(Into::into)?;
1968        self.update_shim()
1969    }
1970}
1971
1972//------------ StaticCompressor ----------------------------------------------
1973
1974/// A domain name compressor that doesn’t require an allocator.
1975///
1976/// This type wraps around an octets builder and implements domain name
1977/// compression. It does not require an allocator but because of that it
1978/// can only remember the position of up to 24 domain names. This should be
1979/// sufficient for most messages.
1980///
1981/// The position of a domain name is calculated relative to the beginning of
1982/// the underlying octets builder. This means that this builder must represent
1983/// the message only. This means that if you are using the [`StreamTarget`],
1984/// you need to place it inside this type, _not_ the other way around.
1985///
1986/// [`StreamTarget`]: struct.StreamTarget.html
1987#[derive(Clone, Debug)]
1988pub struct StaticCompressor<Target> {
1989    /// The underlying octets builder.
1990    target: Target,
1991
1992    /// The domain names we have encountered so far.
1993    ///
1994    /// The value is the position of the domain name within the message.
1995    entries: [u16; 24],
1996
1997    /// The number of entries in `entries`.
1998    len: usize,
1999}
2000
2001impl<Target> StaticCompressor<Target> {
2002    /// Creates a static compressor from an octets builder.
2003    pub fn new(target: Target) -> Self {
2004        StaticCompressor {
2005            target,
2006            entries: Default::default(),
2007            len: 0,
2008        }
2009    }
2010
2011    /// Returns a reference to the underlying octets builder.
2012    pub fn as_target(&self) -> &Target {
2013        &self.target
2014    }
2015
2016    /// Converts the static compressor into the underlying octets builder.
2017    pub fn into_target(self) -> Target {
2018        self.target
2019    }
2020
2021    /// Returns a reference to the octets slice of the content.
2022    pub fn as_slice(&self) -> &[u8]
2023    where
2024        Target: AsRef<[u8]>,
2025    {
2026        self.target.as_ref()
2027    }
2028
2029    /// Returns a reference to the octets slice of the content.
2030    pub fn as_slice_mut(&mut self) -> &mut [u8]
2031    where
2032        Target: AsMut<[u8]>,
2033    {
2034        self.target.as_mut()
2035    }
2036
2037    /// Returns a known position of a domain name if there is one.
2038    fn get<'a, N: Iterator<Item = &'a Label> + Clone>(
2039        &self,
2040        name: N,
2041    ) -> Option<u16>
2042    where
2043        Target: AsRef<[u8]>,
2044    {
2045        self.entries[..self.len].iter().find_map(|&pos| {
2046            if name
2047                .clone()
2048                .eq(Label::iter_slice(self.target.as_ref(), pos as usize))
2049            {
2050                Some(pos)
2051            } else {
2052                None
2053            }
2054        })
2055    }
2056
2057    /// Inserts the position of a new domain name if possible.
2058    fn insert(&mut self, pos: usize) -> bool {
2059        if pos < 0xc000 && self.len < self.entries.len() {
2060            self.entries[self.len] = pos as u16;
2061            self.len += 1;
2062            true
2063        } else {
2064            false
2065        }
2066    }
2067}
2068
2069//--- AsRef and AsMut
2070
2071impl<Target: AsRef<[u8]>> AsRef<[u8]> for StaticCompressor<Target> {
2072    fn as_ref(&self) -> &[u8] {
2073        self.as_slice()
2074    }
2075}
2076
2077impl<Target: AsMut<[u8]>> AsMut<[u8]> for StaticCompressor<Target> {
2078    fn as_mut(&mut self) -> &mut [u8] {
2079        self.as_slice_mut()
2080    }
2081}
2082
2083//--- OctetsBuilder
2084
2085impl<Target: OctetsBuilder> OctetsBuilder for StaticCompressor<Target> {
2086    type AppendError = Target::AppendError;
2087
2088    fn append_slice(
2089        &mut self,
2090        slice: &[u8],
2091    ) -> Result<(), Self::AppendError> {
2092        self.target.append_slice(slice)
2093    }
2094}
2095
2096impl<Target: Composer> Composer for StaticCompressor<Target> {
2097    fn append_compressed_name<N: ToName + ?Sized>(
2098        &mut self,
2099        name: &N,
2100    ) -> Result<(), Self::AppendError> {
2101        let mut name = name.iter_labels().peekable();
2102
2103        loop {
2104            // If the parent is root, just write that and return.
2105            // Because we do that, there will always be a label left here.
2106            if let Some(label) = name.peek() {
2107                if label.is_root() {
2108                    label.compose(self)?;
2109                    return Ok(());
2110                }
2111            }
2112
2113            // If we already know this name, append it as a compressed label.
2114            if let Some(pos) = self.get(name.clone()) {
2115                return (pos | 0xC000).compose(self);
2116            }
2117
2118            // So we don’t know the name. Try inserting it into the
2119            // compressor. If we can’t insert anymore, just write out what’s
2120            // left and return.
2121            if !self.insert(self.target.as_ref().len()) {
2122                for label in &mut name {
2123                    label.compose(self)?;
2124                }
2125                return Ok(());
2126            }
2127
2128            // Advance to the parent.
2129            let label = name.next().unwrap();
2130            label.compose(self)?;
2131        }
2132    }
2133
2134    fn can_compress(&self) -> bool {
2135        true
2136    }
2137}
2138
2139impl<Target: Truncate> Truncate for StaticCompressor<Target> {
2140    fn truncate(&mut self, len: usize) {
2141        self.target.truncate(len);
2142        if len < 0xC000 {
2143            let len = len as u16;
2144            for i in 0..self.len {
2145                if self.entries[i] >= len {
2146                    self.len = i;
2147                    break;
2148                }
2149            }
2150        }
2151    }
2152}
2153
2154impl<Target: FreezeBuilder> FreezeBuilder for StaticCompressor<Target> {
2155    type Octets = Target::Octets;
2156
2157    fn freeze(self) -> Self::Octets {
2158        self.target.freeze()
2159    }
2160}
2161
2162//------------ TreeCompressor ------------------------------------------------
2163
2164/// A domain name compressor that uses a tree.
2165///
2166/// This type wraps around an octets builder and implements domain name
2167/// compression for it. It stores the position of any domain name it has seen
2168/// in a binary tree.
2169///
2170/// The position of a domain name is calculated relative to the beginning of
2171/// the underlying octets builder. This means that this builder must represent
2172/// the message only. This means that if you are using the [`StreamTarget`],
2173/// you need to place it inside this type, _not_ the other way around.
2174///
2175/// [`StreamTarget`]: struct.StreamTarget.html
2176#[cfg(feature = "std")]
2177#[derive(Clone, Debug)]
2178pub struct TreeCompressor<Target> {
2179    /// The underlying octetsbuilder.
2180    target: Target,
2181
2182    /// The topmost node of our tree.
2183    start: Node,
2184}
2185
2186/// A node in our tree.
2187///
2188/// The tree is a bit odd. It follows the labels of the domain names from the
2189/// root towards the left. The root node is for the root label. It contains a
2190/// map that maps all the labels encountered to the immediate left of the
2191/// name traced by this path through the tree to a node for the name resulting
2192/// by adding this label to the name constructed so far.
2193///
2194/// Each node also contains the position of that name in the message.
2195#[cfg(feature = "std")]
2196#[derive(Clone, Debug, Default)]
2197struct Node {
2198    /// The labels immediately to the left of this name and their nodes.
2199    parents: HashMap<Array<64>, Self>,
2200
2201    /// The position of this name in the message.
2202    value: Option<u16>,
2203}
2204
2205#[cfg(feature = "std")]
2206impl Node {
2207    fn drop_above(&mut self, len: u16) {
2208        self.value = match self.value {
2209            Some(value) if value < len => Some(value),
2210            _ => None,
2211        };
2212        self.parents
2213            .values_mut()
2214            .for_each(|node| node.drop_above(len))
2215    }
2216}
2217
2218#[cfg(feature = "std")]
2219impl<Target> TreeCompressor<Target> {
2220    /// Creates a new compressor from an underlying octets builder.
2221    pub fn new(target: Target) -> Self {
2222        TreeCompressor {
2223            target,
2224            start: Default::default(),
2225        }
2226    }
2227
2228    /// Returns a reference to the underlying octets builder.
2229    pub fn as_target(&self) -> &Target {
2230        &self.target
2231    }
2232
2233    /// Converts the compressor into the underlying octets builder.
2234    pub fn into_target(self) -> Target {
2235        self.target
2236    }
2237
2238    /// Returns an octets slice of the data.
2239    pub fn as_slice(&self) -> &[u8]
2240    where
2241        Target: AsRef<[u8]>,
2242    {
2243        self.target.as_ref()
2244    }
2245
2246    /// Returns an mutable octets slice of the data.
2247    pub fn as_slice_mut(&mut self) -> &mut [u8]
2248    where
2249        Target: AsMut<[u8]>,
2250    {
2251        self.target.as_mut()
2252    }
2253
2254    fn get<'a, N: Iterator<Item = &'a Label> + Clone>(
2255        &self,
2256        name: N,
2257    ) -> Option<u16> {
2258        let mut node = &self.start;
2259        for label in name {
2260            if label.is_root() {
2261                return node.value;
2262            }
2263            node = node.parents.get(label.as_ref())?;
2264        }
2265        None
2266    }
2267
2268    fn insert<'a, N: Iterator<Item = &'a Label> + Clone>(
2269        &mut self,
2270        name: N,
2271        pos: usize,
2272    ) -> bool {
2273        if pos >= 0xC000 {
2274            return false;
2275        }
2276        let pos = pos as u16;
2277        let mut node = &mut self.start;
2278        for label in name {
2279            if label.is_root() {
2280                node.value = Some(pos);
2281                break;
2282            }
2283            node = node
2284                .parents
2285                .entry(label.as_ref().try_into().unwrap())
2286                .or_default();
2287        }
2288        true
2289    }
2290}
2291
2292//--- AsRef, AsMut, and OctetsBuilder
2293
2294#[cfg(feature = "std")]
2295impl<Target: AsRef<[u8]>> AsRef<[u8]> for TreeCompressor<Target> {
2296    fn as_ref(&self) -> &[u8] {
2297        self.as_slice()
2298    }
2299}
2300
2301#[cfg(feature = "std")]
2302impl<Target: AsMut<[u8]>> AsMut<[u8]> for TreeCompressor<Target> {
2303    fn as_mut(&mut self) -> &mut [u8] {
2304        self.as_slice_mut()
2305    }
2306}
2307
2308#[cfg(feature = "std")]
2309impl<Target: OctetsBuilder> OctetsBuilder for TreeCompressor<Target> {
2310    type AppendError = Target::AppendError;
2311
2312    fn append_slice(
2313        &mut self,
2314        slice: &[u8],
2315    ) -> Result<(), Self::AppendError> {
2316        self.target.append_slice(slice)
2317    }
2318}
2319
2320#[cfg(feature = "std")]
2321impl<Target: Composer> Composer for TreeCompressor<Target> {
2322    fn append_compressed_name<N: ToName + ?Sized>(
2323        &mut self,
2324        name: &N,
2325    ) -> Result<(), Self::AppendError> {
2326        let mut name = name.iter_labels().peekable();
2327
2328        loop {
2329            // If the parent is root, just write that and return.
2330            // Because we do that, there will always be a label left here.
2331            if let Some(label) = name.peek() {
2332                if label.is_root() {
2333                    label.compose(self)?;
2334                    return Ok(());
2335                }
2336            }
2337
2338            // If we already know this name, append it as a compressed label.
2339            if let Some(pos) = self.get(name.clone()) {
2340                return (pos | 0xC000).compose(self);
2341            }
2342
2343            // So we don’t know the name. Try inserting it into the
2344            // compressor. If we can’t insert anymore, just write out what’s
2345            // left and return.
2346            if !self.insert(name.clone(), self.target.as_ref().len()) {
2347                for label in &mut name {
2348                    label.compose(self)?;
2349                }
2350                return Ok(());
2351            }
2352
2353            // Advance to the parent. If the parent is root, just write that
2354            // and return. Because we do that, there will always be a label
2355            // left here.
2356            let label = name.next().unwrap();
2357            label.compose(self)?;
2358        }
2359    }
2360
2361    fn can_compress(&self) -> bool {
2362        true
2363    }
2364}
2365
2366#[cfg(feature = "std")]
2367impl<Target: Composer> Truncate for TreeCompressor<Target> {
2368    fn truncate(&mut self, len: usize) {
2369        self.target.truncate(len);
2370        if len < 0xC000 {
2371            self.start.drop_above(len as u16)
2372        }
2373    }
2374}
2375
2376//------------ HashCompressor ------------------------------------------------
2377
2378/// A domain name compressor that uses a hash table.
2379///
2380/// This type wraps around an octets builder and implements domain name
2381/// compression for it. It stores the position of any domain name it has seen
2382/// in a hash table.
2383///
2384/// The position of a domain name is calculated relative to the beginning of
2385/// the underlying octets builder. This means that this builder must represent
2386/// the message only. This means that if you are using the [`StreamTarget`],
2387/// you need to place it inside this type, _not_ the other way around.
2388///
2389/// [`StreamTarget`]: struct.StreamTarget.html
2390#[cfg(feature = "std")]
2391#[derive(Clone, Debug)]
2392pub struct HashCompressor<Target> {
2393    /// The underlying octetsbuilder.
2394    target: Target,
2395
2396    /// The names inserted into the message.
2397    ///
2398    /// Consider a set of names, where the "parent" (i.e. tail) of each name is
2399    /// another name in the set.  For example, a set might contain `.`, `org.`,
2400    /// `example.org.`, and `www.example.org.`.  Each of these names (except the
2401    /// root, which is handled specially) is stored as a separate entry in this
2402    /// hash table.  A name `<head>.<tail>` is stored as the index of `<head>`
2403    /// and the index of `<tail>` in the built message.  Its hash is built from
2404    /// `<head>` (the bytes in the label, not the index into the message) and
2405    /// the index of `<tail>`.
2406    ///
2407    /// Lookups are performed by iterating backward through the labels in a name
2408    /// (to go from the root outward).  At each step, the canonical position of
2409    /// `<tail>` is already known; it is hashed together with the next label and
2410    /// searched for in the hash table.  An entry with a matching `<head>` (i.e.
2411    /// where the referenced content in the message matches the searched label)
2412    /// and a matching `<tail>` position represents the same name.
2413    ///
2414    /// The root is handled specially.  It is never inserted in the hash table,
2415    /// and instead has a fixed fake position in the message of 0xFFFF.  That is
2416    /// the initial value that lookups start with.
2417    ///
2418    /// As an example, consider a message `org. example.org. www.example.org.`.
2419    /// In the hash table, the first two entries will look like:
2420    ///
2421    /// ```text
2422    /// - head=0 ("org") tail=0xFFFF
2423    /// - head=5 ("example") tail=0
2424    /// ```
2425    ///
2426    /// Now, to insert `www.example.org.`, the lookup begins from the end.  We
2427    /// search for a label "org" with tail 0xFFFF, and find head=0.  We set this
2428    /// as the next tail, and search for label "example" to find head=5.  Since
2429    /// a label "www" with tail=5 is not already in the hash table, it will be
2430    /// inserted with head=18.
2431    ///
2432    /// This has a space overhead of 4-5 bytes for each entry, accounting for
2433    /// the load factor (which appears to be 87.5%).  Technically, storing the
2434    /// labels indirectly means that comparisons are more expensive; but most
2435    /// labels are relatively short and storing them inline as 64-byte arrays
2436    /// would be quite wasteful.
2437    names: HashTable<HashEntry>,
2438
2439    /// How names in the table are hashed.
2440    hasher: RandomState,
2441}
2442
2443#[cfg(feature = "std")]
2444#[derive(Copy, Clone, Debug)]
2445struct HashEntry {
2446    /// The position of the head label in the name.
2447    head: u16,
2448
2449    /// The position of the tail name.
2450    tail: u16,
2451}
2452
2453#[cfg(feature = "std")]
2454impl HashEntry {
2455    /// Try constructing a [`HashEntry`].
2456    fn new(head: usize, tail: usize) -> Option<Self> {
2457        if head < 0xC000 {
2458            Some(Self {
2459                head: head as u16,
2460                tail: tail as u16,
2461            })
2462        } else {
2463            None
2464        }
2465    }
2466
2467    /// Get the head label for this entry.
2468    fn head<'m>(&self, message: &'m [u8]) -> &'m Label {
2469        Label::split_from(&message[self.head as usize..])
2470            .expect("the message contains valid labels")
2471            .0
2472    }
2473
2474    /// Compute the hash of this entry.
2475    fn hash(&self, message: &[u8], hasher: &RandomState) -> u64 {
2476        hasher.hash_one((self.head(message), self.tail))
2477    }
2478
2479    /// Compare this entry to a label.
2480    fn eq(&self, message: &[u8], query: (&Label, u16)) -> bool {
2481        (self.head(message), self.tail) == query
2482    }
2483}
2484
2485#[cfg(feature = "std")]
2486impl<Target> HashCompressor<Target> {
2487    /// Creates a new compressor from an underlying octets builder.
2488    pub fn new(target: Target) -> Self {
2489        HashCompressor {
2490            target,
2491            names: Default::default(),
2492            hasher: Default::default(),
2493        }
2494    }
2495
2496    /// Returns a reference to the underlying octets builder.
2497    pub fn as_target(&self) -> &Target {
2498        &self.target
2499    }
2500
2501    /// Converts the compressor into the underlying octets builder.
2502    pub fn into_target(self) -> Target {
2503        self.target
2504    }
2505
2506    /// Returns an octets slice of the data.
2507    pub fn as_slice(&self) -> &[u8]
2508    where
2509        Target: AsRef<[u8]>,
2510    {
2511        self.target.as_ref()
2512    }
2513
2514    /// Returns an mutable octets slice of the data.
2515    pub fn as_slice_mut(&mut self) -> &mut [u8]
2516    where
2517        Target: AsMut<[u8]>,
2518    {
2519        self.target.as_mut()
2520    }
2521}
2522
2523//--- AsRef, AsMut, and OctetsBuilder
2524
2525#[cfg(feature = "std")]
2526impl<Target: AsRef<[u8]>> AsRef<[u8]> for HashCompressor<Target> {
2527    fn as_ref(&self) -> &[u8] {
2528        self.as_slice()
2529    }
2530}
2531
2532#[cfg(feature = "std")]
2533impl<Target: AsMut<[u8]>> AsMut<[u8]> for HashCompressor<Target> {
2534    fn as_mut(&mut self) -> &mut [u8] {
2535        self.as_slice_mut()
2536    }
2537}
2538
2539#[cfg(feature = "std")]
2540impl<Target: OctetsBuilder> OctetsBuilder for HashCompressor<Target> {
2541    type AppendError = Target::AppendError;
2542
2543    fn append_slice(
2544        &mut self,
2545        slice: &[u8],
2546    ) -> Result<(), Self::AppendError> {
2547        self.target.append_slice(slice)
2548    }
2549}
2550
2551#[cfg(feature = "std")]
2552impl<Target: Composer> Composer for HashCompressor<Target> {
2553    fn append_compressed_name<N: ToName + ?Sized>(
2554        &mut self,
2555        name: &N,
2556    ) -> Result<(), Self::AppendError> {
2557        let mut name = name.iter_labels();
2558        let message = self.target.as_ref();
2559
2560        // Remove the root label -- we know it's there.
2561        assert!(
2562            name.next_back().is_some_and(|l| l.is_root()),
2563            "absolute names must end with a root label"
2564        );
2565
2566        // The position of the consumed labels from the end of the name.
2567        let mut position = 0xFFFF;
2568
2569        // The last label that must be inserted, if any.
2570        let mut last_label = None;
2571
2572        // Look up each label in reverse order.
2573        while let Some(label) = name.next_back() {
2574            // Look up the labels seen thus far in the hash table.
2575            let query = (label, position);
2576            let hash = self.hasher.hash_one(query);
2577
2578            let entry =
2579                self.names.find(hash, |&name| name.eq(message, query));
2580            if let Some(entry) = entry {
2581                // We found a match, so update the position.
2582                position = entry.head;
2583            } else {
2584                // We will have to write this label.
2585                last_label = Some(label);
2586                break;
2587            }
2588        }
2589
2590        // Write out the remaining labels in the name in regular order.
2591        let mut labels = name.chain(last_label).peekable();
2592        while let Some(label) = labels.next() {
2593            let head = self.target.as_ref().len();
2594            let tail = head + label.compose_len() as usize;
2595
2596            label.compose(self)?;
2597
2598            // Remember this label for future compression, if possible.
2599            //
2600            // If some labels in this name pass the 0xC000 boundary point, then
2601            // none of its remembered labels can be used (since they are looked
2602            // up from right to left, and the rightmost ones will fail first).
2603            // We could check more thoroughly for this, but it's not worth it.
2604            if let Some(mut entry) = HashEntry::new(head, tail) {
2605                // If there is no following label, use the remaining position.
2606                if labels.peek().is_none() {
2607                    entry.tail = position;
2608                }
2609
2610                let message = self.target.as_ref();
2611                let hasher = &self.hasher;
2612                let hash = entry.hash(message, hasher);
2613                self.names.insert_unique(hash, entry, |&name| {
2614                    name.hash(message, hasher)
2615                });
2616            }
2617        }
2618
2619        // Write the compressed pointer or the root label.
2620        if position != 0xFFFF {
2621            (position | 0xC000).compose(self)
2622        } else {
2623            Label::root().compose(self)
2624        }
2625    }
2626
2627    fn can_compress(&self) -> bool {
2628        true
2629    }
2630}
2631
2632#[cfg(feature = "std")]
2633impl<Target: Composer> Truncate for HashCompressor<Target> {
2634    fn truncate(&mut self, len: usize) {
2635        self.target.truncate(len);
2636        if len < 0xC000 {
2637            self.names.retain(|name| name.head < len as u16);
2638        }
2639    }
2640}
2641
2642//============ Errors ========================================================
2643
2644#[derive(Clone, Copy, Debug)]
2645pub enum PushError {
2646    CountOverflow,
2647    ShortBuf,
2648}
2649
2650impl<T: Into<ShortBuf>> From<T> for PushError {
2651    fn from(_: T) -> Self {
2652        Self::ShortBuf
2653    }
2654}
2655
2656impl fmt::Display for PushError {
2657    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2658        match *self {
2659            PushError::CountOverflow => f.write_str("counter overflow"),
2660            PushError::ShortBuf => ShortBuf.fmt(f),
2661        }
2662    }
2663}
2664
2665#[cfg(feature = "std")]
2666impl std::error::Error for PushError {}
2667
2668//============ Testing =======================================================
2669
2670#[cfg(test)]
2671#[cfg(feature = "std")]
2672mod test {
2673    use super::*;
2674    use crate::base::opt;
2675    use crate::base::{Name, Serial, Ttl};
2676    use crate::rdata::{Ns, Soa, A};
2677    use core::str::FromStr;
2678
2679    #[test]
2680    fn message_builder() {
2681        // Make a domain name we can use later on.
2682        let name = Name::<Vec<u8>>::from_str("example.com").unwrap();
2683
2684        // Create a message builder wrapping a compressor wrapping a stream
2685        // target.
2686        let mut msg = MessageBuilder::from_target(StaticCompressor::new(
2687            StreamTarget::new_vec(),
2688        ))
2689        .unwrap();
2690
2691        // Set the RD bit in the header and proceed to the question section.
2692        msg.header_mut().set_rd(true);
2693        let mut msg = msg.question();
2694
2695        // Add a question and proceed to the answer section.
2696        msg.push((&name, Rtype::A)).unwrap();
2697        let mut msg = msg.answer();
2698
2699        // Add two answer and proceed to the additional sections
2700        msg.push((&name, 86400, A::from_octets(192, 0, 2, 1)))
2701            .unwrap();
2702        msg.push((&name, 86400, A::from_octets(192, 0, 2, 2)))
2703            .unwrap();
2704
2705        // Add an authority
2706        let mut msg = msg.authority();
2707        msg.push((&name, 0, Ns::from(name.clone()))).unwrap();
2708
2709        // Add additional
2710        let mut msg = msg.additional();
2711        msg.push((&name, 86400, A::from_octets(192, 0, 2, 1)))
2712            .unwrap();
2713
2714        // Convert the builder into the actual message.
2715        let target = msg.finish().into_target();
2716
2717        // Reparse message and check contents
2718        let msg = Message::from_octets(target.as_dgram_slice()).unwrap();
2719        let q = msg.first_question().unwrap();
2720        assert_eq!(q.qname(), &name);
2721        assert_eq!(q.qtype(), Rtype::A);
2722
2723        let section = msg.answer().unwrap();
2724        let mut records = section.limit_to::<A>();
2725        assert_eq!(
2726            records.next().unwrap().unwrap().data(),
2727            &A::from_octets(192, 0, 2, 1)
2728        );
2729        assert_eq!(
2730            records.next().unwrap().unwrap().data(),
2731            &A::from_octets(192, 0, 2, 2)
2732        );
2733
2734        let section = msg.authority().unwrap();
2735        let mut records = section.limit_to::<Ns<_>>();
2736        let rr = records.next().unwrap().unwrap();
2737        assert_eq!(rr.owner(), &name);
2738        assert_eq!(rr.data().nsdname(), &name);
2739
2740        let section = msg.additional().unwrap();
2741        let mut records = section.limit_to::<A>();
2742        let rr = records.next().unwrap().unwrap();
2743        assert_eq!(rr.owner(), &name);
2744        assert_eq!(rr.data(), &A::from_octets(192, 0, 2, 1));
2745    }
2746
2747    #[cfg(feature = "heapless")]
2748    #[test]
2749    fn exceed_limits() {
2750        // Create a limited message builder.
2751        let buf = heapless::Vec::<u8, 100>::new();
2752
2753        // Initialize it with a message header (12 bytes)
2754        let mut msg = MessageBuilder::from_target(buf).unwrap();
2755        let hdr_len = msg.as_slice().len();
2756
2757        // Add some bytes.
2758        msg.push(|t| t.append_slice(&[0u8; 50]), |_| Ok(()))
2759            .unwrap();
2760        assert_eq!(msg.as_slice().len(), hdr_len + 50);
2761
2762        // Set a push limit below the current length.
2763        msg.set_push_limit(25);
2764
2765        // Verify that push fails.
2766        assert!(msg.push(|t| t.append_slice(&[0u8; 1]), |_| Ok(())).is_err());
2767        assert_eq!(msg.as_slice().len(), hdr_len + 50);
2768
2769        // Remove the limit.
2770        msg.clear_push_limit();
2771
2772        // Verify that push up until capacity succeeds.
2773        for _ in (hdr_len + 50)..100 {
2774            msg.push(|t| t.append_slice(&[0u8; 1]), |_| Ok(())).unwrap();
2775        }
2776        assert_eq!(msg.as_slice().len(), 100);
2777
2778        // Verify that exceeding the underlying capacity limit fails.
2779        assert!(msg.push(|t| t.append_slice(&[0u8; 1]), |_| Ok(())).is_err());
2780        assert_eq!(msg.as_slice().len(), 100);
2781    }
2782
2783    #[test]
2784    fn opt_builder() {
2785        let mut msg = MessageBuilder::new_vec().additional();
2786
2787        // Add an OPT record.
2788        let nsid = opt::nsid::Nsid::from_octets(&b"example"[..]).unwrap();
2789        msg.opt(|o| {
2790            o.set_udp_payload_size(4096);
2791            o.push(&nsid)?;
2792            Ok(())
2793        })
2794        .unwrap();
2795
2796        let msg = msg.finish();
2797        println!("{:?}", msg);
2798        let msg = Message::from_octets(msg).unwrap();
2799        let opt = msg.opt().unwrap();
2800
2801        // Check options
2802        assert_eq!(opt.udp_payload_size(), 4096);
2803        let mut opts = opt.opt().iter::<opt::nsid::Nsid<_>>();
2804        assert_eq!(opts.next(), Some(Ok(nsid)));
2805    }
2806
2807    fn create_compressed<T: Composer>(target: T) -> T
2808    where
2809        T::AppendError: fmt::Debug,
2810    {
2811        let mut msg = MessageBuilder::from_target(target).unwrap().question();
2812        msg.header_mut().set_rcode(Rcode::NXDOMAIN);
2813        msg.header_mut().set_rd(true);
2814        msg.header_mut().set_ra(true);
2815        msg.header_mut().set_qr(true);
2816
2817        msg.push((&"example".parse::<Name<Vec<u8>>>().unwrap(), Rtype::NS))
2818            .unwrap();
2819        let mut msg = msg.authority();
2820
2821        let mname: Name<Vec<u8>> = "a.root-servers.net".parse().unwrap();
2822        let rname = "nstld.verisign-grs.com".parse().unwrap();
2823        msg.push((
2824            Name::root_slice(),
2825            86390,
2826            Soa::new(
2827                mname,
2828                rname,
2829                Serial(2020081701),
2830                Ttl::from_secs(1800),
2831                Ttl::from_secs(900),
2832                Ttl::from_secs(604800),
2833                Ttl::from_secs(86400),
2834            ),
2835        ))
2836        .unwrap();
2837        msg.finish()
2838    }
2839
2840    #[test]
2841    fn compressor() {
2842        // An example negative response to `example. NS` with an SOA to test
2843        // various compressed name situations.
2844        let expect = &[
2845            0x00, 0x00, 0x81, 0x83, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
2846            0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x00, 0x00,
2847            0x02, 0x00, 0x01, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x51,
2848            0x76, 0x00, 0x40, 0x01, 0x61, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d,
2849            0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x03, 0x6e, 0x65, 0x74,
2850            0x00, 0x05, 0x6e, 0x73, 0x74, 0x6c, 0x64, 0x0c, 0x76, 0x65, 0x72,
2851            0x69, 0x73, 0x69, 0x67, 0x6e, 0x2d, 0x67, 0x72, 0x73, 0x03, 0x63,
2852            0x6f, 0x6d, 0x00, 0x78, 0x68, 0x00, 0x25, 0x00, 0x00, 0x07, 0x08,
2853            0x00, 0x00, 0x03, 0x84, 0x00, 0x09, 0x3a, 0x80, 0x00, 0x01, 0x51,
2854            0x80,
2855        ];
2856
2857        let msg = create_compressed(StaticCompressor::new(Vec::new()));
2858        assert_eq!(&expect[..], msg.as_ref());
2859
2860        let msg = create_compressed(TreeCompressor::new(Vec::new()));
2861        assert_eq!(&expect[..], msg.as_ref());
2862    }
2863
2864    #[test]
2865    fn compress_positive_response() {
2866        // An example positive response to `A example.com.` that is compressed
2867        //
2868        // ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 0
2869        // ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
2870        //
2871        // ;; QUESTION SECTION:
2872        // ;example.com.			IN	A
2873        //
2874        // ;; ANSWER SECTION:
2875        // example.com.		3600	IN	A	203.0.113.1
2876        //
2877        // ;; MSG SIZE  rcvd: 45
2878        let expect = &[
2879            0x00, 0x00, 0x81, 0xa0, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
2880            0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63,
2881            0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01,
2882            0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x04, 0xcb, 0x00, 0x71,
2883            0x01,
2884        ];
2885
2886        let name = "example.com.".parse::<Name<Vec<u8>>>().unwrap();
2887        let mut msg =
2888            MessageBuilder::from_target(StaticCompressor::new(Vec::new()))
2889                .unwrap()
2890                .question();
2891        msg.header_mut().set_rcode(Rcode::NOERROR);
2892        msg.header_mut().set_rd(true);
2893        msg.header_mut().set_ra(true);
2894        msg.header_mut().set_qr(true);
2895        msg.header_mut().set_ad(true);
2896
2897        // Question
2898        msg.push((name.clone(), Rtype::A)).unwrap();
2899
2900        // Answer
2901        let mut msg = msg.answer();
2902        msg.push((name.clone(), 3600, A::from_octets(203, 0, 113, 1)))
2903            .unwrap();
2904
2905        let actual = msg.finish().into_target();
2906        assert_eq!(45, actual.len(), "unexpected response size");
2907        assert_eq!(expect[..], actual, "unexpected response data");
2908    }
2909
2910    #[cfg(feature = "std")]
2911    #[test]
2912    fn hash_compress_positive_response() {
2913        // An example positive response to `A example.com.` that is compressed
2914        //
2915        // ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 0
2916        // ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
2917        //
2918        // ;; QUESTION SECTION:
2919        // ;example.com.			IN	A
2920        //
2921        // ;; ANSWER SECTION:
2922        // example.com.		3600	IN	A	203.0.113.1
2923        //
2924        // ;; MSG SIZE  rcvd: 45
2925        let expect = &[
2926            0x00, 0x00, 0x81, 0xa0, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
2927            0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63,
2928            0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01,
2929            0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x04, 0xcb, 0x00, 0x71,
2930            0x01,
2931        ];
2932
2933        let name = "example.com.".parse::<Name<Vec<u8>>>().unwrap();
2934        let mut msg =
2935            MessageBuilder::from_target(HashCompressor::new(Vec::new()))
2936                .unwrap()
2937                .question();
2938        msg.header_mut().set_rcode(Rcode::NOERROR);
2939        msg.header_mut().set_rd(true);
2940        msg.header_mut().set_ra(true);
2941        msg.header_mut().set_qr(true);
2942        msg.header_mut().set_ad(true);
2943
2944        // Question
2945        msg.push((name.clone(), Rtype::A)).unwrap();
2946
2947        // Answer
2948        let mut msg = msg.answer();
2949        msg.push((name.clone(), 3600, A::from_octets(203, 0, 113, 1)))
2950            .unwrap();
2951
2952        let actual = msg.finish().into_target();
2953        assert_eq!(45, actual.len(), "unexpected response size");
2954        assert_eq!(expect[..], actual, "unexpected response data");
2955    }
2956}