RFC 883

Domain names: Implementation specification

๐Ÿ“… published November 1983, from ietf

DOMAIN NAMES - IMPLEMENTATION and SPECIFICATION ๐ŸŽ€

Okay bestie, this is RFC 883, part 1 of 15 ๐ŸŒธ

So the title block says it's from the Network Working Group, it's RFC 883, written by P. Mockapetris at ISI, and dated November 1983 ๐Ÿ“…. The header doesn't list a category or status, and it doesn't say what it obsoletes or updates. Keep that in mind when you read it ๐Ÿ‘€

Here's the abstract box, copied exactly because it's art ๐Ÿ–ผ๏ธ

+-----------------------------------------------------+
|                                                     |
| This memo discusses the implementation of domain    |
| name servers and resolvers, specifies the format of |
| transactions, and discusses the use of domain names |
| in the context of existing mail systems and other   |
| network software.                                   |
|                                                     |
| This memo assumes that the reader is familiar with  |
| RFC 882, "Domain Names - Concepts and Facilities"   |
| which discusses the basic principles of domain      |
| names and their use.                                |
|                                                     |
| The algorithms and internal data structures used in |
| this memo are offered as suggestions rather than    |
| requirements; implementers are free to design their |
| own structures so long as the same external         |
| behavior is achieved.                               |
|                                                     |
+-----------------------------------------------------+

The gist ๐Ÿ’–: this memo is about how name servers and resolvers get built, the format of the transactions between them, and how domain names fit into mail systems and other network software. You need to already know RFC 882, "Domain Names - Concepts and Facilities", which covers the basics. Also, the algorithms and internal data structures are suggestions, not requirements ๐Ÿ’… You can design your own as long as the external behaviour matches.

And now the warning box, also copied exactly ๐Ÿšจ

+-----------------------------------------------+
|                                               |
|             *****  WARNING  *****             |
|                                               |
| This RFC contains format specifications which |
| are preliminary and are included for purposes |
| of explanation only.  Do not attempt to use   |
| this information for actual implementations.  |
|                                               |
+-----------------------------------------------+
Bestie, the format specs here are preliminary and only for explanation. Please do not try to use them in real implementations ๐Ÿ˜ญ

TABLE OF CONTENTS ๐Ÿ’œ

   INTRODUCTION........................................................3
      Overview.........................................................3
      Implementation components........................................2
      Conventions......................................................6
      Design philosophy................................................8
   NAME SERVER TRANSACTIONS...........................................11
      Introduction....................................................11
      Query and response transport....................................11
      Overall message format..........................................13
      The contents of standard queries and responses..................15
      Standard query and response example.............................15
      The contents of inverse queries and responses...................17
      Inverse query and response example..............................18
      Completion queries and responses................................19
      Completion query and response example...........................22
      Recursive Name Service..........................................24
      Header section format...........................................26
      Question section format.........................................29
      Resource record format..........................................30
      Domain name representation and compression......................31
      Organization of the Shared database.............................33
      Query processing................................................36
      Inverse query processing........................................37
      Completion query processing.....................................38
   NAME SERVER MAINTENANCE............................................39
      Introduction....................................................39
      Conceptual model of maintenance operations......................39
      Name server data structures and top level logic.................41
      Name server file loading........................................43
      Name server file loading example................................45
      Name server remote zone transfer................................47
   RESOLVER ALGORITHMS................................................50
      Operations......................................................50
   DOMAIN SUPPORT FOR MAIL............................................52
      Introduction....................................................52
      Agent binding...................................................53
      Mailbox binding.................................................54
   Appendix 1 - Domain Name Syntax Specification......................56
   Appendix 2 - Field formats and encodings...........................57
      TYPE values.....................................................57
      QTYPE values....................................................57
      CLASS values....................................................58
      QCLASS values...................................................58
      Standard resource record formats................................59
   Appendix 3 - Internet specific field formats and operations........67
   REFERENCES and BIBLIOGRAPHY........................................72
   INDEX..............................................................73

INTRODUCTION โœจ

Overview ๐ŸŒˆ

Okay so the whole goal of domain names is giving resources a naming system that actually works across different hosts, networks, protocol families, internets, and administrative organizations. The name is the main character everywhere it shows up ๐Ÿ’…

From the user's side ๐Ÿ‘€, domain names are arguments you hand to a local agent called a resolver, and the resolver goes off and fetches the information tied to that name. So you might ask for the host address or the mail info for a particular name. To say what kind of info you want, you pass a query type along with the name. To the user, the entire domain tree feels like one single information space โœจ

From the resolver's point of view, the database that makes up the domain space is spread out across lots of name servers. Different parts of the space live in different servers, although a given data item is usually stored redundantly in two or more of them ๐Ÿซถ The resolver starts out knowing about at least one name server. When it's handling a user query, it asks a server it knows for the info, and it gets back either the answer or a referral to another server. Through those referrals, resolvers learn about other name servers and what they hold. Resolvers are also the ones dealing with the spread-out nature of the space, and with a server failing, by checking the redundant copies in other servers ๐Ÿ’ช

Name servers manage two kinds of data ๐Ÿ“š The first kind is authoritative data, held in sets called zones. Each zone is the complete database for one particular subtree of the domain space. A name server checks from time to time that its zones are up to date, and if they aren't, it grabs a fresh copy of the updated zones from master files stored locally or from another name server. The second kind is cached data, which a local resolver picked up along the way. Cached data might be incomplete, but it speeds things up when non-local data gets accessed over and over. Cached data is eventually thrown out by a timeout mechanism โณ

Honestly, this setup is so clean ๐Ÿ˜ญ It isolates the problems of user interface, failure recovery, and distribution in the resolvers, and it isolates the database update and refresh problems in the name servers ๐Ÿงš

Implementation components ๐Ÿ“

A host can join the domain name system in a bunch of different ways, depending on whether it runs programs that retrieve info from the domain system, name servers that answer queries from other hosts, or some mix of both. The simplest, and maybe most typical, setup looks like this:

             Local Host                        |  Foreign
                                               |
+---------+               +----------+         |  +--------+
|         | user queries  |          |queries  |  |        |
|  User   |-------------->|          |---------|->|Foreign |
| Program |               | Resolver |         |  |  Name  |
|         |<--------------|          |<--------|--| Server |
|         | user responses|          |responses|  |        |
+---------+               +----------+         |  +--------+
                            |     A            |
            cache additions |     | references |
                            V     |            |
                          +----------+         |
                          | database |         |
                          +----------+         |

User programs talk to the domain name space through resolvers. The format of user queries and user responses depends on the host and its operating system. User queries will typically be operating system calls, and the resolver and its database will usually be part of the host operating system. Less capable hosts might choose to build the resolver as a subroutine that gets linked into every program that needs it ๐ŸŒธ

Resolvers answer user queries using info they get from queries to foreign name servers, and they might also cache or reference domain info in the local database ๐Ÿ’–

Heads up ๐Ÿ‘€: a resolver may have to make several queries to several different foreign name servers to answer one user query. That means resolving a user query can involve several network accesses and an arbitrary amount of time โฐ The queries to foreign name servers and their responses follow a standard format described in this memo, and they may be datagrams ๐Ÿ“ฆ

Depending on what it can do, a name server could be a standalone program on a dedicated machine, or a process (or processes) on a big timeshared host. A simple setup might look like this:

             Local Host                        |  Foreign
                                               |
  +---------+                                  |
 /         /|                                  |
+---------+ |             +----------+         |  +--------+
|         | |             |          |responses|  |        |
|         | |             |   Name   |---------|->|Foreign |
|  Master |-------------->|  Server  |         |  |Resolver|
|  files  | |             |          |<--------|--|        |
|         |/              |          | queries |  +--------+
+---------+               +----------+         |

Here the name server gets info about one or more zones by reading master files from its local file system, and it answers queries about those zones that arrive from foreign resolvers ๐Ÿฆ‹

A more sophisticated name server might acquire zones from foreign name servers as well as from local master files. This configuration is shown below:

                   Local Host                        |  Foreign
                                                     |
        +---------+                                  |
       /         /|                                  |
      +---------+ |             +----------+         |  +--------+
      |         | |             |          |responses|  |        |
      |         | |             |   Name   |---------|->|Foreign |
      |  Master |-------------->|  Server  |         |  |Resolver|
      |  files  | |             |          |<--------|--|        |
      |         |/              |          | queries |  +--------+
      +---------+               +----------+         |
                                  A     |maintenance |  +--------+
                                  |     \------------|->|        |
                                  |      queries     |  |Foreign |
                                  |                  |  |  Name  |
                                  \------------------|--| Server |
                               maintenance responses |  +--------+

Okay so in this setup, the name server pops over to a foreign name server every so often, opens a virtual circuit, and either grabs a fresh copy of a zone or double checks that the copy it already has hasn't changed. ๐Ÿฆ‹ The maintenance messages look just like queries and responses, but the message sequences are a little different, so keep your eyes open ๐Ÿ‘€

Here's the info flow for a host that does everything in the domain name system:

                   Local Host                        |  Foreign
                                                     |
      +---------+               +----------+         |  +--------+
      |         | user queries  |          |queries  |  |        |
      |  User   |-------------->|          |---------|->|Foreign |
      | Program |               | Resolver |         |  |  Name  |
      |         |<--------------|          |<--------|--| Server |
      |         | user responses|          |responses|  |        |
      +---------+               +----------+         |  +--------+
                                  |     A            |
                  cache additions |     | references |
                                  V     |            |
                                +----------+         |
                                |  Shared  |         |
                                | database |         |
                                +----------+         |
                                  A     |            |
        +---------+     refreshes |     | references |
       /         /|               |     V            |
      +---------+ |             +----------+         |  +--------+
      |         | |             |          |responses|  |        |
      |         | |             |   Name   |---------|->|Foreign |
      |  Master |-------------->|  Server  |         |  |Resolver|
      |  files  | |             |          |<--------|--|        |
      |         |/              |          | queries |  +--------+
      +---------+               +----------+         |
                                  A     |maintenance |  +--------+
                                  |     \------------|->|        |
                                  |      queries     |  |Foreign |
                                  |                  |  |  Name  |
                                  \------------------|--| Server |
                               maintenance responses |  +--------+

The shared database is where the domain space data lives for both the local name server and the resolver ๐Ÿ’œ It's usually a mix of authoritative data that the name server keeps fresh with its periodic refreshes, plus cached data from earlier resolver requests. The structure of the domain data, and the need for name servers and resolvers to stay in sync, hint at the general vibe of this database. The actual format, though? That's up to whoever is implementing it. This memo suggests a multiple tree format, just saying ๐ŸŒณ

This memo splits the implementation discussion into these sections:

  • NAME SERVER TRANSACTIONS: the formats for name server queries and the responses that go with them ๐Ÿ“ฌ
  • NAME SERVER MAINTENANCE: strategies, algorithms, and formats for keeping the data in name servers up to date. These services periodically refresh local copies of zones that come from other hosts ๐Ÿ”„
  • RESOLVER ALGORITHMS: the internal structure of resolvers. This part also covers sharing the database between a name server and a resolver on the same host ๐Ÿงš
  • DOMAIN SUPPORT FOR MAIL: how the domain system gets used to support mail transfer ๐Ÿ’Œ

Conventions

Okay, bestie, the domain system has a few conventions for the low-level but super fundamental stuff ๐Ÿค“ You're totally free to break these conventions WITHIN YOUR OWN SYSTEM. But when other hosts are looking at what you do, you have to follow them in ALL behavior. No exceptions, no drama ๐Ÿ’…

Data Transmission Order ๐ŸŽ€

The order that the header and data get sent in is nailed down all the way to the octet level. Whenever a diagram shows a group of octets, they go out in the normal order you'd read them in English. For example, in the diagram below, the octets get transmitted in the order they're numbered.

                    0                   1
                    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
                   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                   |       1       |       2       |
                   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                   |       3       |       4       |
                   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                   |       5       |       6       |
                   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Transmission Order of Bytes

Whenever an octet holds a number, the leftmost bit in the diagram is the high order bit, also called the most significant bit. So the bit labeled 0 is the most significant one. For example, the diagram below shows the value 170 (decimal) ๐Ÿ”ข

                            0 1 2 3 4 5 6 7
                           +-+-+-+-+-+-+-+-+
                           |1 0 1 0 1 0 1 0|
                           +-+-+-+-+-+-+-+-+

Significance of Bits

Same deal for a multi-octet field that holds a number. The leftmost bit of the whole field is the most significant bit, and the most significant octet is the one that gets sent first โœจ

Character Case ๐Ÿ”ค

All comparisons between character strings (labels, domain names, and so on) are done in a case-insensitive way. So x.y and X.Y are the same name as far as the system is concerned ๐Ÿ™ˆ

When data enters the domain system, its original case should be preserved whenever that's possible. Sometimes it just can't be done. For example, if the two domain names x.y and X.Y both get entered into the domain database, they're treated as the same name and can end up with a single representation. The basic rule is that case can only be thrown away when the data is being used to define structure in a database, and two names count as identical when you compare them case-insensitively. Basically, case is only dropped when it's structurally necessary ๐Ÿ’€

Losing case-sensitive data has to be kept to a minimum. So even though data for x.y and X.Y can both be stored under x.y, data for a.x and B.X can be stored as a.x and B.x. It can't be stored as A.x, A.X, b.x, or b.X. In general, this keeps the first component of a domain name from losing its case information ๐ŸŒธ

Systems administrators who enter data into the domain database should take care to represent that data in a case-consistent way if their system is case-sensitive. The data distribution system within the domain system will make sure consistent representations get preserved ๐Ÿซถ


Design philosophy

The design in this memo is trying to give a base that works for several existing networks. An equally important goal is to provide these services inside a framework that can adjust as services evolve in early clients, and that can also fit new networks ๐ŸŒˆ

Since nobody can predict how all these developments will go, the domain system tries to allow for evolution by being an extensible framework. This section covers the areas where we expect to see evolution right away ๐Ÿฆ‹

DEFINING THE DATABASE ๐Ÿ“š

This memo defines methods for partitioning the database, along with the data for host names, host addresses, gateway information, and mail support. Experience with this system will guide future additions โœจ

The present system allows for lots of new RR types, classes, and so on. But the authors feel it's more important to get the basic services up and running than to cover an exhaustive set of information. So the data types are limited to the ones considered essential. Designers are cautioned to avoid implementations that are based on the number of existing types and classes. Extensibility in this area is very important ๐Ÿ”‘

Partitioning the database is only part of it. Policies for administering the orderly connection of separate domains, and guidelines for constructing the data that makes up a particular domain, will be just as important to the system's success. Unfortunately, the authors feel that experience with prototype systems is needed before this question can be properly addressed. So even though this memo has minimal discussion of these issues, it's a critical area for development ๐Ÿง

TYING TOGETHER INTERNETS ๐ŸŒ

It's really hard to characterize the types of networks, protocols, and applications that will be clients of the domain system. But it's very obvious that some of these applications will cross the boundaries of networks and protocols. At the very least, mail is one of those services ๐Ÿ’Œ

Trying to unify two such systems has to deal with two major problems:

  1. Differing formats for environment sensitive data. For example, network addresses vary in format, and it's unreasonable to expect consistent conventions to be enforced ๐Ÿ™ƒ
  2. Connectivity may require intermediaries. For example, it's a frequent occurrence that mail is sent between hosts that share no common protocol ๐Ÿ“ฎ

The domain system knows these are very difficult problems, and tries to deal with both of them through its CLASS mechanism:

  1. The CLASS field in RRs lets data get tagged so that all programs in the domain system can identify the format in use ๐Ÿท๏ธ
  2. The CLASS field lets the requestor identify the format of data that the requestor can understand ๐Ÿง 
  3. The CLASS field guides the search for the requested data ๐Ÿ”

The last point is the big one, bestie ๐Ÿซถ When a query crosses protocol boundaries, it MUST be guided through agents that can do whatever translation is needed ๐Ÿ”ฅ Say a mailer wants to find where a mailbox lives in a part of the domain system that doesn't speak a compatible protocol. The query MUST be guided to a name server that can cross the boundary itself, or that forms one link in a chain able to bridge the differences โœจ

If query and response transport were the only problem, this could be handled inside the name servers themselves. But the applications that use domain service have similar problems ๐Ÿ’€ For example, mail may need to be directed through mail gateways, and the characteristics of one environment may not permit frequent connectivity between name servers in all environments.

So connectivity is going to come from a mix of measures ๐ŸŒˆ

  • Translation name servers that act as relays between different protocols.
  • Translation application servers that translate application level transactions.
  • Default database entries that route traffic through application level forwarders in ways that depend on the class of the requestor.

Honestly, this approach seems best given where we are right now, but we know that resource data that transcends class may be appropriate in future designs or applications ๐Ÿฆ‹ By not tying class directly to protocol, network, etc., we can add such services later by defining a new "universal" class, while the current use of class gives us service today ๐Ÿ’–

This problem needs more thought and experience before solutions show up. CLASS, recursive servers and the other mechanisms are tools for gathering experience, not final answers ๐Ÿงš


NAME SERVER TRANSACTIONS ๐ŸŽ€

Introduction

The main job of a name server is to receive queries from resolvers and send back responses ๐Ÿ’… The overall model is that a program (usually a resolver) asks the name server questions (queries), and gets responses that either answer the question or refer the questioner to another name server. Other functions related to name server database maintenance use similar procedures and formats, and we'll get to those in a later section of this memo.

There are three kinds of queries defined right now:

  1. Standard queries that ask for a specified resource attached to a given domain name.
  2. Inverse queries that specify a resource and ask for a domain name that has that resource.
  3. Completion queries that specify a partial domain name and a target domain, and ask that the partial domain name be completed with a domain name close to the target domain.

In this memo, an unqualified reference to queries means either all queries or standard queries, whenever the context makes that clear โœจ

Query and response transport

Name servers and resolvers use one single message format for all communications ๐Ÿ“ The format is a variable-length octet string that includes binary values.

Messages in the domain system are designed so they can be carried over either datagrams or virtual circuits. To make datagrams work, all responses carry the query as part of the response ๐Ÿฆ‹

Datagrams are allowed in any context, but some activities are kinda ill suited to them ๐Ÿ™ˆ Maintenance transactions and recursive queries typically need the error control of virtual circuits, so datagram use SHOULD be restricted to simple queries.

The domain system assumes that a datagram service provides:

  1. A non-reliable (i.e. best effort) method of transporting a message of up to 512 octets.

Hence datagram messages are limited to 512 octets. If a datagram message would exceed 512 octets, it is truncated and a truncation flag is set in its header.

  1. A message size that gives the number of octets in the datagram.

The main implications for programs accessing name servers via datagrams are:

  1. Datagrams SHOULD NOT be used for maintenance transactions and recursive queries.
  2. Since datagrams may be lost, the originator of a query MUST perform error recovery (such as retransmissions) as appropriate.
  3. Since network or host delay may cause retransmission when a datagram has not been lost, the originator of a query MUST be ready to deal with duplicate responses.

The domain system assumes that a virtual circuit service provides:

  1. A reliable method of transmitting a message of up to 65535 octets.
  2. A message size that gives the number of octets in the message.

If the virtual circuit service does not provide for message boundary detection or limits transmission size to less than 65535 octets, then messages are prefaced with an unsigned 16 bit length field and broken up into separate transmissions as required. The length field is only prefaced on the first message. This technique is used for TCP virtual circuits.

  1. Multiple messages may be sent over a virtual circuit.
  2. A method for closing a virtual circuit.
  3. A method for detecting that the other party has requested that the virtual circuit be closed.

The main implications for programs accessing name servers via virtual circuits are:

  1. Either end of a virtual circuit MAY initiate a close when there is no activity in progress. The other end SHOULD comply.

The decision to initiate a close is a matter of individual site policy. Some name servers MAY leave a virtual circuit open for an indeterminate period following a query, to allow for subsequent queries. Other name servers MAY choose to initiate a close following the completion of the first query on a virtual circuit. Of course, name servers SHOULD NOT close the virtual circuit in the midst of a multiple message stream used for zone transfer.

  1. Since network delay may cause one end to erroneously believe that no activity is in progress, a program which receives a virtual circuit close while a query is in progress SHOULD close the virtual circuit and resubmit the query on a new virtual circuit.

All messages MAY use a compression scheme to reduce the space consumed by repetitive domain names ๐ŸŒธ Using the compression scheme is OPTIONAL for the sender of a message, but all receivers MUST be capable of decoding compressed domain names ๐Ÿ’œ

Overall message format

All messages sent by the domain system are divided into 5 sections (some of which are empty in certain cases), shown below ๐Ÿงš

       +---------------------+
       |        Header       |
       +---------------------+
       |       Question      | the question for the name server
       +---------------------+
       |        Answer       | answering resource records (RRs)
       +---------------------+
       |      Authority      | RRs pointing toward an authority
       +---------------------+
       |      Additional     | RRs holding pertinent information
       +---------------------+

The header section is always present โœจ It includes fields that specify which of the remaining sections are present, and also specify whether the message is a query, inverse query, completion query, or response.

The question section has fields that describe a question to a name server. These fields are a query type (QTYPE), a query class (QCLASS), and a query domain name (QNAME).

The last three sections share the same format: a possibly empty list of concatenated resource records (RRs). The answer section has RRs that answer the question. The authority section has RRs that point toward an authoritative name server. The additional records section has RRs that relate to the query but aren't strictly answers for the question ๐Ÿ’…

The next two sections of this memo show these message sections through examples. A detailed discussion of data formats comes after the examples ๐ŸŽ€

The contents of standard queries and responses

When a name server processes a standard query, it first figures out whether it is an authority for the domain name in the query ๐Ÿ”

If the name server is an authority, it returns one of these:

  1. The specified resource information.
  2. An indication that the specified name does not exist.
  3. An indication that the requested resource information does not exist.

If the name server is not an authority for the specified name, it returns whatever relevant resource information it has, along with resource records that the requesting resolver can use to locate an authoritative name server ๐Ÿฆ‹

Standard query and response example

Here's the overall structure of a query for retrieving Internet mail information for domain F.ISI.ARPA ๐Ÿ’Œ

                  +-----------------------------------------+
    Header        |          OPCODE=QUERY, ID=2304          |
                  +-----------------------------------------+
   Question       |QTYPE=MAILA, QCLASS=IN, QNAME=F.ISI.ARPA |
                  +-----------------------------------------+
    Answer        |                 <empty>                 |
                  +-----------------------------------------+
   Authority      |                 <empty>                 |
                  +-----------------------------------------+
  Additional      |                 <empty>                 |
                  +-----------------------------------------+

The header has an opcode field that says this datagram is a query, plus an ID field that's used to match replies back to the original query. (Some extra header fields are left out for clarity ๐Ÿ™ˆ) The question section says the query is for mail agent information, that only ARPA Internet information is to be considered, and that the domain name of interest is F.ISI.ARPA. The remaining sections are empty and wouldn't use any octets in a real query ๐Ÿ’–

One possible response to this query might be:

                          +-----------------------------------------+
            Header        |        OPCODE=RESPONSE, ID=2304         |
                          +-----------------------------------------+
           Question       |QTYPE=MAILA, QCLASS=IN, QNAME=F.ISI.ARPA |
                          +-----------------------------------------+
            Answer        |                 <empty>                 |
                          +-----------------------------------------+
           Authority      |          ARPA NS IN A.ISI.ARPA          |
                          |                 -------                 |
                          |          ARPA NS IN F.ISI.ARPA          |
                          +-----------------------------------------+
           Additional     |        F.ISI.ARPA A IN 10.2.0.52        |
                          |                 -------                 |
                          |        A.ISI.ARPA A IN 10.1.0.22        |
                          +-----------------------------------------+

Okay bestie, this is what a response looks like when the name server is NOT the authority for F.ISI.ARPA ๐Ÿ™ˆ It's giving "I don't own this, but here's who might know" ๐Ÿ’… The header says this datagram is a response to the query with ID 2304 ๐ŸŽ€. The question section gets copied over from the query datagram, because of course it does โœจ

The answer section is empty because this name server had nothing to answer the query with ๐Ÿ’€ (Name servers can still have cached info even when they aren't authoritative, so it's not always a total loss ๐Ÿฆ‹)

The best this name server could do was pass back info for the domain ARPA ๐ŸŒธ The authority section lists two name servers for ARPA using the Internet family: A.ISI.ARPA and F.ISI.ARPA. Lowkey iconic: F.ISI.ARPA shows up as a name server for ARPA AND as the thing we asked about. That's just a coincidence, not a plot twist ๐Ÿ˜ญ

Then the name server put the Internet addresses for those two hosts in the additional records section. Such additional data is almost always available, so you can usually count on it ๐Ÿซถ

Now, with this response in hand, the process that sent the original query might resend it to the name server on A.ISI.ARPA, but with a fresh ID of 2305 ๐Ÿฆ‹ Here's what that name server might send back:

                          +-----------------------------------------+
            Header        |        OPCODE=RESPONSE, ID=2305         |
                          +-----------------------------------------+
           Question       |QTYPE=MAILA, QCLASS=IN, QNAME=F.ISI.ARPA |
                          +-----------------------------------------+
            Answer        |       F.ISI.ARPA MD IN F.ISI.ARPA       |
                          |                 -------                 |
                          |       F.ISI.ARPA MF IN A.ISI.ARPA       |
                          +-----------------------------------------+
           Authority      |                 <empty>                 |
                          +-----------------------------------------+
          Additional      |        F.ISI.ARPA A IN 10.2.0.52        |
                          |                 -------                 |
                          |        A.ISI.ARPA A IN 10.1.0.22        |
                          +-----------------------------------------+

This one is the main character moment ๐Ÿ‘‘ The query went straight to an authoritative name server, so the response has an answer but no authority records ๐ŸŒˆ The answer says mail for F.ISI.ARPA can either be delivered to F.ISI.ARPA or forwarded to A.ISI.ARPA ๐Ÿ“ฌ And the additional records section gives the Internet addresses for both of those hosts so you can actually reach them โœจ

The contents of inverse queries and responses

Okay, so inverse queries are basically the reverse of standard queries ๐Ÿ”„ A standard query maps a domain name to a resource, while an inverse query maps a resource to a domain name. For example, a standard query might bind a domain name to a host address, and the matching inverse query binds that host address back to a domain name ๐Ÿงš

Inverse query mappings are not guaranteed to be unique or complete ๐Ÿ’€ The reason is that the domain system has no internal mechanism for working out authority from resource records the way it can work out authority from a domain name. So in general, resolvers will be configured to send inverse queries to a name server that is known to have the info they want ๐ŸŽ€

Name servers are not REQUIRED to support any form of inverse query ๐Ÿ™ˆ It's expected that most name servers will support address to domain name conversions, but no other inverse mappings. If a name server gets an inverse query it doesn't support, it returns an error response with the "Not Implemented" error set in the header. Inverse query support is OPTIONAL, but all name servers MUST be at least able to return that error response. Non-negotiable, bestie ๐Ÿ’…

When a name server processes an inverse query, it either returns:

  1. zero, one, or multiple domain names for the specified resource
  2. an error code indicating that the name server doesn't support inverse mapping of the specified resource type.

Inverse query and response example

Here's the overall structure of an inverse query for retrieving the domain name that corresponds to Internet address 10.2.0.52 ๐Ÿฆ‹

                          +-----------------------------------------+
            Header        |          OPCODE=IQUERY, ID=997          |
                          +-----------------------------------------+
           Question       |                 <empty>                 |
                          +-----------------------------------------+
            Answer        |        <anyname> A IN 10.2.0.52         |
                          +-----------------------------------------+
           Authority      |                 <empty>                 |
                          +-----------------------------------------+
          Additional      |                 <empty>                 |
                          +-----------------------------------------+

This query asks for a question whose answer is the Internet style address 10.2.0.52 ๐ŸŒธ Since the owner name is unknown, any domain name can be used as a placeholder, and it gets ignored. The response to this query might look like this:

                          +-----------------------------------------+
            Header        |         OPCODE=RESPONSE, ID=997         |
                          +-----------------------------------------+
           Question       |   QTYPE=A, QCLASS=IN, QNAME=F.ISI.ARPA  |
                          +-----------------------------------------+
            Answer        |       F.ISI.ARPA A IN 10.2.0.52         |
                          +-----------------------------------------+
           Authority      |                 <empty>                 |
                          +-----------------------------------------+
          Additional      |                 <empty>                 |
                          +-----------------------------------------+

Note that the QTYPE in a response to an inverse query is the same as the TYPE field in the answer section of the inverse query ๐Ÿง  And when the inverse isn't unique, responses to inverse queries may contain multiple questions ๐ŸŒˆ

Completion queries and responses

Completion queries ask a name server to complete a partial domain name and return a set of RRs whose domain names meet a specified set of "closeness" criteria for that partial input โœจ This is a super handy local shorthand for domain names, kind of like command completion in TOPS-20 ๐Ÿ“

Implementation of completion query processing is OPTIONAL in a name server ๐Ÿ’… However, a name server MUST return a "Not Implemented" (NI) error response if it does not support completion. No ghosting, just an honest error ๐Ÿซถ

The arguments in a completion query specify:

  1. A type in QTYPE that specifies the type of the desired name. The type restricts which RRs will match the partial input, so completion queries can be used for mailbox names, host names, or any other type of RR in the domain system without worrying about matching the wrong type of resource ๐ŸŽ€
  2. A class in QCLASS, which specifies the desired class of the RR. ๐Ÿ’œ
  3. A partial domain name that gives the input to be completed. All returned RRs will begin with the partial string. The search first looks for names that qualify under the assumption that the partial string ends with a full label ("whole label match"). If that search fails, the search continues under the assumption that the last label in the partial string may be an incomplete label ("partial label match"). For example, if the partial string "Smith" was used in a mailbox completion, it would match Smith@ISI.ARPA before Smithsonian@ISI.ARPA ๐Ÿ‘‘

The partial name is supplied by the user through the user program that is using domain services. For example, if the user program is a mail handler, the string might be "Mockap", which the user intends as a shorthand for the mailbox Mockapetris@ISI.ARPA. If the user program is TELNET, the user might specify "F" for F.ISI.ARPA ๐Ÿงš

To keep parsing of messages consistent, the partial name is supplied in domain name format (a sequence of labels terminated with a zero length octet). However, the trailing root label is ignored during matching ๐Ÿ™ˆ

  1. A target domain name that specifies the domain to be examined for matches. This name is specified in the additional section using a NULL RR. All returned names will end with the target name ๐ŸŒธ

The user program that constructs the query uses the target name to restrict the search. For example, user programs running at ISI might restrict completion to names that end in ISI.ARPA, and user programs running at MIT might restrict completion to the domain MIT.ARPA ๐Ÿฆ‹

The target domain name is also used by the resolver to determine which name server should process the query. In general, queries SHOULD be directed to a name server that is authoritative for the target domain name. User programs that want completion for more than one target can issue multiple completion queries, each directed at a different target. Choosing the target name and the number of searches depends on the goals of the user program โœจ

  1. An opcode for the query. There are two types of completion queries: "Completion Query - Multiple", or CQUERYM, which asks for all RRs that could complete the specified input, and "Completion Query - Unique", or CQUERYU, which asks for the "best" completion ๐Ÿ”ฅ

CQUERYM is used by user programs that want to know whether ambiguities exist, or that want to make their own decision about the best choice among the available candidates ๐ŸŒˆ

CQUERYU is used by user programs that either don't want to deal with multiple choices, or that are willing to use the closeness criteria CQUERYU applies to select the best match ๐Ÿ’–

When a name server gets either completion query, it first hunts for RRs that begin (on the left) with the same labels as QNAME, root deleted ๐ŸŒธ, and that match the QTYPE and QCLASS. That's called "whole label" matching ๐Ÿฆ‹. If it finds one or more hits, it either returns all of them (CQUERYM) or uses the closeness criteria below to trim the list down to one (CQUERYU) ๐Ÿ’….

If the whole label match comes back empty, the name server assumes the rightmost label of QNAME (after root deletion) isn't a complete label yet. So it looks for candidates that would match if characters were added on the right of that rightmost label ๐Ÿ‘€. Again, if there are hits, it either returns all of them (CQUERYM) or uses the closeness criteria to narrow things down to one (CQUERYU) โœจ.

When a CQUERYU query finds multiple hits, the name server runs through these rules, in order, to throw out the extras ๐Ÿซถ:

  1. Discard candidates that have more labels than others. Since every candidate starts with the partial name and ends with the target name, this basically means picking the entries that need the fewest added labels. For example, a host search with a target of "ISI.ARPA" and a partial name of "A" will select A.ISI.ARPA over A.IBM-PCS.ISI.ARPA ๐ŸŽ€.
  2. If partial label matching was used, discard the labels that needed more characters to be added. For example, a mailbox search for partial "X" and target "ISI.ARPA" would prefer XX@ISI.ARPA over XYZZY@ISI.ARPA ๐Ÿ’œ.

If there are still multiple hits after that, return all of them ๐ŸŒˆ.

Okay, real talk, bestie: completion query mappings are not guaranteed to be unique or complete ๐Ÿ˜ญ. The domain system has no internal mechanism for figuring out authority from a partial domain name the way it can from a complete one. So in general, resolvers get configured to send completion queries to a name server that's known to have the info they want ๐Ÿงš.

When a name server processes a completion query, it either returns:

  1. An answer giving zero, one, or more possible completions.
  2. an error response with Not Implemented (NI) set.

Completion query and response example โœจ

Picture this: the completion service is being used by a TELNET program so a user can type a partial domain name for the host they want. So a user might ask to be connected to "B" ๐Ÿ“. Assuming the query came from an ISI machine, it might look like:

                    +-----------------------------------------+
      Header        |         OPCODE=CQUERYU, ID=409          |
                    +-----------------------------------------+
     Question       |       QTYPE=A, QCLASS=IN, QNAME=B       |
                    +-----------------------------------------+
      Answer        |                 <empty>                 |
                    +-----------------------------------------+
     Authority      |                 <empty>                 |
                    +-----------------------------------------+
    Additional      |             ISI.ARPA NULL IN            |
                    +-----------------------------------------+

So the partial name in the query is "B", the mappings we care about are ARPA Internet address records, and the target domain is ISI.ARPA ๐Ÿฆ‹. Quick side note: NULL is a special type of NULL resource record that's used as a placeholder and has no significance ๐Ÿ™ˆ. NULL RRs follow the standard format but don't have any other function.

The response to this completion query might be:

                    +-----------------------------------------+
      Header        |         OPCODE=RESPONSE, ID=409         |
                    +-----------------------------------------+
     Question       |       QTYPE=A, QCLASS=IN, QNAME=B       |
                    +-----------------------------------------+
      Answer        |        B.ISI.ARPA A IN 10.3.0.52        |
                    +-----------------------------------------+
     Authority      |                 <empty>                 |
                    +-----------------------------------------+
    Additional      |             ISI.ARPA NULL IN            |
                    +-----------------------------------------+

And that's it, the response has completed B to mean B.ISI.ARPA ๐ŸŽ‰.

Another query might be:

                    +-----------------------------------------+
      Header        |         OPCODE=CQUERYM, ID=410          |
                    +-----------------------------------------+
     Question       |       QTYPE=A, QCLASS=IN, QNAME=B       |
                    +-----------------------------------------+
      Answer        |                 <empty>                 |
                    +-----------------------------------------+
     Authority      |                 <empty>                 |
                    +-----------------------------------------+
    Additional      |               ARPA NULL IN              |
                    +-----------------------------------------+

This one is similar to the previous query, but it specifies a target of ARPA instead of ISI.ARPA ๐ŸŒธ. It also allows multiple matches. In this case the same name server might return:

                    +-----------------------------------------+
      Header        |         OPCODE=RESPONSE, ID=410         |
                    +-----------------------------------------+
     Question       |       QTYPE=A, QCLASS=IN, QNAME=B       |
                    +-----------------------------------------+
      Answer        |        B.ISI.ARPA A IN 10.3.0.52        |
                    |                    -                    |
                    |        B.BBN.ARPA A IN 10.0.0.49        |
                    |                    -                    |
                    |        B.BBNCC.ARPA A IN 8.1.0.2        |
                    +-----------------------------------------+
     Authority      |                 <empty>                 |
                    +-----------------------------------------+
    Additional      |               ARPA NULL IN              |
                    +-----------------------------------------+

That response has three answers: B.ISI.ARPA, B.BBN.ARPA, and B.BBNCC.ARPA ๐ŸŒˆ.

Recursive Name Service ๐Ÿ”ฅ

Okay, so recursive service is an optional feature of name servers ๐Ÿ’œ.

When a name server gets a query about part of the name space that isn't in one of its zones, the standard response is a message that refers the requestor to another name server ๐Ÿงš. The requestor keeps iterating on these referrals until it's pointed at a name server that has the info it needs ๐Ÿฆ‹.

Name servers may also implement recursive service. In this type of service, a name server either answers right away from its local zone info, or it goes off and pursues the query for the requestor and sends the eventual result back to the original requestor ๐Ÿ’….

A name server that supports recursive service sets the Recursion Available (RA) bit in all responses it generates. A requestor asks for recursive service by setting the Recursion Desired (RD) bit in queries. In some situations where recursive service is the only path to the desired information (see below), the name server may go recursive even if RD is zero ๐Ÿ‘€.

If a query requests recursion (RD set), but the name server doesn't support recursion, and the query needs recursive service for an answer, the name server returns a "Not Implemented" (NI) error code ๐Ÿ˜ญ. If the query can be answered without recursion because the name server is authoritative for it, the name server ignores the RD bit โœจ.

Because it's hard to pick good timeouts and handle errors, recursive service is best suited to virtual circuits, although it's allowed for datagrams ๐ŸŽ€.

Recursive service is valuable in several special situations:

  • In a system of small personal computers clustered around one or more large hosts that support name servers, the recursive approach minimizes the amount of code in the resolvers on the personal computers. Such a design moves complexity out of the resolver and into the name server, and may be appropriate for such systems ๐Ÿ’–.
  • Name servers on the boundaries of different networks may wish to offer recursive service to create connectivity between different networks. Such name servers may wish to provide recursive service regardless of the setting of RD ๐ŸŒ.
  • Name servers that translate between domain name service and some other name service may wish to adopt the recursive style. Implicit recursion may be valuable here as well ๐Ÿงฉ.

These concepts are still under development ๐Ÿ› ๏ธ.

Header section format ๐Ÿ’…

Here's the big warning, bestie, and yes it's serious ๐Ÿšจ:

     +-----------------------------------------------+
     |                                               |
     |             *****  WARNING  *****            |
     |                                               |
     |  The following format is preliminary and is   |
     | included for purposes of explanation only. In |
     | particular, the size and position of the      |
     | OPCODE, RCODE fields and the number and       |
     | meaning of the single bit fields are subject  |
     | to change.                                    |
     |                                               |
     +-----------------------------------------------+

The header contains the following fields ๐ŸŽ€:

                                     1  1  1  1  1  1
       0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                      ID                       |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |QR|   Opcode  |AA|TC|RD|RA|        |   RCODE   |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    QDCOUNT                    |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    ANCOUNT                    |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    NSCOUNT                    |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    ARCOUNT                    |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

So, where:

  • ID is a 16 bit identifier assigned by the program that generates any kind of query ๐Ÿ†”. This identifier is copied into all replies, so the requestor can use it to match replies to outstanding questions ๐Ÿ’œ.
  • QR is a one bit field that specifies whether this message is a query (0), or a response (1) ๐Ÿ”.
  • OPCODE is a four bit field that specifies the kind of query in this message ๐Ÿฆ‹. The originator of a query sets this value, and it gets copied into the response. The values are:

Okay so the OPCODE field is where the header gets spicy ๐ŸŒถ๏ธ, bestie. It's a 4-bit value, and these are the codes:

0   a standard query (QUERY)
1   an inverse query (IQUERY)

2   an completion query allowing multiple
    answers (CQUERYM)

2   an completion query requesting a single
    answer (CQUERYU)

4-15 reserved for future use

Yes, two entries are both marked 2. Iconic ๐Ÿ’€ Just keep that in mind when you read it. ๐Ÿ™ˆ

Now the flag bits, which are giving main character energy โœจ

  • AA (Authoritative Answer) ๐Ÿ‘‘ This bit is only meaningful in responses. It says the responding name server is an authority for the domain name in the query.
  • TC (TrunCation) โœ‚๏ธ This bit says the message got chopped because it was longer than 512 characters. It's valid in datagram messages, but NOT in messages sent over virtual circuits.
Heads up: TC only lives on datagrams. Over virtual circuits it doesn't apply, so don't go looking for it there ๐Ÿ™…โ€โ™€๏ธ
  • RD (Recursion Desired) ๐Ÿฆ‹ A query can set this bit, and it gets copied into the response. If RD is set, it asks the name server to chase the query recursively. Recursive query support is optional, though, so the server doesn't have to do it.
  • RA (Recursion Available) ๐ŸŒธ This bit gets set or cleared in a response, and it tells you whether the name server actually has recursive query support.
  • RCODE (Response code) ๐Ÿ’… This 4-bit field gets filled in on responses. Here's what the values mean:
    • 0 No error condition โœจ
    • 1 Format error. The name server couldn't interpret the query ๐Ÿ™ƒ
    • 2 Server failure. The name server couldn't process the query because something on the name server was broken ๐Ÿ˜ญ
    • 3 Name Error. This one only counts for responses from an authoritative name server, and it means the domain name in the query doesn't exist ๐Ÿ’€
    • 4 Not Implemented. The name server doesn't support that kind of query ๐Ÿงš
    • 5 Refused. The name server won't do the operation for policy reasons. Like, it might not want to give the info to that particular requestor, or it might not want to do a certain operation (zone transfer is the example given) for particular data ๐Ÿซถ
    • 6-15 Reserved for future use.

Next up are the four counts. Each one is an unsigned 16 bit integer:

  • QDCOUNT is the number of entries in the question section.
  • ANCOUNT is the number of resource records in the answer section.
  • NSCOUNT is the number of name server resource records in the authority records section.
  • ARCOUNT is the number of resource records in the additional records section.

Question section format

The question section is used in every kind of query except inverse queries. In responses to inverse queries it can hold multiple entries. For all other responses it holds a single entry. Each entry looks like this ๐ŸŽ€

                                     1  1  1  1  1  1
       0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                                               |
     /                     QNAME                     /
     /                                               /
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                     QTYPE                     |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                     QCLASS                    |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Here's what each piece is doing:

  • QNAME is a variable number of octets that spell out a domain name. It uses the compressed domain name format from the next section, and you can use it to derive a text string for the name. It might be an odd number of octets, and no padding is used ๐ŸŒˆ
  • QTYPE is a two octet code for the type of the query. It includes every code valid for a TYPE field, plus some broader codes that can match more than one type of RR. For example, QTYPE might be A and only match type A RRs, or it might be MAILA, which matches MF and MD type RRs. The values are listed in Appendix 2 ๐Ÿฆ‹
  • QCLASS is a two octet code for the class of the query. For example, QCLASS is IN for the ARPA Internet, CS for the CSNET, and so on. The numerical values are defined in Appendix 2 โœจ

Resource record format

The answer, authority, and additional sections all share the same format. Each one holds a variable number of resource records, and the count for that section in the header tells you how many there are. Every resource record looks like this ๐Ÿ’–

                                     1  1  1  1  1  1
       0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                                               |
     /                                               /
     /                      NAME                     /
     |                                               |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                      TYPE                     |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                     CLASS                     |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                      TTL                      |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                   RDLENGTH                    |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
     /                     RDATA                     /
     /                                               /
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Breaking it down:

  • NAME is a compressed domain name that this resource record is about ๐ŸŒธ
  • TYPE is two octets holding one of the RR type codes from Appendix 2. It tells you what the data in RDATA means ๐Ÿงš
  • CLASS is two octets that say what class the data in RDATA is in ๐Ÿ’œ
  • TTL is a 16 bit unsigned integer for how long, in seconds, the resource record can be cached before it should be thrown out. A zero value means the RR can only be used for the transaction in progress and should NOT be cached. For example, SOA records are always sent with a zero TTL so they can't be cached. Zero can also be used for extremely volatile data ๐Ÿ“
  • RDLENGTH is an unsigned 16 bit integer for the length, in octets, of the RDATA field ๐Ÿ“
  • RDATA is a variable length string of octets that describes the resource. Its format depends on the TYPE and CLASS of the resource record. For example, if TYPE is A and CLASS is IN, then RDATA is a 4 octet ARPA Internet address ๐ŸŒ

Formats for particular resource records are shown in Appendices 2 and 3 ๐Ÿ“š

Domain name representation and compression

Domain name messages are written as a sequence of labels. Each label is one octet of length followed by that many octets. Since every domain name ends with the null label of the root, a compressed domain name always ends with a length byte of zero. The high order two bits of the length field must be zero, and the remaining six bits limit the label to 63 octets or less ๐Ÿ”’

To keep implementations simple, the total length of the label octets plus the label length octets that make up a domain name is capped at 255 octets or less. The trailing root label and its dot aren't printed, so printed domain names are 254 octets or less ๐Ÿงฎ

Labels can technically contain any 8 bit values, but it's strongly recommended that they follow the syntax in Appendix 1 of this memo, which fits with existing host naming conventions. Name servers and resolvers must compare labels case-insensitively, so A=a, and all character strings must be ASCII with zero parity. Non-alphabetic codes must match exactly ๐Ÿ”ค

Whenever possible, name servers and resolvers must preserve all 8 bits of the domain names they process. When a name server gets data for the same name under two different case usages, that isn't always possible. For example, if a name server gets data for ISI.ARPA and isi.arpa, it should create a single node, not two, and so it will keep a single casing of the label. Systems with case sensitivity should take special precautions to make sure the domain data for the system is created with consistent case ๐Ÿซง

To cut down on the space used by repeated domain names, the octet sequence that defines a domain name can end with a pointer to the length octet of a previously specified label string. The label string the pointer points to gets appended to the label string already specified. Copying a previous label string exactly takes a single pointer, and multiple levels are allowed โœจ

Pointers can only be used in positions of the message where the format is NOT class specific. If that weren't the case, a name server handling an RR for another class could make erroneous copies of RRs. There aren't any such cases yet, but they might show up in future RDATA formats ๐Ÿ‘€

If a domain name is inside a part of the message that has a length field (like the RDATA section of an RR) and compression is used, the length of the compressed name is what goes into the length calculation, not the length of the expanded name ๐Ÿง 

Pointers are represented as a two octet field. The high order 2 bits are ones, and the low order 14 bits specify an offset from the start of the message. The 01 and 10 values of the high order bits are reserved for future use and should not be used ๐Ÿ”ฎ

Okay so programs are totally allowed to skip pointers in the datagrams they make ๐Ÿ’…, but bestie, that makes each datagram hold less stuff ๐Ÿซ . Still, every program is required to understand arriving messages that contain pointers ๐Ÿ”ฅ.

For example, a datagram might need the domain names F.ISI.ARPA, FOO.F.ISI.ARPA, ARPA, and the root ๐ŸŒˆ. If we ignore the other fields in the message, they could look like this:

             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          20 |           1           |           F           |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          22 |           3           |           I           |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          24 |           S           |           I           |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          26 |           4           |           A           |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          28 |           R           |           P           |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          30 |           A           |           0           |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          40 |           3           |           F           |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          42 |           O           |           O           |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          44 | 1  1|                20                       |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          64 | 1  1|                26                       |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          92 |           0           |                       |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

The domain name F.ISI.ARPA lives at offset 20 ๐Ÿงš. FOO.F.ISI.ARPA is at offset 40, and it uses a pointer to glue a FOO label onto the F.ISI.ARPA we already defined ๐ŸŽ€. ARPA is defined at offset 64 with a pointer to the ARPA part of F.ISI.ARPA at 20. Ngl, that only works because ARPA is the last label in the string at 20 ๐Ÿ‘€. The root domain name is just one octet of zeros at 92, since the root has no labels ๐Ÿ’–.

Organization of the Shared database

Name server implementations can use whatever internal data structures they like ๐Ÿ’…, but the suggested setup is several separate trees ๐ŸŒณ. Each tree copies the shape of the domain name space, with RRs hanging off nodes and leaves. Every zone of authoritative data gets its own tree, and one tree holds all the non-authoritative data ๐Ÿฆ‹. All the zone trees are managed the same way, but the non-authoritative (cache) tree has its own management rules โœจ.

The data can be stored in whatever form is easiest for the name server, as long as it can be turned back into the format needed for messages ๐Ÿซถ. The database will probably use structure instead of expanded domain names, and it will also turn many of the time intervals from the domain system into absolute local times โฐ.

Each zone tree holds complete info for a "pruned" subtree of the domain space ๐ŸŒธ. The top node of a zone has a SOA record that marks where the zone starts. The bottom edge of the zone is marked by nodes with NS records, which signal delegation of authority to other zones, or by leaves of the domain tree ๐Ÿ“. When a name server holds abutting zones, one tree ends with a bottom node containing an NS record, and the other tree begins with a tree location containing a SOA record ๐Ÿ’œ.

Heads up, bestie: there is one special case to think about when you implement a name server ๐Ÿ™ˆ. A node that holds a SOA RR for the start of a zone will also have NS records naming the name servers that are expected to have a copy of the zone. So a name server will usually find itself (and maybe other redundant name servers) mentioned in NS records sitting in the same spot in the tree as the SOA records. The fix is to never read an NS record as ending a zone that starts with a SOA at that same point in the tree. (The sample programs in this memo handle this by processing SOA records only after the NS records have been processed ๐Ÿง .)

Zones can also overlap a particular part of the name space when they are of different classes ๐ŸŒˆ.

Other than the abutting and separate class cases, trees are always expected to be disjoint ๐Ÿ™…โ€โ™€๏ธ. Overlapping zones count as a non-fatal error ๐Ÿ˜ฌ. The scheme in this memo dodges the overlap problem by keeping separate trees, and other designs have to take proper measures to guard against possible overlap ๐Ÿ›ก๏ธ.

Non-authoritative data lives in its own separate tree ๐Ÿซง. This tree is different from the zone trees because it may have "holes" ๐Ÿ•ณ๏ธ. Every RR in the cache tree has its own TTL, managed separately ๐Ÿ•ฐ๏ธ. The data in this tree is never used if authoritative data is available from a zone tree, which avoids trouble from cached data that conflicts with authoritative data ๐Ÿ™Œ.

The shared database will also hold data structures for processing inverse queries and completion queries, if the local system supports these optional features ๐Ÿ’ซ. There are lots of ways to do this, but this memo describes a scheme based on tables of pointers that invert the database according to key ๐Ÿ”‘.

Each kind of retrieval has its own set of tables, with one table per zone ๐Ÿ“š. Whenever a zone gets updated, these tables have to be updated too. The contents of these tables are covered in the "Inverse query processing" and "Completion query processing" sections of this memo ๐Ÿ“–.

The database implementation described here has two locks that control concurrent access and modification of the database by name server query processing, name server maintenance operations, and resolver access ๐Ÿ”:

  • The first lock ("main lock") controls access to all of the trees. Multiple concurrent reads are allowed, but write access can only be acquired by a single process. Read and write access are mutually exclusive. Resolvers and name server processes that answer queries acquire this lock in read mode, and unlock it when the current message is complete. This lock is acquired in write mode by a name server maintenance process when it is about to change data in the shared database. The actual update procedures are described under "NAME SERVER MAINTENANCE" but are designed to be brief โšก.
  • The second lock ("cache queue lock") controls access to the cache queue ๐Ÿšฆ. This queue is used by a resolver that wants to add information to the cache tree. The resolver acquires this lock, then places the RRs to be cached into the queue. The name server maintenance procedure periodically acquires this lock and adds the queue information to the cache. The reasoning is that it lets the resolver work with read-only access to the shared database, and lets the update process batch cache additions and their associated costs for inversion calculations ๐Ÿง. The name server maintenance procedure must take appropriate precautions to avoid problems with data already in the cache, inversions, and so on ๐Ÿซฃ.

This organization solves several difficulties, and honestly it's iconic ๐Ÿ‘‘:

  • When searching the domain space for the answer to a query, a name server can limit its search for authoritative data to the tree that matches the most labels on the right side of the domain name of interest ๐ŸŽฏ.
  • Since updates to a zone must be atomic with respect to searches, maintenance operations can simply acquire the main lock, insert a new copy of a particular zone without disturbing other zones, and then release the storage used by the old copy. Assuming a central table points to valid zone trees, this can be a simple pointer swap ๐Ÿ”.
  • TTL management of zones can be done using the SOA record for the zone. This avoids potential trouble if individual RRs in a zone could time out separately. This issue is discussed further in the maintenance section ๐Ÿ•Š๏ธ.

Query processing

Here's the algorithm for what happens at a name server when a query arrives ๐Ÿ“ฌ:

  1. Search the list of zones to find zones that have the same class as the QCLASS field in the query and a top domain name that matches the right end of the QNAME field. If there are none, go to step 2. If there is more than one, pick the zone with the longest match and go to step 3 ๐Ÿ”.
  2. Since the zone search failed, the only possible RRs are in the non-authoritative tree ๐Ÿซ . Search the cache tree for the NS record that has the same class as the QCLASS field and the largest right end match for the domain name. Add the NS record or records to the authority section of the response. If the cache tree has RRs that are pertinent to the question (domain names match, classes agree, not timed-out, and the type field is relevant to the QTYPE), copy those RRs into the answer section of the response. The name server may also search the cache queue. Go to step 4 ๐Ÿ’Œ.
  3. Since this zone is the best match, the zone where QNAME resides is either this zone or a zone this zone will delegate authority to, directly or indirectly ๐ŸŒŸ. Search down the tree looking for an NS RR or the node specified by QNAME.
    • If the node exists and has no NS record, copy the relevant RRs to the answer section of the response and go to step 4 โœ….
    • If an NS RR is found, either matching part or all of QNAME, then QNAME is in a delegated zone outside of this zone. If so, copy the NS record or records into the authority section of the response, and search the rest of the zone for an A type record corresponding to the NS reference. If the A record is found, add it to the additional section. Go to step 2 ๐Ÿƒโ€โ™€๏ธ.
    • If the node is not found and an NS is not found, there is no such name. Set the Name error bit in the response and exit ๐Ÿ’€.
  4. When this step is reached, the answer and authority sections are complete ๐ŸŽ‰. What's left is to complete the additional section. This procedure is only possible if the name server knows the data formats implied by the class of records in the answer and authority sections, so this procedure is class dependent. Appendix 3 discusses this procedure for Internet class data ๐Ÿงš.

While this algorithm handles typical queries and databases, several additions are required that depend on the database the name server supports:


Inverse query processing ๐Ÿ”

Name servers that support inverse queries can handle them with exhaustive searches of their databases, but that gets impractical as the database grows ๐Ÿ˜ญ. An alternative is to invert the database according to the search key ๐Ÿฆ‹.

For name servers that support multiple zones and a large amount of data, the RECOMMENDED approach is separate inversions for each zone ๐Ÿ‘‘. That way, when one zone changes during a refresh, only its inversions need to be redone โœจ.

Support for transfer of this type of inversion MAY be included in future versions of the domain system, but it is not supported in this version ๐Ÿ’œ.

Completion query processing ๐ŸŒธ

Completion query processing has a lot of the same data structure headaches as inverse queries ๐Ÿ™ƒ, but it's its own thing because top level labels (i.e., ARPA, CSNET) get used constantly ๐Ÿ˜ฉ. A name server that wants to be efficient with its memory MAY well choose to invert only the occurrences of ARPA, etc. that sit below the top level, and do a search for the rare case where top level labels are used to constrain a completion ๐Ÿงš.


NAME SERVER MAINTENANCE ๐Ÿ› ๏ธ

Introduction ๐Ÿ’–

Name servers do maintenance on their databases so the data they hand out stays accurate and fresh โœจ. How much work that is depends on how big the database is, how fast it changes, and how complicated it is ๐Ÿค“.

Maintenance is totally different for authoritative and non-authoritative data ๐Ÿซถ. A name server actively works to keep authoritative data accurate and timely by refreshing it from master copies ๐Ÿ’…. Non-authoritative data just gets purged when its time-to-live runs out ๐Ÿ’€, and the name server doesn't try to refresh it ๐Ÿ™….

Refreshing is pretty simple to build, but it's a bit less powerful than what other distributed database systems use ๐Ÿฅบ. An update to the master doesn't instantly update the copies. It SHOULD be seen as slowly percolating through the distributed database ๐ŸŒŠ. That's totally fine for the vast majority of apps ๐Ÿ’œ. But if timeliness is critical, the master name server gets the final say: it can prohibit caching of copies or give copies short timeouts ๐Ÿšจ.

Conceptual model of maintenance operations ๐Ÿง 

Most of the information in the domain system comes from master files scattered across the hosts that run name servers ๐ŸŒ. Some name servers have no master files, and others have one or more ๐Ÿ“. Each master file holds the master data for a single zone of authority, not the data for the whole domain name space ๐Ÿ’…. The administrator of a zone controls it by updating its master file โœจ.

Master files and zone copies from remote servers can include RRs that are outside the zone of authority, when an NS record delegates authority to a domain name that is a descendant of the name where authority is delegated ๐Ÿ™ˆ. These forward references are a problem because there's no reasonable way to guarantee that the A type records for the delegatee are available, unless they can somehow be attached to the NS records ๐Ÿ˜ญ.

For example, say the ARPA zone delegates authority at MIT.ARPA and states that the name server is on AI.MIT.ARPA. If a resolver gets the NS record but not the A type record for AI.MIT.ARPA, it might try asking the MIT name server for the address of AI.MIT.ARPA ๐Ÿ’€.

The fix is to let A type records outside the zone of authority be copied along with the zone ๐Ÿฆ‹. These records won't show up in a search for the A type record itself, but they're protected by the zone refreshing system and get passed back whenever the name server passes back a referral to the corresponding NS record ๐ŸŽ€. If a query for the A record comes in, the name server passes back a referral to the name server with the A record in the additional section, rather than the answer section ๐Ÿซถ.

The only exception to using master files is a small amount of data stored in boot files ๐Ÿ“ฆ. Boot file data gives name servers enough resource records to import zones from foreign servers (e.g. the address of the server) and to set up the name and address of root servers ๐Ÿ‘‘. Boot file records establish the initial contents of the cache tree, so they can be overridden by later loads of authoritative data ๐ŸŒˆ.

The data in a master file first becomes available to users of the domain name system when the corresponding name server loads it ๐ŸŽ‰. By definition, data from a master file is authoritative ๐Ÿ’….

Other name servers that want to be authoritative for a particular zone do it by transferring a copy of the zone from the name server holding the master copy, using a virtual circuit ๐Ÿ”Œ. These copies include parameters that specify the conditions under which the data in the copy is authoritative ๐Ÿ“œ. In the most common case, those conditions specify a refresh interval and the policies to follow when the refresh operation can't be performed โฐ.

A name server may acquire multiple zones from different name servers and master files, but it MUST maintain each zone separately from the others and from non-authoritative data ๐Ÿ’œ.

When the refresh interval for a particular zone copy expires, the name server holding the copy MUST consult the name server that holds the master copy ๐Ÿ™‹. If the data in the zone hasn't changed, the master name server tells the copy name server to reset the refresh interval โณ. If the data has changed, the master passes a new copy of the zone and its associated conditions to the copy name server ๐Ÿšš. Either way, the copy name server starts a new refresh interval once that transaction is done โœจ.

Copy name servers MUST also deal with error conditions where they can't communicate with the name server holding the master copy ๐Ÿ˜ต. The policies a copy name server uses are determined by other parameters that come with every copy ๐Ÿงฉ. Those conditions include a retry interval and a maximum holding time โฑ๏ธ. When a copy name server can't establish communications with a master, or can't complete the refresh transaction, it MUST retry the refresh operation at the rate set by the retry interval ๐Ÿ”. That retry interval is usually substantially shorter than the refresh interval ๐Ÿƒ. Retries continue until the maximum holding time is reached โŒ›. At that point, the copy name server MUST assume that its copy of the data for the zone in question is no longer authoritative ๐Ÿšซ.

Queries MUST be processed while maintenance operations are in progress, because a zone transfer can take a long time ๐Ÿข. But to avoid problems caused by access to partial databases, maintenance operations create new copies of data rather than directly modifying the old copies ๐Ÿง. When the new copy is complete, the maintenance process locks out queries for a short time using the main lock, and switches pointers to replace the old data with the new ๐Ÿ”„. After the pointers are swapped, the maintenance process unlocks the main lock and reclaims the storage used by the old copy ๐Ÿงน.

Name server data structures and top level logic ๐Ÿ—๏ธ

The name server MUST multiplex its attention between multiple activities ๐Ÿคน. For example, a name server SHOULD be able to answer queries while it's also performing refresh activities for a particular zone ๐Ÿ™Œ. You could build a name server that gives each query and each refresh activity its own process ๐Ÿค”, but the model in this memo assumes a single process doing all the maintenance operations, plus one or more processes devoted to handling queries ๐Ÿ’…. The model also assumes shared memory for several control structures, the domain database, locks, etc. ๐Ÿ”’.

The model name server uses the following files and shared data structures:

  1. A configuration file that describes the master and boot files the name server should load, plus the zones it should try to load from foreign name servers ๐Ÿ“. This file establishes the initial contents of the status table ๐Ÿ—‚๏ธ.
  2. Domain data files that contain the master and boot data to be loaded ๐Ÿ“‚.
  3. A status table derived from the configuration file ๐Ÿ“Š. Each entry describes a source of data and has a zone number ๐Ÿ”ข. The zone number is zero for non-authoritative sources, and authoritative sources are assigned separate non-zero numbers ๐Ÿ’–.
  4. The shared database that holds the domain data ๐Ÿ—„๏ธ. This database is assumed to be organized as a tree that parallels the domain name space, with a list of resource records attached to each node and leaf ๐ŸŒณ. The elements of the resource record lists don't need to hold the exact data present in the corresponding output format, but they MUST contain data sufficient to create that output format ๐Ÿงฉ. For example, the records don't need to contain the domain name associated with the resource, because that name can be derived from the tree structure ๐ŸŒฒ. Each resource record also carries internal data that the name server uses to organize its data ๐Ÿ—‚๏ธ.

Name server maintenance, continued ๐Ÿฆ‹

  1. Inversion data structures that let the name server handle inverse queries and completion queries ๐Ÿ”. Lots of structures could work here, but the implementation in this memo assumes one array for every inversion the name server can handle ๐Ÿ’…. Each array holds a list of pointers to resource records, sorted by the inverted quantities โœจ.
  2. The main and cache queue locks ๐Ÿ”’
  3. The cache queue ๐ŸŒธ

The maintenance process starts by loading the status table from the configuration file ๐Ÿ“‹. Then it keeps checking each entry to see whether its refresh interval has run out โฐ. If it hasn't, it just moves on to the next entry ๐Ÿƒโ€โ™€๏ธ. If it has, the process does something different depending on which entry it is ๐Ÿซถ:

If the entry is for zone 0, or the cache tree: the maintenance process checks whether anything needs to be added or deleted ๐Ÿงน. Additions come from the cache queue, and it grabs them using the cache queue lock ๐Ÿ”. Deletions are spotted with TTL checks โณ. If anything changed, the process recalculates the inversion data structures and then alters the cache tree while holding the main lock ๐Ÿ‘‘. Every time it modifies the cache tree, it resets the refresh interval to the minimum of the contained TTLs and the desired time interval for cache additions ๐Ÿ’–.

If the entry is not zone 0 and it refers to a local file: the maintenance process checks whether the file has been modified since its last load ๐Ÿ“‚. If it has, the file gets reloaded using the procedures under "Name server file loading" ๐Ÿ”„. The refresh interval gets reset to whatever the SOA record says, but only if the file is a master file ๐ŸŽ€.

If the entry is for a remote master file: the maintenance process checks for a new version using the procedure described in "Names server remote zone transfer" ๐Ÿ›ฐ๏ธ.


Name server file loading ๐Ÿ“œ

Master files are kept in text form so system maintainers can edit them easily ๐Ÿ’ป. Name servers don't swap these files with each other ๐Ÿ™…โ€โ™€๏ธ. When zones get transferred, they use the standard message format instead ๐Ÿ“จ.

Some organizations want a domain but don't want to run a name server, and that's totally valid ๐ŸŒˆ. They can use these files to hand a domain definition to another organization that runs a name server for them ๐Ÿค. Say organization X wants a domain but no name server. It can find organization Y, which has a name server and is willing to provide service for X ๐Ÿ’…. X defines domain X in the master file format and ships a copy to Y by mail, FTP, or some other method ๐Ÿ“ฌ. A system administrator at Y configures Y's name server to read in X's file, so it supports the X domain ๐Ÿฆ„. X can keep maintaining the master file in a text editor and send new versions to Y for installation โœจ.

These files have a simple line-oriented format, with one RR per line ๐Ÿ“. Fields are separated by any combination of blanks and tab characters ๐Ÿ“. Tabs get treated the same as spaces, so in the rest of this discussion "blank" means either a tab or a blank ๐Ÿซง. A line can be a blank (which gets ignored), an RR, or a $INCLUDE line ๐Ÿงš.

If an RR line starts with a domain name, that name tells you where the record goes in the domain space, which is the owner ๐Ÿ“. If an RR line starts with a blank, it gets loaded into the location specified by the most recent location specifier ๐Ÿ’œ.

Location specifiers are assumed to be relative to some origin that the user of a file provides, unless the location specifier contains the root label ๐ŸŒ. This is a super convenient shorthand, and it also stops errors in master files from leaking into other zones ๐Ÿ›ก๏ธ. It's especially useful for master files imported from other sites ๐Ÿซถ.

An include line begins with $INCLUDE, starting at the first line position, and it's followed by a local file name and an optional offset modifier ๐Ÿ—‚๏ธ. The file name follows the appropriate local conventions ๐ŸŽ€. The offset is one or more labels that get added to the offset in use for the file that contained the $INCLUDE ๐Ÿ”—. If the offset is left out, the included file is loaded with the offset of the file that contained the $INCLUDE command ๐Ÿ’…. For example, a file being loaded at offset ARPA might contain these lines:

$INCLUDE <subsys>isi.data ISI
$INCLUDE <subsys>addresses.data

The first line tells the loader to load the file <subsys>isi.data at offset ISI.ARPA ๐Ÿงญ. The second line is a request to load data at offset ARPA ๐ŸŒŸ.

Note that $INCLUDE commands do not put data into a different zone or tree ๐Ÿ™…โ€โ™€๏ธ. They're just a way to organize a zone's data across separate files ๐Ÿ—ƒ๏ธ. For example, mailbox data might be kept apart from host data using this mechanism ๐Ÿ“ซ.

Resource records are entered as a sequence of fields for the owner name, TTL, CLASS, TYPE and RDATA components ๐Ÿงฉ. (This order is different from the order used in examples and from the order in the actual RRs, but it makes parsing and defaulting way easier ๐Ÿง .)

  • The owner name is derived from the location specifier ๐Ÿ“.
  • The TTL field is optional and written as a decimal number. If it's omitted, TTL defaults to zero โณ.
  • The CLASS field is also optional. If it's omitted, CLASS defaults to the most recent value of the CLASS field in a previous RR ๐Ÿ”.
  • The RDATA fields depend on the CLASS and TYPE of the RR. In general, the fields that make up RDATA are decimal numbers or domain names. There are some exceptions, and they're documented in the RDATA definitions in Appendicies 2 and 3 of this memo ๐Ÿ“š.

CLASS and TYPE fields don't contain any common identifiers, and they're never decimal numbers. That means the parse is always unique ๐Ÿ’–.

Because these are text files, some special encodings are needed so arbitrary data can be loaded ๐ŸŽจ. The big ones are:

  • . A free-standing dot refers to the current domain name ๐Ÿ“.
  • @ A free-standing @ denotes the current origin ๐ŸŒธ.
  • .. Two free-standing dots represent the null domain name of the root ๐ŸŒณ.
  • \X Where X is any character other than a digit (0-9), this quotes that character so its special meaning doesn't apply. For example, "\." can place a dot character in a label ๐Ÿ™ˆ.
  • \DDD Where each D is a digit, this is the octet for the decimal number DDD. The resulting octet is assumed to be text and is not checked for special meaning ๐Ÿ”ข.
  • ( ) Parentheses group data that crosses a line boundary. Basically, line terminations aren't recognized inside parentheses ๐Ÿซง.
  • ; A semicolon starts a comment, and the rest of the line gets ignored ๐Ÿ’ฌ.

Name server file loading example ๐ŸŒˆ

A name server for F.ISI.ARPA, acting as an authority for the ARPA and ISI.ARPA domains, might use a boot file and two master files ๐Ÿงšโ€โ™€๏ธ. The boot file initializes some non-authoritative data, and it gets loaded without an origin ๐ŸŒŸ:

..              9999999 IN      NS      B.ISI.ARPA
                9999999 CS      NS      UDEL.CSNET
B.ISI.ARPA      9999999 IN      A       10.3.0.52
UDEL.CSNET      9999999 CS      A       302-555-0000

This file loads non-authoritative data that gives the identities and addresses of root name servers ๐ŸŒณ. The first line has an NS RR that gets loaded at the root ๐ŸŒฑ. The second line starts with a blank, so it's loaded at the most recent location specifier, which here is the root ๐Ÿซถ. The third and fourth lines load RRs at B.ISI.ARPA and UDEL.CSNET ๐ŸŽ€. The timeouts are set to high values (9999999) so this data doesn't get thrown out for timing out โณ.

The first master file loads authoritative data for the ARPA domain ๐Ÿ‘‘. It's designed to be loaded with an origin of ARPA, which lets the location specifiers skip the trailing .ARPA labels ๐Ÿ’…:

@   IN  SOA     F.ISI.ARPA       Action.E.ISI.ARPA (
                                 20     ; SERIAL
                                 3600   ; REFRESH
                                 600    ; RETRY
                                 3600000; EXPIRE
                                 60)    ; MINIMUM
        NS      F.ISI.ARPA ; F.ISI.ARPA is a name server for ARPA
        NS      A.ISI.ARPA ; A.ISI.ARPA is a name server for ARPA
MIT     NS      AI.MIT.ARPA; delegation to MIT name server
ISI     NS      F.ISI.ARPA ; delegation to ISI name server

UDEL    MD      UDEL.ARPA
        A       10.0.0.96
NBS     MD      NBS.ARPA
        A       10.0.0.19
DTI     MD      DTI.ARPA
        A       10.0.0.12

AI.MIT  A       10.2.0.6
F.ISI   A       10.2.0.52

The first group of lines has the SOA record and its parameters, and it names the name servers for this zone and for delegated zones ๐Ÿ“‹. The Action.E.ISI.ARPA field is a mailbox spec for the person responsible for the zone. It's the domain name encoding of the mail destination Action@E.ISI.ARPA ๐Ÿ“ฌ. The second group sets data for domain names inside this zone ๐Ÿก. The last group has forward references for name server address resolution for AI.MIT.ARPA and F.ISI.ARPA ๐Ÿ”Ž. That data isn't technically within the zone, and it's only used for additional record resolution for NS records used in referrals ๐Ÿช„. Still, it's protected by the zone timeouts in the SOA, so it'll stick around as long as the NS references do ๐Ÿ’œ.

The second master file defines the ISI.ARPA environment and is loaded with an origin of ISI.ARPA ๐ŸŒบ:

@   IN  SOA     F.ISI.ARPA      Action\.ISI.E.ISI.ARPA (
                                 20     ; SERIAL
                                 7200   ; REFRESH
                                 600    ; RETRY
                                 3600000; EXPIRE
                                 60)    ; MINIMUM
        NS      F.ISI.ARPA ; F.ISI.ARPA is a name server
A       A       10.1.0.32
        MD      A.ISI.ARPA
        MF      F.ISI.ARPA
B       A       10.3.0.52
        MD      B.ISI.ARPA
        MF      F.ISI.ARPA
F       A       10.2.0.52
        MD      F.ISI.ARPA
        MF      A.ISI.ARPA
$INCLUDE <SUBSYS>ISI-MAILBOXES.TXT

The file <SUBSYS>ISI-MAILBOXES.TXT looks like this ๐Ÿ“ซ:

MOE     MB      F.ISI.ARPA
LARRY   MB      A.ISI.ARPA
CURLEY  MB      B.ISI.ARPA
STOOGES MB      B.ISI.ARPA
        MG      MOE.ISI.ARPA
        MG      LARRY.ISI.ARPA
        MG      CURLEY.ISI.ARPA

Check out the \ character in the SOA RR ๐Ÿ•ต๏ธโ€โ™€๏ธ. It's what specifies the responsible person's mailbox "Action.ISI@E.ISI.ARPA" ๐Ÿ’….


Name server remote zone transfer ๐Ÿ›ฐ๏ธโœจ

Okay so, when a name server wants to make its first copy of a zone, or check whether its existing copy needs a refresh, it starts by trying to open a virtual circuit to the foreign name server. ๐Ÿ’Œ

If that open attempt fails and it was an initial load, it schedules a retry and bails ๐Ÿ™ƒ. If it was a refresh, the name server checks the status table to see whether the maximum holding time (derived from the SOA EXPIRE field) has elapsed yet. If it hasn't, the name server schedules a retry. If the maximum holding time has expired, it invalidates the zone in the status table and scans every resource record tagged with this zone number. For each record, it decrements the TTL fields by however long it's been since the data was last refreshed. If the new TTL value is negative, the record gets deleted ๐Ÿ’€. If the TTL is still positive, the RR gets moved into the cache tree and a retry is scheduled.

If the open works, the name server sends a query to the foreign name server with QTYPE=SOA, QCLASS set according to the status table info from the configuration file, and QNAME set to the domain name of the zone of interest. ๐ŸŽฏ

The foreign name server will either send back a SOA record saying "yep, I have the zone" or an error. If there's an error, the virtual circuit gets closed, and it's handled the same way as a failed open attempt.

If a SOA record comes back and this was a refresh (not an initial load), the name server compares the SERIAL field in the new SOA record with the SERIAL field in the SOA record of the existing zone copy. If they match, the zone hasn't changed since the last copy, so there's no reason to recopy it. The name server just resets the times in the existing SOA record and closes the virtual circuit to wrap things up. Done and dusted ๐ŸŽ‰.

If this is an initial load, or the SERIAL fields were different, the name server requests a copy of the zone by sending the foreign name server an AXFR query that specifies the zone by its QCLASS and QNAME fields. ๐Ÿ“ฆ

When the foreign name server gets the AXFR request, it sends each node from the zone to the requestor in a separate message. It starts with the node containing the SOA record, walks the tree in breadth-first order, and finishes by resending the node containing the SOA record again. ๐ŸŒณ

Several error conditions are possible:

  • If the AXFR request can't be matched to a SOA, the foreign name server returns a single message that does not contain the AXFR request. (The normal SOA query before the AXFR is designed to avoid this, but it's still possible ๐Ÿ™ˆ.)
  • The foreign name server can detect an internal error, or some other condition (like the system going down, running out of resources, etc.), that forces the transfer to be aborted. If that happens, it sends a message with the "Server failure" condition set. If the AXFR can be retried right away with some chance of success, it leaves the virtual circuit open. Otherwise, it initiates a close.
  • If the foreign name server doesn't want to do the operation for policy reasons (like the sysadmin wants to forbid zone copies), it returns a "Refused" condition. ๐Ÿšซ

The requestor receives these records and builds a new tree. This tree isn't in the status table yet, so its data isn't used to process queries. The old copy of the zone, if there is one, can still satisfy requests while the transfer is in progress ๐Ÿซถ.

When the requestor receives the second copy of the SOA node, it compares the SERIAL field in the first copy of the SOA against the SERIAL field in the last copy of the SOA record. If these don't match, the foreign server updated its zone while the transfer was in progress, so the requestor repeats the AXFR request to get the newer version. ๐Ÿ”

If the AXFR transfer eventually succeeds, the name server closes the virtual circuit and creates new versions of the inversion data structures for this zone. Once that's complete, the name server acquires the main lock in write mode and replaces any old copy of the zone and inversion data structures with the new ones. Then it releases the main lock, and it can reclaim the storage used by the old copy. โœจ

If an error occurs during the AXFR transfer, the name server can copy any partial information into its cache tree if it wants, although it won't normally do that if the zone transfer was a refresh rather than an initial load.

RESOLVER ALGORITHMS โœจ

Operations

Resolvers have a great deal of latitude in the semantics they allow in user calls. For example, a resolver might support different user calls that specify whether the returned information must come from an authoritative name server or not. Resolvers are also responsible for enforcing any local restrictions on access, etc. ๐Ÿ’…

In any case, the resolver will transform the user query into a number of shared database accesses and queries to remote name servers. When a user requests a resource associated with a particular domain name, the resolver will execute the following steps:

  1. The resolver first checks the local shared database, if any, for the desired information. If it's found, it checks the applicable timeout. If the timeout check succeeds, the information is used to satisfy the user request. If not, the resolver goes to step 2. ๐Ÿ‘€
  2. The resolver consults the shared database for the name server that most closely matches the domain name in the user query. Multiple redundant name servers may be found. The resolver goes to step 3. ๐Ÿ”
  3. The resolver chooses one of the available name servers and sends off a query. If the query fails, it tries another name server. If all of them fail, an error indication is returned to the user. If a reply is received, the resolver adds the returned RRs to its database and goes to step 4. ๐Ÿ“ฌ
  4. The resolver interprets the reply. If the reply contains the desired information, the resolver returns it to the user. If the reply indicates that the domain name in the user query doesn't exist, the resolver returns an error to the user. If the reply contains a transient name server failure, the resolver can either wait and retry the query, or go back to step 3 and try a different name server. If the reply doesn't contain the desired information but does contain a pointer to a closer name server, the resolver returns to step 2, where the closer name servers will be queried. ๐ŸŒธ

Several modifications to this algorithm are possible. A resolver may not support a local cache, and instead only cache information during the course of a single user request, discarding it upon completion. The resolver may also find that a datagram reply was truncated, and open a virtual circuit so that the complete reply can be recovered. ๐Ÿฆ‹

Inverse and completion queries must be treated in an environment-sensitive manner, because the domain system doesn't provide a method for guaranteeing that it can locate the correct information. The typical choice will be to configure a resolver to use a particular set of known name servers for inverse queries. ๐Ÿงš

Domain Support for Mail ๐Ÿ’Œโœจ

Introduction

okay so mail is a particularly sensitive topic in the domain system ๐Ÿ˜ญ because there's no consistent way to name mailboxes or even hosts, and existing services still have to keep working while everything changes. this section is about an evolutionary approach to adding consistent domain name support for mail ๐Ÿ’…

the crucial issue is deciding which types of binding to support ๐ŸŽ€ most mail systems specify a mail destination with a two part construct like X@Y. the left side, X, is a string, often a user or account, and Y is a string, often a host. in this section we call the left part X the local part, and the right part Y the global part.

most existing mail systems route mail based on the global part ๐Ÿฆ‹ a mailer with mail for X@Y decides which host to contact using only Y. we call this type of binding "agent binding."

For example, mail addressed to Mockapetris@ISIF is delivered to host USC-ISIF (USC-ISIF is the official name for the host specified by nickname ISIF).

more sophisticated mail systems use both the local and global parts, so both X and Y, to figure out which host should receive the mail ๐Ÿงš these fancier systems usually separate the binding of the destination to the host from the actual delivery. this lets the global part be a generic name instead of being locked to a single host. we call this type of binding "mailbox binding."

For example, mail addressed to Mockapetris@ISI might be bound to host F.ISI.ARPA, and subsequently delivered to that host, while mail for Cohen@ISI might be bound to host B.ISI.ARPA.

the domain support for mail has two levels ๐ŸŒธ and they match these two binding models:

  • The first level, agent binding, is compatible with existing ARPA Internet mail procedures. It maps a global part onto one or more hosts that will accept the mail. This type of binding uses the MAILA QTYPE.
  • The second level, mailbox binding, offers extended services. It maps a local part and a global part onto one or more sets of data via the MAILB QTYPE. The sets of data include hosts that will accept the mail, mailing list members (mail groups), and mailboxes for reporting errors or requests to change a mail group.

here's how the domain system handles names ๐Ÿ“ it encodes the global part as a domain name and uses dots in the global part to separate labels in the encoded domain name. for the local part it encodes a single label, and any dots in that part are simply copied into the label. then it forms a complete mail destination by joining the local label to the domain string for the global part. we call this a mailbox.

For example, the mailbox Mockapetris@F.ISI.ARPA has a global domain name of three labels, F.ISI.ARPA. The domain name encoding for the whole mailbox is Mockapetris.F.ISI.ARPA. The mailbox Mockapetris.cad@F.ISI.ARPA has the same domain name for the global part and a 4 label domain name for the mailbox of Mockapetris\.cad.F.ISI.ARPA (the \ is not stored in the label, it's just used to denote the "quoted" dot).

it's anticipated that the Internet system will adopt agent binding as part of the initial implementation of the domain system ๐Ÿ’œ and that mailbox binding will eventually become the preferred style as organizations convert their mail systems to the new style. to make this work, the domain information for the two binding styles is organized so a requestor can figure out which types of support are available. the information is kept in two disjoint classes โœจ

Agent binding

in agent binding, a mail system uses the global part of the mail destination as a domain name, with dots denoting structure ๐ŸŒˆ the domain name gets resolved using a MAILA query, which returns MF and MD RRs that specify the domain name of the right host to receive the mail. MD (Mail delivery) RRs specify hosts that are expected to have the mailbox. MF (Mail forwarding) RRs specify hosts that are expected to be intermediaries willing to accept the mail for eventual forwarding. the hosts are hints rather than definite answers, since the query gets made without the full mail destination specification ๐Ÿค”

for example, mail for MOCKAPETRIS@F.ISI.ARPA would result in a query with QTYPE=MAILA and QNAME=F.ISI.ARPA, which might return two RRs:

                      F.ISI.ARPA MD IN F.ISI.ARPA
                      F.ISI.ARPA MF IN A.ISI.ARPA

the mailer would read these to mean that the mail agent on F.ISI.ARPA should be able to deliver the mail directly, but that A.ISI.ARPA is willing to accept the mail for probable forwarding ๐Ÿ“ฌ

using this system, an organization could use organization names for global parts instead of the usual host names ๐Ÿ’… but all mail for the organization would get routed the same way, no matter its local part. so an organization with lots of hosts would expect to see lots of forwarding operations ๐Ÿ™ˆ

Mailbox binding

in mailbox binding, the mailer uses the entire mail destination specification to construct a domain name ๐Ÿง the encoded domain name for the mailbox is used as the QNAME field in a QTYPE=MAILB query. there are a few possible outcomes for this query:

  1. The query can return a name error, which means the mailbox doesn't exist as a domain name. long term, that would mean the specified mailbox doesn't exist. but until mailbox binding is universal, this error should be interpreted to mean that the organization identified by the global part doesn't support mailbox binding ๐Ÿ˜ญ the right move is to revert to agent binding at this point.
  2. The query can return a Mail Rename (MR) RR. The MR RR carries a new mailbox specification in its RDATA field. the mailer should replace the old mailbox with the new one and retry the operation ๐Ÿ”
  3. The query can return a MB RR. The MB RR carries a domain name for a host in its RDATA field. the mailer should deliver the message to that host via whatever protocol is applicable, e.g. SMTP ๐Ÿฆ‹
  4. The query can return one or more Mail Group (MG) RRs. this means the mailbox was actually a mailing list or mail group, not a single mailbox ๐Ÿ’Œ each MG RR has a RDATA field that identifies a mailbox that is a member of the group. the mailer should deliver a copy of the message to each member.
  5. The query can return a MB RR as well as one or more MG RRs. this means the mailbox was actually a mailing list ๐Ÿซถ the mailer can either deliver the message to the host specified by the MB RR, which will then do the delivery to all members, or the mailer can use the MG RRs to do the expansion itself.
In any of these cases, the response may include a Mail Information (MINFO) RR. This RR is usually associated with a mail group, but it's legal with a MB. The MINFO RR identifies two mailboxes. One of them identifies a responsible person for the original mailbox name, and this mailbox should be used for requests to be added to a mail group, etc. The second mailbox name in the MINFO RR identifies a mailbox that should receive error messages for mail failures. this is especially useful for mailing lists when errors in member names should go to a different person than the one who sends a message to the list. New fields may be added to this RR in the future ๐Ÿ‘‘

Appendix 1 - Domain Name Syntax Specification

the preferred syntax of domain names is given by the following BNF rules ๐ŸŽ€ following this syntax means fewer problems with lots of applications that use domain names (e.g., mail, TELNET). just know that some applications use domain names with binary information in them, so they don't follow this syntax ๐Ÿ™ˆ

      <domain> ::=  <subdomain> | " "

      <subdomain> ::=  <label> | <subdomain> "." <label>

      <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]

      <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>

      <let-dig-hyp> ::= <let-dig> | "-"

      <let-dig> ::= <letter> | <digit>

      <letter> ::= any one of the 52 alphabetic characters A through Z
      in upper case and a through z in lower case

      <digit> ::= any one of the ten digits 0 through 9

okay so upper and lower case letters are allowed in domain names, but no significance is attached to the case ๐ŸŒธ that means two names with the same spelling but different case are treated as identical ๐Ÿ’œ

the labels have to follow the rules for ARPANET host names ๐Ÿงš they must start with a letter, end with a letter or digit, and have as interior characters only letters, digits, and hyphen. there are also some length restrictions. labels must be 63 characters or less โœจ

for example, these strings identify hosts in the ARPA Internet:

      F.ISI.ARPA     LINKABIT-DCN5.ARPA     UCL-TAC.ARPA

Appendix 2 - Field formats and encodings

           +-----------------------------------------------+
           |                                               |
           |             *****  WARNING  *****             |
           |                                               |
           |  The following formats are preliminary and    |
           | are included for purposes of explanation only.|
           | In particular, new RR types will be added,    |
           | and the size, position, and encoding of       |
           | fields are subject to change.                 |
           |                                               |
           +-----------------------------------------------+

TYPE values

TYPE fields are used in resource records ๐ŸŒˆ these types are not the same as the QTYPE fields used in queries, even though their functions are often similar ๐Ÿค“

      TYPE value meaning

      A      1   a host address

      NS     2   an authoritative name server

      MD     3   a mail destination

      MF     4   a mail forwarder

      CNAME  5   the canonical name for an alias

      SOA    6   marks the start of a zone of authority

      MB     7   a mailbox domain name

      MG     8   a mail group member

      MR     9   a mail rename domain name

      NULL  10   a null RR

      WKS   11   a well known service description

      PTR   12   a domain name pointer

      HINFO 13   host information

      MINFO 14   mailbox or mail list information

QTYPE values

QTYPE fields show up in the question part of a query ๐Ÿ’… they include the values of TYPE, plus these extra ones:

      AXFR   252 A request for a transfer of an entire zone of authority

      MAILB  253 A request for mailbox-related records (MB, MG or MR)

      MAILA  254 A request for mail agent RRs (MD and MF)

      *      255 A request for all records

CLASS values

CLASS fields appear in resource records ๐Ÿฆ‹

      CLASS value meaning

      IN      1   the ARPA Internet
      CS      2   the computer science network (CSNET)

QCLASS values ๐ŸŽ€

okay so QCLASS fields show up in the question section of a query ๐Ÿ’… and they include all the CLASS values we just saw, plus one extra glow-up:

  • 255 any class ๐Ÿฆ‹

Standard resource record formats โœจ

bestie, every single RR has the SAME top-level layout, so once you get this you get them all ๐Ÿซถ

                                     1  1  1  1  1  1
         0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       |                                               |
       /                                               /
       /                      NAME                     /
       |                                               |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       |                      TYPE                     |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       |                     CLASS                     |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       |                      TTL                      |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       |                   RDLENGTH                    |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
       /                     RDATA                     /
       /                                               /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

  • NAME - a compressed domain name to which this resource record pertains. basically, whose record is it? ๐ŸŒธ
  • TYPE - two octets containing one of the RR type codes defined in Appendix 2. This field specifies the meaning of the data in the RDATA field. it tells you how to read RDATA ๐Ÿ‘€
  • CLASS - two octets which specifies the class of the data in the RDATA field. ๐Ÿงš
  • TTL - a 16 bit signed integer that specifies the time interval that the resource record may be cached before the source of the information should again be consulted. Zero values are interpreted to mean that the RR can only be used for the transaction in progress, and should not be cached. For example, SOA records are always distributed with a zero TTL to prohibit caching. Zero values can also be used for extremely volatile data. ngl the zero TTL is giving "do not save this, babe" ๐Ÿ’€
  • RDLENGTH - an unsigned 16 bit integer that specifies the length in octets of the RDATA field. ๐Ÿ“
  • RDATA - a variable length string of octets that describes the resource. The format of this information varies according to the TYPE and CLASS of the resource record. ๐Ÿ’–

The format of the RDATA field is standard for all classes for the RR types NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR, HINFO, MINFO and NULL. These formats are shown below together with the appropriate additional section RR processing. it's the same vibe across all of them, iykyk ๐Ÿฆ‹

CNAME RDATA format ๐Ÿ”ฅ

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                     CNAME                     /
       /                                               /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

  • CNAME - A compressed domain name which specifies that the domain name of the RR is an alias for a canonical name specified by CNAME. so it's basically "I'm just a nickname for this other name" ๐Ÿ’…

CNAME records cause no additional section processing. The RDATA section of a CNAME line in a master file is a standard printed domain name.

HINFO RDATA format ๐Ÿ’ป

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                      CPU                      /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                       OS                      /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

  • CPU - A character string which specifies the CPU type. The character string is represented as a single octet length followed by that number of characters. The following standard strings are defined:
PDP-11/70   C/30        C/70        VAX-11/780
H-316       H-516       DEC-2060    DEC-1090T
ALTO        IBM-PC      IBM-PC/XT   PERQ
IBM-360/67  IBM-370/145
  • OS - A character string which specifies the operating system type. The character string is represented as a single octet length followed by that number of characters. The following standard types are defined:
ASP         AUGUST      BKY         CCP
DOS/360     ELF         EPOS        EXEC-8
GCOS        GPOS        ITS         INTERCOM
KRONOS      MCP         MOS         MPX-RT
MULTICS     MVT         NOS         NOS/BE
OS/MVS      OS/MVT      RIG         RSX11
RSX11M      RT11        SCOPE       SIGNAL
SINTRAN     TENEX       TOPS10      TOPS20
TSS         UNIX        VM/370      VM/CMS
VMS         WAITS

HINFO records cause no additional section processing.

HINFO records are used to acquire general information about a host. The main use is for protocols such as FTP that can use special procedures when talking between machines or operating systems of the same type. this is so cute, two machines that match can just skip the awkward small talk ๐Ÿงš

MB RDATA format ๐Ÿ“ฌ

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                   MADNAME                     /
       /                                               /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

  • MADNAME - A compressed domain name which specifies a host which has the specified mailbox. ๐Ÿ 

MB records cause additional section processing which looks up an A type record corresponding to MADNAME. The RDATA section of a MB line in a master file is a standard printed domain name.

MD RDATA format ๐Ÿ“จ

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                   MADNAME                     /
       /                                               /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

  • MADNAME - A compressed domain name which specifies a host which has a mail agent for the domain which should be able to deliver mail for the domain. the delivery girlie of the group ๐Ÿšš

MD records cause additional section processing which looks up an A type record corresponding to MADNAME. The RDATA section of a MD line in a master file is a standard printed domain name.

MF RDATA format ๐Ÿ“ฎ

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                   MADNAME                     /
       /                                               /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

  • MADNAME - A compressed domain name which specifies a host which has a mail agent for the domain which will accept mail for forwarding to the domain. the forwarding bestie ๐Ÿฆ‹

MF records cause additional section processing which looks up an A type record corresponding to MADNAME. The RDATA section of a MF line in a master file is a standard printed domain name.

MG RDATA format ๐Ÿ‘ฏ

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                   MGMNAME                     /
       /                                               /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

  • MGMNAME - A compressed domain name which specifies a mailbox which is a member of the mail group specified by the domain name. the group chat member, basically ๐Ÿ’œ

MF records cause no additional section processing. The RDATA section of a MF line in a master file is a standard printed domain name.

MINFO RDATA format ๐Ÿ“‹

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                    RMAILBX                    /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                    EMAILBX                    /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

  • RMAILBX - A compressed domain name which specifies a mailbox which is responsible for the mailing list or mailbox. If this domain name names the root, the owner of the MINFO RR is responsible for itself. Note that many existing mailing lists use a mailbox X-request for the RMAILBX field of mailing list X, e.g. Msgroup-request for Msgroup. This field provides a more general mechanism. ok the "X-request" thing is so iconic, that's the mailing list hall of fame ๐ŸŽ€
  • EMAILBX - A compressed domain name which specifies a mailbox which is to receive error messages related to the mailing list or mailbox specified by the owner of the MINFO RR (similar to the ERRORS-TO: field which has been proposed). If this domain name names the root, errors should be returned to the sender of the message. ๐Ÿ™ˆ

MINFO records cause no additional section processing. Although these records can be associated with a simple mailbox, they are usually used with a mailing list. The MINFO section of a MF line in a master file is a standard printed domain name.

MR RDATA format ๐Ÿฆ‹

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                   NEWNAME                     /
       /                                               /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

  • NEWNAME - A compressed domain name which specifies a mailbox which is the proper rename of the specified mailbox. the glow-up-but-make-it-email name change ๐ŸŒˆ

MR records cause no additional section processing. The RDATA section of a MR line in a master file is a standard printed domain name.

NULL RDATA format ๐ŸŒ€

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                  <anything>                   /
       /                                               /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Anything at all may be in the RDATA field so long as it is 65535 octets or less. no rules, just vibes (up to a limit) ๐Ÿซ 

NULL records cause no additional section processing. NULL RRs are not allowed in master files.

NULL RRs are not allowed in master files. not in my zone file, not ever ๐Ÿšซ

NS RDATA format ๐Ÿฐ

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                   NSDNAME                     /
       /                                               /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

  • NSDNAME - A compressed domain name which specifies a host which has a name server for the domain. the house that holds the domain's records ๐Ÿก

NS records cause both the usual additional section processing to locate a type A record, and a special search of the zone in which they reside. The RDATA section of a NS line in a master file is a standard printed domain name.

PTR RDATA format ๐Ÿ”ฎ

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                   PTRDNAME                    /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

๐Ÿ’– okay so the PTR record's data is a PTRDNAME, which is a compressed domain name that points to some location in the domain name space ๐Ÿงš

PTR records cause no additional section processing ๐Ÿ™ˆ They're used in special domains to point to some other location in the domain space. They're just simple data, so they don't trigger any special processing like CNAME does for aliases ๐Ÿ’… For the ARPA Internet address domain and how these records get used there, check out Appendix 3 ๐ŸŒธ

SOA RDATA format โœจ

Here's the layout of an SOA's RDATA section, bestie ๐ŸŽ€

     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     /                     MNAME                     /
     /                                               /
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     /                     RNAME                     /
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    SERIAL                     |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    REFRESH                    |
     |                                               |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                     RETRY                     |
     |                                               |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    EXPIRE                     |
     |                                               |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    MINIMUM                    |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Here's what each field means ๐Ÿ‘‘

  • MNAME ๐Ÿ”ฅ is the domain name of the name server that was the original source of data for this zone.
  • RNAME ๐Ÿ’œ is a domain name that specifies the mailbox of the person responsible for this zone.
  • SERIAL ๐Ÿฆ‹ is the unsigned 16 bit version number of the original copy of the zone. It wraps around, so you should compare it using sequence space arithmetic.
  • REFRESH ๐ŸŒˆ is the unsigned 32 bit time interval before the zone should be refreshed.
  • RETRY ๐Ÿ“ is the unsigned 32 bit time interval that should pass before a failed refresh gets retried.
  • EXPIRE โญ is a 32 bit time value that sets the upper limit on how long the zone can go without being refreshed before it stops being authoritative.
  • MINIMUM ๐Ÿซถ is the unsigned 16 bit minimum TTL field that should be exported with any RR from this zone (except the SOA itself).

SOA records cause no additional section processing either ๐Ÿ’… In a master file, the RDATA section of an SOA line is a standard printed domain name for MNAME, a standard X@Y mailbox specification for RNAME, and decimal numbers for the remaining parameters. All times are in seconds โฑ๏ธ

Most of these fields only matter for name server maintenance operations ๐Ÿ™ˆ But MINIMUM shows up in every query that pulls RRs from a zone. Whenever an RR goes out in a response, its TTL gets set to the maximum of its own TTL and the MINIMUM field in the appropriate SOA. So MINIMUM is a lower bound on the TTL for every RR in a zone โœจ Also, RRs in a zone are never thrown away because of a timeout unless the whole zone gets deleted. That's what keeps partial copies of zones from showing up, and honestly iconic of it ๐Ÿ˜ญ๐Ÿซถ

Appendix 3 - Internet specific field formats and operations โœจ

Message transport ๐Ÿ“ฌ

okay so the Internet talks to name servers over TCP [10] on server port 53 (decimal) ๐Ÿ’…, and it also uses UDP [11] on UDP port 53 (decimal) for datagram access ๐Ÿฆ‹. Messages sent over TCP virtual circuits get an unsigned 16 bit length field in front of them ๐ŸŽ€. That length field tells you how long the message is, and it doesn't count itself ๐Ÿซถ.

Heads up, this part is giving very "not final yet" energy ๐Ÿ™ˆ:

    +-----------------------------------------------+
    |                                               |
    |             *****  WARNING  *****             |
    |                                               |
    |  The following formats are preliminary and    |
    | are included for purposes of explanation only.|
    | In particular, new RR types will be added,    |
    | and the size, position, and encoding of       |
    | fields are subject to change.                 |
    |                                               |
    +-----------------------------------------------+

A RDATA format ๐ŸŒธ

the A record is literally just an address ๐Ÿ˜ญ. Its RDATA is one 32 bit ARPA internet address โœจ.

    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ADDRESS                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

ADDRESS is a 32 bit ARPA internet address.

If a host has more than one ARPA Internet address, it gets more than one A record ๐Ÿ“.

A records cause no additional section processing ๐Ÿ’œ. In a master file, the RDATA section of an A line is an Internet address written as four decimal numbers separated by dots, with no spaces hiding in there ๐Ÿ”ฅ. Examples: "10.2.0.52" or "192.0.5.6".

WKS RDATA format ๐Ÿฆ‹

this one is the well known services record, and it's kinda iconic ๐Ÿ‘‘.

    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ADDRESS                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |       PROTOCOL        |                       |
    +--+--+--+--+--+--+--+--+                       |
    |                                               |
    /                   <BIT MAP>                   /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

ADDRESS is a 32 bit ARPA Internet address.

PROTOCOL is an 8 bit IP protocol number.

<BIT MAP> is a variable length bit map. The bit map must be a multiple of 8 bits long ๐Ÿ™ˆ.

The WKS record describes the well known services that a particular protocol supports on a particular internet address ๐Ÿงš. The PROTOCOL field names an IP protocol number, and the bit map has one bit for each port of that protocol. The first bit is port 0, the second is port 1, and so on ๐Ÿ’–. If there are fewer than 256 bits, the rest are assumed to be zero. The right values for ports and protocols are listed in [13] โœจ.

For example, if PROTOCOL=TCP (6), the 26th bit is TCP port 25 (SMTP) ๐Ÿ“ฌ. If that bit is set, an SMTP server should be listening on TCP port 25 ๐Ÿซถ. If it's zero, SMTP isn't supported on that address ๐Ÿ’€.

WKS RRs are meant to tell you which servers are available over TCP and UDP ๐Ÿ’…. If a server handles both TCP and UDP, or has multiple Internet addresses, you use multiple WKS RRs ๐ŸŒˆ.

WKS RRs cause no additional section processing too ๐Ÿ’œ. The RDATA section of a WKS record is a decimal protocol number, followed by mnemonic identifiers that name the bits to set to 1 ๐Ÿ“.

IN-ADDR special domain ๐Ÿ—บ๏ธ

the ARPA internet has a special domain for two things: finding gateways on a network, and mapping an ARPA Internet address back to a host name ๐Ÿ˜ญ. The goal is that you can ask for all the gateways on one network, and you always have a guaranteed way to go from host address to host name ๐Ÿ’–.

These two services are similar to what inverse queries can do โœจ. The difference is that this part of the domain name space is organised by address, so the right data can be found without searching the whole domain space ๐Ÿ”ฅ. The plan is that ARPA Internet resolvers will use this special tree for all gateway location services ๐Ÿงš. For address to name lookups, the resolver first tries an inverse query on the local name server database, and if that fails it queries the special space ๐Ÿฆ‹.

The domain is a top level domain called IN-ADDR, and its substructure follows the ARPA Internet addressing structure ๐Ÿ‘‘.

Domain names in the IN-ADDR domain can have up to four labels, on top of the IN-ADDR label ๐ŸŽ€. Each label is a character string that expresses a decimal value from 0 to 255. Leading zeros are left out, except for a zero octet, which is written as a single zero ๐Ÿ’…. These labels line up with the 4 octets of an ARPA Internet address ๐Ÿ’œ.

Host addresses are domain names with all four labels filled in ๐ŸŒธ. So the data for ARPA Internet address 10.2.0.52 lives at the domain name 52.0.2.10.IN-ADDR ๐Ÿ’–. Reversing the order is a bit awkward to read, but it lets zones follow the natural grouping of hosts in networks ๐Ÿซถ. For example, 10.IN-ADDR can be a zone with data for the ARPANET, and 26.IN-ADDR can be its own zone for MILNET ๐ŸŒˆ. Address nodes hold pointers to primary host names in the normal domain space ๐Ÿ“.

Network addresses match some of the non-terminal nodes in the IN-ADDR tree, since ARPA Internet network numbers are 1, 2, or 3 octets long ๐Ÿงš. Network nodes hold pointers to primary host names in the normal domain space, and those hosts happen to be gateways ๐Ÿฆ‹. A gateway is on more than one network by definition, so it usually has two or more network nodes pointing at it ๐Ÿ”ฅ. Gateways also get host level pointers at their fully qualified addresses โœจ.

Both the gateway pointers at network nodes and the normal host pointers at full address nodes use the PTR RR to point back to the primary domain names of the matching hosts ๐Ÿ’….

Here's an example ๐ŸŽ€. Part of the IN-ADDR domain has info about the ISI to MILNET and MIT gateways, and about the hosts F.ISI.ARPA and MULTICS.MIT.ARPA ๐Ÿ˜ญ. The ISI gateway has addresses 10.2.0.22 and 26.0.0.103, and its name is MILNET-GW.ISI.ARPA. The MIT gateway has addresses 10.0.0.77 and 18.10.0.4, and its name is GW.MIT.ARPA. So the domain database would contain:

    10.IN-ADDR           PTR  IN MILNET-GW.ISI.ARPA
    10.IN-ADDR           PTR  IN GW.MIT.ARPA
    18.IN-ADDR           PTR  IN GW.MIT.ARPA
    26.IN-ADDR           PTR  IN MILNET-GW.ISI.ARPA
    22.0.2.10.IN-ADDR    PTR  IN MILNET-GW.ISI.ARPA
    103.0.0.26.IN-ADDR   PTR  IN MILNET-GW.ISI.ARPA
    77.0.0.10.IN-ADDR    PTR  IN GW.MIT.ARPA
    4.0.10.18.IN-ADDR    PTR  IN GW.MIT.ARPA
    52.0.2.10.IN-ADDR    PTR  IN F.ISI.ARPA
    6.0.0.10.IN-ADDR     PTR  IN MULTICS.MIT.ARPA

So if a program wants to find the gateways on net 10, it sends a query with QTYPE=PTR, QCLASS=IN, and QNAME=10.IN-ADDR ๐Ÿงš. It gets back two RRs:

    10.IN-ADDR           PTR  IN MILNET-GW.ISI.ARPA
    10.IN-ADDR           PTR  IN GW.MIT.ARPA

After that, the program can send QTYPE=A, QCLASS=IN queries for MILNET-GW.ISI.ARPA and GW.MIT.ARPA to find those gateways' ARPA Internet addresses ๐Ÿฆ‹.

Now say a resolver wants the host name for ARPA Internet host address 10.0.0.6 ๐ŸŒธ. It might first try an inverse query on the local name server, but that info isn't there ๐Ÿ˜ญ. Then it can query with QTYPE=PTR, QCLASS=IN, and QNAME=6.0.0.10.IN-ADDR, and it gets back:

    6.0.0.10.IN-ADDR     PTR  IN MULTICS.MIT.ARPA

A few cautions apply when you use these services ๐Ÿ™ˆ:

  • Because the IN-ADDR special domain and the normal domain for a particular host or gateway live in different zones, the data might not match up ๐Ÿ’€.
  • Gateways often have two names in separate domains, and only one of them can be primary ๐Ÿซ .
  • Systems that use the domain database to set up their routing tables have to start with enough gateway information to be sure they can reach the right name server ๐Ÿšจ.
  • Gateway data only shows that a gateway exists, in the same way the current HOSTS.TXT file does. It doesn't replace the dynamic availability info from GGP or EGP ๐Ÿ’….

REFERENCES and BIBLIOGRAPHY ๐Ÿ“š

[1] E. Feinler, K. Harrenstien, Z. Su, and V. White, "DOD Internet Host Table Specification", RFC 810, Network Information Center, SRI International, March 1982.

[2] J. Postel, "Computer Mail Meeting Notes", RFC 805, USC/Information Sciences Institute, February 1982.

[3] Z. Su, and J. Postel, "The Domain Naming Convention for Internet User Applications", RFC 819, Network Information Center, SRI International, August 1982.

[4] Z. Su, "A Distributed System for Internet Name Service", RFC 830, Network Information Center, SRI International, October 1982.

[5] K. Harrenstien, and V. White, "NICNAME/WHOIS", RFC 812, Network Information Center, SRI International, March 1982.

[6] M. Solomon, L. Landweber, and D. Neuhengen, "The CSNET Name Server", Computer Networks, vol 6, nr 3, July 1982.

[7] K. Harrenstien, "NAME/FINGER", RFC 742, Network Information Center, SRI International, December 1977.

[8] J. Postel, "Internet Name Server", IEN 116, USC/Information Sciences Institute, August 1979.

[9] K. Harrenstien, V. White, and E. Feinler, "Hostnames Server", RFC 811, Network Information Center, SRI International, March 1982.

[10] J. Postel, "Transmission Control Protocol", RFC 793, USC/Information Sciences Institute, September 1981.

[11] J. Postel, "User Datagram Protocol", RFC 768, USC/Information Sciences Institute, August 1980.

[12] J. Postel, "Simple Mail Transfer Protocol", RFC 821, USC/Information Sciences Institute, August 1980.

[13] J. Reynolds, and J. Postel, "Assigned Numbers", RFC 870, USC/Information Sciences Institute, October 1983.

[14] P. Mockapetris, "Domain names - Concepts and Facilities," RFC 882, USC/Information Sciences Institute, November 1983.

Index โœจ

  • usage ........ 37, 57
  • A RDATA format ........ 67
  • byte order ........ 6
  • cache queue ........ 35, 42
  • character case ........ 7, 31
  • CLASS ........ 9, 58
  • completion ........ 19
  • compression ........ 31
  • CNAME RR ........ 60
  • header format ........ 26
  • HINFO RR ........ 60
  • include files ........ 43
  • inverse queries ........ 17
  • mailbox names ........ 53
  • master files ........ 43
  • MB RR ........ 61
  • MD RR ........ 61
  • message format ........ 13
  • MF RR ........ 62
  • MG RR ........ 62
  • MINFO RR ........ 63
  • MR RR ........ 63
  • NULL RR ........ 64
  • NS RR ........ 64
  • PTR RR ........ 64, 69
  • QCLASS ........ 58
  • QTYPE ........ 57
  • queries (standard) ........ 15
  • recursive service ........ 24
  • RR format ........ 59
  • SOA RR ........ 65
  • Special domains ........ 68
  • TYPE ........ 57
  • WKS type RR ........ 68

๐ŸŽ€ And that's the whole index, bestie! ๐Ÿ’– Every term, every page number, all lined up and ready for you to flip to. You did it, we did it, it's a whole vibe ๐Ÿฆ‹๐Ÿ’…

๐Ÿ“ฆ where this page comes from