RFC 1034

Domain names - concepts and facilities

๐Ÿ“… published November 1987, from ietf

1. STATUS OF THIS MEMO โœจ

Okay bestie, this one is an intro to the Domain Name System (DNS) ๐ŸŒธ. It skips a bunch of nitty-gritty stuff, which lives in a companion RFC called "Domain Names - Implementation and Specification" [RFC-1035]. That companion assumes you already get the concepts in this memo, so this is the one to read first ๐Ÿซถ

Here's the vibe: a subset of DNS functions and data types is the official protocol ๐Ÿ‘‘ That includes standard queries, their responses, and most of the Internet class data formats (think host addresses).

BUT the domain system is intentionally extensible ๐Ÿฆ‹ Researchers are always cooking up new data types, query types, classes, functions, and so on. So the official parts are expected to stay basically the same and run as a production service, while anything beyond the official protocol should be treated as experimental ๐Ÿงช Experimental or obsolete features get clearly marked in these RFCs, and you should use that info with caution โš ๏ธ

Don't depend on the values in the examples being current or complete. They're there to teach, not to be copy-pasted into your life ๐Ÿ’€

Distribution of this memo is unlimited ๐ŸŽ€

2. INTRODUCTION ๐ŸŒˆ

This RFC introduces domain-style names, how they're used for Internet mail and host address support, and the protocols and servers that make domain name facilities work ๐Ÿ’–

2.1. The history of domain names ๐Ÿ•ฐ๏ธ

So why did we even need domains? Because the Internet was growing like crazy ๐Ÿ“ˆ

  • Host name to address mappings were kept by the Network Information Center (NIC) in one single file, HOSTS.TXT, which every host FTPed down [RFC-952, RFC-953]. Shipping a new version around this way eats total network bandwidth in proportion to the square of the number of hosts ๐Ÿ˜ญ Even with multiple levels of FTP, the outgoing FTP load on the NIC host is still huge. Explosive host growth was not looking good for the future ๐Ÿ’€
  • The network crowd was changing too ๐Ÿ–ฅ๏ธ The timeshared hosts of the original ARPANET were being swapped out for local networks of workstations. Local orgs were managing their own names and addresses, but they had to wait for the NIC to edit HOSTS.TXT before anyone else on the Internet could see the changes. Orgs also wanted some local structure in the name space ๐Ÿงฉ
  • Applications were getting more sophisticated, which meant the Internet needed a general purpose name service ๐Ÿš€

The result was a bunch of ideas about name spaces and how to manage them [IEN-116, RFC-799, RFC-819, RFC-830]. They differed, but the shared main idea was a hierarchical name space, roughly matching organizational structure, with names using . to mark the boundary between levels ๐ŸŒณ A design built on a distributed database and generalized resources was described in [RFC-882, RFC-883]. After lots of hands-on experience with implementations, the system evolved into the scheme in this memo ๐Ÿ“

The words "domain" and "domain name" get used in plenty of contexts beyond the DNS described here. Lowkey, "domain name" often just means a name with dots in it and zero connection to the DNS, which is especially true in mail addressing [Quarterman 86] ๐Ÿ™ˆ

2.2. DNS design goals ๐ŸŽฏ

The DNS design goals shape its structure, and they are:

  • The primary goal is a consistent name space for referring to resources. To avoid the mess caused by ad hoc encodings, names should not have to contain network identifiers, addresses, routes, or similar info as part of the name ๐Ÿ’…
  • The sheer size of the database and how often it updates mean it has to be maintained in a distributed way, with local caching for speed โšก Approaches that try to collect one consistent copy of the whole database get more expensive and difficult over time, so they should be avoided ๐Ÿ™…โ€โ™€๏ธ The same goes for the structure of the name space, especially the mechanisms for creating and deleting names. Those should be distributed too ๐ŸŒ
  • When there are tradeoffs between the cost of acquiring data, the speed of updates, and the accuracy of caches, the source of the data should be the one in control of that tradeoff ๐ŸŽ›๏ธ
  • The costs of building this facility mean it has to be generally useful and not limited to one application ๐Ÿ› ๏ธ We should be able to use names to get host addresses, mailbox data, and other information nobody has even thought of yet ๐Ÿ”ฎ All data tied to a name is tagged with a type, and queries can be limited to a single type ๐Ÿท๏ธ
  • Because we want the name space to be useful across different networks and applications, we give you the ability to use the same name space with different protocol families or management setups ๐ŸŒ For example, host address formats differ between protocols, even though every protocol has the notion of an address. The DNS tags all data with a class as well as a type, so different address formats can be used in parallel ๐Ÿง 
  • We want name server transactions to be independent of the communications system carrying them ๐Ÿ“ก Some systems may use datagrams for queries and responses, and only set up virtual circuits for transactions that need the reliability (like database updates or long transactions). Other systems will use virtual circuits exclusively ๐Ÿฆ‹
  • The system should be useful across a wide spectrum of host capabilities ๐Ÿ–ฅ๏ธ๐Ÿ“ฑ Both personal computers and large timeshared hosts should be able to use it, though maybe in different ways ๐Ÿ‘‘

2.3. Assumptions about usage ๐Ÿง

The domain system is organized the way it is because of assumptions about what its users need and how they use it. It's designed to dodge a lot of the complicated problems you'd find in general purpose database systems ๐Ÿ™Œ

The assumptions are:

  • The size of the total database starts out proportional to the number of hosts using the system. Eventually it grows to be proportional to the number of users on those hosts, once mailboxes and other info get added to the domain system ๐Ÿ“ฌ
  • Most of the data in the system changes very slowly (think mailbox bindings and host addresses), but the system should be able to handle subsets that change more rapidly, on the order of seconds or minutes โฑ๏ธ
  • Administrative boundaries, which are used to spread out responsibility for the database, will usually line up with organizations that have one or more hosts ๐Ÿข Each organization responsible for a particular set of domains will provide redundant name servers, either on its own hosts or on other hosts it arranges to use ๐Ÿซ‚
  • Clients of the domain system should be able to identify the trusted name servers they prefer to use before accepting referrals to name servers outside of that trusted set ๐Ÿ”
  • Access to information matters more than instant updates or guarantees of consistency ๐Ÿ’œ So the update process lets updates percolate out through the users of the domain system, instead of guaranteeing that all copies get updated at the same moment ๐ŸŒŠ When updates can't happen because of network or host failure, the usual move is to keep believing the old info while still trying to update it ๐Ÿ” The general model is that copies get distributed with timeouts for refreshing. The distributor sets the timeout value, and the recipient of the distribution is responsible for doing the refresh โณ In special situations, very short intervals can be specified, or the owner can prohibit copies altogether ๐Ÿšซ
  • In any system with a distributed database, a particular name server may get a query that only some other server can answer ๐Ÿคทโ€โ™€๏ธ There are two general ways to deal with this. "Recursive" means the first server chases the query for the client at another server. "Iterative" means the server refers the client to another server and lets the client chase the query itself ๐Ÿƒโ€โ™€๏ธ Both have pros and cons, but the iterative approach is preferred for the datagram style of access ๐Ÿ“จ The domain system requires implementation of the iterative approach, and allows the recursive approach as an option ๐ŸŽ€

The domain system assumes all data originates in master files scattered across the hosts that use the domain system ๐Ÿ“‚ Those master files get updated by local system administrators. They're text files that are read by a local name server, which is how they become available through the name servers to users of the domain system ๐Ÿ’ป User programs reach name servers through standard programs called resolvers ๐Ÿงš

The standard format of master files lets them get exchanged between hosts (via FTP, mail, or some other mechanism) ๐Ÿ“ค This is super handy when an organization wants a domain but doesn't want to run a name server. The org can keep its master files locally in a text editor, transfer them to a foreign host that runs a name server, and then arrange with that server's system administrator to get the files loaded ๐Ÿฅฐ

Each host's name servers and resolvers get configured by a local system administrator [RFC-1033] ๐Ÿ› ๏ธ For a name server, that config includes the identity of local master files and instructions on which non-local master files should be loaded from foreign servers. The name server uses the master files or copies to load its zones ๐Ÿ—‚๏ธ For resolvers, the config identifies the name servers that should be the primary sources of information ๐Ÿฅ‡

The domain system defines procedures for accessing data and for referrals to other name servers. It also defines procedures for caching retrieved data and for periodically refreshing data that the system administrator defined ๐Ÿ”„

The system administrators provide:

  • The definition of zone boundaries.
  • Master files of data.
  • Updates to master files.
  • Statements of the refresh policies desired.

The domain system provides:

  • Standard formats for resource data.
  • Standard methods for querying the database.
  • Standard methods for name servers to refresh local data from foreign name servers.

2.4. Elements of the DNS ๐Ÿงฑ

Part 2 is coming up next, so stay tuned ๐Ÿ’–

2.4. Elements of the DNS โœจ

okay bestie, the DNS has three major components ๐Ÿงš and they all work together like a squad:

  • The DOMAIN NAME SPACE and RESOURCE RECORDS ๐ŸŒณ are the specs for a tree-shaped name space plus the data attached to those names. Every node and leaf in the tree names a set of information, and a query is basically asking for a specific type of info from one particular set. You say which domain name you want and what kind of resource info you're after. For example, the Internet uses some domain names to identify hosts, so address queries return Internet host addresses ๐Ÿ’–
  • NAME SERVERS ๐Ÿ  are server programs that hold info about the tree's structure and its sets of data. A name server can cache structure or set info about any part of the tree, but usually a given name server has complete info about one subset of the name space, plus pointers to other name servers that can lead you to info from any other part of the tree. Name servers know which parts they have complete info for, and a name server is said to be an AUTHORITY for those parts ๐Ÿ‘‘ The authoritative info is grouped into units called ZONEs, and those zones can be automatically distributed to the name servers that provide redundant service for the zone's data ๐Ÿซถ
  • RESOLVERS ๐Ÿ” are programs that pull info out of name servers when clients ask for it. A resolver has to be able to reach at least one name server, and it can either use that server's info to answer the query directly, or chase the query through referrals to other name servers. A resolver is usually a system routine that user programs can call directly, so there's no protocol needed between the resolver and the user program ๐Ÿ’…

These three components roughly line up with the three layers or views of the domain system, and honestly this part is so satisfying ๐Ÿฆ‹

  • From the user's point of view, the domain system is reached through a simple procedure or OS call to a local resolver. The domain space is one single tree, and the user can ask for info from any section of it โœจ
  • From the resolver's point of view, the domain system is made up of an unknown number of name servers. Each name server holds one or more pieces of the whole tree's data, but the resolver treats each of those databases as essentially static ๐ŸงŠ
  • From a name server's point of view, the domain system is separate sets of local info called zones. The name server has local copies of some of those zones. It has to refresh its zones periodically from master copies, either in local files or on foreign name servers, and it has to handle queries from resolvers at the same time ๐Ÿ”„

For performance, implementations are allowed to couple these functions together ๐Ÿš€ For example, a resolver on the same machine as a name server might share one database that holds both the zones the name server manages and the cache the resolver manages. Lowkey genius.


3. DOMAIN NAME SPACE and RESOURCE RECORDS ๐ŸŽ€

3.1. Name space specifications and terminology

Okay so the domain name space is a tree structure ๐ŸŒฒ Every node and every leaf on the tree corresponds to a resource set, and that set might be empty, which is fine. The domain system doesn't care how you use interior nodes versus leaves, so this memo just says "node" to mean both ๐Ÿ’œ

Each node has a label that's zero to 63 octets long. Brother nodes can't share a label, but two nodes that aren't brothers can have the same label, which is very much allowed ๐Ÿ™ˆ There's one reserved label, and that's the null label (zero length), which is used for the root ๐Ÿ‘‘

The domain name of a node is the list of labels on the path from that node up to the root. By convention, you print or read those labels left to right, going from the most specific one (the lowest, farthest from the root) to the least specific one (the highest, closest to the root) ๐Ÿ“

Under the hood, programs that handle domain names should store them as sequences of labels, where each label is a length octet followed by an octet string. Since every domain name ends at the root (which has a null string for its label), you can use a length byte of zero to mark the end of a name ๐Ÿงš

Names can be stored in any case, but every present domain function compares names case-insensitively, assuming ASCII and a high order zero bit ๐ŸŒˆ This means you can create a node labeled "A" or a node labeled "a", but not both as brothers, and you can refer to either one using "a" or "A". When you receive a domain name or label, keep its case as it is. The reason for this design is that we might someday need full binary domain names for new services, and existing services wouldn't have to change ๐Ÿฆ‹

When a human types a domain name, the length of each label is dropped and the labels are separated by dots ("."). Since a complete domain name ends with the root label, the printed form ends in a dot. That's how we tell two kinds of strings apart ๐Ÿ‘€

  • A character string that represents a complete domain name is often called "absolute". For example, "poneria.ISI.EDU." ๐Ÿ’…
  • A character string that represents the starting labels of a domain name that's incomplete is often called "relative", and local software should finish it using knowledge of the local domain. For example, "poneria" used in the ISI.EDU domain ๐Ÿซถ

Relative names are taken relative to either a well known origin, or to a list of domains used as a search list. Relative names show up mostly at the user interface, where how they're interpreted varies from implementation to implementation, and in master files, where they're relative to a single origin domain name. The most common interpretation uses the root "." as either the single origin or as one member of the search list, so a multi-label relative name is often one where the trailing dot has been left off to save typing โŒจ๏ธ

To keep implementations simple, the total number of octets that represent a domain name (that's the sum of all label octets plus all label lengths) is limited to 255 ๐ŸŽฏ

A domain is identified by a domain name, and it's the part of the name space at or below that name. One domain is a subdomain of another if it's contained within it, and you can check this by seeing whether the subdomain's name ends with the containing domain's name. For example, A.B.C.D is a subdomain of B.C.D, C.D, D, and " " โœจ

3.2. Administrative guidelines on use

As a matter of policy, the DNS technical specs don't force a particular tree structure or rules for picking labels ๐Ÿ™Œ The goal is to be as general as possible so it can be used to build arbitrary applications. The system was designed so the name space didn't have to follow network boundaries, name servers, and so on. The reasoning isn't that the name space should have no implied meaning. It's that the choice of meaning should be left open for whatever problem you're solving, and different parts of the tree can have different meanings. For example, the IN-ADDR.ARPA domain is organized and distributed by network and host address because its job is translating network or host numbers into names, while NetBIOS domains [RFC-1001, RFC-1002] are flat because that's what suits that application ๐ŸŒธ

That said, there are some guidelines for the "normal" parts of the name space, the ones used for hosts, mailboxes, and so on. Following them makes the name space more uniform, leaves room for growth, and cuts down on problems when software is converted from the older host table ๐Ÿ“‹ The political decisions about the top levels of the tree started in RFC-920. Current policy for the top levels is discussed in [RFC-1032], and MILNET conversion issues are covered in [RFC-1031] ๐Ÿ—บ๏ธ

Lower domains that will eventually be split into multiple zones should provide branching at the top of the domain, so the eventual split can happen without renaming anything ๐ŸŒฟ Node labels that use special characters, leading digits, and similar things are likely to break older software that depends on more restrictive choices. โš ๏ธ

Heads up: special characters and leading digits in labels can break older software, so think before you get fancy ๐Ÿ’€

3.3. Technical guidelines on use

Before the DNS can hold naming info for some kind of object, two needs have to be met ๐Ÿงฉ

  • A convention for mapping between object names and domain names. This describes how info about an object is accessed.
  • RR types and data formats for describing the object.

These rules can be super simple or pretty complex ๐Ÿ’ซ Very often, the designer has to account for existing formats and plan for upward compatibility with existing usage. Multiple mappings, or levels of mapping, may be needed.

For hosts, the mapping depends on the existing syntax for host names, which is a subset of the usual text representation for domain names, along with RR formats for describing host addresses and so on. Because we need a reliable inverse mapping from address to host name, there's also a special mapping for addresses into the IN-ADDR.ARPA domain ๐Ÿ–ฅ๏ธ

For mailboxes, it gets a bit more involved ๐Ÿ“ฌ The usual mail address <local-part>@<mail-domain> is mapped into a domain name by three steps. First, <local-part> is converted into a single label, regardless of any dots it contains. Second, <mail-domain> is converted into a domain name using the usual text format for domain names, where dots mark label breaks. Third, the two are concatenated to form a single domain name. So the mailbox HOSTMASTER@SRI-NIC.ARPA is represented as the domain name HOSTMASTER.SRI-NIC.ARPA. To really get why this design makes sense, you also have to look at the scheme for mail exchanges [RFC-974] ๐Ÿ’Œ

Most users don't need to define these rules, but it helps to know they're usually the result of lots of compromises ๐Ÿค Compromises between upward compatibility with old usage, interactions between different object definitions, and the inevitable urge to add new features whenever rules get written. How the DNS gets used to support some object is often more crucial than the restrictions built into the DNS itself ๐Ÿซ 

3.4. Example name space

The figure below shows part of the current domain name space, and it's used in lots of examples in this RFC. Heads up, the tree is a super tiny subset of the actual name space ๐ŸŒธ

                                   |
                                   |
             +---------------------+------------------+
             |                     |                  |
            MIL                   EDU                ARPA
             |                     |                  |
             |                     |                  |
       +-----+-----+               |     +------+-----+-----+
       |     |     |               |     |      |           |
      BRL  NOSC  DARPA             |  IN-ADDR  SRI-NIC     ACC
                                   |
       +--------+------------------+---------------+--------+
       |        |                  |               |        |
      UCI      MIT                 |              UDEL     YALE
                |                 ISI
                |                  |
            +---+---+              |
            |       |              |
           LCS  ACHILLES  +--+-----+-----+--------+
            |             |  |     |     |        |
            XX            A  C   VAXA  VENERA Mockapetris

In this example, the root domain has three immediate subdomains: MIL,

EDU, and ARPA. ๐ŸŒธ The LCS.MIT.EDU domain has one immediate subdomain named XX.LCS.MIT.EDU. All of the leaves are also domains. ๐Ÿ“

3.5. Preferred name syntax โœจ

okay so the DNS specs are lowkey SO flexible about how you build a domain name ๐Ÿ’… The whole point is that the name of basically any existing object can be turned into a domain name with minimal changes. BUT when you're actually picking a name for something, the prudent user picks one that works with BOTH the rules of the domain system AND any existing rules for that object, whether those rules are written down or just implied by existing programs ๐ŸŽ€

For example, when you're naming a mail domain, you should satisfy both the rules of this memo and the ones in RFC-822. When you create a new host name, the old HOSTS.TXT rules should be followed. This avoids problems when old software gets converted to use domain names ๐Ÿซถ

The following syntax will result in fewer problems with lots of applications that use domain names (mail, TELNET, etc.) ๐Ÿฆ‹

<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

Note that while upper and lower case letters are allowed in domain names, case doesn't matter ๐Ÿ™ˆ Two names with the same spelling but different case are to be treated as if they're identical.

The labels must 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 restrictions on length: labels must be 63 characters or less ๐Ÿ’œ

For example, these strings identify hosts on the Internet:

A.ISI.EDU  XX.LCS.MIT.EDU  SRI-NIC.ARPA

3.6. Resource Records ๐Ÿงš

A domain name identifies a node. Each node has a set of resource information, which may be empty. That set is made up of separate resource records (RRs). The order of RRs in a set is not significant, and name servers, resolvers, and other parts of the DNS don't need to preserve it โœจ

When we talk about a specific RR, we assume it has the following parts:

  • owner: the domain name where the RR is found.
  • type: an encoded 16 bit value that specifies the type of the resource in this RR. Types refer to abstract resources. This memo uses these types:
    • A: a host address
    • CNAME: identifies the canonical name of an alias
    • HINFO: identifies the CPU and OS used by a host
    • MX: identifies a mail exchange for the domain. See [RFC-974 for details.
    • NS: the authoritative name server for the domain
    • PTR: a pointer to another part of the domain name space
    • SOA: identifies the start of a zone of authority]
  • class: an encoded 16 bit value that identifies a protocol family or instance of a protocol. This memo uses these classes:
    • IN: the Internet system
    • CH: the Chaos system
  • TTL: the time to live of the RR. This field is a 32 bit integer in units of seconds, and it's mainly used by resolvers when they cache RRs. The TTL describes how long an RR can be cached before it should be discarded ๐Ÿ•ฐ๏ธ
  • RDATA: the type and sometimes class dependent data that describes the resource:
    • A: for the IN class, a 32 bit IP address. For the CH class, a domain name followed by a 16 bit octal Chaos address.
    • CNAME: a domain name.
    • MX: a 16 bit preference value (lower is better) followed by a host name willing to act as a mail exchange for the owner domain.
    • NS: a host name.
    • PTR: a domain name.
    • SOA: several fields.

The owner name is often implicit rather than an integral part of the RR. For example, many name servers internally form tree or hash structures for the name space, and chain RRs off nodes. The rest of the RR is the fixed header (type, class, TTL), which is consistent for all RRs, plus a variable part (RDATA) that fits the needs of the resource being described ๐Ÿ’…

Now the TTL. It's a time limit on how long an RR can be kept in a cache. This limit does NOT apply to authoritative data in zones, which also times out but is governed by the refreshing policies for the zone instead. The TTL is assigned by the administrator for the zone where the data originates. Short TTLs can be used to minimize caching, and a zero TTL prohibits caching, but the realities of Internet performance suggest these times should be on the order of days for the typical host ๐ŸŒˆ If a change can be anticipated, the TTL can be reduced before the change to minimize inconsistency during it, and then increased back to its former value afterward โญ

The data in the RDATA section of RRs is carried as a combination of binary strings and domain names. Domain names are frequently used as "pointers" to other data in the DNS ๐Ÿ”ฅ

3.6.1. Textual expression of RRs ๐ŸŽ€

RRs are represented in binary form in the packets of the DNS protocol, and they're usually shown in a highly encoded form when stored in a name server or resolver. In this memo, we use a style similar to the one used in master files to show the contents of RRs. In this format most RRs are shown on a single line, although continuation lines are possible using parentheses ๐Ÿฆ‹

The start of the line gives the owner of the RR. If a line begins with a blank, the owner is assumed to be the same as the previous RR's. Blank lines are often included for readability.

After the owner, we list the TTL, type, and class of the RR. Class and type use the mnemonics defined above, and TTL is an integer that comes before the type field. To avoid ambiguity in parsing, type and class mnemonics are disjoint, TTLs are integers, and the type mnemonic is always last. The IN class and TTL values are often omitted from examples for clarity ๐Ÿ“

The RDATA section of the RR is given using knowledge of the typical representation for the data.

For example, we might show the RRs carried in a message like this:

    ISI.EDU.        MX      10 VENERA.ISI.EDU.
                    MX      10 VAXA.ISI.EDU.
    VENERA.ISI.EDU. A       128.9.0.32
                    A       10.1.0.52
    VAXA.ISI.EDU.   A       10.2.0.27
                    A       128.9.0.33

The MX RRs have an RDATA section made of a 16 bit number followed by a domain name. The address RRs use a standard IP address format to hold a 32 bit internet address. This example shows six RRs, with two RRs at each of three domain names ๐Ÿ‘‘

Similarly, we might see:

    XX.LCS.MIT.EDU. IN      A       10.0.0.44
                    CH      A       MIT.EDU. 2420

This example shows two addresses for XX.LCS.MIT.EDU, each in a different class ๐Ÿซง

3.6.2. Aliases and canonical names ๐ŸŒท

In existing systems, hosts and other resources often have several names that identify the same resource. For example, C.ISI.EDU and USC-ISIC.ARPA both identify the same host. In the case of mailboxes, many organizations provide lots of names that actually go to the same mailbox. For example, Mockapetris@C.ISI.EDU, Mockapetris@B.ISI.EDU, and PVM@ISI.EDU all go to the same mailbox (though the mechanism behind this is somewhat complicated) ๐Ÿ™ƒ

Most of these systems have a notion that one name in the equivalent set is the canonical or primary name, and all the others are aliases.

The domain system provides this feature using the canonical name (CNAME) RR. A CNAME RR identifies its owner name as an alias, and specifies the corresponding canonical name in the RDATA section. If a CNAME RR is present at a node, no other data should be present. This makes sure the data for a canonical name and its aliases can't be different. It also insures that a cached CNAME can be used without checking with an authoritative server for other RR types ๐Ÿ’–

CNAME RRs cause special action in DNS software. When a name server fails to find a desired RR in the resource set for a domain name, it checks whether that set consists of a CNAME record with a matching class. If it does, the name server includes the CNAME record in the response and restarts the query at the domain name in the CNAME's data field. The one exception is that queries matching the CNAME type are not restarted ๐Ÿ˜ค

For example, suppose a name server was processing a query for USC-ISIC.ARPA asking for type A information, and it had these resource records:

    USC-ISIC.ARPA   IN      CNAME   C.ISI.EDU

    C.ISI.EDU       IN      A       10.0.0.52

Both of these RRs would be returned in the response to the type A query, while a type CNAME or * query should return just the CNAME ๐Ÿ’…

Domain names in RRs that point at another name should always point at the primary name and not the alias. This avoids extra indirections when accessing information. For example, the address-to-name RR for the host above should be:

    52.0.0.10.IN-ADDR.ARPA  IN      PTR     C.ISI.EDU

rather than pointing at USC-ISIC.ARPA. Of course, by the robustness principle, domain software should not fail when presented with CNAME chains or loops. CNAME chains should be followed, and CNAME loops should be signalled as an error ๐ŸŒˆ

3.7. Queries ๐Ÿ“ฌ

Queries are messages that may be sent to a name server to provoke a response. On the Internet, queries are carried in UDP datagrams or over TCP connections. The name server's response either answers the question posed in the query, refers the requester to another set of name servers, or signals some error condition ๐Ÿ’Œ

In general, the user doesn't generate queries directly. Instead, they make a request to a resolver, which in turn sends one or more queries to name servers and deals with any error conditions and referrals that may result. The kinds of questions a query can ask do shape the kind of service a resolver can provide ๐Ÿง 

DNS queries and responses are carried in a standard message format. The message format has a header containing a number of fixed fields that are always present, and four sections that carry query parameters and RRs โœจ

The most important field in the header is a four bit field called an opcode, which separates different queries. Of the possible 16 values, one (standard query) is part of the official protocol, two (inverse query and status query) are options, one (completion) is obsolete, and the rest are unassigned ๐Ÿฆ‹

Okay so the message has four sections and they each have a job ๐ŸŽ€

Question        Carries the query name and other query parameters.

Answer          Carries RRs which directly answer the query.

Authority       Carries RRs which describe other authoritative servers.
                May optionally carry the SOA RR for the authoritative
                data in the answer section.

Additional      Carries RRs which may be helpful in using the RRs in the
                other sections.

Bestie, the content of these sections changes depending on the header opcode, but the format stays the same ๐Ÿ’…

3.7.1. Standard queries ๐Ÿ’–

A standard query names a target domain name (QNAME), a query type (QTYPE), and a query class (QCLASS), and then asks for the RRs that match. This is the kind of query that makes up basically all DNS traffic, so whenever we just say "query," we mean standard query unless we say otherwise ๐Ÿ™ˆ Both the QTYPE and QCLASS fields are 16 bits long, and they're a superset of the defined types and classes. Iconic ๐Ÿ‘‘

The QTYPE field may contain:

<any type>      matches just that type. (e.g., A, PTR).

AXFR            special zone transfer QTYPE.

MAILB           matches all mail box related RRs (e.g. MB and MG).

*               matches all RR types.

The QCLASS field may contain:

<any class>     matches just that class (e.g., IN, CH).

*               matches aLL RR classes.

So the name server takes the query domain name, QTYPE, and QCLASS and goes hunting for matching RRs โœจ But it's not just about the records you asked for. The name server might also send back RRs that point toward a name server that has the info you want, or RRs that are likely to help you make sense of the relevant ones. For example, a name server that doesn't have the answer might know which name server does, and a name server that hands back a domain name in a relevant RR might also include the RR that ties that name to an address. Main character helper energy ๐Ÿงš

Here's a cute example. A mailer trying to send mail to Mockapetris@ISI.EDU might ask the resolver for mail info about ISI.EDU, which turns into a query for QNAME=ISI.EDU, QTYPE=MX, QCLASS=IN. The answer section would look like this:

    ISI.EDU.        MX      10 VENERA.ISI.EDU.
                    MX      10 VAXA.ISI.EDU.

and the additional section might look like this:

    VAXA.ISI.EDU.   A       10.2.0.27
                    A       128.9.0.33
    VENERA.ISI.EDU. A       10.1.0.52
                    A       128.9.0.32

Why include the addresses? Because the server figures that if you're asking for mail exchange info, you'll probably want the mail exchanges' addresses right after ๐Ÿซถ It's giving anticipating your needs.

Now, the QCLASS=* construct needs some special handling when it comes to authority ๐Ÿฅบ A particular name server might not know every class that exists in the domain system, so it can never be sure it's authoritative for all of them. Which means responses to QCLASS=* queries can never be authoritative ๐Ÿ’€

3.7.2. Inverse queries (Optional) ๐Ÿฆ‹

Name servers may also support inverse queries, which go the other way: they map a particular resource back to the domain name or names that have it. Like, a standard query might map a domain name to a SOA RR, and the matching inverse query would map that SOA RR back to the domain name ๐Ÿ”„

Supporting this is optional for a name server. Still, every name server must at least be able to understand an inverse query message and send back a not-implemented error response, no excuses ๐Ÿ™…โ€โ™€๏ธ

Bestie, the domain system can't guarantee that inverse queries are complete or unique. The whole system is organized by domain name, not by host address or any other resource type, so it's kind of a limitation ๐ŸŒธ Inverse queries are mostly useful for debugging and database maintenance.

Inverse queries may not return the proper TTL, and they don't tell you when the identified RR is one of a set (like one address out of several for a host with multiple addresses). So the RRs returned in inverse queries should never be cached ๐Ÿšซ

Inverse queries are NOT an acceptable method for mapping host addresses to host names. Use the IN-ADDR.ARPA domain instead. Don't be that person ๐Ÿ˜ญ

A detailed discussion of inverse queries is contained in [RFC-1035].

3.8. Status queries (Experimental) ๐Ÿงช

To be defined.

3.9. Completion queries (Obsolete) ๐Ÿชฆ

The optional completion services described in RFCs 882 and 883 have been deleted. Redesigned services may show up in the future, or the opcodes may be reclaimed for other use โœจ


4. NAME SERVERS ๐Ÿ 

4.1. Introduction ๐ŸŽ€

Name servers are the repositories of the information that makes up the domain database. The database is split into sections called zones, which get distributed across the name servers. Name servers can have several optional functions and sources of data, but their essential job is answering queries using the data in their zones. The design is pretty simple: a response can always be generated from local data alone, and it either contains the answer or a referral to other name servers that are "closer" to the info you want ๐Ÿ’…

A given zone is available from several name servers so it stays up even when a host or communication link fails. By administrative fiat, every zone must be available on at least two servers, and plenty of zones have even more redundancy than that ๐Ÿ›ก๏ธ

A given name server typically supports one or more zones. That gives it authoritative info about only a small section of the domain tree. It may also hold some cached non-authoritative data about other parts of the tree. The name server marks its responses so the requester can tell whether they came from authoritative data or not ๐Ÿ”–

4.2. How the database is divided into zones ๐Ÿฐ

The domain database gets partitioned in two ways: by class, and by "cuts" made in the name space between nodes ๐Ÿ”ช

The class partition is pretty straightforward. The database for any class is organized, delegated, and maintained separately from all the other classes. The name spaces are the same for all classes by convention, so you can picture the separate classes as an array of parallel namespace trees ๐ŸŒณ๐ŸŒณ Note that the data attached to nodes will be different across these parallel classes. The most common reasons to create a new class are needing a new data format for existing types, or wanting a separately managed version of the existing name space.

Within a class, "cuts" can be made between any two adjacent nodes in the name space. Once all the cuts are made, each group of connected name space is its own separate zone. The zone is said to be authoritative for all names in that connected region. The "cuts" might be in different places for different classes, and the name servers might be different too, etc. ๐Ÿ™ƒ

So every zone has at least one node, and therefore at least one domain name, that it's authoritative for, and all of the nodes in a zone are connected. Because of the tree structure, every zone has a highest node that's closer to the root than any other node in the zone. The name of that node is often used to identify the zone ๐Ÿท๏ธ

It would be possible to partition the name space so each domain name sits in its own zone, or so that all nodes live in a single zone. Not particularly useful though ๐Ÿ˜ด Instead, the database gets partitioned wherever a particular organization wants to take over control of a subtree. Once an organization controls its own zone, it can change the data in the zone whenever it wants, grow new tree sections connected to the zone, delete existing nodes, or delegate new subzones under its zone ๐Ÿ‘‘

If the organization has substructure, it might want more internal partitions to get nested delegations of name space control. Sometimes those divisions are made purely to make database maintenance more convenient ๐Ÿง

4.2.1. Technical considerations ๐Ÿ”ง

The data that describes a zone has four major parts:

  • Authoritative data for all nodes within the zone.
  • Data that defines the top node of the zone (can be thought of as part of the authoritative data).
  • Data that describes delegated subzones, i.e., cuts around the bottom of the zone.
  • Data that allows access to name servers for subzones (sometimes called "glue" data).

All of this data is expressed as RRs, so a zone can be completely described as a set of RRs. Whole zones can be transferred between name servers by moving the RRs, either in a series of messages or by FTPing a master file, which is a textual representation ๐Ÿ“ฆ

The authoritative data for a zone is basically all the RRs attached to all the nodes from the zone's top node down to the leaf nodes, or to nodes above the cuts around the bottom edge of the zone ๐ŸŒฟ

Even though they're logically part of the authoritative data, the RRs that describe the zone's top node are super important for managing the zone ๐Ÿฅน There are two types: name server RRs, which list (one per RR) all of the servers for the zone, and a single SOA RR that describes zone management parameters.

The RRs that describe cuts around the bottom of the zone are NS RRs that name the servers for the subzones. Since the cuts sit between nodes, these RRs are NOT part of the zone's authoritative data. They should be exactly the same as the corresponding RRs in the top node of the subzone. Name servers are always tied to zone boundaries, so NS RRs only show up at nodes that are the top node of some zone. In zone data, NS RRs appear at the top node of the zone (where they're authoritative) and at cuts around the bottom of the zone (where they're not authoritative), but never in between โœ‚๏ธ

One of the goals of the zone structure is that any zone has all the data it needs to set up communication with the name servers for its subzones. In other words, parent zones have everything they need to reach the servers for their child zones ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง The NS RRs that name subzone servers often aren't enough for this, because they name the servers but don't give their addresses. Things get really messy if the name of the name server is itself inside the subzone. Then the NS RRs tell you that to learn a name server's address, you should contact the server using the very address you're trying to learn ๐ŸŒ€ To fix this, a zone contains "glue" RRs. These aren't part of the authoritative data, and they're address RRs for the servers. Glue RRs are only necessary if the name server's name is "below" the cut, and they're only used as part of a referral response ๐Ÿงท

4.2.2. Administrative considerations ๐Ÿ“‹

When an organization wants to control its own domain, the first step is to identify the proper parent zone and get the parent zone's owners to agree to the delegation of control ๐Ÿค There are no particular technical constraints on where in the tree this can happen. Some administrative groupings discussed in [RFC-1032] deal with top level organization, and middle level zones are free to make their own rules. For example, one university might choose a single zone, while another might organize by subzones dedicated to individual departments or schools ๐ŸŽ“ [RFC-1033] catalogs available DNS software and discusses administration procedures.

Once the proper name for the new subzone is selected, the new owners should be required to demonstrate redundant name server support ๐Ÿ’ช Note that there is no requirement that the servers for a zone reside on a host that has a name in that domain. In many cases a zone will be more accessible to the internet at large if its servers are widely distributed, rather than sitting inside the physical facilities controlled by the same organization that manages the zone ๐ŸŒ For example, in the current DNS, one of the name servers for the United Kingdom, or UK domain, is found in the US. That lets US hosts get UK data without using limited transatlantic bandwidth ๐Ÿ‡ฌ๐Ÿ‡ง๐Ÿ‡บ๐Ÿ‡ธโœจ

As the last installation step, the delegation NS RRs and glue RRs

The stuff that makes a delegation actually work has to get added to the parent zone too ๐Ÿ’… And the admins on both sides of the cut need to keep their NS and glue RRs consistent with each other, forever, no exceptions ๐Ÿซถ

4.3. Name server internals ๐Ÿ”ฅ

4.3.1. Queries and responses โœจ

Name servers basically exist to answer standard queries ๐Ÿ’– Both the query and the response use a standard message format that's described in [RFC-1035]. The query carries a QTYPE, QCLASS, and QNAME, which tell you the types and classes of info you want and the name you're asking about.

How the server answers depends on whether it's in recursive mode or not ๐Ÿ‘€

  • The simplest mode for the server is non-recursive, since it can answer using only local info. The response is an error, the answer, or a referral to some other server "closer" to the answer. All name servers must implement non-recursive queries.
  • The simplest mode for the client is recursive, since the name server acts like a resolver and gives back either an error or the answer, never referrals. This service is optional for a name server, and the name server may also choose to limit which clients can use recursive mode.

Recursive service is seriously helpful in a few situations:

  • a simple requester that can only handle a direct answer to its question.
  • a request that needs to cross protocol or other boundaries and can be sent to a server that can act as an intermediary.
  • a network where you want to concentrate the cache, instead of having a separate cache for each client.

Non-recursive service is the move if the requester can chase referrals and is interested in info that'll help with future requests ๐Ÿฆ‹

Recursive mode is only used when both the client and the name server agree to it ๐Ÿค They negotiate using two bits in query and response messages:

  • The recursion available bit, or RA, is set or cleared by a name server in all responses. It's true if the name server is willing to provide recursive service for the client, whether or not the client asked for it. So RA signals availability, not use ๐ŸŒธ
  • Queries contain a bit called recursion desired, or RD. This bit specifies whether the requester wants recursive service for this query. Clients may request recursive service from any name server, but they should only depend on getting it from servers that have previously sent an RA, or from servers that agreed to provide service through private agreement or some other means outside of the DNS protocol ๐Ÿ’…

Recursive mode happens when a query with RD set arrives at a server that's willing to provide recursive service. The client can verify that recursive mode was used by checking that both RA and RD are set in the reply. Also, the name server should never perform recursive service unless it's asked via RD, since that interferes with troubleshooting name servers and their databases ๐Ÿ™ˆ

If recursive service is requested and available, the recursive response to a query will be one of the following:

  • The answer to the query, possibly prefaced by one or more CNAME RRs that specify aliases encountered on the way to an answer.
  • A name error indicating that the name does not exist. This may include CNAME RRs that indicate the original query name was an alias for a name that does not exist.
  • A temporary error indication.

If recursive service is not requested or is not available, the non-recursive response will be one of the following:

  • An authoritative name error indicating that the name does not exist.
  • A temporary error indication.
  • Some combination of:
    • RRs that answer the question, together with an indication of whether the data comes from a zone or is cached.
    • A referral to name servers that have zones which are closer ancestors to the name than the server sending the reply.
  • RRs that the name server thinks will prove useful to the requester ๐ŸŽ€

4.3.2. Algorithm ๐Ÿง 

The actual algorithm the name server uses depends on the local OS and the data structures used to store RRs. The following algorithm assumes the RRs are organized in several tree structures, one for each zone, and another for the cache ๐ŸŒณ

  1. Set or clear the value of recursion available in the response, depending on whether the name server is willing to provide recursive service. If recursive service is available and requested via the RD bit in the query, go to step 5, otherwise step 2.
  2. Search the available zones for the zone that is the nearest ancestor to QNAME. If such a zone is found, go to step 3, otherwise step 4.
  3. Start matching down, label by label, in the zone. The matching process can terminate several ways:
    • a. If the whole of QNAME is matched, we have found the node.
    • If the data at the node is a CNAME, and QTYPE doesn't match CNAME, copy the CNAME RR into the answer section of the response, change QNAME to the canonical name in the CNAME RR, and go back to step 1.
    • Otherwise, copy all RRs that match QTYPE into the answer section and go to step 6.
    • b. If a match would take us out of the authoritative data, we have a referral. This happens when we encounter a node with NS RRs marking cuts along the bottom of a zone.
    • Copy the NS RRs for the subzone into the authority section of the reply. Put whatever addresses are available into the additional section, using glue RRs if the addresses are not available from authoritative data or the cache. Go to step 4.
    • c. If at some label a match is impossible (i.e., the corresponding label does not exist), look to see if a * label exists.
    • If the * label does not exist, check whether the name we are looking for is the original QNAME in the query or a name we have followed due to a CNAME. If the name is original, set an authoritative name error in the response and exit. Otherwise just exit.
    • If the * label does exist, match RRs at that node against QTYPE. If any match, copy them into the answer section, but set the owner of the RR to be QNAME, and not the node with the * label. Go to step 6.
  4. Start matching down in the cache. If QNAME is found in the cache, copy all RRs attached to it that match QTYPE into the answer section. If there was no delegation from authoritative data, look for the best one from the cache and put it in the authority section. Go to step 6.
  5. Use the local resolver, or a copy of its algorithm (see the resolver section of this memo), to answer the query. Store the results, including any intermediate CNAMEs, in the answer section of the response.
  6. Using local data only, attempt to add other RRs that may be useful to the additional section of the query. Exit.

4.3.3. Wildcards ๐Ÿƒ

In the previous algorithm, special treatment was given to RRs with owner names starting with the label *. These RRs are called wildcards, and they can be thought of as instructions for synthesizing RRs ๐Ÿช„ When the appropriate conditions are met, the name server creates RRs with an owner name equal to the query name and contents taken from the wildcard RRs.

This facility is most often used to create a zone that forwards mail from the Internet to some other mail system ๐Ÿ“ฌ The general idea is that any name in that zone that's presented to the server in a query will be assumed to exist, with certain properties, unless explicit evidence exists to the contrary. Note that the use of the term zone here, instead of domain, is intentional. These defaults don't propagate across zone boundaries, although a subzone may choose to achieve that look by setting up similar defaults.

The contents of the wildcard RRs follow the usual rules and formats for RRs. The wildcards in the zone have an owner name that controls the query names they will match. The owner name of a wildcard RR is of the form *.<anydomain>, where <anydomain> is any domain name. <anydomain> should not contain other * labels, and it should be in the authoritative data of the zone. The wildcards potentially apply to descendants of <anydomain>, but not to <anydomain> itself. Another way to look at this is that the * label always matches at least one whole label and sometimes more, but always whole labels ๐ŸŒˆ

Wildcard RRs do not apply in these cases:

  • When the query is in another zone. That is, delegation cancels the wildcard defaults.
  • When the query name, or a name between the wildcard domain and the query name, is known to exist. For example, if a wildcard RR has an owner name of *.X, and the zone also contains RRs attached to B.X, the wildcards would apply to queries for the name Z.X (presuming there is no explicit information for Z.X), but not to B.X, A.B.X, or X.

A * label appearing in a query name has no special effect, but it can be used to test for wildcards in an authoritative zone. Such a query is the only way to get a response containing RRs with an owner name with * in it. The result of such a query should not be cached.

Note that the contents of the wildcard RRs are not modified when they're used to synthesize RRs.

To illustrate the use of wildcard RRs, suppose a large company with a large, non-IP/TCP network wanted to create a mail gateway. If the company was called X.COM, and its IP/TCP capable gateway machine was called A.X.COM, the following RRs might be entered into the COM zone ๐Ÿข

X.COM           MX      10      A.X.COM

*.X.COM         MX      10      A.X.COM

A.X.COM         A       1.2.3.4
A.X.COM         MX      10      A.X.COM

*.A.X.COM       MX      10      A.X.COM

This would cause any MX query for any domain name ending in X.COM to return an MX RR pointing at A.X.COM. Two wildcard RRs are required, since the effect of the wildcard at *.X.COM is inhibited in the A.X.COM subtree by the explicit data for A.X.COM. Note also that the explicit MX data at X.COM and A.X.COM is required, and that none of the RRs above would match a query name of XX.COM ๐Ÿ™ƒ

4.3.4. Negative response caching (Optional) ๐ŸงŠ

The DNS provides an optional service that allows name servers to distribute, and resolvers to cache, negative results with TTLs. For example, a name server can distribute a TTL along with a name error indication, and a resolver that receives such information is allowed to assume that the name does not exist during the TTL period without consulting authoritative data. Similarly, a resolver can make a query with a QTYPE that matches multiple types, and cache the fact that some of the types are not present.

This feature can be especially important in a system that implements naming shorthands using search lists, because a popular shorthand that happens to require a suffix toward the end of the search list will generate multiple name errors every time it's used ๐Ÿ˜ญ

The method is that a name server may add an SOA RR to the additional section of a response when that response is authoritative. The SOA must be that of the zone that was the source of the authoritative data in the answer section, or name error if applicable. The MINIMUM field of the SOA controls the length of time that the negative result may be cached โฐ

Okay so the SOA stuff in the additional section has some rules, bestie ๐Ÿ’… Note that in some circumstances, the answer section can have multiple owner names ๐Ÿ‘€ In that case, the SOA mechanism should only be used for the data that matches QNAME, because that's the only authoritative data in that section โœจ

Name servers and resolvers should never try to add SOAs to the additional section of a non-authoritative response, and they should never try to infer results that aren't directly stated in an authoritative response ๐Ÿ™…โ€โ™€๏ธ There are a few reasons, and they're kind of iconic: cached info usually isn't enough to match up RRs with their zone names, SOA RRs might be cached because of direct SOA queries, and name servers aren't required to output the SOAs in the authority section either ๐Ÿ’€

This feature is optional ๐Ÿฆ‹ but a refined version is expected to become part of the standard protocol down the line. Name servers are not required to add SOA RRs in every authoritative response, and resolvers aren't required to cache negative results. Both are recommended. ๐Ÿ’– All resolvers and recursive name servers are required to at least be able to ignore the SOA RR when it shows up in a response ๐Ÿซถ

There are also some experiments that have been proposed to use this feature ๐Ÿงช The vibe is: if cached data is known to come from a particular zone, and an authoritative copy of that zone's SOA is obtained, and the zone's SERIAL hasn't changed since the data was cached, then the TTL of the cached data can be reset to the zone MINIMUM value if it's smaller ๐Ÿคฏ This is only mentioned for planning purposes, and it is not recommended as yet ๐Ÿ™ˆ

4.3.5. Zone maintenance and transfers

Part of a zone administrator's job is keeping the zones up to date at all of the name servers that are authoritative for the zone ๐Ÿงน When the inevitable changes happen, they have to be distributed to every one of those name servers. FTP or some other ad hoc procedure can do the job, but the preferred method is the zone transfer part of the DNS protocol ๐Ÿššโœจ

The general model for automatic zone transfer (or refreshing) is that one of the name servers is the master or primary for the zone ๐Ÿ‘‘ Changes get coordinated at the primary, usually by editing a master file for the zone. After editing, the admin tells the master server to load the new zone. The other servers, called non-master or secondary servers, periodically check for changes (at a selectable interval) and grab new zone copies when something has changed ๐Ÿ”„

To detect changes, secondaries just check the SERIAL field of the zone's SOA ๐Ÿ‘€ Whatever other changes get made, the SERIAL field in the zone's SOA is always advanced whenever any change is made to the zone ๐Ÿ“ˆ The advancing can be a simple increment, or it could be based on the write date and time of the master file, etc. The point is to make it possible to tell which of two copies of a zone is more recent by comparing serial numbers ๐Ÿ•ฐ๏ธ Serial number advances and comparisons use sequence space arithmetic, so there's a theoretical limit on how fast a zone can be updated: basically, old copies must die out before the serial number covers half of its 32 bit range ๐ŸŒ€ In practice, the only real concern is that the compare operation handles comparisons around the boundary between the most positive and most negative 32 bit numbers ๐Ÿง 

The periodic polling of secondary servers is controlled by parameters in the zone's SOA RR, which set the minimum acceptable polling intervals โฐ They're called REFRESH, RETRY, and EXPIRE. Whenever a new zone gets loaded into a secondary, the secondary waits REFRESH seconds before checking with the primary for a new serial. If that check can't be completed, new checks start every RETRY seconds ๐Ÿ” The check is just a simple query to the primary for the zone's SOA RR. If the serial field in the secondary's zone copy is equal to the serial the primary returns, then nothing has changed, and the REFRESH interval wait restarts ๐Ÿ™Œ If the secondary finds it impossible to do a serial check for the EXPIRE interval, it must assume its copy of the zone is obsolete and discard it ๐Ÿ’”

When the poll shows the zone has changed, the secondary server must request a zone transfer via an AXFR request for the zone ๐Ÿ“ฆ The AXFR may cause an error, like refused, but it normally gets answered by a sequence of response messages. The first and last messages must contain the data for the top authoritative node of the zone ๐Ÿ” Intermediate messages carry all of the other RRs from the zone, both authoritative and non-authoritative ones ๐Ÿงฉ That stream of messages lets the secondary build its own copy of the zone. Because accuracy is essential, TCP or some other reliable protocol must be used for AXFR requests ๐Ÿ›ก๏ธ

Each secondary server is required to perform the following operations against the master, but it may also optionally perform them against other secondary servers ๐Ÿซ‚ This strategy can make transfers better when the primary is unavailable because of host downtime or network problems, or when a secondary has better network access to an "intermediate" secondary than to the primary ๐ŸŒ


5. RESOLVERS

5.1. Introduction

Resolvers are programs that connect user programs to domain name servers ๐Ÿ”Œ In the simplest case, a resolver gets a request from a user program (like mail programs, TELNET, or FTP) as a subroutine call, system call, etc., and hands back the info you wanted in a form that fits the local host's data formats ๐ŸŽ€

The resolver lives on the same machine as the program that's asking for its services, but it may need to consult name servers on other hosts ๐Ÿ  Since a resolver might need to check several name servers, or might already have the answer in a local cache, the time it takes to finish can vary a lot, from milliseconds to several seconds โฑ๏ธ

A very important goal of the resolver is to cut out network delay and name server load for most requests by answering them from its cache of prior results ๐Ÿง So caches that are shared by multiple processes, users, machines, etc., are more efficient than non-shared caches. Big shared-cache energy ๐ŸŒธ

5.2. Client-resolver interface

5.2.1. Typical functions

The client interface to the resolver is shaped by the local host's conventions, but the typical resolver-client interface has three functions ๐Ÿ’…

  1. Host name to host address translation.

This function is often defined to mimic an earlier HOSTS.TXT based function. Given a character string, the caller wants one or more 32 bit IP addresses. Under the DNS, it turns into a request for type A RRs. Since the DNS doesn't preserve the order of RRs, this function may choose to sort the returned addresses or select the "best" address if the service only returns one choice to the client. Note that a multiple address return is recommended, but a single address may be the only way to emulate prior HOSTS.TXT services ๐Ÿ—บ๏ธ

  1. Host address to host name translation

This function will often follow the form of earlier functions. Given a 32 bit IP address, the caller wants a character string. The octets of the IP address are reversed, used as name components, and suffixed with "IN-ADDR.ARPA". A type PTR query is used to get the RR with the primary name of the host. For example, a request for the host name corresponding to IP address 1.2.3.4 looks for PTR RRs for domain name 4.3.2.1.IN-ADDR.ARPA ๐Ÿ”„

  1. General lookup function

This function retrieves arbitrary info from the DNS, and it has no counterpart in previous systems ๐Ÿ†• The caller supplies a QNAME, QTYPE, and QCLASS, and wants all of the matching RRs. This function will often use the DNS format for all RR data instead of the local host's, and it returns all RR content (like TTL) instead of a processed form with local quoting conventions ๐Ÿงพ

When the resolver performs the indicated function, it usually has one of the following results to pass back to the client:

  • One or more RRs giving the requested data.

In this case the resolver returns the answer in the appropriate format โœ…

  • A name error (NE).

This happens when the referenced name does not exist. For example, a user may have mistyped a host name ๐Ÿ™ƒ

  • A data not found error.

This happens when the referenced name exists, but data of the appropriate type does not. For example, a host address function applied to a mailbox name would return this error, since the name exists but no address RR is present ๏ฟฝรฌยญ

It's important to note that the functions for translating between host names and addresses may combine the "name error" and "data not found" error conditions into a single type of error return, but the general function should not ๐Ÿšซ One reason is that applications may ask first for one type of info about a name, then send a second request to the same name for some other type. If the two errors are combined, useless queries may slow the application down ๐ŸŒ

5.2.2. Aliases

While trying to resolve a particular request, the resolver may find that the name in question is an alias ๐ŸŽญ For example, the resolver might find that the name given for host name to address translation is an alias when it finds the CNAME RR. If possible, the alias condition should be signalled back from the resolver to the client ๐Ÿ“ฃ

In most cases a resolver just restarts the query at the new name when it hits a CNAME ๐Ÿ” However, when performing the general function, the resolver should not pursue aliases when the CNAME RR matches the query type. This allows queries that ask whether an alias is present ๐Ÿ‘€ For example, if the query type is CNAME, the user is interested in the CNAME RR itself, not the RRs at the name it points to ๐ŸŽฏ

Several special conditions can happen with aliases. Multiple levels of aliases should be avoided because they're not efficient, but they should not be signalled as an error ๐Ÿฅด Alias loops, and aliases that point to non-existent names, should be caught, and an error condition passed back to the client ๐Ÿšจ

5.2.3. Temporary failures

In a less than perfect world, every resolver will occasionally be unable to resolve a particular request ๐ŸŒง๏ธ This can happen when a resolver gets separated from the rest of the network because of a link failure or gateway problem, or less often from coincident failure or unavailability of all servers for a particular domain ๐Ÿ”Œ

It is essential that this sort of condition is not signalled to applications as a name or data not present error ๐Ÿ™…โ€โ™€๏ธ This kind of behavior is annoying to humans, and it can wreak havoc when mail systems use the DNS ๐Ÿ“ฌ๐Ÿ’€

While in some cases it's possible to deal with a temporary problem by blocking the request indefinitely, this is usually not a good choice, especially when the client is a server process that could move on to other tasks ๐Ÿƒโ€โ™€๏ธ The recommended solution is to always have temporary failure as one of the possible results of a resolver function, even though this may make emulating existing HOSTS.TXT functions harder ๐Ÿงธ

5.3. Resolver internals

Every resolver implementation uses slightly different algorithms, and typically spends way more logic dealing with errors of various sorts than with typical occurrences ๐Ÿค“ This section outlines a recommended basic strategy for resolver operation, but leaves the details to [RFC-1035] ๐Ÿ“–

5.3.1. Stub resolvers

One option for implementing a resolver is to move the resolution function out of the local machine and into a name server that supports recursive queries ๐Ÿ›ธ This can be an easy way to give domain service to a PC that lacks the resources to do the resolver function, or it can centralize the cache for a whole local network or organization ๐Ÿขโœจ

5.3.1. Stub resolvers ๐ŸŽ€

okay so all the stub needs is a list of name server addresses that will do the recursive requests for it ๐Ÿ’… this type of resolver presumably needs that list in a configuration file, since it probably doesn't have the brainpower to find the servers in the domain database itself ๐Ÿงš the user also has to double-check that the listed servers will actually do recursive service, because a name server is totally allowed to refuse recursive service for any or all clients ๐Ÿ™ˆ so the user should ask the local system administrator which name servers are willing to do the job โœจ

this setup has some drawbacks tho ๐Ÿ˜ญ recursive requests can take an arbitrary amount of time, so the stub may struggle to tune its retransmission intervals to handle both lost UDP packets and dead servers ๐Ÿ’€ and the name server can get overloaded super easily by a zealous stub if it treats retransmissions as brand new requests. using TCP might be an answer, but TCP may well put burdens on the host's capabilities that are similar to those of a real resolver ๐Ÿฅบ


5.3.2. Resources ๐ŸŒธ

in addition to its own resources, the resolver may also have shared access to zones maintained by a local name server ๐Ÿฆ‹ that gives the resolver the advantage of faster access, but the resolver has to be really careful to never let cached information override zone data ๐Ÿšซ in this discussion, the term "local information" means the union of the cache and those shared zones, with the understanding that authoritative data is always used in preference to cached data when both are present ๐Ÿ‘‘

the resolver algorithm below assumes all functions have been turned into one general lookup function, and it uses these data structures to track the state of a request in progress:

  • SNAME is the domain name we are searching for.
  • STYPE is the QTYPE of the search request.
  • SCLASS is the QCLASS of the search request.
  • SLIST is the structure that describes the name servers and the zone the resolver is currently trying to query ๐Ÿง  it holds the resolver's current best guess about which name servers have the info it wants, and it gets updated whenever new info changes that guess. it includes the equivalent of a zone name, the known name servers for the zone, the known addresses for those name servers, and history info that can suggest which server is most likely the best one to try next. the zone name equivalent is a match count: the number of labels from the root down that SNAME has in common with the zone being queried. this is used as a measure of how "close" the resolver is to SNAME ๐Ÿ’–
  • SBELT is a "safety belt" structure of the same form as SLIST. it gets initialized from a configuration file and lists servers that should be used when the resolver doesn't have any local information to guide name server selection ๐Ÿซถ its match count will be -1 to indicate that no labels are known to match.
  • CACHE is the structure that stores results from previous responses. resolvers are responsible for discarding old RRs whose TTL has expired, so most implementations convert the interval in arriving RRs into some absolute time when the RR is stored in the cache โฐ instead of counting TTLs down one by one, the resolver just ignores or discards old RRs when it runs across them during a search, or discards them during periodic sweeps to reclaim the memory they're using ๐Ÿงน

5.3.3. Algorithm ๐Ÿ”ฅ

the top-level algorithm has four steps, and honestly it's giving very organized ๐Ÿ’…

  1. See if the answer is in local information, and if so return it to the client.
  2. Find the best servers to ask.
  3. Send them queries until one returns a response.
  4. Analyze the response, either:
    • a. if the response answers the question or contains a name error, cache the data as well as returning it back to the client.
    • b. if the response contains a better delegation to other servers, cache the delegation information, and go to step 2.
    • c. if the response shows a CNAME and that is not the answer itself, cache the CNAME, change the SNAME to the canonical name in the CNAME RR and go to step 1.
    • d. if the response shows a servers failure or other bizarre contents, delete the server from the SLIST and go back to step 3.

step 1 searches the cache for the desired data ๐Ÿ‘€ if the data is in the cache, it's assumed to be good enough for normal use. some resolvers have an option at the user interface that forces the resolver to ignore cached data and consult an authoritative server instead. this is not recommended as the default ๐Ÿ™…โ€โ™€๏ธ if the resolver has direct access to a name server's zones, it should check whether the desired data is present in authoritative form, and if so, use the authoritative data in preference to cached data โœจ

step 2 looks for a name server to ask for the required data ๐Ÿ” the general strategy is to look for locally-available name server RRs, starting at SNAME, then the parent domain name of SNAME, then the grandparent, and so on toward the root. so if SNAME were Mockapetris.ISI.EDU, this step would look for NS RRs for Mockapetris.ISI.EDU, then ISI.EDU, then EDU, and then . (the root). these NS RRs list the names of hosts for a zone at or above SNAME. copy those names into SLIST, then set up their addresses using local data ๐Ÿงฉ the addresses might not be available, and the resolver has lots of choices here. the best one is to start parallel resolver processes looking for the addresses while continuing onward with the addresses that are available ๐Ÿƒโ€โ™€๏ธ honestly the design choices and options are complicated and depend on the local host's capabilities. the recommended priorities for the resolver designer are:

  1. Bound the amount of work (packets sent, parallel processes started) so that a request can't get into an infinite loop or start off a chain reaction of requests or queries with other implementations EVEN IF SOMEONE HAS INCORRECTLY CONFIGURED SOME DATA ๐Ÿšจ
  2. Get back an answer if at all possible.
  3. Avoid unnecessary transmissions.
  4. Get the answer as quickly as possible.

if the search for NS RRs fails, the resolver initializes SLIST from the safety belt SBELT ๐Ÿชข the basic idea is that when the resolver has no idea which servers to ask, it should use info from a configuration file that lists several servers expected to be helpful. there are special situations, but the usual choice is two of the root servers and two of the servers for the host's domain ๐Ÿ‘‘ the reason for two of each is redundancy. the root servers will provide eventual access to all of the domain space, and the two local servers let the resolver keep resolving local names even if the local network gets cut off from the internet because of a gateway or link failure ๐ŸŒˆ

besides the names and addresses of the servers, the SLIST data structure can be sorted so the best servers get used first, and so that all addresses of all servers get used in a round-robin manner ๐Ÿ”„ the sorting can be a simple function of preferring addresses on the local network over others, or it can involve statistics from past events, like previous response times and batting averages ๐Ÿ“Š

step 3 sends out queries until a response is received ๐Ÿ“ค the strategy is to cycle around all of the addresses for all of the servers, with a timeout between each transmission. in practice it's important to use all addresses of a multihomed host, and too aggressive a retransmission policy actually slows down responses when it's used by multiple resolvers contending for the same name server, and even occasionally by a single resolver ๐Ÿ˜ญ SLIST typically contains data values that control the timeouts and keep track of previous transmissions โฑ๏ธ

step 4 involves analyzing responses ๐Ÿ•ต๏ธโ€โ™€๏ธ the resolver should be highly paranoid when parsing responses. it should also check that the response matches the query it sent, using the ID field in the response ๐Ÿ”

the ideal answer is one from a server authoritative for the query that either gives the required data or a name error ๐Ÿ’ฏ the data is passed back to the user and entered in the cache for future use if its TTL is greater than zero.

if the response shows a delegation, the resolver should check that the delegation is "closer" to the answer than the servers in SLIST are ๐Ÿ“ this can be done by comparing the match count in SLIST with the one computed from SNAME and the NS RRs in the delegation. if they don't line up, the reply is bogus and should be ignored ๐Ÿ—‘๏ธ if the delegation is valid, the NS delegation RRs and any address RRs for the servers should be cached. the name servers get entered in the SLIST, and the search is restarted ๐Ÿ”

if the response contains a CNAME, the search is restarted at the CNAME unless the response already has the data for the canonical name, or the CNAME is the answer itself ๐Ÿช„

details and implementation hints can be found in [RFC-1035]. ๐Ÿ“–


6. A SCENARIO ๐Ÿงš

in our sample domain space, suppose we wanted separate administrative control for the root, MIL, EDU, MIT.EDU and ISI.EDU zones ๐Ÿ—บ๏ธ we might allocate name servers like this:

                                   |(C.ISI.EDU,SRI-NIC.ARPA
                                   | A.ISI.EDU)
             +---------------------+------------------+
             |                     |                  |
            MIL                   EDU                ARPA
             |(SRI-NIC.ARPA,       |(SRI-NIC.ARPA,    |
             | A.ISI.EDU           | C.ISI.EDU)       |
       +-----+-----+               |     +------+-----+-----+
       |     |     |               |     |      |           |
      BRL  NOSC  DARPA             |  IN-ADDR  SRI-NIC     ACC
                                   |
       +--------+------------------+---------------+--------+
       |        |                  |               |        |
      UCI      MIT                 |              UDEL     YALE
                |(XX.LCS.MIT.EDU, ISI
                |ACHILLES.MIT.EDU) |(VAXA.ISI.EDU,VENERA.ISI.EDU,
            +---+---+              | A.ISI.EDU)
            |       |              |
           LCS   ACHILLES +--+-----+-----+--------+
            |             |  |     |     |        |
            XX            A  C   VAXA  VENERA Mockapetris

in this example, the authoritative name server is shown in parentheses at the point in the domain tree where it takes over control ๐Ÿ‘€

so the root name servers are on C.ISI.EDU, SRI-NIC.ARPA, and A.ISI.EDU ๐ŸŒ the MIL domain is served by SRI-NIC.ARPA and A.ISI.EDU. the EDU domain is served by SRI-NIC.ARPA and C.ISI.EDU. note that servers may have zones that are contiguous or disjoint ๐Ÿงฉ in this scenario, C.ISI.EDU has contiguous zones at the root and EDU domains. A.ISI.EDU has contiguous zones at the root and MIL domains, but it also has a non-contiguous zone at ISI.EDU ๐Ÿคฏ

6.1. C.ISI.EDU name server ๐Ÿ’œ

C.ISI.EDU is a name server for the root, MIL, and EDU domains of the IN class, and it would have zones for these domains ๐Ÿซถ the zone data for the

okay so the root zone's master file might look something like this ๐ŸŒธ

.       IN      SOA     SRI-NIC.ARPA. HOSTMASTER.SRI-NIC.ARPA. (
                        870611          ;serial
                        1800            ;refresh every 30 min
                        300             ;retry every 5 min
                        604800          ;expire after a week
                        86400)          ;minimum of a day
                NS      A.ISI.EDU.
                NS      C.ISI.EDU.
                NS      SRI-NIC.ARPA.

MIL.    86400   NS      SRI-NIC.ARPA.
        86400   NS      A.ISI.EDU.

EDU.    86400   NS      SRI-NIC.ARPA.
        86400   NS      C.ISI.EDU.

SRI-NIC.ARPA.   A       26.0.0.73
                A       10.0.0.51
                MX      0 SRI-NIC.ARPA.
                HINFO   DEC-2060 TOPS20

ACC.ARPA.       A       26.6.0.65
                HINFO   PDP-11/70 UNIX
                MX      10 ACC.ARPA.

USC-ISIC.ARPA.  CNAME   C.ISI.EDU.

73.0.0.26.IN-ADDR.ARPA.  PTR    SRI-NIC.ARPA.
65.0.6.26.IN-ADDR.ARPA.  PTR    ACC.ARPA.
51.0.0.10.IN-ADDR.ARPA.  PTR    SRI-NIC.ARPA.
52.0.0.10.IN-ADDR.ARPA.  PTR    C.ISI.EDU.

103.0.3.26.IN-ADDR.ARPA. PTR    A.ISI.EDU.

A.ISI.EDU. 86400 A      26.3.0.103
C.ISI.EDU. 86400 A      10.0.0.52

This is written the way it would look in a master file ๐Ÿ“„ Most RRs are single line entries. The one exception is the SOA RR, which uses "(" to start a multi-line RR and ")" to show where it ends. Since every RR in a zone has to share the same class, only the first RR in a zone needs to name the class ๐Ÿงš When a name server loads a zone, it bumps the TTL of all authoritative RRs up to at least the MINIMUM field of the SOA, which here is 86400 seconds, or one whole day โฐ The NS RRs marking the delegation of the MIL and EDU domains, plus the glue RRs holding the servers' host addresses, aren't authoritative data in the zone, so they get explicit TTLs ๐Ÿ’œ

Four RRs are attached to the root node: the SOA that describes the root zone, and the 3 NS RRs that list the root's name servers ๐Ÿ‘‘ The SOA data describes how the zone is managed. The zone data is maintained on host SRI-NIC.ARPA, and the responsible party for the zone is HOSTMASTER@SRI-NIC.ARPA. The big item in the SOA is the 86400 second minimum TTL. That means all authoritative data in the zone has at least that TTL, although higher values can be set explicitly ๐Ÿซถ

The NS RRs for the MIL and EDU domains mark the boundary between the root zone and the MIL and EDU zones. In this example, the lower zones just happen to be supported by name servers that also support the root zone ๐ŸŒˆ

The master file for the EDU zone might be written relative to the origin EDU. The zone data for the EDU domain might look like this:

EDU.  IN SOA SRI-NIC.ARPA. HOSTMASTER.SRI-NIC.ARPA. (
                        870729 ;serial
                        1800 ;refresh every 30 minutes
                        300 ;retry every 5 minutes
                        604800 ;expire after a week
                        86400 ;minimum of a day
                        )
                NS SRI-NIC.ARPA.
                NS C.ISI.EDU.

UCI 172800 NS ICS.UCI
                172800 NS ROME.UCI
ICS.UCI 172800 A 192.5.19.1
ROME.UCI 172800 A 192.5.19.31
ISI 172800 NS VAXA.ISI
                172800 NS A.ISI
                172800 NS VENERA.ISI.EDU.
VAXA.ISI 172800 A 10.2.0.27
                172800 A 128.9.0.33
VENERA.ISI.EDU. 172800 A 10.1.0.52
                172800 A 128.9.0.32
A.ISI 172800 A 26.3.0.103

UDEL.EDU.  172800 NS LOUIE.UDEL.EDU.
                172800 NS UMN-REI-UC.ARPA.
LOUIE.UDEL.EDU. 172800 A 10.0.0.96
                172800 A 192.5.39.3

YALE.EDU.  172800 NS YALE.ARPA.
YALE.EDU.  172800 NS YALE-BULLDOG.ARPA.

MIT.EDU.  43200 NS XX.LCS.MIT.EDU.
                  43200 NS ACHILLES.MIT.EDU.
XX.LCS.MIT.EDU.  43200 A 10.0.0.44
ACHILLES.MIT.EDU. 43200 A 18.72.0.8

Note the relative names here ๐Ÿ‘€ The owner name for ISI.EDU. is written as a relative name, and so are two of the name server RR contents. Relative and absolute domain names can be freely mixed together in a master file ๐ŸŽ€

6.2. Example standard queries โœจ

The following queries and responses show how name servers behave. Unless otherwise noted, the queries don't have recursion desired (RD) set in the header. The answers to non-recursive queries do depend on which server you ask, but they don't depend on who's asking ๐Ÿ’…

6.2.1. QNAME=SRI-NIC.ARPA, QTYPE=A ๐Ÿฆ‹

The query would look like:

           +---------------------------------------------------+
Header     | OPCODE=SQUERY                                     |
           +---------------------------------------------------+
Question   | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=A           |
           +---------------------------------------------------+
Answer     | <empty>                                           |
           +---------------------------------------------------+
Authority  | <empty>                                           |
           +---------------------------------------------------+
Additional | <empty>                                           |
           +---------------------------------------------------+

The response from C.ISI.EDU would be:

           +---------------------------------------------------+
Header     | OPCODE=SQUERY, RESPONSE, AA                       |
           +---------------------------------------------------+
Question   | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=A           |
           +---------------------------------------------------+
Answer     | SRI-NIC.ARPA. 86400 IN A 26.0.0.73                |
           |               86400 IN A 10.0.0.51                |
           +---------------------------------------------------+
Authority  | <empty>                                           |
           +---------------------------------------------------+
Additional | <empty>                                           |
           +---------------------------------------------------+

The header of the response looks like the header of the query, except the RESPONSE bit is set, which tells you this message is a response and not a query. The Authoritative Answer (AA) bit is also set, which means the address RRs in the answer section come from authoritative data. The question section of the response matches the question section of the query ๐ŸŒธ

If the same query was sent to some other server that isn't authoritative for SRI-NIC.ARPA, the response might be:

           +---------------------------------------------------+
Header     | OPCODE=SQUERY,RESPONSE                            |
           +---------------------------------------------------+
Question   | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=A           |
           +---------------------------------------------------+
Answer     | SRI-NIC.ARPA. 1777 IN A 10.0.0.51                 |
           |               1777 IN A 26.0.0.73                 |
           +---------------------------------------------------+
Authority  | <empty>                                           |
           +---------------------------------------------------+
Additional | <empty>                                           |
           +---------------------------------------------------+

This one is different from the last in two ways: AA isn't set, and the TTLs are different. So the inference is that the data didn't come from a zone, it came from a cache ๐Ÿง The gap between the authoritative TTL and this TTL is just aging in the cache. The different ordering of the RRs in the answer section isn't significant ๐Ÿ™ˆ

6.2.2. QNAME=SRI-NIC.ARPA, QTYPE=* ๐ŸŽ€

A query like the previous one, but using a QTYPE of *, would get this response from C.ISI.EDU:

           +---------------------------------------------------+
Header     | OPCODE=SQUERY, RESPONSE, AA                       |
           +---------------------------------------------------+
Question   | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=*           |
           +---------------------------------------------------+
Answer     | SRI-NIC.ARPA. 86400 IN  A     26.0.0.73           |
           |                         A     10.0.0.51           |
           |                         MX    0 SRI-NIC.ARPA.     |
           |                         HINFO DEC-2060 TOPS20     |
           +---------------------------------------------------+
Authority  | <empty>                                           |
           +---------------------------------------------------+
Additional | <empty>                                           |
           +---------------------------------------------------+

If a similar query was sent to two name servers that aren't authoritative for SRI-NIC.ARPA, the responses might be:

           +---------------------------------------------------+
Header     | OPCODE=SQUERY, RESPONSE                           |
           +---------------------------------------------------+
Question   | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=*           |
           +---------------------------------------------------+
Answer     | SRI-NIC.ARPA. 12345 IN     A       26.0.0.73      |
           |                            A       10.0.0.51      |
           +---------------------------------------------------+
Authority  | <empty>                                           |
           +---------------------------------------------------+
Additional | <empty>                                           |
           +---------------------------------------------------+

and

           +---------------------------------------------------+
Header     | OPCODE=SQUERY, RESPONSE                           |
           +---------------------------------------------------+
Question   | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=*           |
           +---------------------------------------------------+
Answer     | SRI-NIC.ARPA. 1290 IN HINFO  DEC-2060 TOPS20      |
           +---------------------------------------------------+
Authority  | <empty>                                           |
           +---------------------------------------------------+
Additional | <empty>                                           |
           +---------------------------------------------------+

Neither of these answers has AA set, so neither one comes from authoritative data ๐Ÿซ  The different contents and different TTLs suggest that the two servers cached data at different times. The first server cached a response to a QTYPE=A query, and the second one cached a response to a HINFO query ๐Ÿ’€

6.2.3. QNAME=SRI-NIC.ARPA, QTYPE=MX ๐Ÿ’Œ

This kind of query might come from a mailer trying to look up routing info for the mail destination HOSTMASTER@SRI-NIC.ARPA.

The response from C.ISI.EDU would look like this ๐ŸŽ€

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY, RESPONSE, AA                       |
               +---------------------------------------------------+
    Question   | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=MX          |
               +---------------------------------------------------+
    Answer     | SRI-NIC.ARPA. 86400 IN     MX      0 SRI-NIC.ARPA.|
               +---------------------------------------------------+
    Authority  | <empty>                                           |
               +---------------------------------------------------+
    Additional | SRI-NIC.ARPA. 86400 IN     A       26.0.0.73      |
               |                            A       10.0.0.51      |
               +---------------------------------------------------+

This response carries the MX RR in the answer section ๐Ÿ’– The additional section has the address RRs too, because the name server at C.ISI.EDU guesses the requester will need those addresses to properly use what the MX tells them ๐Ÿงš

6.2.4. QNAME=SRI-NIC.ARPA, QTYPE=NS ๐Ÿ’…

C.ISI.EDU would reply to this query with:

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY, RESPONSE, AA                       |
               +---------------------------------------------------+
    Question   | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=NS          |
               +---------------------------------------------------+
    Answer     | <empty>                                           |
               +---------------------------------------------------+
    Authority  | <empty>                                           |
               +---------------------------------------------------+
    Additional | <empty>                                           |
               +---------------------------------------------------+

The only difference between the response and the query is the AA and RESPONSE bits in the header ๐Ÿฆ‹ So the vibe is: the server is authoritative for the name, and the name exists, but there are no RRs of type NS there at all ๐Ÿ™ˆ

6.2.5. QNAME=SIR-NIC.ARPA, QTYPE=A ๐ŸŒธ

If a user mistyped a host name, this is the kind of query we might see ๐Ÿ˜ญ

C.ISI.EDU would answer it with:

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY, RESPONSE, AA, RCODE=NE             |
               +---------------------------------------------------+
    Question   | QNAME=SIR-NIC.ARPA., QCLASS=IN, QTYPE=A           |
               +---------------------------------------------------+
    Answer     | <empty>                                           |
               +---------------------------------------------------+
    Authority  | . SOA SRI-NIC.ARPA. HOSTMASTER.SRI-NIC.ARPA.      |
               |       870611 1800 300 604800 86400                |
               +---------------------------------------------------+
    Additional | <empty>                                           |
               +---------------------------------------------------+

This response says the name does not exist, and that's signalled in the response code (RCODE) section of the header ๐Ÿ’€

The SOA RR in the authority section is the optional negative caching info. It lets the resolver using this response assume the name won't exist for the SOA MINIMUM (86400) seconds โœจ

6.2.6. QNAME=BRL.MIL, QTYPE=A ๐Ÿฆ‹

If this query is sent to C.ISI.EDU, the reply would be:

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY, RESPONSE                           |
               +---------------------------------------------------+
    Question   | QNAME=BRL.MIL, QCLASS=IN, QTYPE=A                 |
               +---------------------------------------------------+
    Answer     | <empty>                                           |
               +---------------------------------------------------+
    Authority  | MIL.             86400 IN NS       SRI-NIC.ARPA.  |
               |                  86400    NS       A.ISI.EDU.     |
               +---------------------------------------------------+
    Additional | A.ISI.EDU.                A        26.3.0.103     |
               | SRI-NIC.ARPA.             A        26.0.0.73      |
               |                           A        10.0.0.51      |
               +---------------------------------------------------+

So this response has an empty answer section, but it's not authoritative, which makes it a referral ๐Ÿ‘‘ The name server on C.ISI.EDU knows it isn't authoritative for the MIL domain, so it refers the requester to the servers on A.ISI.EDU and SRI-NIC.ARPA, which it knows are authoritative for MIL. Iconic redirect energy ๐Ÿ’œ

6.2.7. QNAME=USC-ISIC.ARPA, QTYPE=A ๐ŸŒˆ

The response to this query from A.ISI.EDU would be:

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY, RESPONSE, AA                       |
               +---------------------------------------------------+
    Question   | QNAME=USC-ISIC.ARPA., QCLASS=IN, QTYPE=A          |
               +---------------------------------------------------+
    Answer     | USC-ISIC.ARPA. 86400 IN CNAME      C.ISI.EDU.     |
               | C.ISI.EDU.     86400 IN A          10.0.0.52      |
               +---------------------------------------------------+
    Authority  | <empty>                                           |
               +---------------------------------------------------+
    Additional | <empty>                                           |
               +---------------------------------------------------+

Note that the AA bit in the header guarantees the data matching QNAME is authoritative, but it doesn't say anything about whether the data for C.ISI.EDU is authoritative ๐Ÿค” This complete reply is possible only because A.ISI.EDU happens to be authoritative for both the ARPA domain where USC-ISIC.ARPA lives and the ISI.EDU domain where the C.ISI.EDU data is found. Lucky break, honestly ๐Ÿ“

If the same query was sent to C.ISI.EDU, its response might be the same as shown above if it had its own address in its cache. It might also be:

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY, RESPONSE, AA                       |
               +---------------------------------------------------+
    Question   | QNAME=USC-ISIC.ARPA., QCLASS=IN, QTYPE=A          |
               +---------------------------------------------------+
    Answer     | USC-ISIC.ARPA.   86400 IN CNAME   C.ISI.EDU.      |
               +---------------------------------------------------+
    Authority  | ISI.EDU.        172800 IN NS      VAXA.ISI.EDU.   |
               |                           NS      A.ISI.EDU.      |
               |                           NS      VENERA.ISI.EDU. |
               +---------------------------------------------------+
    Additional | VAXA.ISI.EDU.   172800    A       10.2.0.27       |
               |                 172800    A       128.9.0.33      |
               | VENERA.ISI.EDU. 172800    A       10.1.0.52       |
               |                 172800    A       128.9.0.32      |
               | A.ISI.EDU.      172800    A       26.3.0.103      |
               +---------------------------------------------------+

This reply has an authoritative answer for the alias USC-ISIC.ARPA, plus a referral to the name servers for ISI.EDU. It's not super likely when the query is for the host name of the name server being asked, but it would be common for other aliases ๐Ÿงšโ€โ™€๏ธ

6.2.8. QNAME=USC-ISIC.ARPA, QTYPE=CNAME โœจ

If this query is sent to either A.ISI.EDU or C.ISI.EDU, the reply would be:

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY, RESPONSE, AA                       |
               +---------------------------------------------------+
    Question   | QNAME=USC-ISIC.ARPA., QCLASS=IN, QTYPE=A          |
               +---------------------------------------------------+
    Answer     | USC-ISIC.ARPA. 86400 IN CNAME      C.ISI.EDU.     |
               +---------------------------------------------------+
    Authority  | <empty>                                           |
               +---------------------------------------------------+
    Additional | <empty>                                           |
               +---------------------------------------------------+

Because QTYPE=CNAME, the CNAME RR itself answers the query, and the name server doesn't try to look anything up for C.ISI.EDU. (Except possibly for the additional section.) Main character behavior, no notes ๐Ÿ’…

6.3. Example resolution ๐Ÿ”ฅ

The following examples show the operations a resolver has to perform for its client. We assume the resolver is starting without a cache, like it might be right after system boot. We also assume the system is not one of the hosts in the data, and that the host is located somewhere on net 26. Its safety belt (SBELT) data structure has this info:

    Match count = -1
    SRI-NIC.ARPA.   26.0.0.73       10.0.0.51
    A.ISI.EDU.      26.3.0.103

This info specifies the servers to try, their addresses, and a match count of -1, which says the servers aren't very close to the target. The -1 isn't supposed to be an accurate closeness measure. It's just a value so later stages of the algorithm still work ๐Ÿซถ

The following examples show how the cache gets used, so each example assumes earlier requests have already completed ๐ŸŒธ

6.3.1. Resolve MX for ISI.EDU. ๐Ÿ’–

Suppose the first request to the resolver comes from the local mailer, which has mail for PVM@ISI.EDU. The mailer might then ask for type MX RRs for the domain name ISI.EDU.

The resolver would look in its cache for MX RRs at ISI.EDU, but the empty cache isn't helpful yet ๐Ÿ˜ญ The resolver would recognize that it needs to query foreign servers, so it would try to figure out the best servers to query. This search looks for NS RRs for the domains ISI.EDU, EDU, and the root. Those cache searches would also fail. As a last resort, the resolver would use the information from the SBELT, copying it into its SLIST structure.

At this point the resolver needs to pick one of the three available addresses to try. Since the resolver is on net 26, it should choose either 26.0.0.73 or 26.3.0.103 as its first choice. It would then send off a query of this form:

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY                                     |
               +---------------------------------------------------+
    Question   | QNAME=ISI.EDU., QCLASS=IN, QTYPE=MX               |
               +---------------------------------------------------+
    Answer     | <empty>                                           |
               +---------------------------------------------------+
    Authority  | <empty>                                           |
               +---------------------------------------------------+
    Additional | <empty>                                           |
               +---------------------------------------------------+

The resolver would then wait for a response to its query, or a timeout. If the timeout happens, it would try different servers, then different addresses of the same servers, and lastly retry addresses it already tried โณโœจ

It might eventually get a reply back from SRI-NIC.ARPA, and it'll look something like this ๐Ÿ’Œ:

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY, RESPONSE                           |
               +---------------------------------------------------+
    Question   | QNAME=ISI.EDU., QCLASS=IN, QTYPE=MX               |
               +---------------------------------------------------+
    Answer     | <empty>                                           |
               +---------------------------------------------------+
    Authority  | ISI.EDU.        172800 IN NS       VAXA.ISI.EDU.  |
               |                           NS       A.ISI.EDU.     |
               |                           NS       VENERA.ISI.EDU.|
               +---------------------------------------------------+
    Additional | VAXA.ISI.EDU.   172800    A        10.2.0.27      |
               |                 172800    A        128.9.0.33     |
               | VENERA.ISI.EDU. 172800    A        10.1.0.52      |
               |                 172800    A        128.9.0.32     |
               | A.ISI.EDU.      172800    A        26.3.0.103     |
               +---------------------------------------------------+

Okay so the resolver checks this and goes "ooh, this is a closer delegation to ISI.EDU than my current SLIST," because it matches three labels ๐Ÿ‘€. So it caches everything in this response and builds a fresh SLIST out of it:

    Match count = 3
    A.ISI.EDU.      26.3.0.103
    VAXA.ISI.EDU.   10.2.0.27       128.9.0.33
    VENERA.ISI.EDU. 10.1.0.52       128.9.0.32

A.ISI.EDU shows up on this list and the previous one, but that's purely a coincidence ๐Ÿ™ƒ. The resolver starts sending and waiting for responses again, and eventually it gets its answer:

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY, RESPONSE, AA                       |
               +---------------------------------------------------+
    Question   | QNAME=ISI.EDU., QCLASS=IN, QTYPE=MX               |
               +---------------------------------------------------+
    Answer     | ISI.EDU.                MX 10 VENERA.ISI.EDU.     |
               |                         MX 20 VAXA.ISI.EDU.       |
               +---------------------------------------------------+
    Authority  | <empty>                                           |
               +---------------------------------------------------+
    Additional | VAXA.ISI.EDU.   172800  A  10.2.0.27              |
               |                 172800  A  128.9.0.33             |
               | VENERA.ISI.EDU. 172800  A  10.1.0.52              |
               |                 172800  A  128.9.0.32             |
               +---------------------------------------------------+

The resolver tucks this info into its cache and hands the MX RRs back to its client. Slay โœจ

6.3.2. Get the host name for address 26.6.0.65

Here the resolver turns the job into a request for PTR RRs for 65.0.6.26.IN-ADDR.ARPA. That isn't in the cache, so it goes looking for foreign servers to ask. None of them match, so it falls back to SBELT again. (Side note: the servers for ISI.EDU are sitting in the cache, but ISI.EDU isn't an ancestor of 65.0.6.26.IN-ADDR.ARPA, so SBELT is the move ๐Ÿง .)

Since this request falls within the authoritative data of both servers in SBELT, eventually one of them answers with this:

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY, RESPONSE, AA                       |
               +---------------------------------------------------+
    Question   | QNAME=65.0.6.26.IN-ADDR.ARPA.,QCLASS=IN,QTYPE=PTR |
               +---------------------------------------------------+
    Answer     | 65.0.6.26.IN-ADDR.ARPA.    PTR     ACC.ARPA.      |
               +---------------------------------------------------+
    Authority  | <empty>                                           |
               +---------------------------------------------------+
    Additional | <empty>                                           |
               +---------------------------------------------------+

6.3.3. Get the host address of poneria.ISI.EDU

This one turns into a type A request for poneria.ISI.EDU. No cached data exists for that name, but when the resolver goes hunting for foreign servers, it finds the NS RRs for ISI.EDU sitting in the cache ๐ŸŽ€. Using that data, it builds a SLIST that looks like this:

    Match count = 3

    A.ISI.EDU.      26.3.0.103
    VAXA.ISI.EDU.   10.2.0.27       128.9.0.33
    VENERA.ISI.EDU. 10.1.0.52

A.ISI.EDU goes first on the list, on the assumption that the resolver orders its choices by preference, and A.ISI.EDU is on the same network as it ๐Ÿ’–. One of these servers then answers the query.

7. REFERENCES and BIBLIOGRAPHY ๐Ÿ“šโœจ

[Dyer 87] Dyer, S., and F. Hsu, "Hesiod", Project Athena Technical Plan - Name Service, April 1987, version 1.9. This one describes the fundamentals of the Hesiod name service ๐Ÿงš

[IEN-116] J. Postel, "Internet Name Server", IEN-116, USC/Information Sciences Institute, August 1979. A name service that got obsoleted by the Domain Name System, but it's still in use ๐Ÿ’€

[Quarterman 86] Quarterman, J., and J. Hoskins, "Notable Computer Networks",Communications of the ACM, October 1986, volume 29, number 10.

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

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

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

[RFC-799] D. Mills, "Internet Name Domains", RFC-799, COMSAT, September 1981. Suggests a hierarchy instead of a flat name space for the Internet ๐ŸŒณ

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

[RFC-810] E. Feinler, K. Harrenstien, Z. Su, and V. White, "DOD Internet Host Table Specification", RFC-810, Network Information Center, SRI International, March 1982. Obsolete, so go check RFC-952 instead ๐Ÿ™ˆ

[RFC-811] K. Harrenstien, V. White, and E. Feinler, "Hostnames Server", RFC-811, Network Information Center, SRI International, March 1982. Obsolete, so go check RFC-953 instead ๐Ÿ™ˆ

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

[RFC-819] Z. Su, and J. Postel, "The Domain Naming Convention for Internet User Applications", RFC-819, Network Information Center, SRI International, August 1982. Early thoughts on the design of the domain system. The current implementation is completely different ๐ŸŒธ

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

[RFC-830] Z. Su, "A Distributed System for Internet Name Service", RFC-830, Network Information Center, SRI International, October 1982. Early thoughts on the design of the domain system. The current implementation is completely different ๐ŸŒธ

[RFC-882] P. Mockapetris, "Domain names - Concepts and Facilities," RFC-882, USC/Information Sciences Institute, November 1983. Superseded by this memo ๐Ÿ‘‘

[RFC-883] P. Mockapetris, "Domain names - Implementation and Specification," RFC-883, USC/Information Sciences Institute, November 1983. Superseded by this memo ๐Ÿ‘‘

[RFC-920] J. Postel and J. Reynolds, "Domain Requirements", RFC-920, USC/Information Sciences Institute October 1984. Explains the naming scheme for top level domains ๐ŸŒˆ

[RFC-952] K. Harrenstien, M. Stahl, E. Feinler, "DoD Internet Host Table Specification", RFC-952, SRI, October 1985. Specifies the format of HOSTS.TXT, the host/address table replaced by the DNS ๐Ÿ“

[RFC-953] K. Harrenstien, M. Stahl, E. Feinler, "HOSTNAME Server", RFC-953, SRI, October 1985. This RFC contains the official specification of the hostname server protocol, which is obsoleted by the DNS. This TCP based protocol accesses information stored in the RFC-952 format, and is used to obtain copies of the host table ๐Ÿฆ‹

[RFC-973] P. Mockapetris, "Domain System Changes and Observations", RFC-973, USC/Information Sciences Institute, January 1986. Describes changes to RFC-882 and RFC-883 and the reasons for them. Now obsolete ๐Ÿ™ƒ

[RFC-974] C. Partridge, "Mail routing and the domain system", RFC-974, CSNET CIC BBN Labs, January 1986. Describes the transition from HOSTS.TXT based mail addressing to the more powerful MX system used with the domain system ๐Ÿ’Œ

[RFC-1001] NetBIOS Working Group, "Protocol standard for a NetBIOS service on a TCP/UDP transport: Concepts and Methods", RFC-1001, March 1987. This RFC and RFC-1002 are a preliminary design for NETBIOS on top of TCP/IP, which proposes basing NetBIOS name service on top of the DNS ๐Ÿงฉ

[RFC-1002] NetBIOS Working Group, "Protocol standard for a NetBIOS service on a TCP/UDP transport: Detailed Specifications", RFC-1002, March 1987.

[RFC-1010] J. Reynolds and J. Postel, "Assigned Numbers", RFC-1010, USC/Information Sciences Institute, May 1987. Contains socket numbers and mnemonics for host names, operating systems, etc. ๐Ÿ”ข

[RFC-1031] W. Lazear, "MILNET Name Domain Transition", RFC-1031, November 1987. Describes a plan for converting the MILNET to the DNS ๐Ÿ›ฃ๏ธ

[RFC-1032] M. K. Stahl, "Establishing a Domain - Guidelines for Administrators", RFC-1032, November 1987. Describes the registration policies the NIC uses to administer the top level domains and delegate subzones ๐Ÿ“‹

[RFC-1033] M. K. Lottor, "Domain Administrators Operations Guide", RFC-1033, November 1987. A cookbook for domain administrators ๐Ÿณ

[Solomon 82] M. Solomon, L. Landweber, and D. Neuhengen, "The CSNET Name Server", Computer Networks, vol 6, nr 3, July 1982. Describes a name service for CSNET which is independent from the DNS and from DNS use in CSNET ๐ŸŒท

Index โœจ

okay bestie, this is the index, your cheat sheet for jumping straight to any term ๐Ÿ—‚๏ธ๐Ÿ’–

          A   12
          Absolute names   8
          Aliases   14, 31
          Authority   6
          AXFR   17

          Case of characters   7
          CH   12
          CNAME   12, 13, 31
          Completion queries   18

          Domain name   6, 7

          Glue RRs   20

          HINFO   12

          IN   12
          Inverse queries   16
          Iterative   4

          Label   7

          Mailbox names   9
          MX   12

          Name error   27, 36
          Name servers   5, 17
          NE   30
          Negative caching   44
          NS   12

          Opcode   16

          PTR   12

          QCLASS   16
          QTYPE   16

          RDATA   13
          Recursive   4
          Recursive service   22
          Relative names   7
          Resolvers   6
          RR   12
          Safety belt   33
          Sections   16
          SOA   12
          Standard queries   22

          Status queries   18
          Stub resolvers   32

          TTL   12, 13

          Wildcards   25

          Zone transfers   28
          Zones   19

that's the whole thing, we made it through! ๐ŸŽ€๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from