Module domain::bits::message_builder [−][src]
Building a new message.
DNS messages consist of five sections. The first, the header section contain, among other things, the number of entries in the following four section which then contain these entries without any further delimitation. In order to safely build a correct message, it thus needs to be assembled step by step, entry by entry. This module provides four types, each responsible for assembling one of the entry sections.
You start out with a MessageBuilder
which you can either create from
an existing Composer
or, as a shortcut, either completely new()
or from an existing bytes vector via from_vec()
. Like all of these
type, the MessageBuilder
allows access to the header section. In
addition, it is used for building the question section of the message.
This section contains Question
s to be asked of a name server,
normally exactly one. You can add questions using the
push()
method.
Once you are happy with the question section, you can proceed to the
next section, the answer section, by calling the
answer()
method. In a
response, this section contains those resource records that answer the
question. The section is represented by the AnswerBuilder
type.
It, too, has a push()
method,
but for Record
s.
A call to authority()
moves on to the authority section. It contains resource records that
point to the name servers that serve authoritative for the question.
Like with the answer section,
push()
adds records to this
section.
The final section is the additional section. Here a name server can add
information it believes will help the client to get to the answer it
really wants. Which these are depends on the question and is generally
given in RFCs that define the record types. Unsurprisingly, you will
arrive at a AdditionalBuilder
by calling the
additional()
method
once you are done with the authority section.
Once you are done with the additional section, too, you call
finish()
to retrieve
the bytes vector with the assembled message data.
Since at least some of the sections are empty in many messages, for
instance, a simple request only contains a single question, there are
shortcuts in place to skip over sections. Each type can go to any later
section through the methods named above. Each type also has a finish()
method to arrive at the final data quickly.
Example
To summarize all of this, here is an example that builds a response to an A query for example.com that contains two A records and nothing else.
use std::str::FromStr; use domain::bits::{ComposeMode, DNameBuf, MessageBuilder, Question}; use domain::iana::Rtype; use domain::rdata::A; let name = DNameBuf::from_str("example.com.").unwrap(); let mut msg = MessageBuilder::new(ComposeMode::Limited(512), true).unwrap(); msg.header_mut().set_rd(true); msg.push((&name, Rtype::A)); let mut msg = msg.answer(); msg.push((&name, 86400, A::from_octets(192, 0, 2, 1))).unwrap(); msg.push((&name, 86400, A::from_octets(192, 0, 2, 2))).unwrap(); let _ = msg.finish(); // get the Vec<u8>
Structs
AdditionalBuilder |
A type for building the additional section of a DNS message. |
AnswerBuilder |
A type for building the answer section of a DNS message. |
AuthorityBuilder |
A type for building the authority section of a DNS message. |
MessageBuilder |
A type for building the question section of a DNS message. |
OptBuilder |
A type for building an OPT record on the fly. |