Mike Zhang

DNS DevOps CISSP CISA Security+ 摄影 程序员 北京

RFC1034 域名概念及工具

08 Jul 2018 » dns, rfc

1. RFC1034简介

本篇RFC主要是介绍DNS的概念, 关于实施细节性的内容将在其他的RFC中给出, 其中RFC1035将具体的介绍DNS的数据包封包和解包格式等细节,这些RFC共同完善了DNS的数据类型和功能定义。域名系统本身设计成为可扩展的系统,因此当前仍旧不断有新的RFC或者草案被提出来,不断增加一些新的实验性的功能特征,对于新的RFC的信息,应当保持谨慎(有可能未被任何DNS软件实施)

2. 域名简介

2.1 域名发展历史

早期的主机名称到IP地址的映射由统一的NIC(网络信息中心)管理维护,并使用FTP来分发管理一个单一的HOSTS.TXT文件,随着主机数量的增加管理成本越来越高,带宽需求也越来越大(考虑到早期的网络带宽可能只有几Kb左右),尽管当时已经提出了多级别的FTP来承载文件的下发管理。

那时候的主机HOSTS.txt文件也跟当前的不一样,包含了很多协议相关的内容

; DoD Internet Host Table
;  22-Mar-85
;  Version number 436
HOST : 8.0.0.14 : BBNJ,CSNET4 : VAX-11/750 : UNIX : TCP/TELNET,TCP/FTP,TCP/SMTP,TCP/TIME :
HOST : 8.1.0.14 : BBN-NOC,BBN-NU,NOC : C/70 : UNIX : TCP/TELNET,TCP/FTP,TCP/SMTP,TCP/TIME :
HOST : 8.2.0.14 : DIV6-TAC,D6TAC,DIV6TAC : C/30 : TAC : TCP :
HOST : 8.4.0.14 : BBN-NOC2,NOC2 : C/70 : UNIX : TCP/TELNET,TCP/FTP,TCP/SMTP,TCP/TIME :
HOST : 8.5.0.14 : CSNET-DEV,CSNET3 : VAX-11/750 : UNIX : TCP/TELNET,TCP/FTP,TCP/SMTP,ICMP :
HOST : 8.6.0.14 : DIV1-TAC,DIV-1-TAC : C/30 : TAC : TCP :

随着ARPANet逐步进化,越来越多的本地网络出现,这些本地网络如果管理自己的域名映射也需要等待NIC去修改HOST文件后才能生效,修改后无法立刻生效。

同时伴随因特网上的应用的多样化,对于域名的需求也越来越高. 因此出现了多个RFC来定义如何更方便的管理和使用域名比如RFC-799, RFC-819, RFC-830等, 这些RFC尽管不尽相同,但是都包含了域名分层设计的概念。后来出现了RFC882和RFC883,定义了使用分布式的数据存储模型和域名管理方式成为后期DNS的实施基础,本篇RFC1034则是结合了多个不同方式的实施的相关内容。

2.2 DNS的设计目标

主要的设计目标如下:

  • 完成域名和IP等资源的映射,且名称不应该包含任何的网络描述符,地址路由信息等
  • 数据的容量和更新的频率要求数据库存储应该是分布式,更方便的管理维护
  • 域名所有者应该可以通过修改配置来平衡数数据的生效时间,缓存时间和修改时间
  • 域名系统应该被用于多个协议,不管是邮件协议,还是FTP协议都可以直接使用
  • 域名系统的实施可以基于UDP或者TCP甚至其他的协议实现查询和解析
  • 系统应该可以在不同的网络环境下使用
  • 系统可以在不同的主机上进行使用

2.3 一些系统使用的设想

关于DNS系统的使用模式和需求决定了整个DNS系统的设计,并且设计本身应当避免任何通用的数据库系统存在的复杂问题。

如下可能的一些假设:

  • 整个数据库的大小应该和整个域中主机数量或者用户数量成正比(用户可能使用邮件或者其他的依赖于DNS的系统应用)
  • 大部分的域名数据变化都会不太频繁,但是系统本身应该能够处理子集的不断修改
  • 客户端应该可以选择自己喜欢的域名服务器去查询域名
  • 更新数据的时候,当更新不可用的使用,应该保持原有的数据可用并且不断的尝试去更新,分发数据模型应该包含超时信息和刷新信息,子集需要负责刷新数据。
  • 在数据查询过程中,如果服务器不包含查询的数据的时候,可以通过两种方式解决:递归查询或者迭代查询, 递归查询中第一个服务器负责帮助客户端查询并响应客户端。 迭代查询则返回用户需要的信息,比如应该去哪里查询获得结果。

域名系统的所有数据被保存在特定的域名文件中,并且分散在不同的域名服务器中管理,域名管理员修改本地的域名文件,本地域名服务器读取文件并提供用户使用。 用户访问域名服务器通过标准的解析器(resolver)完成域名的查询。

域名文件的格式应该使用标准格式,这样更方便进行主机配置的交换,比如一个组织可以修改域名文件数据,并将域名文件分发给运行域名服务器的外部主机上去加载并运行。

域名系统定义访问数据的流程以及如何引用其他域名服务器数据, 同时提供缓存域名数据以及如何周期性的刷新域名数据。域名系统本身还需要提供:

  1. 标准的资源数据格式
  2. 标准的数据查询方式
  3. 标准的域名数据刷新策略(解析器去刷新外部权威域名数据等)

作为域名管理者则需要提供:

  1. 域名区域边界(定义域名范围,比如CN区域或者COM区域)
  2. 配置数据文件
  3. 更新数据
  4. 刷新策略等

2.4 DNS基础

DNS包含三个主要组成部分:

  1. 域名空间以及资源记录。域名空间指的是域名的树形结构,包含了所有此域的域名数据,每个树形结构中的节点和叶子代表了一个特定的名称信息。查询操作一般包含域名以及所属的类型信息。

  2. 域名权威服务器 : 存储域名数据的服务器,一般仅包含整个DNS解析数据中的一部分内容,比如COM权威服务器仅仅包含COM区域的域名数据,以及一些指向其他的权威服务器的数据。权威信息通过Zone(区)的概念进行管理,这些区数据可以自动的分发到其他的冗余服务器上提供数据查询和备份

  3. 域名递归解析器: 用户利用递归解析器获得DNS数据,递归解析器帮助用户查询域名数据,它负责查询权威服务器,并获得权威服务器的信息,通过多次权威查询最终查询到域名。

另外关于实施方面,则有可能不会有如此清晰的节点,有时候会耦合其中的多个部分实现。比如权威服务器与递归解析器共享其中的权威数据并缓存数据用于查询使用。

3. 域名空间和资源记录

3.1 域名空间规范和术语

域名空间是一个树形结构,每一个节点都代表了一个域名资源集合,节点包含一个label标签代表当前节点的名称比如域名www.isc.org, 在树形机构中则是由四个节点组成,叶子节点的标签为www, 中间为isc节点,上层为org节点,最顶层为根节点(节点label是空,长度为0)。

  • 每个域名由至少一个label组成(根域名仅仅包含一个label,且label长度为0)
  • 每个label的长度0-63个字符组成
  • 字符不区分大小写
  • 总的域名长度限制到255个字符,不同label之间通过点号( . )进行隔离

当输入域名的时候,标签之间通过.符号进行隔离, 可以使用绝对输入方式,比如www.isc.org.或者使用相对名称输入,比如www(如果设置了搜索域为isc.org)。其中相对名称可结合本地搜索列表使用,最常用的是相对于root根“.”,这样我们在输入域名的时候可以省略其中最后的“.”,不用再输入。

3.2 管理指南

DNS技术实施并未强制要求任何指定的树形结构或者标签选择方面的特殊规则, 因此可以构建任何形式的应用,但是总体目标(通用性方面)要保持一致。另外存在一些指南应用在域名空间的某些部分,以适应不断增长的域名空间,并减少问题的发生, 比如一些关于顶级域的实施指南被写在RFC1032中,关于MILNet的则在RFC1031中给出相关解释。

3.3 技术指南

在DNS技术实施上需要完成以下两个前提:

  1. 域名和对象(IP信息等)的映射方式
  2. 域名资源记录和数据类型的定义

规则实施起来可能很简单也可能会很复杂, 系统设计人员需要充分考虑已经存在的系统和格式来向后兼容,保证可使用性。由于需要地址到域名的反向映射,因此还需要定义一个地址到IN-ADDR.ARPA的反向映射规范。

对于邮件系统,则稍微有所不同,比如<local-part>@<mail-domain>中local-part不会再细分多个label,即便是存在点好分割。后面的mail-domain则按照正常的域名解析完成,因此组成的新的查询域名为local-part.mail-domain, 比如hostmaster@sri-nic.arpa会被解释成域名hostmaster.sri-nic.arpa.

一般用户不会考虑这些规则,但是应该理解DNS系统本身为了满足多方面的需要做了充分的折中考虑(兼容性,新特性,数据对象的交互等等)。

3.4 域名空间实例

下图代表了一个基本的DNS树形结构,其中根域名包含三个子域,分别是MIL, EDU和ARPA。每个子域本身又包含多个子域(下图在文档中多处被使用)

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

3.5 名称语法规范

域名组成中依赖下面的规则进行定义,其中域名包含多个label组成,不同label使用(.)进行隔离,每个label必须满足ARPANET主机名规则,字母开始,结束必须是字母或者数字,组成内容必须是字符,数字和-符号,长度必须小于等于63。 域名中大小写无关,因此域名仅仅字符的大小写拼写不同认为是相同的域名.

以下为域名定义规范说明, 该定义充分考虑了不同应用的约束,并防止出现任何的字符问题。

<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

3.6 资源记录

树形结构中每一个节点代表了一个域名, 每一个节点又包含多个资源信息(可为空), 与该域名相关的一系列的资源信息称之为资源记录(RR),资源记录的顺序并不重要。

当定义一个资源记录的时候,必须同时定义资源记录的以下属性:

  • 所有者:该资源记录属于哪一个域名
  • 类型(type): 一个16位编码的值代表了资源的类型信息,比如类型A代表了主机地址,MX代表了当前域名的邮件交换地址,HINFO则代表了当前服务器的CPU或者OS使用信息等等。
  • 类别(class):一个16位编码的值代表了使用的协议族,其中IN代表了InternetSystem互联网系统, CH则代表了Chaos系统(基于开源项目OpenMosix实现的协议族)

  • TTL: 32位字符长度,存储资源生存时间,主要用于递归服务器缓存使用
  • RDATA: 具体存储的数据,比如对于A类型,则代表了一个32位的IP地址,如果是CNAME类型,则是一个新的域名字符串

其中资源记录中的所有者信息可能不会直接被包含在资源记录中。 很多域名服务器内部实现通过树形结构或者Hash结构来组成域名空间, 将RR记录通过链式结构保存下来,每个RR记录使用固定的头部信息(上述属性字段)以及对应的数据内容保存。

TTL定义了数据缓存的时间,使用0代表禁止缓存,在选择区域数据的TTL时应该结合实际需要,过短的时间将导致流量的增加,过长的则会导致数据更新过慢。当计划修改数据的时候适当的降低TTL,等待一段时间后再去修改,待修改完成后再调整回来。

3.6.1 资源记录的文本形式

以下为资源记录信息在权威数据文件的一种保存形式, 大部分的资源记录按照行的格式进行保存,行首代表了所有者信息,类型以及RDATA紧随其后,如果该行没有所有者,则默认为同上一个资源记录一致。 类别信息(一般默认为IN)和TTL有时候会被忽略(按照Zone统一的TTL使用)。

下面的是两种形式

    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

形式二:

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

3.6.2 CNAME

现实情况下,多个域名可能指向相同的IP地址(邮箱使用同样存在这种问题, 多个邮箱地址指向同一个地址)。大部分系统处理的时候会将其中一个名称成为主名,其他的则为别名。域名系统实施的时候使用CNAME来代表域名别名如下面所示:

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

如果资源记录中存在CNAME记录,则不允许其他的数据的存在,防止出现数据不一致的情况。同样确保了可以使用一个缓存的CNAME记录,而不需要在权威服务器中去检查任何其他的类型记录

这需要在DNS软件实施的时候,当查询的类型不存在的时候,会尝试去查询是否存在CNAME记录,如果CNAME记录存在则启动新的DNS查询(除非查询的是CNAME记录),上述的记录如果查询A类型,应当同时返回CNAME记录和A记录。DNS软件应该可以处理任何可能导致CNAME循环查找的错误。

同时地址到RR的反向查询记录需要指向主域名而不是任何的别名记录:

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

3.7 DNS查询

DNS查询信息可以通过UDP协议或者TCP协议进行传递,服务器接收到查询请求后,查找并响应给用户相关信息。用户也并非直接查询权威服务器,而是通过向递归服务器发送一个DNS查询请求,等待递归帮助完成所有的查询。所有的DNS查询和响应消息存储在标准的信息格式中,消息格式包含一个预先定义的头部信息(不同的字段存储不同的含义),字段中比较重要的DNS头部信息是其中的opcode字段(4个字节组成)用于区分不同查询类型。下图截取自RFC1035中的DNS头部信息:

    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      ID                       |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    QDCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ANCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    NSCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ARCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

后面的四个COUNT则代表了查询数量,响应资源的数量,NS(域名服务器)数量和额外字段的数量

3.7.1 标准查询

一个标准的查询包含查询的名称(QName),类型(QType)以及查询的类别(QClass) , 其中查询类型可能包含任何已定义的类型(A, PTR, AXFR,MAILB等等, 星号来匹配所有资源记录,类别可能包含IN或者CH类别 , 星号匹配所有类别。

比如如果用户想要发送邮件到 Mockapetris@ISI.EDU, 需要发送请求给递归服务器查询域名isi.edu的MX记录, 完整的数据查询是: QNAME=ISI.EDU, QTYPE=MX, QCLASS=IN

实际的响应信息应该是:

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

另外还会返回一些补充字段信息,提供给用户相关的IP信息是基于一定的需求假设,服务器认为用户在查询MX记录的时候应该也需要实际的IP地址。

    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

其中QCLASS=* 的查询永远不会是权威查询,因为服务器本身并不能知道所有的域名系统的类别信息,也无法知道是否本身是所有类别的权威。

3.7.2 反向查询(可选)

在使用主机地址到主机名称的查询的时候,应该使用IN-ADDR.ARPA来完成,而不是借助于反向查询,反向查询并非DNS软件必须实现的一部分,注意这里的反向查询指的是针对标准查询的反向操作,比如映射一个域名到一个SOA RR,则反向查询应该能够映射一个SOA RR到指定的域名。

4. 域名服务器

4.1 简介

域名服务器可以看做是数据仓库,这些仓库共同的组成整个的域名数据库,每个域名服务器仅管理部分数据。 这一部分的数据称之为区数据,而域名服务器的基本职责是响应属于本区的DNS查询。一般域名服务器包含2台及以上的服务器组成,同时提供相同的域名解析功能。名称服务器可以同时包含多个区数据提供解析服务,同时域名服务器也可以标记响应是否是权威响应,用以通知客户端是否是权威响应。

4.2 数据库如何分区

域名数据库通过两种方式进行分割,通过类和通过树形结构中节点之间的切分。首先按类别进行划分,不同类别包含不同的树形结构(资源数据不同)。在每一个独立的类别中,按照树形结构中节点进行切分,切分后连接在一起的域名空间被称为一个区,比如COM区包含所有顶级域名为com的域名空间。

每一个区至少一个节点,一个区中的所有的节点连接在一起,每一个区都有一个最高的节点,相对其他的节点更接近于根节点。这个节点也被用于标识整个区域,比如COM区中的COM节点相对于Google.com更接近于根节点,也作为整个区的标示。

4.2.1 技术方面的考虑

描述一个区的数据定义包含四个主要部分:

  • 所属该区的所有节点的权威数据
  • 该区域的顶级节点数据
  • 代理子区域的数据(底层可能被切分到其他的区)
  • 允许访问子区域的数据(Glue信息)

所有这些信息都以RR记录的形式存储,一个区可以通过一系列的RR记录进行描述,也可以传递到其他的服务器上使用。一个区的权威数据包含所有的节点信息(子区的相关区域信息),以及相关的RR记录。 关于一个区的顶层节点的描述上需要包含一些额外的信息,比如SOA资源RR,NS名称服务器RR 用于区域数据的管理。

NS域名服务器的RR记录仅仅会包含在顶层节点中和子区的节点中,而不会出现在任何其他的中间位置。比如COM节点中包含COM的NSRR, 而google.com节点中则包含切分出去的的子区的NSRR记录。

父区域包含所有子区域的域名信息,但是仅仅是NS记录可能不够,因为并未包含实际的IP地址, 特别是如果这个NS同时属于本区域则形成loop,为了解决这个问题,需要在区数据中加入glue记录解决。比如下面例子解释了相关的问题:

Your browser: 
		Hi! I need the IP address of example.com. What is it? 
.com nameserver: 
		I don't know, but you can ask its nameserver. It was ns1.example.com the last time I checked. 
Your browser: 
		Thanks! Okay, in order to send a query to ns1.example.com, I need its IP address. What is it? 
.com nameserver: 
		I don't know, but you can ask its parent example.com. 
Your browser: 
		:-(

我们可以直接将NS和对应的IP地址写入权威数据中,如下面所示,尽管该地址并非属于该区的权威数据。

example.com NS ns1.example.com
example.com NS ns2.example.com
ns1.example.com A 192.0.2.10 
ns2.example.com A 192.0.2.20
4.2.2 管理方面的考虑

任何组织如果想要获得本域名的自由管理权,需要向父区域的申请,并将区数据中该域名相关记录代理到指定的NS域名服务器上,除此之外,并没有相关的技术限制。 管理方面的建议主要是针对顶级区域的,可以参考相关的RFC-1032,子区域代理到新的NS记录需要在父区数据中添加相关的NS资源记录,以及对应的glue记录。

4.3 域名服务器内部实现

4.3.1 查询和响应

域名服务器的主要功能是接收用户的DNS查询,并响应给用户需要的数据, 在RFC1035中定义了具体的查询和响应数据包的格式。 查询消息中会包含所查域名的类型和类别。 并且基于是否启用递归模式,服务器的处理行为也不相同。

对于服务器端最简单的模式是非递归模式,服务器仅仅依据本地加载的数据,响应信息可能包含查询的信息,错误代码或者是其他的NS记录指向其他区。

对于客户端最简单的模式是递归模式,客户端不需要处理任何迭代查询,只需要告诉服务器需要什么域名信息即可,递归服务器负责帮助客户端去进行多次的迭代查询,获得最后的结果或者返回一些错误信息。

  • RA位:递归可用比特位,由服务器去设置或者清除,代表了域名服务器愿意为客户端去提供递归服务们不管客户端是否要求递归服务查询

  • RD位: 递归期望比特位,客户端期望域名服务器能够帮助处理递归查询,尽管客户端应该依赖于之前发送的请求中服务器是否返回一个RA位或者域名服务器同意提供相关服务等。

递归服务器可以通过检查返回的响应数据中是否ra和rd都设置为true来确定,并且域名服务器应该仅在客户端明确的发送rd请求后才去执行递归请求。

当递归服务器接收到请求后,响应消息应该包含以下几种类型:

  1. 查询域名相关信息,可能会先处理CNAME的别名类型,再根据别名获得查询内容
  2. 查询域名不存在
  3. 其他的错误信息
 dig a www.baidu.com

; <<>> DiG 9.10.6 <<>> a www.baidu.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43835
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.baidu.com.			IN	A

;; ANSWER SECTION:
www.baidu.com.		767	IN	CNAME	www.a.shifen.com.
www.a.shifen.com.	184	IN	CNAME	www.wshifen.com.
www.wshifen.com.	184	IN	A	103.235.46.39

如果一个权威服务器收到请求后,响应的类型:

  1. 域名不存在
  2. 错误信息
  3. 响应包含正确数据的rr记录
  4. 响应包含一些帮助信息的rr记录,比如外部的NS记录
  5. 拒绝查询REFUSED

比如我们向com的ns服务器发送一个域名查询,获得的是该域名的参考信息,尽管我们设置了rd,但是响应中去并未包含ra位。

dig @d.gtld-servers.net. api.google.com

; <<>> DiG 9.10.6 <<>> @d.gtld-servers.net. api.google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52898
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 9
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;api.google.com.			IN	A

;; AUTHORITY SECTION:
google.com.		172800	IN	NS	ns2.google.com.
google.com.		172800	IN	NS	ns1.google.com.
google.com.		172800	IN	NS	ns3.google.com.
google.com.		172800	IN	NS	ns4.google.com.

;; ADDITIONAL SECTION:
ns2.google.com.		172800	IN	AAAA	2001:4860:4802:34::a
ns2.google.com.		172800	IN	A	216.239.34.10
ns1.google.com.		172800	IN	AAAA	2001:4860:4802:32::a
ns1.google.com.		172800	IN	A	216.239.32.10
ns3.google.com.		172800	IN	AAAA	2001:4860:4802:36::a
ns3.google.com.		172800	IN	A	216.239.36.10
ns4.google.com.		172800	IN	AAAA	2001:4860:4802:38::a
ns4.google.com.		172800	IN	A	216.239.38.10
4.3.2 算法

域名服务器使用的算法依赖于OS以及使用存储RR的数据结构, 下面的算法假设RR使用树形结构,每一个区使用一个树形结构,对于缓存则使用另外的一个树形结构。

需要处理的步骤如下:

  1. 如果域名服务器不提供递归查询服务,则应该设置或者清除对应的RA位。如果本身可以提供递归查询,且客户端请求中包含RD则 前往第5步,否则继续第2步
  2. 搜索可用的区域,并查询最接近查询域名的锚节点,如果区域查找到,则前往第3步,否则前往第4步
  3. 在树形结构下,按照标签进行搜索查找,具体的匹配流程可以有以下终止方式:
    • 如果查询域名匹配到,则按照类型进行查询,如果域名仅仅包含CNAME,且查询的不是CNAME类型,将CNAME记录RR拷贝到对应的响应字段总,并设置CNAME域名作为QNAME并返回步骤1, 否则拷贝对应的RR以及类型到响应字段,并前往第6步
    • 如果查询域名不存在,仅仅包含对应的域名的NS记录,则复制对应的NS记录到响应字段,并将glue记录也包含进去并前往第4步
    • 查询域名不存在,查看是否包含星号标签,如果星号(*)标签存在则,查询对应的类型是否存在,如果存在则设置对应的RR的所有者为QNAME,而不是星号,如果星号不存在,则检查对应的查询名称和QNAME是否一致(有可能是CNAME引导过来的),如果一致则相应查询类型不存在,否则退出查询(只返回CNAME记录)
  4. 开始完成缓存数据的匹配, 如果QNAME在缓存数据中查找到,则复制对应的RR记录到响应字段,如果当前没有权威数据授权,则从缓存中查询最佳的结果放入响应字段

  5. 使用一个本地的解析器或者按照对应的算法处理并响应用户的查询,存储结果,包含任何的中间CNAME记录在响应字段。

  6. 使用本地数据,尝试增加其他的资源记录可能对于查询有用的,并退出
4.3.3 通配符

当一个域名标签为(*)则这样的域名成为通配符域名,但是如下的条件下通配符不会生效:

  1. 当域名被代理到其他的区域,尽管不存在此区,但是会返回NS记录,而不是通配符记录
  2. 当查询域名中包含B.x 以及*.x的时候,当用户查询B.x,或者A.B.X的时候都不会获得对应的通配符匹配。

一个通配符域名的查询不会被缓存下来。通配符域名最常用的是将所有指定区的MX记录传递到其他的Mail system如下面使用:

    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
4.3.4 否定响应缓存(可选)

权威服务器通过增加一个SOA记录到additional区域,这个SOA必须是所属区域的权威应答数据,里面包含的MINIMUM字段代表了否则响应的缓存时间。名称服务器(非权威应答)或者递归服务器不能增加任何的SOA记录到响应字段中。所有的解析器或者递归服务器被要求至少可以忽略响应数据中的SOA记录。

4.3.5 区维护及传输

当权威服务器有多台的时候,区数据的修改需要同步到所有的机器上。分发可以通过FTP或者其他任何直接的命令操作,但是推荐使用DNS协议本身提供的区传输方式。

在所有的域名服务器中,有一台作为master或者primary服务器,任何修改都只会作用在这台机器上,任何编辑完成后(比如直接修改master配置文件), 管理员重新加载数据,其他非master或者二级服务器周期性的检查修改获得新的修改内容。

为了侦测任何变化,二级检查SOA序列号是否一致(任何变化都会导致SOA号的修改),SOA的序列号可以基于持续增加的数字,或者修改的日期时间。周期性的检查基于当前SOA号中的参数,REFRESH, RETRY以及EXPIRE

  • REFRESH : 当一个新的区数据加载到二级服务器后,二级服务器会等待REFRESH秒去重新检查主服务器的变化。检查操作将发送一个查询去查主服务器的SOA记录。如果序列号相同则等待REFRESH秒后重新开始检查。
  • RETRY: 当发现无法正常查询到结果的时候,等待重试的间隔
  • EXPIRE: 如果二级发现在超过EXPIRE时间后仍旧不能查询到结果,则认为当前的数据无效。

如果发现主服务器的SOA号增大,则认为出现了修改、 二级服务器发送AXFR请求区数据传送,可能发生拒绝的错误,但是正常情况下回复内容将包含一些列的响应消息,AXFR消息中第一条和最后一条消息必须包含区域数据的顶级节点信息, 中间的消息则是所有该区域的RR记录信息。二级接收到这些消息后可以完成构造整个区数据的副本,为了保证数据的可靠,应该使用TCP或者更加可靠的协议进行传输。

上述操作,所有的二级服务器均通过这种方式执行,但是同样可以应用在二级之间的通信使用。提供更加灵活的数据传输策略。

5 Resolvers

5.1 介绍

Resolvers(解析器)帮助用户程序查询域名服务器,获得查询结果。一般解析器还需要与多个权威域名服务器进行通信来获得最终的结果。并且为了降低权威服务器负载和缩短查询时间,解析器本身还需要提供缓存数据服务,用于下次查询使用。

5.2 客户端-解析器接口

5.2.1 典型功能

主要功能包含以下三个部分:

  1. 主机名到主机地址的转换(提供类似于早期的HOSTS.txt文件的功能)
  2. 主机地址到主机名的转换:(PTR查询)
  3. 通用的查询功能(基于QNAME, QTYPE 和 QCLASS)

返回的结果一般属于下面的三种:

  1. 给定的结果
  2. 查询域名不存在
  3. 查询类别不存在
5.2.2 CNAME查询

当用户查询一个A记录的时候,如果解析器获得的结果是一个CNAME记录,则会重新发送查询将新的域名作为QNAME,来查询该域名的A类型记录。除非用户明确需要查询的是CNAME类型、

另外CNAME本身如果出现循环的话,或者CNAME的域名不存在,解析器应该返回错误信息并终止查询。

5.2.3 临时错误

解析器的网络中断或者查询某些特殊域名的所有服务器都失败,都会导致解析器查询不可用。解析器不应该返回域名数据不存在的错误,某些情况下可以尝试暂时拒绝查询,但是不推荐,比较好的处理办法是传递给客户端一些临时的错误信息,告知不可用等。

5.3 解析器内部实现

每一个解析器实现都基于不同的算法,而且大部分都需要花费很多的的代码逻辑用于错误信息的处理,此处只是给出一些推荐策略更多的参考RFC-1035

5.3.1 Stub resolver(递归服务器)

将解析器本身作为一个域名服务器,代替用户去递归查询域名,提供给企业或者多人共同使用,并且使用中心化的缓存来处理DNS查询数据。

递归服务器本身可以限制某些客户端的查询,另外递归请求可能会出现丢包或者服务器不可达的问题,需要考虑适当的重传机制或者协议方面的考虑,使用TCP往往会对整个的服务器资源带来比较大的消耗

5.3.2 资源

解析器可能与一些本地的域名服务器共享访问区数据,使得解析器能够更快速的获得结果。但是同样要保证解析器的缓存信息不要覆盖权威解析数据本身,任何查询权威数据都应该优先使用本地的数据内容,而不是缓存。

一些解析器算法中使用到的名词解释如下:

  1. SNAME : 待搜索的域名
  2. STYPE : 待查询的类型
  3. SCLASS : 待查询的类别
  4. SLIST : 一个结构包含许多的域名服务器以及对应的区数据信息。区名称,已知的域名服务器和响应的地址(以及建议的用于查询的最佳服务器),通过区数据的标签,用于决定查询的SNAME是否与其更加接近。

  5. SBELT: 从配置文件中导入的信息,列举一些域名服务器比如根服务器,至少当解析器本身没有任何本地数据的时候使用的域名服务器。

  6. CACHE: 一个结构体保存之前查询的结果,因为解析器本身还负责删除过期的数据,但部分实施转化TTL到一个绝对的时间,来用于后期的删除使用。
5.3.3 算法

解析器的主要算法包含以下几个步骤:

  1. 查询是否包含在本地信息中,如果有的话则直接返回
  2. 寻找最佳的查询服务器
  3. 发送查询到服务器,并获得响应结果。
  4. 分析响应内容,主要包含:
    • 如果响应结果包含错误信息,缓存响应数据并返回客户端
    • 如果响应消息包含其他的代理的服务器,缓存信息并返回步骤二重新发送请求
    • 如果响应包含一个CNAME, 修改SNAME为CNAME并继续返回到步骤一(前提用户查询的不是CNAME)
    • 如果服务器响应返回一个ServerFail,则在SLIST中删除此服务器并返回到步骤三重新查询

步骤一搜索缓存数据,如果数据存在在缓存中,一些解析器可以通过选项开关强制访问域名服务器(忽略任何缓存数据 ,如果解析器具有直接的访问域名服务区数据,应该检查是否期望的数据存在于权威数据中,如果存在使用权威数据而不是缓存数据。

步骤二中查询名称服务器获取需要的数据,通用策略是查询本地可用的服务器记录,并从查询域名本身开始,比如域名Mockapetris.ISI.EDU, 应该先查询Mockapetris.ISI.EDU的NS记录,如果没有则去查询 ISI.EDU,紧接着是edu.最后是根服务器,如果有新增的服务器,需要将服务器数据加入到SLIST中,对于找不到NS地址的时候,推荐的优先处理策略:

  1. 防止请求陷入循环查询,以及防止启动一些列的连锁查询
  2. 如果可以的话直接返回应答结果
  3. 避免不必要的传输
  4. 尽快给出响应

如果搜索NS失败,没有可用的NS查询的话,应当使用SBELT中的配置文件中载入的NS来发送查询内容。配置中应该包含多个根服务器的NS或本地域的NS服务器(如果本地网络属于隔离的网络)

SLIST列表中的数据包含一些域名服务器地址,应当通过某些策略来进行排序,获得最佳的查询效果,并结合一定的轮询算法,排序可以基于之前的统计信息(响应时间等)

第四部中分析结果中,解析器应当保持谨慎处理,检查查询的响应ID是否匹配,理想情况下,权威服务器响应权威应答或者返回错误信息,数据被解析器传递到客户端用户,并被保存在缓存中提供将来使用(TTL大于0);如果响应展示了一个代理的NS服务器,则解析器应当检查是否下一步查询新的NS相对于之前的SLIST中NS服务器更接近于应答结果。 如果匹配结果合适,新的域名服务器将被加入到SLIST中

6 场景演示

以下为一个简单的域名空间,包含多个区域(Root, MIL, EDU, ARPA, MIT.EDU 以及ISI.EDU),对应的域名服务器添加到括号中间。比如root服务器为(C.ISI.EDU, SRI-NIC.ARPA,A.ISI.EDU) ,同时我们可以看到C.ISI.EDU同时包含根区和edu区的数据,而A.ISI.EDU则包含根区和MIL区以及ISI.edu区数据。

                               |(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

6.1 C.ISI.EDU的名称服务器配置

C.ISI.EDU同时包含了多个区的数据,因此在配置上分隔开,下面是根服务器的区数据文件配置, 大部分的RR记录都是单行存储,除了SOA记录意外,使用(和)括号来保存所有的配置项目。由于整个的区数据都必须是同一类别,因此只需要在第一条RR记录上声明类别(这里是IN,其他选项比如CH)即可.

.       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

当权威服务器载入数据的时候,载入对应的SOA配置,这里定义了管理主机的地址为SRI-NIC.ARPA., 管理人员为HOSTMASTER@SRI-NIC.ARPA., minimum的值设置为1天,代表了所有属于此区域的权威数据的TTL为1天时间(可显示的更改),其中MIL或者EDU通过代理的方式给出对应的NS记录以及对应的glue记录IP地址。

代理出去的区数据由于不属于权威数据,因此不会使用相同的TTL作为缓存时间

6.2 标准查询

下面是一些典型的针对DNS域名的查询, 并且查询(由于针对的是权威服务器)不包含RD比特,

6.2.1 QNAME=SRI-NIC.ARPA, QTYPE=A

查询数据包的结构如下所示:

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

响应的数据大致如下面所示, 其中RESPONSE bit被设置,描述了这是一个DNS响应消息, 并且AA bit设置代表了这是一个权威应答,

               +---------------------------------------------------+
    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>                                       |
               +---------------------------------------------------+    

当我们向递归发送请求的时候,该权威应答bit不会被设置, 因为这不是一个权威的应答,除非直接向相关的NS服务器发送。

6.2.2 QNAME=SRI-NIC.ARPA, QTYPE=*

查询的类型为*, 发送包与上面的数据包大致相同,响应包的结构基本如下所示:

               +---------------------------------------------------+
    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>                                           |
               +---------------------------------------------------+

当向非权威服务器,比如递归服务器查询数据的时候,往往返回的内容可能只包含一部分数据,且TTL也不同。

6.2.3 QNAME=SRI-NIC.ARPA, QTYPE=MX

接收到的数据包格式如下所示, 尽管查询的是MX记录,服务器在响应的时候也会将对应的A地址放入additional字段中保存,

               +---------------------------------------------------+
    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      |
               +---------------------------------------------------+
6.2.4 QNAME=SRI-NIC.ARPA, QTYPE=NS

由于查询的NS记录不存在,因此尽管是权威应答所有的响应字段也都为空

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

当查询的域名不存在的时候,服务器将响应一个RCODE代表域名不存在,返回SOA记录用于否定缓存使用

           +---------------------------------------------------+
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>                                           |
           +---------------------------------------------------+

比如我们查询一个不存在的com域名的时候,将返回对应的SOA记录

com.			899 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. (
				1541729201 ; serial
				1800       ; refresh (30 minutes)
				900        ; retry (15 minutes)
				604800     ; expire (1 week)
				86400      ; minimum (1 day)
				)
6.2.6 QNAME=BRL.MIL, QTYPE=A

当向一个非权威服务器发送查询的时候,会给出对应的NS记录,并将NS对应的地址返回给客户端,放置在additinal字段中。

           +---------------------------------------------------+
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      |
           +---------------------------------------------------+

比如我们向根服务器查询www.baidu.cn的域名,由于部署权威,但是可以给出最接近的区的NS以及对应的NSglue记录。

6.2.7. QNAME=USC-ISIC.ARPA, QTYPE=A

当查询一个域名的时候,且这个域名本身是具有CNAME类型的,则查询域名

           +---------------------------------------------------+
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>                                           |
           +---------------------------------------------------+
6.2.8 QNAME=USC-ISIC.ARPA, QTYPE=A

当向A.ISI.EDU发送此查询的时候,由于A.ISI.EDU属于USC-ISIC.ARPA.的权威,因此响应如下, 包含权威应答AAbit设置为true.(A.ISI.EDU同时是ISI.EDU域的权威)

           +---------------------------------------------------+
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>                                           |
           +---------------------------------------------------+

如果向C.ISI.EDU发送请求的时候,由于仅仅包含CNAME信息因此查询终止,并响应相关的信息给服务器,包含权威应答字段中的NS记录,以及Additional字段中的Glue记录。

           +---------------------------------------------------+
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      |
           +---------------------------------------------------+
6.2.9 QNAME=USC-ISIC.ARPA, QTYPE=CNAME

当直接向 A.ISI.EDU 或者 C.ISI.EDU查询CNAME的时候,响应信息将只会返回必要的CNAME信息:

           +---------------------------------------------------+
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>                                           |
           +---------------------------------------------------+

6.3 解析实例

当解析器刚刚启动的时候,缓存内容可能会空,这里配置的查询缺省的服务器SBELT的信息如下面所示, 其中的Match count为-1代表了服务器与查询域名直接的匹配精确度不高,后期会随着使用而发生变化。

Match count = -1
SRI-NIC.ARPA.   26.0.0.73       10.0.0.51
A.ISI.EDU.      26.3.0.103
6.3.1 解析ISI.EDU的 MX记录

假设查询的第一个域名来自于邮件系统,查询邮件地址PVM@ISI.EDU.因此想要查询域名ISI.EDU.的MX记录,但是当前服务器并没有任何的缓存信息,服务器必须查询外部的权威服务器获得相关的结果,因此搜索过程如下:

  1. 缓存中查询ISI.EDU,EDU以及根服务器的NS记录
  2. 由于没有结果,解析器将检查本身的SBelt记录,也就是上面的两个服务器,并将Server信息复制到SLIST结构中
  3. 解析器从SLIST中选择服务器发送请求,并等待响应,或者超时后重试其他的服务器。
               +---------------------------------------------------+
    Header     | OPCODE=SQUERY                                     |
               +---------------------------------------------------+
    Question   | QNAME=ISI.EDU., QCLASS=IN, QTYPE=MX               |
               +---------------------------------------------------+
    Answer     | <empty>                                           |
               +---------------------------------------------------+
    Authority  | <empty>                                           |
               +---------------------------------------------------+
    Additional | <empty>                                           |
               +---------------------------------------------------+
  1. 当接收到正常的解析响应的时候,比如下面的:
    
                +---------------------------------------------------+
     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     |
                +---------------------------------------------------+
    

当收到上面的响应的时候,NS服务器更接近于当前需要查询的域名的数据,因此缓存该信息到SLIST中, 并重新发送请求到这些新的服务器上,

    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

最终的响应信息是:

           +---------------------------------------------------+
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             |
           +---------------------------------------------------+
6.3.2 获取地址的主机名

当我们查询一个地址26.6.0.65的主机名的时候,解析器将请求转为查询65.0.6.26.IN-ADDR.ARPA.的PTR记录,由于此时也没有合适的服务器供查询,因此还是查询了SBLET服务器,并最终获得响应信息如下:

   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 获得poneria.ISI.EDU主机IP地址

当查询域名poneria.ISI.EDU的地址的时候,转化为查询他的A类型,尽管没有查找到直接的缓存信息,但是由于包含新的ISI.EDU的NS记录因此,查询将发送给缓存的地址并最终获得响应。