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(&mut OptBuilder<Target>) -> Result<(), Target::AppendError>,
1421    {
1422        self.authority.answer.builder.push(
1423            |target| OptBuilder::new(target)?.build(op),
1424            |counts| counts.inc_arcount(),
1425        )
1426    }
1427}
1428
1429/// # Conversions
1430///
1431/// Additional conversion methods are available via the `Deref`
1432/// implementation.
1433impl<Target: Composer> AdditionalBuilder<Target> {
1434    /// Rewinds to an empty additional section.
1435    ///
1436    /// All previously added additional records will be lost.
1437    pub fn rewind(&mut self) {
1438        self.authority.as_target_mut().truncate(self.start);
1439        self.counts_mut().set_arcount(0);
1440    }
1441
1442    /// Converts the additional builder into a message builder.
1443    ///
1444    /// All questions and records will be dropped and all sections will be
1445    /// empty.
1446    pub fn builder(self) -> MessageBuilder<Target> {
1447        self.question().builder()
1448    }
1449
1450    /// Converts the additional builder into a question builder.
1451    ///
1452    /// All answer, authority, and additional records will be dropped. All
1453    /// previously added questions will, however, remain.
1454    pub fn question(self) -> QuestionBuilder<Target> {
1455        self.answer().question()
1456    }
1457
1458    /// Converts the additional builder into an answer builder.
1459    ///
1460    /// All authority and additional records will be dropped. All questions
1461    /// and answer records will remain.
1462    pub fn answer(self) -> AnswerBuilder<Target> {
1463        self.authority().answer()
1464    }
1465
1466    /// Converts the additional builder into an authority builder.
1467    ///
1468    /// All additional records will be dropped. All questions, answer, and
1469    /// authority records will remain.
1470    pub fn authority(mut self) -> AuthorityBuilder<Target> {
1471        self.rewind();
1472        self.authority
1473    }
1474
1475    /// Converts the additional builder into an additional builder.
1476    ///
1477    /// In other words, does absolutely nothing.
1478    pub fn additional(self) -> AdditionalBuilder<Target> {
1479        self
1480    }
1481
1482    /// Converts the additional builder into the underlying octets builder.
1483    pub fn finish(self) -> Target {
1484        self.authority.finish()
1485    }
1486}
1487
1488impl<Target: FreezeBuilder> AdditionalBuilder<Target> {
1489    /// Converts the additional builder into the final message.
1490    ///
1491    /// The method will return a message atop whatever octets sequence the
1492    /// builder’s octets builder converts into.
1493    pub fn into_message(self) -> Message<Target::Octets> {
1494        self.authority.into_message()
1495    }
1496}
1497
1498impl<Target> AdditionalBuilder<Target> {
1499    /// Returns a reference to the underlying message builder.
1500    pub fn as_builder(&self) -> &MessageBuilder<Target> {
1501        self.authority.as_builder()
1502    }
1503
1504    /// Returns a mutable reference to the underlying message builder.
1505    pub fn as_builder_mut(&mut self) -> &mut MessageBuilder<Target> {
1506        self.authority.as_builder_mut()
1507    }
1508}
1509
1510//--- From
1511
1512impl<Target> From<MessageBuilder<Target>> for AdditionalBuilder<Target>
1513where
1514    Target: Composer,
1515{
1516    fn from(src: MessageBuilder<Target>) -> Self {
1517        src.additional()
1518    }
1519}
1520
1521impl<Target> From<QuestionBuilder<Target>> for AdditionalBuilder<Target>
1522where
1523    Target: Composer,
1524{
1525    fn from(src: QuestionBuilder<Target>) -> Self {
1526        src.additional()
1527    }
1528}
1529
1530impl<Target> From<AnswerBuilder<Target>> for AdditionalBuilder<Target>
1531where
1532    Target: Composer,
1533{
1534    fn from(src: AnswerBuilder<Target>) -> Self {
1535        src.additional()
1536    }
1537}
1538
1539impl<Target> From<AuthorityBuilder<Target>> for AdditionalBuilder<Target>
1540where
1541    Target: Composer,
1542{
1543    fn from(src: AuthorityBuilder<Target>) -> Self {
1544        src.additional()
1545    }
1546}
1547
1548impl<Target> From<AdditionalBuilder<Target>> for Message<Target::Octets>
1549where
1550    Target: FreezeBuilder,
1551{
1552    fn from(src: AdditionalBuilder<Target>) -> Self {
1553        src.into_message()
1554    }
1555}
1556
1557//--- Deref, DerefMut, AsRef, and AsMut
1558
1559impl<Target> Deref for AdditionalBuilder<Target> {
1560    type Target = MessageBuilder<Target>;
1561
1562    fn deref(&self) -> &Self::Target {
1563        self.as_builder()
1564    }
1565}
1566
1567impl<Target> DerefMut for AdditionalBuilder<Target> {
1568    fn deref_mut(&mut self) -> &mut Self::Target {
1569        self.as_builder_mut()
1570    }
1571}
1572
1573impl<Target> AsRef<MessageBuilder<Target>> for AdditionalBuilder<Target> {
1574    fn as_ref(&self) -> &MessageBuilder<Target> {
1575        self.as_builder()
1576    }
1577}
1578
1579impl<Target> AsMut<MessageBuilder<Target>> for AdditionalBuilder<Target> {
1580    fn as_mut(&mut self) -> &mut MessageBuilder<Target> {
1581        self.as_builder_mut()
1582    }
1583}
1584
1585impl<Target> AsRef<Target> for AdditionalBuilder<Target> {
1586    fn as_ref(&self) -> &Target {
1587        self.as_target()
1588    }
1589}
1590
1591impl<Target: AsRef<[u8]>> AsRef<[u8]> for AdditionalBuilder<Target> {
1592    fn as_ref(&self) -> &[u8] {
1593        self.as_slice()
1594    }
1595}
1596
1597//------------ RecordSectionBuilder ------------------------------------------
1598
1599/// A section that can have records pushed to it.
1600///
1601/// This trait exists to make it possible to write code that works for all
1602/// three record sections. It basically just duplicates the `push` method of
1603/// these sections.
1604///
1605/// (This method is available on the sections as a method, too, so you don’t
1606/// need to import the `RecordSectionBuilder` all the time.)
1607pub trait RecordSectionBuilder<Target: Composer> {
1608    /// Appends a record to a record section.
1609    ///
1610    /// The methods accepts anything that implements the [`ComposeRecord`] trait.
1611    /// Apart from record values and references, this are tuples of the owner
1612    /// domain name, optionally the class (which is taken to be IN if
1613    /// missing), the TTL, and record data.
1614    fn push(&mut self, record: impl ComposeRecord) -> Result<(), PushError>;
1615}
1616
1617impl<Target> RecordSectionBuilder<Target> for AnswerBuilder<Target>
1618where
1619    Target: Composer,
1620{
1621    fn push(&mut self, record: impl ComposeRecord) -> Result<(), PushError> {
1622        Self::push(self, record)
1623    }
1624}
1625
1626impl<Target: Composer> RecordSectionBuilder<Target>
1627    for AuthorityBuilder<Target>
1628{
1629    fn push(&mut self, record: impl ComposeRecord) -> Result<(), PushError> {
1630        Self::push(self, record)
1631    }
1632}
1633
1634impl<Target> RecordSectionBuilder<Target> for AdditionalBuilder<Target>
1635where
1636    Target: Composer,
1637{
1638    fn push(&mut self, record: impl ComposeRecord) -> Result<(), PushError> {
1639        Self::push(self, record)
1640    }
1641}
1642
1643//------------ OptBuilder ----------------------------------------------------
1644
1645/// Builds an OPT record.
1646///
1647/// A mutable reference of this type is passed to the closure given to
1648/// [`AdditionalBuilder::opt`] allowing this closure to manipulate both the
1649/// header values of the record and push options to the record data.
1650///
1651/// [`AdditionalBuilder::opt`]: struct.AdditonalBuilder.html#method.opt
1652pub struct OptBuilder<'a, Target: ?Sized> {
1653    start: usize,
1654    target: &'a mut Target,
1655}
1656
1657impl<'a, Target: Composer + ?Sized> OptBuilder<'a, Target> {
1658    /// Creates a new opt builder atop an additional builder.
1659    fn new(target: &'a mut Target) -> Result<Self, ShortBuf> {
1660        let start = target.as_ref().len();
1661        OptHeader::default().compose(target).map_err(Into::into)?;
1662        Ok(OptBuilder { start, target })
1663    }
1664
1665    fn build<F>(&mut self, op: F) -> Result<(), ShortBuf>
1666    where
1667        F: FnOnce(&mut Self) -> Result<(), Target::AppendError>,
1668    {
1669        self.target.append_slice(&[0; 2]).map_err(Into::into)?;
1670        let pos = self.target.as_ref().len();
1671        match op(self) {
1672            Ok(_) => match u16::try_from(self.target.as_ref().len() - pos) {
1673                Ok(len) => {
1674                    self.target.as_mut()[pos - 2..pos]
1675                        .copy_from_slice(&(len).to_be_bytes());
1676                    Ok(())
1677                }
1678                Err(_) => {
1679                    self.target.truncate(pos);
1680                    Err(ShortBuf)
1681                }
1682            },
1683            Err(_) => {
1684                self.target.truncate(pos);
1685                Err(ShortBuf)
1686            }
1687        }
1688    }
1689
1690    /// Replaces the contents of this [`OptBuilder`] with the given
1691    /// [`OptRecord`]`.
1692    pub fn clone_from<T: AsRef<[u8]>>(
1693        &mut self,
1694        source: &OptRecord<T>,
1695    ) -> Result<(), Target::AppendError> {
1696        self.target.truncate(self.start);
1697        source.as_record().compose(self.target)
1698    }
1699
1700    /// Appends an option to the OPT record.
1701    pub fn push<Opt: ComposeOptData + ?Sized>(
1702        &mut self,
1703        opt: &Opt,
1704    ) -> Result<(), Target::AppendError> {
1705        self.push_raw_option(opt.code(), opt.compose_len(), |target| {
1706            opt.compose_option(target)
1707        })
1708    }
1709
1710    /// Appends a raw option to the OPT record.
1711    ///
1712    /// The method will append an option with the given option code. The data
1713    /// of the option will be written via the closure `op`.
1714    pub fn push_raw_option<F>(
1715        &mut self,
1716        code: OptionCode,
1717        option_len: u16,
1718        op: F,
1719    ) -> Result<(), Target::AppendError>
1720    where
1721        F: FnOnce(&mut Target) -> Result<(), Target::AppendError>,
1722    {
1723        code.compose(self.target)?;
1724        option_len.compose(self.target)?;
1725        op(self.target)
1726    }
1727
1728    /// Returns the current UDP payload size field of the OPT record.
1729    ///
1730    /// This field contains the largest UDP datagram the sender can accept.
1731    /// This is not the path MTU but really what the sender can work with
1732    /// internally.
1733    #[must_use]
1734    pub fn udp_payload_size(&self) -> u16 {
1735        self.opt_header().udp_payload_size()
1736    }
1737
1738    /// Sets the UDP payload size field of the OPT record.
1739    pub fn set_udp_payload_size(&mut self, value: u16) {
1740        self.opt_header_mut().set_udp_payload_size(value)
1741    }
1742
1743    /// Returns the extended rcode of the message.
1744    ///
1745    /// The method assembles the rcode both from the message header and the
1746    /// OPT header.
1747    #[must_use]
1748    pub fn rcode(&self) -> OptRcode {
1749        self.opt_header()
1750            .rcode(*Header::for_message_slice(self.target.as_ref()))
1751    }
1752
1753    /// Sets the extended rcode of the message.
1754    //
1755    /// The method will update both the message header and the OPT header.
1756    pub fn set_rcode(&mut self, rcode: OptRcode) {
1757        Header::for_message_slice_mut(self.target.as_mut())
1758            .set_rcode(rcode.rcode());
1759        self.opt_header_mut().set_rcode(rcode)
1760    }
1761
1762    /// Returns the EDNS version of the OPT header.
1763    ///
1764    /// Only EDNS version 0 is currently defined.
1765    #[must_use]
1766    pub fn version(&self) -> u8 {
1767        self.opt_header().version()
1768    }
1769
1770    /// Sets the EDNS version of the OPT header.
1771    pub fn set_version(&mut self, version: u8) {
1772        self.opt_header_mut().set_version(version)
1773    }
1774
1775    /// Returns the value of the DNSSEC OK (DO) bit.
1776    ///
1777    /// By setting this bit, a resolver indicates that it is interested in
1778    /// also receiving the DNSSEC-related resource records necessary to
1779    /// validate an answer. The bit and the related procedures are defined in
1780    /// [RFC 3225].
1781    ///
1782    /// [RFC 3225]: https://tools.ietf.org/html/rfc3225
1783    #[must_use]
1784    pub fn dnssec_ok(&self) -> bool {
1785        self.opt_header().dnssec_ok()
1786    }
1787
1788    /// Sets the DNSSEC OK (DO) bit to the given value.
1789    pub fn set_dnssec_ok(&mut self, value: bool) {
1790        self.opt_header_mut().set_dnssec_ok(value)
1791    }
1792
1793    /// Returns a reference to the full OPT header.
1794    fn opt_header(&self) -> &OptHeader {
1795        OptHeader::for_record_slice(&self.target.as_ref()[self.start..])
1796    }
1797
1798    /// Returns a mutual reference to the full OPT header.
1799    fn opt_header_mut(&mut self) -> &mut OptHeader {
1800        let start = self.start;
1801        OptHeader::for_record_slice_mut(&mut self.target.as_mut()[start..])
1802    }
1803
1804    /// Returns a reference to the underlying octets builder.
1805    pub fn as_target(&self) -> &Target {
1806        self.target
1807    }
1808}
1809
1810//------------ StreamTarget --------------------------------------------------
1811
1812/// A builder target for sending messages on stream transports.
1813///
1814/// TODO: Rename this type and adjust the doc comments as it is usable both
1815/// for datagram AND stream transports via [`as_dgram_slice`] and
1816/// [`as_stream_slice`].
1817///
1818/// When messages are sent over stream-oriented transports such as TCP, a DNS
1819/// message is preceded by a 16 bit length value in order to determine the end
1820/// of a message. This type transparently adds this length value as the first
1821/// two octets of an octets builder and itself presents an octets builder
1822/// interface for building the actual message. Whenever data is pushed to that
1823/// builder interface, the type will update the length value.
1824///
1825/// Because the length is 16 bits long, the assembled message can be at most
1826/// 65536 octets long, independently of the maximum length the underlying
1827/// builder allows.
1828///
1829/// [`as_dgram_slice`]: Self::as_dgram_slice
1830/// [`as_stream_slice`]: Self::as_stream_slice
1831#[derive(Clone, Debug, Default)]
1832pub struct StreamTarget<Target> {
1833    /// The underlying octets builder.
1834    target: Target,
1835}
1836
1837impl<Target: Composer> StreamTarget<Target> {
1838    /// Creates a new stream target wrapping an octets builder.
1839    ///
1840    /// The function will truncate the builder back to empty and append the
1841    /// length value. Because of the latter, this can fail if the octets
1842    /// builder doesn’t even have space for that.
1843    pub fn new(mut target: Target) -> Result<Self, Target::AppendError> {
1844        target.truncate(0);
1845        0u16.compose(&mut target)?;
1846        Ok(StreamTarget { target })
1847    }
1848}
1849
1850#[cfg(feature = "std")]
1851impl StreamTarget<Vec<u8>> {
1852    /// Creates a stream target atop an empty `Vec<u8>`.
1853    #[must_use]
1854    pub fn new_vec() -> Self {
1855        infallible(Self::new(Vec::new()))
1856    }
1857}
1858
1859#[cfg(feature = "bytes")]
1860impl StreamTarget<BytesMut> {
1861    /// Creates a stream target atop an empty `Vec<u8>`.
1862    pub fn new_bytes() -> Self {
1863        infallible(Self::new(BytesMut::new()))
1864    }
1865}
1866
1867impl<Target> StreamTarget<Target> {
1868    /// Returns a reference to the underlying octets builder.
1869    pub fn as_target(&self) -> &Target {
1870        &self.target
1871    }
1872
1873    /// Converts the stream target into the underlying octets builder.
1874    ///
1875    /// The returned builder will contain the 16 bit length value with the
1876    /// correct content and the assembled message.
1877    pub fn into_target(self) -> Target {
1878        self.target
1879    }
1880}
1881
1882impl<Target: AsRef<[u8]> + AsMut<[u8]>> StreamTarget<Target> {
1883    /// Updates the length value to the current length of the target.
1884    fn update_shim(&mut self) -> Result<(), ShortBuf> {
1885        match u16::try_from(self.target.as_ref().len() - 2) {
1886            Ok(len) => {
1887                self.target.as_mut()[..2].copy_from_slice(&len.to_be_bytes());
1888                Ok(())
1889            }
1890            Err(_) => Err(ShortBuf),
1891        }
1892    }
1893}
1894
1895impl<Target: AsRef<[u8]>> StreamTarget<Target> {
1896    /// Returns an octets slice of the message for stream transports.
1897    ///
1898    /// The slice will start with the length octets and can be send as is
1899    /// through a stream transport such as TCP.
1900    pub fn as_stream_slice(&self) -> &[u8] {
1901        self.target.as_ref()
1902    }
1903
1904    /// Returns an octets slice of the message for datagram transports.
1905    ///
1906    /// The slice will not contain the length octets but only the actual
1907    /// message itself. This slice can be used for sending via datagram
1908    /// transports such as UDP.
1909    pub fn as_dgram_slice(&self) -> &[u8] {
1910        &self.target.as_ref()[2..]
1911    }
1912}
1913
1914//--- AsRef, AsMut
1915
1916impl<Target: AsRef<[u8]>> AsRef<[u8]> for StreamTarget<Target> {
1917    fn as_ref(&self) -> &[u8] {
1918        &self.target.as_ref()[2..]
1919    }
1920}
1921
1922impl<Target: AsMut<[u8]>> AsMut<[u8]> for StreamTarget<Target> {
1923    fn as_mut(&mut self) -> &mut [u8] {
1924        &mut self.target.as_mut()[2..]
1925    }
1926}
1927
1928//--- OctetsBuilder, Truncate, Composer
1929
1930impl<Target> OctetsBuilder for StreamTarget<Target>
1931where
1932    Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>,
1933    Target::AppendError: Into<ShortBuf>,
1934{
1935    type AppendError = ShortBuf;
1936
1937    fn append_slice(
1938        &mut self,
1939        slice: &[u8],
1940    ) -> Result<(), Self::AppendError> {
1941        self.target.append_slice(slice).map_err(Into::into)?;
1942        self.update_shim()
1943    }
1944}
1945
1946impl<Target: Composer> Truncate for StreamTarget<Target> {
1947    fn truncate(&mut self, len: usize) {
1948        self.target
1949            .truncate(len.checked_add(2).expect("long truncate"));
1950        self.update_shim().expect("truncate grew buffer???")
1951    }
1952}
1953
1954impl<Target> Composer for StreamTarget<Target>
1955where
1956    Target: Composer,
1957    Target::AppendError: Into<ShortBuf>,
1958{
1959    fn append_compressed_name<N: ToName + ?Sized>(
1960        &mut self,
1961        name: &N,
1962    ) -> Result<(), Self::AppendError> {
1963        self.target
1964            .append_compressed_name(name)
1965            .map_err(Into::into)?;
1966        self.update_shim()
1967    }
1968}
1969
1970//------------ StaticCompressor ----------------------------------------------
1971
1972/// A domain name compressor that doesn’t require an allocator.
1973///
1974/// This type wraps around an octets builder and implements domain name
1975/// compression. It does not require an allocator but because of that it
1976/// can only remember the position of up to 24 domain names. This should be
1977/// sufficient for most messages.
1978///
1979/// The position of a domain name is calculated relative to the beginning of
1980/// the underlying octets builder. This means that this builder must represent
1981/// the message only. This means that if you are using the [`StreamTarget`],
1982/// you need to place it inside this type, _not_ the other way around.
1983///
1984/// [`StreamTarget`]: struct.StreamTarget.html
1985#[derive(Clone, Debug)]
1986pub struct StaticCompressor<Target> {
1987    /// The underlying octets builder.
1988    target: Target,
1989
1990    /// The domain names we have encountered so far.
1991    ///
1992    /// The value is the position of the domain name within the message.
1993    entries: [u16; 24],
1994
1995    /// The number of entries in `entries`.
1996    len: usize,
1997}
1998
1999impl<Target> StaticCompressor<Target> {
2000    /// Creates a static compressor from an octets builder.
2001    pub fn new(target: Target) -> Self {
2002        StaticCompressor {
2003            target,
2004            entries: Default::default(),
2005            len: 0,
2006        }
2007    }
2008
2009    /// Returns a reference to the underlying octets builder.
2010    pub fn as_target(&self) -> &Target {
2011        &self.target
2012    }
2013
2014    /// Converts the static compressor into the underlying octets builder.
2015    pub fn into_target(self) -> Target {
2016        self.target
2017    }
2018
2019    /// Returns a reference to the octets slice of the content.
2020    pub fn as_slice(&self) -> &[u8]
2021    where
2022        Target: AsRef<[u8]>,
2023    {
2024        self.target.as_ref()
2025    }
2026
2027    /// Returns a reference to the octets slice of the content.
2028    pub fn as_slice_mut(&mut self) -> &mut [u8]
2029    where
2030        Target: AsMut<[u8]>,
2031    {
2032        self.target.as_mut()
2033    }
2034
2035    /// Returns a known position of a domain name if there is one.
2036    fn get<'a, N: Iterator<Item = &'a Label> + Clone>(
2037        &self,
2038        name: N,
2039    ) -> Option<u16>
2040    where
2041        Target: AsRef<[u8]>,
2042    {
2043        self.entries[..self.len].iter().find_map(|&pos| {
2044            if name
2045                .clone()
2046                .eq(Label::iter_slice(self.target.as_ref(), pos as usize))
2047            {
2048                Some(pos)
2049            } else {
2050                None
2051            }
2052        })
2053    }
2054
2055    /// Inserts the position of a new domain name if possible.
2056    fn insert(&mut self, pos: usize) -> bool {
2057        if pos < 0xc000 && self.len < self.entries.len() {
2058            self.entries[self.len] = pos as u16;
2059            self.len += 1;
2060            true
2061        } else {
2062            false
2063        }
2064    }
2065}
2066
2067//--- AsRef and AsMut
2068
2069impl<Target: AsRef<[u8]>> AsRef<[u8]> for StaticCompressor<Target> {
2070    fn as_ref(&self) -> &[u8] {
2071        self.as_slice()
2072    }
2073}
2074
2075impl<Target: AsMut<[u8]>> AsMut<[u8]> for StaticCompressor<Target> {
2076    fn as_mut(&mut self) -> &mut [u8] {
2077        self.as_slice_mut()
2078    }
2079}
2080
2081//--- OctetsBuilder
2082
2083impl<Target: OctetsBuilder> OctetsBuilder for StaticCompressor<Target> {
2084    type AppendError = Target::AppendError;
2085
2086    fn append_slice(
2087        &mut self,
2088        slice: &[u8],
2089    ) -> Result<(), Self::AppendError> {
2090        self.target.append_slice(slice)
2091    }
2092}
2093
2094impl<Target: Composer> Composer for StaticCompressor<Target> {
2095    fn append_compressed_name<N: ToName + ?Sized>(
2096        &mut self,
2097        name: &N,
2098    ) -> Result<(), Self::AppendError> {
2099        let mut name = name.iter_labels().peekable();
2100
2101        loop {
2102            // If the parent is root, just write that and return.
2103            // Because we do that, there will always be a label left here.
2104            if let Some(label) = name.peek() {
2105                if label.is_root() {
2106                    label.compose(self)?;
2107                    return Ok(());
2108                }
2109            }
2110
2111            // If we already know this name, append it as a compressed label.
2112            if let Some(pos) = self.get(name.clone()) {
2113                return (pos | 0xC000).compose(self);
2114            }
2115
2116            // So we don’t know the name. Try inserting it into the
2117            // compressor. If we can’t insert anymore, just write out what’s
2118            // left and return.
2119            if !self.insert(self.target.as_ref().len()) {
2120                for label in &mut name {
2121                    label.compose(self)?;
2122                }
2123                return Ok(());
2124            }
2125
2126            // Advance to the parent.
2127            let label = name.next().unwrap();
2128            label.compose(self)?;
2129        }
2130    }
2131
2132    fn can_compress(&self) -> bool {
2133        true
2134    }
2135}
2136
2137impl<Target: Truncate> Truncate for StaticCompressor<Target> {
2138    fn truncate(&mut self, len: usize) {
2139        self.target.truncate(len);
2140        if len < 0xC000 {
2141            let len = len as u16;
2142            for i in 0..self.len {
2143                if self.entries[i] >= len {
2144                    self.len = i;
2145                    break;
2146                }
2147            }
2148        }
2149    }
2150}
2151
2152impl<Target: FreezeBuilder> FreezeBuilder for StaticCompressor<Target> {
2153    type Octets = Target::Octets;
2154
2155    fn freeze(self) -> Self::Octets {
2156        self.target.freeze()
2157    }
2158}
2159
2160//------------ TreeCompressor ------------------------------------------------
2161
2162/// A domain name compressor that uses a tree.
2163///
2164/// This type wraps around an octets builder and implements domain name
2165/// compression for it. It stores the position of any domain name it has seen
2166/// in a binary tree.
2167///
2168/// The position of a domain name is calculated relative to the beginning of
2169/// the underlying octets builder. This means that this builder must represent
2170/// the message only. This means that if you are using the [`StreamTarget`],
2171/// you need to place it inside this type, _not_ the other way around.
2172///
2173/// [`StreamTarget`]: struct.StreamTarget.html
2174#[cfg(feature = "std")]
2175#[derive(Clone, Debug)]
2176pub struct TreeCompressor<Target> {
2177    /// The underlying octetsbuilder.
2178    target: Target,
2179
2180    /// The topmost node of our tree.
2181    start: Node,
2182}
2183
2184/// A node in our tree.
2185///
2186/// The tree is a bit odd. It follows the labels of the domain names from the
2187/// root towards the left. The root node is for the root label. It contains a
2188/// map that maps all the labels encountered to the immediate left of the
2189/// name traced by this path through the tree to a node for the name resulting
2190/// by adding this label to the name constructed so far.
2191///
2192/// Each node also contains the position of that name in the message.
2193#[cfg(feature = "std")]
2194#[derive(Clone, Debug, Default)]
2195struct Node {
2196    /// The labels immediately to the left of this name and their nodes.
2197    parents: HashMap<Array<64>, Self>,
2198
2199    /// The position of this name in the message.
2200    value: Option<u16>,
2201}
2202
2203#[cfg(feature = "std")]
2204impl Node {
2205    fn drop_above(&mut self, len: u16) {
2206        self.value = match self.value {
2207            Some(value) if value < len => Some(value),
2208            _ => None,
2209        };
2210        self.parents
2211            .values_mut()
2212            .for_each(|node| node.drop_above(len))
2213    }
2214}
2215
2216#[cfg(feature = "std")]
2217impl<Target> TreeCompressor<Target> {
2218    /// Creates a new compressor from an underlying octets builder.
2219    pub fn new(target: Target) -> Self {
2220        TreeCompressor {
2221            target,
2222            start: Default::default(),
2223        }
2224    }
2225
2226    /// Returns a reference to the underlying octets builder.
2227    pub fn as_target(&self) -> &Target {
2228        &self.target
2229    }
2230
2231    /// Converts the compressor into the underlying octets builder.
2232    pub fn into_target(self) -> Target {
2233        self.target
2234    }
2235
2236    /// Returns an octets slice of the data.
2237    pub fn as_slice(&self) -> &[u8]
2238    where
2239        Target: AsRef<[u8]>,
2240    {
2241        self.target.as_ref()
2242    }
2243
2244    /// Returns an mutable octets slice of the data.
2245    pub fn as_slice_mut(&mut self) -> &mut [u8]
2246    where
2247        Target: AsMut<[u8]>,
2248    {
2249        self.target.as_mut()
2250    }
2251
2252    fn get<'a, N: Iterator<Item = &'a Label> + Clone>(
2253        &self,
2254        name: N,
2255    ) -> Option<u16> {
2256        let mut node = &self.start;
2257        for label in name {
2258            if label.is_root() {
2259                return node.value;
2260            }
2261            node = node.parents.get(label.as_ref())?;
2262        }
2263        None
2264    }
2265
2266    fn insert<'a, N: Iterator<Item = &'a Label> + Clone>(
2267        &mut self,
2268        name: N,
2269        pos: usize,
2270    ) -> bool {
2271        if pos >= 0xC000 {
2272            return false;
2273        }
2274        let pos = pos as u16;
2275        let mut node = &mut self.start;
2276        for label in name {
2277            if label.is_root() {
2278                node.value = Some(pos);
2279                break;
2280            }
2281            node = node
2282                .parents
2283                .entry(label.as_ref().try_into().unwrap())
2284                .or_default();
2285        }
2286        true
2287    }
2288}
2289
2290//--- AsRef, AsMut, and OctetsBuilder
2291
2292#[cfg(feature = "std")]
2293impl<Target: AsRef<[u8]>> AsRef<[u8]> for TreeCompressor<Target> {
2294    fn as_ref(&self) -> &[u8] {
2295        self.as_slice()
2296    }
2297}
2298
2299#[cfg(feature = "std")]
2300impl<Target: AsMut<[u8]>> AsMut<[u8]> for TreeCompressor<Target> {
2301    fn as_mut(&mut self) -> &mut [u8] {
2302        self.as_slice_mut()
2303    }
2304}
2305
2306#[cfg(feature = "std")]
2307impl<Target: OctetsBuilder> OctetsBuilder for TreeCompressor<Target> {
2308    type AppendError = Target::AppendError;
2309
2310    fn append_slice(
2311        &mut self,
2312        slice: &[u8],
2313    ) -> Result<(), Self::AppendError> {
2314        self.target.append_slice(slice)
2315    }
2316}
2317
2318#[cfg(feature = "std")]
2319impl<Target: Composer> Composer for TreeCompressor<Target> {
2320    fn append_compressed_name<N: ToName + ?Sized>(
2321        &mut self,
2322        name: &N,
2323    ) -> Result<(), Self::AppendError> {
2324        let mut name = name.iter_labels().peekable();
2325
2326        loop {
2327            // If the parent is root, just write that and return.
2328            // Because we do that, there will always be a label left here.
2329            if let Some(label) = name.peek() {
2330                if label.is_root() {
2331                    label.compose(self)?;
2332                    return Ok(());
2333                }
2334            }
2335
2336            // If we already know this name, append it as a compressed label.
2337            if let Some(pos) = self.get(name.clone()) {
2338                return (pos | 0xC000).compose(self);
2339            }
2340
2341            // So we don’t know the name. Try inserting it into the
2342            // compressor. If we can’t insert anymore, just write out what’s
2343            // left and return.
2344            if !self.insert(name.clone(), self.target.as_ref().len()) {
2345                for label in &mut name {
2346                    label.compose(self)?;
2347                }
2348                return Ok(());
2349            }
2350
2351            // Advance to the parent. If the parent is root, just write that
2352            // and return. Because we do that, there will always be a label
2353            // left here.
2354            let label = name.next().unwrap();
2355            label.compose(self)?;
2356        }
2357    }
2358
2359    fn can_compress(&self) -> bool {
2360        true
2361    }
2362}
2363
2364#[cfg(feature = "std")]
2365impl<Target: Composer> Truncate for TreeCompressor<Target> {
2366    fn truncate(&mut self, len: usize) {
2367        self.target.truncate(len);
2368        if len < 0xC000 {
2369            self.start.drop_above(len as u16)
2370        }
2371    }
2372}
2373
2374//------------ HashCompressor ------------------------------------------------
2375
2376/// A domain name compressor that uses a hash table.
2377///
2378/// This type wraps around an octets builder and implements domain name
2379/// compression for it. It stores the position of any domain name it has seen
2380/// in a hash table.
2381///
2382/// The position of a domain name is calculated relative to the beginning of
2383/// the underlying octets builder. This means that this builder must represent
2384/// the message only. This means that if you are using the [`StreamTarget`],
2385/// you need to place it inside this type, _not_ the other way around.
2386///
2387/// [`StreamTarget`]: struct.StreamTarget.html
2388#[cfg(feature = "std")]
2389#[derive(Clone, Debug)]
2390pub struct HashCompressor<Target> {
2391    /// The underlying octetsbuilder.
2392    target: Target,
2393
2394    /// The names inserted into the message.
2395    ///
2396    /// Consider a set of names, where the "parent" (i.e. tail) of each name is
2397    /// another name in the set.  For example, a set might contain `.`, `org.`,
2398    /// `example.org.`, and `www.example.org.`.  Each of these names (except the
2399    /// root, which is handled specially) is stored as a separate entry in this
2400    /// hash table.  A name `<head>.<tail>` is stored as the index of `<head>`
2401    /// and the index of `<tail>` in the built message.  Its hash is built from
2402    /// `<head>` (the bytes in the label, not the index into the message) and
2403    /// the index of `<tail>`.
2404    ///
2405    /// Lookups are performed by iterating backward through the labels in a name
2406    /// (to go from the root outward).  At each step, the canonical position of
2407    /// `<tail>` is already known; it is hashed together with the next label and
2408    /// searched for in the hash table.  An entry with a matching `<head>` (i.e.
2409    /// where the referenced content in the message matches the searched label)
2410    /// and a matching `<tail>` position represents the same name.
2411    ///
2412    /// The root is handled specially.  It is never inserted in the hash table,
2413    /// and instead has a fixed fake position in the message of 0xFFFF.  That is
2414    /// the initial value that lookups start with.
2415    ///
2416    /// As an example, consider a message `org. example.org. www.example.org.`.
2417    /// In the hash table, the first two entries will look like:
2418    ///
2419    /// ```text
2420    /// - head=0 ("org") tail=0xFFFF
2421    /// - head=5 ("example") tail=0
2422    /// ```
2423    ///
2424    /// Now, to insert `www.example.org.`, the lookup begins from the end.  We
2425    /// search for a label "org" with tail 0xFFFF, and find head=0.  We set this
2426    /// as the next tail, and search for label "example" to find head=5.  Since
2427    /// a label "www" with tail=5 is not already in the hash table, it will be
2428    /// inserted with head=18.
2429    ///
2430    /// This has a space overhead of 4-5 bytes for each entry, accounting for
2431    /// the load factor (which appears to be 87.5%).  Technically, storing the
2432    /// labels indirectly means that comparisons are more expensive; but most
2433    /// labels are relatively short and storing them inline as 64-byte arrays
2434    /// would be quite wasteful.
2435    names: HashTable<HashEntry>,
2436
2437    /// How names in the table are hashed.
2438    hasher: RandomState,
2439}
2440
2441#[cfg(feature = "std")]
2442#[derive(Copy, Clone, Debug)]
2443struct HashEntry {
2444    /// The position of the head label in the name.
2445    head: u16,
2446
2447    /// The position of the tail name.
2448    tail: u16,
2449}
2450
2451#[cfg(feature = "std")]
2452impl HashEntry {
2453    /// Try constructing a [`HashEntry`].
2454    fn new(head: usize, tail: usize) -> Option<Self> {
2455        if head < 0xC000 {
2456            Some(Self {
2457                head: head as u16,
2458                tail: tail as u16,
2459            })
2460        } else {
2461            None
2462        }
2463    }
2464
2465    /// Get the head label for this entry.
2466    fn head<'m>(&self, message: &'m [u8]) -> &'m Label {
2467        Label::split_from(&message[self.head as usize..])
2468            .expect("the message contains valid labels")
2469            .0
2470    }
2471
2472    /// Compute the hash of this entry.
2473    fn hash(&self, message: &[u8], hasher: &RandomState) -> u64 {
2474        hasher.hash_one((self.head(message), self.tail))
2475    }
2476
2477    /// Compare this entry to a label.
2478    fn eq(&self, message: &[u8], query: (&Label, u16)) -> bool {
2479        (self.head(message), self.tail) == query
2480    }
2481}
2482
2483#[cfg(feature = "std")]
2484impl<Target> HashCompressor<Target> {
2485    /// Creates a new compressor from an underlying octets builder.
2486    pub fn new(target: Target) -> Self {
2487        HashCompressor {
2488            target,
2489            names: Default::default(),
2490            hasher: Default::default(),
2491        }
2492    }
2493
2494    /// Returns a reference to the underlying octets builder.
2495    pub fn as_target(&self) -> &Target {
2496        &self.target
2497    }
2498
2499    /// Converts the compressor into the underlying octets builder.
2500    pub fn into_target(self) -> Target {
2501        self.target
2502    }
2503
2504    /// Returns an octets slice of the data.
2505    pub fn as_slice(&self) -> &[u8]
2506    where
2507        Target: AsRef<[u8]>,
2508    {
2509        self.target.as_ref()
2510    }
2511
2512    /// Returns an mutable octets slice of the data.
2513    pub fn as_slice_mut(&mut self) -> &mut [u8]
2514    where
2515        Target: AsMut<[u8]>,
2516    {
2517        self.target.as_mut()
2518    }
2519}
2520
2521//--- AsRef, AsMut, and OctetsBuilder
2522
2523#[cfg(feature = "std")]
2524impl<Target: AsRef<[u8]>> AsRef<[u8]> for HashCompressor<Target> {
2525    fn as_ref(&self) -> &[u8] {
2526        self.as_slice()
2527    }
2528}
2529
2530#[cfg(feature = "std")]
2531impl<Target: AsMut<[u8]>> AsMut<[u8]> for HashCompressor<Target> {
2532    fn as_mut(&mut self) -> &mut [u8] {
2533        self.as_slice_mut()
2534    }
2535}
2536
2537#[cfg(feature = "std")]
2538impl<Target: OctetsBuilder> OctetsBuilder for HashCompressor<Target> {
2539    type AppendError = Target::AppendError;
2540
2541    fn append_slice(
2542        &mut self,
2543        slice: &[u8],
2544    ) -> Result<(), Self::AppendError> {
2545        self.target.append_slice(slice)
2546    }
2547}
2548
2549#[cfg(feature = "std")]
2550impl<Target: Composer> Composer for HashCompressor<Target> {
2551    fn append_compressed_name<N: ToName + ?Sized>(
2552        &mut self,
2553        name: &N,
2554    ) -> Result<(), Self::AppendError> {
2555        let mut name = name.iter_labels();
2556        let message = self.target.as_ref();
2557
2558        // Remove the root label -- we know it's there.
2559        assert!(
2560            name.next_back().is_some_and(|l| l.is_root()),
2561            "absolute names must end with a root label"
2562        );
2563
2564        // The position of the consumed labels from the end of the name.
2565        let mut position = 0xFFFF;
2566
2567        // The last label that must be inserted, if any.
2568        let mut last_label = None;
2569
2570        // Look up each label in reverse order.
2571        while let Some(label) = name.next_back() {
2572            // Look up the labels seen thus far in the hash table.
2573            let query = (label, position);
2574            let hash = self.hasher.hash_one(query);
2575
2576            let entry =
2577                self.names.find(hash, |&name| name.eq(message, query));
2578            if let Some(entry) = entry {
2579                // We found a match, so update the position.
2580                position = entry.head;
2581            } else {
2582                // We will have to write this label.
2583                last_label = Some(label);
2584                break;
2585            }
2586        }
2587
2588        // Write out the remaining labels in the name in regular order.
2589        let mut labels = name.chain(last_label).peekable();
2590        while let Some(label) = labels.next() {
2591            let head = self.target.as_ref().len();
2592            let tail = head + label.compose_len() as usize;
2593
2594            label.compose(self)?;
2595
2596            // Remember this label for future compression, if possible.
2597            //
2598            // If some labels in this name pass the 0xC000 boundary point, then
2599            // none of its remembered labels can be used (since they are looked
2600            // up from right to left, and the rightmost ones will fail first).
2601            // We could check more thoroughly for this, but it's not worth it.
2602            if let Some(mut entry) = HashEntry::new(head, tail) {
2603                // If there is no following label, use the remaining position.
2604                if labels.peek().is_none() {
2605                    entry.tail = position;
2606                }
2607
2608                let message = self.target.as_ref();
2609                let hasher = &self.hasher;
2610                let hash = entry.hash(message, hasher);
2611                self.names.insert_unique(hash, entry, |&name| {
2612                    name.hash(message, hasher)
2613                });
2614            }
2615        }
2616
2617        // Write the compressed pointer or the root label.
2618        if position != 0xFFFF {
2619            (position | 0xC000).compose(self)
2620        } else {
2621            Label::root().compose(self)
2622        }
2623    }
2624
2625    fn can_compress(&self) -> bool {
2626        true
2627    }
2628}
2629
2630#[cfg(feature = "std")]
2631impl<Target: Composer> Truncate for HashCompressor<Target> {
2632    fn truncate(&mut self, len: usize) {
2633        self.target.truncate(len);
2634        if len < 0xC000 {
2635            self.names.retain(|name| name.head < len as u16);
2636        }
2637    }
2638}
2639
2640//============ Errors ========================================================
2641
2642#[derive(Clone, Copy, Debug)]
2643pub enum PushError {
2644    CountOverflow,
2645    ShortBuf,
2646}
2647
2648impl<T: Into<ShortBuf>> From<T> for PushError {
2649    fn from(_: T) -> Self {
2650        Self::ShortBuf
2651    }
2652}
2653
2654impl fmt::Display for PushError {
2655    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2656        match *self {
2657            PushError::CountOverflow => f.write_str("counter overflow"),
2658            PushError::ShortBuf => ShortBuf.fmt(f),
2659        }
2660    }
2661}
2662
2663#[cfg(feature = "std")]
2664impl std::error::Error for PushError {}
2665
2666//============ Testing =======================================================
2667
2668#[cfg(test)]
2669#[cfg(feature = "std")]
2670mod test {
2671    use super::*;
2672    use crate::base::opt;
2673    use crate::base::{Name, Serial, Ttl};
2674    use crate::rdata::{Ns, Soa, A};
2675    use core::str::FromStr;
2676
2677    #[test]
2678    fn message_builder() {
2679        // Make a domain name we can use later on.
2680        let name = Name::<Vec<u8>>::from_str("example.com").unwrap();
2681
2682        // Create a message builder wrapping a compressor wrapping a stream
2683        // target.
2684        let mut msg = MessageBuilder::from_target(StaticCompressor::new(
2685            StreamTarget::new_vec(),
2686        ))
2687        .unwrap();
2688
2689        // Set the RD bit in the header and proceed to the question section.
2690        msg.header_mut().set_rd(true);
2691        let mut msg = msg.question();
2692
2693        // Add a question and proceed to the answer section.
2694        msg.push((&name, Rtype::A)).unwrap();
2695        let mut msg = msg.answer();
2696
2697        // Add two answer and proceed to the additional sections
2698        msg.push((&name, 86400, A::from_octets(192, 0, 2, 1)))
2699            .unwrap();
2700        msg.push((&name, 86400, A::from_octets(192, 0, 2, 2)))
2701            .unwrap();
2702
2703        // Add an authority
2704        let mut msg = msg.authority();
2705        msg.push((&name, 0, Ns::from(name.clone()))).unwrap();
2706
2707        // Add additional
2708        let mut msg = msg.additional();
2709        msg.push((&name, 86400, A::from_octets(192, 0, 2, 1)))
2710            .unwrap();
2711
2712        // Convert the builder into the actual message.
2713        let target = msg.finish().into_target();
2714
2715        // Reparse message and check contents
2716        let msg = Message::from_octets(target.as_dgram_slice()).unwrap();
2717        let q = msg.first_question().unwrap();
2718        assert_eq!(q.qname(), &name);
2719        assert_eq!(q.qtype(), Rtype::A);
2720
2721        let section = msg.answer().unwrap();
2722        let mut records = section.limit_to::<A>();
2723        assert_eq!(
2724            records.next().unwrap().unwrap().data(),
2725            &A::from_octets(192, 0, 2, 1)
2726        );
2727        assert_eq!(
2728            records.next().unwrap().unwrap().data(),
2729            &A::from_octets(192, 0, 2, 2)
2730        );
2731
2732        let section = msg.authority().unwrap();
2733        let mut records = section.limit_to::<Ns<_>>();
2734        let rr = records.next().unwrap().unwrap();
2735        assert_eq!(rr.owner(), &name);
2736        assert_eq!(rr.data().nsdname(), &name);
2737
2738        let section = msg.additional().unwrap();
2739        let mut records = section.limit_to::<A>();
2740        let rr = records.next().unwrap().unwrap();
2741        assert_eq!(rr.owner(), &name);
2742        assert_eq!(rr.data(), &A::from_octets(192, 0, 2, 1));
2743    }
2744
2745    #[cfg(feature = "heapless")]
2746    #[test]
2747    fn exceed_limits() {
2748        // Create a limited message builder.
2749        let buf = heapless::Vec::<u8, 100>::new();
2750
2751        // Initialize it with a message header (12 bytes)
2752        let mut msg = MessageBuilder::from_target(buf).unwrap();
2753        let hdr_len = msg.as_slice().len();
2754
2755        // Add some bytes.
2756        msg.push(|t| t.append_slice(&[0u8; 50]), |_| Ok(()))
2757            .unwrap();
2758        assert_eq!(msg.as_slice().len(), hdr_len + 50);
2759
2760        // Set a push limit below the current length.
2761        msg.set_push_limit(25);
2762
2763        // Verify that push fails.
2764        assert!(msg.push(|t| t.append_slice(&[0u8; 1]), |_| Ok(())).is_err());
2765        assert_eq!(msg.as_slice().len(), hdr_len + 50);
2766
2767        // Remove the limit.
2768        msg.clear_push_limit();
2769
2770        // Verify that push up until capacity succeeds.
2771        for _ in (hdr_len + 50)..100 {
2772            msg.push(|t| t.append_slice(&[0u8; 1]), |_| Ok(())).unwrap();
2773        }
2774        assert_eq!(msg.as_slice().len(), 100);
2775
2776        // Verify that exceeding the underlying capacity limit fails.
2777        assert!(msg.push(|t| t.append_slice(&[0u8; 1]), |_| Ok(())).is_err());
2778        assert_eq!(msg.as_slice().len(), 100);
2779    }
2780
2781    #[test]
2782    fn opt_builder() {
2783        let mut msg = MessageBuilder::new_vec().additional();
2784
2785        // Add an OPT record.
2786        let nsid = opt::nsid::Nsid::from_octets(&b"example"[..]).unwrap();
2787        msg.opt(|o| {
2788            o.set_udp_payload_size(4096);
2789            o.push(&nsid)?;
2790            Ok(())
2791        })
2792        .unwrap();
2793
2794        let msg = msg.finish();
2795        println!("{:?}", msg);
2796        let msg = Message::from_octets(msg).unwrap();
2797        let opt = msg.opt().unwrap();
2798
2799        // Check options
2800        assert_eq!(opt.udp_payload_size(), 4096);
2801        let mut opts = opt.opt().iter::<opt::nsid::Nsid<_>>();
2802        assert_eq!(opts.next(), Some(Ok(nsid)));
2803    }
2804
2805    fn create_compressed<T: Composer>(target: T) -> T
2806    where
2807        T::AppendError: fmt::Debug,
2808    {
2809        let mut msg = MessageBuilder::from_target(target).unwrap().question();
2810        msg.header_mut().set_rcode(Rcode::NXDOMAIN);
2811        msg.header_mut().set_rd(true);
2812        msg.header_mut().set_ra(true);
2813        msg.header_mut().set_qr(true);
2814
2815        msg.push((&"example".parse::<Name<Vec<u8>>>().unwrap(), Rtype::NS))
2816            .unwrap();
2817        let mut msg = msg.authority();
2818
2819        let mname: Name<Vec<u8>> = "a.root-servers.net".parse().unwrap();
2820        let rname = "nstld.verisign-grs.com".parse().unwrap();
2821        msg.push((
2822            Name::root_slice(),
2823            86390,
2824            Soa::new(
2825                mname,
2826                rname,
2827                Serial(2020081701),
2828                Ttl::from_secs(1800),
2829                Ttl::from_secs(900),
2830                Ttl::from_secs(604800),
2831                Ttl::from_secs(86400),
2832            ),
2833        ))
2834        .unwrap();
2835        msg.finish()
2836    }
2837
2838    #[test]
2839    fn compressor() {
2840        // An example negative response to `example. NS` with an SOA to test
2841        // various compressed name situations.
2842        let expect = &[
2843            0x00, 0x00, 0x81, 0x83, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
2844            0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x00, 0x00,
2845            0x02, 0x00, 0x01, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x51,
2846            0x76, 0x00, 0x40, 0x01, 0x61, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d,
2847            0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x03, 0x6e, 0x65, 0x74,
2848            0x00, 0x05, 0x6e, 0x73, 0x74, 0x6c, 0x64, 0x0c, 0x76, 0x65, 0x72,
2849            0x69, 0x73, 0x69, 0x67, 0x6e, 0x2d, 0x67, 0x72, 0x73, 0x03, 0x63,
2850            0x6f, 0x6d, 0x00, 0x78, 0x68, 0x00, 0x25, 0x00, 0x00, 0x07, 0x08,
2851            0x00, 0x00, 0x03, 0x84, 0x00, 0x09, 0x3a, 0x80, 0x00, 0x01, 0x51,
2852            0x80,
2853        ];
2854
2855        let msg = create_compressed(StaticCompressor::new(Vec::new()));
2856        assert_eq!(&expect[..], msg.as_ref());
2857
2858        let msg = create_compressed(TreeCompressor::new(Vec::new()));
2859        assert_eq!(&expect[..], msg.as_ref());
2860    }
2861
2862    #[test]
2863    fn compress_positive_response() {
2864        // An example positive response to `A example.com.` that is compressed
2865        //
2866        // ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 0
2867        // ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
2868        //
2869        // ;; QUESTION SECTION:
2870        // ;example.com.			IN	A
2871        //
2872        // ;; ANSWER SECTION:
2873        // example.com.		3600	IN	A	203.0.113.1
2874        //
2875        // ;; MSG SIZE  rcvd: 45
2876        let expect = &[
2877            0x00, 0x00, 0x81, 0xa0, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
2878            0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63,
2879            0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01,
2880            0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x04, 0xcb, 0x00, 0x71,
2881            0x01,
2882        ];
2883
2884        let name = "example.com.".parse::<Name<Vec<u8>>>().unwrap();
2885        let mut msg =
2886            MessageBuilder::from_target(StaticCompressor::new(Vec::new()))
2887                .unwrap()
2888                .question();
2889        msg.header_mut().set_rcode(Rcode::NOERROR);
2890        msg.header_mut().set_rd(true);
2891        msg.header_mut().set_ra(true);
2892        msg.header_mut().set_qr(true);
2893        msg.header_mut().set_ad(true);
2894
2895        // Question
2896        msg.push((name.clone(), Rtype::A)).unwrap();
2897
2898        // Answer
2899        let mut msg = msg.answer();
2900        msg.push((name.clone(), 3600, A::from_octets(203, 0, 113, 1)))
2901            .unwrap();
2902
2903        let actual = msg.finish().into_target();
2904        assert_eq!(45, actual.len(), "unexpected response size");
2905        assert_eq!(expect[..], actual, "unexpected response data");
2906    }
2907
2908    #[cfg(feature = "std")]
2909    #[test]
2910    fn hash_compress_positive_response() {
2911        // An example positive response to `A example.com.` that is compressed
2912        //
2913        // ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 0
2914        // ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
2915        //
2916        // ;; QUESTION SECTION:
2917        // ;example.com.			IN	A
2918        //
2919        // ;; ANSWER SECTION:
2920        // example.com.		3600	IN	A	203.0.113.1
2921        //
2922        // ;; MSG SIZE  rcvd: 45
2923        let expect = &[
2924            0x00, 0x00, 0x81, 0xa0, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
2925            0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63,
2926            0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01,
2927            0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x04, 0xcb, 0x00, 0x71,
2928            0x01,
2929        ];
2930
2931        let name = "example.com.".parse::<Name<Vec<u8>>>().unwrap();
2932        let mut msg =
2933            MessageBuilder::from_target(HashCompressor::new(Vec::new()))
2934                .unwrap()
2935                .question();
2936        msg.header_mut().set_rcode(Rcode::NOERROR);
2937        msg.header_mut().set_rd(true);
2938        msg.header_mut().set_ra(true);
2939        msg.header_mut().set_qr(true);
2940        msg.header_mut().set_ad(true);
2941
2942        // Question
2943        msg.push((name.clone(), Rtype::A)).unwrap();
2944
2945        // Answer
2946        let mut msg = msg.answer();
2947        msg.push((name.clone(), 3600, A::from_octets(203, 0, 113, 1)))
2948            .unwrap();
2949
2950        let actual = msg.finish().into_target();
2951        assert_eq!(45, actual.len(), "unexpected response size");
2952        assert_eq!(expect[..], actual, "unexpected response data");
2953    }
2954}