liveBook · Manning

Domain name system

As explained in Rust in Action: Systems programming concepts and techniques

The Domain Name System is a distributed naming system that maps domain names to network resource records such as IP addresses.

The Domain Name System (DNS) converts human-readable domain names into IP addresses that can be used for internet communication. TCP does not interpret domain names, so applications ask DNS servers to perform domain name resolution. section 8.4.2

A DNS request can travel over UDP or TCP, including TCP protected with TLS. A server may recursively ask other servers, while clients can choose a public or custom DNS server. section 8.4.2

The resolve utility

Running `resolve www.rustinaction.com` produces an IPv4 address such as `35.185.44.232`. The utility uses trust-dns to handle DNS protocol details while exposing the request structure.

Table 8.1 Terms that are used in RFC 1035, the trust_dns crate, and listing 8.9, and how these interlink (view table figure)

Term

Definition

Representation in code

Domain name

A domain name is almost what you probably think of when you use the term domain name in your everyday language.

The technical definition includes some special cases such as the root domain, which is encoded as a single dot, and domain names that need to be case-insensitive.

Defined in trust_dns::domain::Name
pub struct Name {
    is_fqdn: bool,      ①
    labels: Vec<Label>,
}

① fqdn stands for fully-qualified domain name.

Message

A message is a container for both requests to DNS servers (called queries) and responses back to clients (called answers).

Messages must contain a header, but other fields are not required. A Message struct represents this and includes several Vec<T> fields. These do not need to be wrapped in Option to represent missing values as their length can be 0.

Defined in trust_dns::domain::Name
struct Message {
  header: Header,
  queries: Vec<Query>,
  answers: Vec<Record>,
  name_servers: Vec<Record>,
  additionals: Vec<Record>,
  sig0: Vec<Record>,       ①
  edns: Option<Edns>,      ②
 
}

① sig0, a cryptographically signed record, verifies the message’s integrity. It is defined in RFC 2535.

② edns indicates whether the message includes extended DNS.

Message type

A message type identifies the message as a query or as an answer. Queries can also be updates, which are functionality that our code ignores.

Defined in trust_dns::op::MessageType
pub enum MessageType {
    Query,
    Response,
}

Message ID

A number that is used for senders to link queries and answers.

u16

Resource record type

The resource record type refers to the DNS codes that you’ve probably encountered if you’ve ever configured a domain name.

Of note is how trust_dns handles invalid codes. The RecordType enum contains an Unknown(u16) variant that can be used for codes that it doesn’t understand.

Defined in trust_dns::rr::record_type::RecordType
pub enum RecordType {
    A,
    AAAA,
    ANAME,
    ANY,
    // ...
    Unknown(u16),
    ZERO,
}

Query

A Query struct holds the domain name and the record type that we’re seeking the DNS details for.

These traits also describe the DNS class and allow queries to distinguish between messages sent over the internet from other transport protocols.

Defined in trust_dns::op::Query
pub struct Query {
    name: Name,
    query_type: RecordType,
    query_class: DNSClass,
}

Opcode

An OpCode enum is, in some sense, a subtype of MessageType. This is an extensibility mechanism that allows future functionality. For example, RFC 1035 defines the Query and Status opcodes but others were defined later. The Notify and Update opcodes are defined by RFC 1996 and RFC 2136, respectively.

Defined in trust_dns::op::OpCode
pub enum OpCode {
    Query,
    Status,
    Notify,
    Update,
}

Use the terminology table to connect domain names, messages, queries, answers, and their Rust representations. section 8.4.2

How Rust in Action: Systems programming concepts and techniques covers it

How deep it goes
Explains recursive resolution and constructs an IPv4 query, but delegates most protocol details to trust-dns.
Examples
Demonstrates the resolve command, public DNS services, and a Rust message requesting an IPv4 A record.
What it assumes
Assumes basic hostnames, IP addresses, and internet messaging while introducing DNS terminology through a working resolver.
What you can do after
Build it from scratch: create a command-line Rust utility that resolves hostnames through a selected DNS server.
How it connects
Connects domain names with IP addresses, TCP, UDP, TLS, DNS queries, and recursive resolution.

Also explained in

Compare how 7 books explain domain name system →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Rust in Action: Systems programming concepts and techniques. The section links point to the parts of the book it draws on.