Skip to main content

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