非官方中文译本声明:本页为 IETF RFC 1034《DOMAIN NAMES - CONCEPTS AND FACILITIES》 的非官方中文译本,由 ztpop.net 整理翻译,仅供学习参考。RFC 文档由 IETF 发布、不受版权限制;依据 BCP 78,本译本为署名翻译作品,译文力求忠实但不构成官方版本,权威性以英文原文为准。英文原文见 rfc-editor.org/rfc/rfc1034。
RFC 1034《域名系统——概念与设施》中文译本
摘要
本文档是域名系统(DNS)的入门性总纲。它介绍域式名称(domain style names)及其在互联网邮件和主机地址支持中的用途,并描述用于实现域名设施(domain name facilities)的协议与服务器。本文档定义了域名空间与资源记录的概念、名称服务器与解析器的角色、委派与缓存机制,并通过一个完整场景展示 DNS 的工作方式。许多实现层面的细节略去不述,可在姊妹篇 RFC 1035《域名系统——实现与规范》[RFC-1035] 中找到;两者共同构成互联网标准 STD 13。
1. 本备忘录的状态
本 RFC 是对域名系统(DNS)的入门性介绍,略去了许多细节;这些细节可在姊妹篇 RFC《域名——实现与规范》[RFC-1035] 中找到。该 RFC 假定读者已熟悉本备忘录中所讨论的概念。
DNS 功能与数据类型的一个子集构成官方协议(official protocol)。官方协议包括标准查询及其响应,以及大部分互联网类别(Internet class)的数据格式(例如主机地址)。
然而,域名系统是有意设计为可扩展的。研究人员不断提出、实现并试验新的数据类型、查询类型、类别、功能等。因此,尽管官方协议的组成部分预计将基本保持不变、并作为生产性服务运行,但在官方协议之外的扩展中,应始终预期会出现实验性行为。实验性或已废弃的特性在这两篇 RFC 中均有明确标注,此类信息应谨慎使用。
特别提醒读者:不要依赖示例中出现的数值是最新或完整的,因为这些数值的主要目的是教学。本备忘录的分发不受限制。
2. 引言
本 RFC 介绍域式名称、它们在互联网邮件和主机地址支持中的用途,以及用于实现域名设施的协议与服务器。
2.1. 域名系统的历史
推动域名系统发展的动力是互联网的增长:
- 主机名到地址的映射由网络信息中心(NIC)在单一文件(HOSTS.TXT)中维护,所有主机通过 FTP 获取该文件 [RFC-952, RFC-953]。通过这种方案分发新版本所消耗的网络总带宽与网络中主机数量的平方成正比,即使采用多级 FTP,NIC 主机上的出站 FTP 负载也相当可观。主机数量的爆炸式增长对该方案的未来而言并非吉兆。
- 网络用户群体的性质也在发生变化。构成最初 ARPANET 的分时主机正被工作站的局域网络所取代。本地组织自行管理自己的名称和地址,但必须等待 NIC 修改 HOSTS.TXT,才能使这些变更对整个互联网可见。各组织还希望在名称空间上具有一定的本地结构。
- 互联网上的应用日益复杂,产生了对通用名称服务(general purpose name service)的需求。
结果是出现了若干关于名称空间及其管理的构想 [IEN-116, RFC-799, RFC-819, RFC-830]。这些提案各不相同,但共同点是层级式名称空间的想法:层级大致对应于组织结构,名称使用 "." 作为标记层级之间边界的字符。采用分布式数据库和通用资源的设计在 [RFC-882, RFC-883] 中有所描述。基于多个实现的经验,该系统最终演变为本备忘录所描述的方案。
"域"(domain)或"域名"(domain name)这两个术语在诸多语境中被使用,超出了本文所描述的 DNS 范围。很多时候,"域名"一词被用来指代由点表示结构、但与 DNS 毫无关系的名称。这在邮件寻址中尤为常见 [Quarterman 86]。
2.2. DNS 的设计目标
DNS 的设计目标影响其结构。这些目标是:
- 首要目标是建立一个一致的名称空间,用于引用资源。为避免临时拼凑的编码所造成的问题,不应要求名称中包含网络标识符、地址、路由或类似信息作为名称的一部分。
- 数据库的庞大体积和更新频率表明,数据库必须以分布式方式维护,并通过本地缓存来提高性能。试图汇集整个数据库一致副本的做法将变得越来越昂贵和困难,因此应当避免。同样的原则也适用于名称空间的结构,尤其是名称的创建与删除机制;这些机制也应当是分布式的。
- 在获取数据的成本、更新的速度与缓存的准确性之间存在权衡取舍时,数据源应当控制这一权衡。
- 实现此类设施的成本决定了它应当具有通用性,而不应局限于单一应用。我们应当能够使用名称来检索主机地址、邮箱数据以及其它尚待确定的信息。与名称关联的所有数据都带有类型标签,查询可以限定为单一类型。
- 因为我们希望名称空间在不同类型的网络和应用中都有用,所以提供了在相同名称空间下使用不同协议族或管理方式的能力。例如,主机地址格式在不同协议间有所差异,尽管所有协议都有地址的概念。DNS 为所有数据同时标注类别(class)与类型(type),从而使不同格式的数据可以并行用于地址类型的数据。
- 我们希望名称服务器的事务处理独立于承载它们的通信系统。有些系统可能希望用数据报进行查询和响应,仅为需要可靠性的交易(例如数据库更新、长事务)建立虚电路;另一些系统则将完全使用虚电路。
- 该系统应能在广泛的主机能力范围内发挥作用。个人计算机和大型分时主机都应能够使用该系统,尽管使用方式可能有所不同。
2.3. 关于使用的假设
域名系统的组织源自对其用户群体的需求与使用模式的一些假设,其设计目的是避免通用数据库系统中常见的许多复杂问题。
这些假设是:
- 整个数据库的规模最初将与使用该系统的主机数量成正比,但随着邮箱及其它信息被加入域名系统,它最终将增长为与这些主机上的用户数量成正比。
- 系统中的大部分数据变化非常缓慢(例如邮箱绑定、主机地址),但系统应当能够处理变化更快的数据子集(秒级或分钟级)。
- 用于分配数据库管理责任的行政边界通常对应于拥有一台或多台主机的组织。每个负责一组特定域的组织都将提供冗余的名称服务器,无论是在组织自己的主机上,还是在组织安排使用的其它主机上。
- 域名系统的客户端应当能够在接受指向"受信任"集合之外名称服务器的转介(referrals)之前,识别出自己优先使用的受信任名称服务器。
- 对信息的可访问性比即时更新或一致性保证更为关键。因此,更新过程允许更新通过域名系统的使用者逐渐扩散,而不是保证所有副本同时更新。当由于网络或主机故障而无法更新时,通常的做法是相信旧信息,同时继续努力更新它。一般模型是:副本以带有刷新超时的方式分发。分发者设置超时值,分发的接收者负责执行刷新。在特殊情况下,可以指定非常短的间隔,或者所有者可以禁止复制。
- 在任何拥有分布式数据库的系统中,某个名称服务器可能会遇到只能由其它服务器回答的查询。处理这一问题的两种通用方法是"递归"(recursive)和"迭代"(iterative):前者由第一个服务器在另一台服务器处为客户端继续追查查询;后者由服务器将客户端转介到另一台服务器,让客户端自行继续追查。两种方法各有利弊,但对于数据报式访问,迭代方法更受青睐。域名系统要求实现迭代方法,但允许将递归方法作为一种可选项。
域名系统假定所有数据都源自散布在使用域名系统的主机中的主文件(master files)。这些主文件由本地系统管理员更新。主文件是文本文件,由本地名称服务器读取,因此可以通过名称服务器提供给域名系统的用户使用。用户程序通过称为解析器(resolvers)的标准程序访问名称服务器。
主文件的标准格式使它们能够在主机之间交换(通过 FTP、邮件或其它机制);当一个组织想要拥有一个域、却不想自行支持名称服务器时,这一设施很有用。该组织可以用文本编辑器在本地维护主文件,将它们传送到一台运行名称服务器的外部主机上,然后与该名称服务器的系统管理员协商加载这些文件。
每台主机的名称服务器和解析器都由本地系统管理员配置 [RFC-1033]。对于名称服务器,此配置数据包括本地主文件的标识,以及关于应从外部服务器加载哪些非本地主文件的指令。名称服务器使用主文件或其副本加载自己的区(zones)。对于解析器,配置数据标识哪些名称服务器应作为主要信息来源。
域名系统定义了访问数据以及转介到其它名称服务器的过程。域名系统还定义了缓存检索到的数据以及按系统管理员规定定期刷新数据的过程。
系统管理员提供:
- 区边界的定义。
- 数据主文件。
- 主文件的更新。
- 所需刷新策略的声明。
域名系统提供:
- 资源数据的标准格式。
- 查询数据库的标准方法。
- 名称服务器从外部名称服务器刷新本地数据的标准方法。
2.4. DNS 的构成要素
DNS 有三个主要组成部分:
- 域名空间与资源记录(DOMAIN NAME SPACE and RESOURCE RECORDS),即树状结构名称空间及其与名称关联数据的规范。从概念上讲,域名空间树的每个节点和叶子命名一组信息,查询操作就是从特定信息组中提取特定类型信息的尝试。查询给出感兴趣的域名,并描述所需资源信息的类型。例如,互联网用其部分域名来标识主机;对地址资源的查询返回互联网主机地址。
- 名称服务器(NAME SERVERS),即保存域名树结构信息与集合信息的服务器程序。名称服务器可以缓存域名树任何部分的结构信息或集合信息,但一般而言,某个名称服务器只对域名空间的一个子集拥有完整信息,并持有指向其它名称服务器的指针,这些指针可用来通向域名树任何部分的信息。名称服务器知道自己对域名树的哪些部分拥有完整信息;称该名称服务器是名称空间这些部分的权威(AUTHORITY)。权威信息被组织成称为区(ZONE)的单元,这些区可以自动分发给为区内数据提供冗余服务的名称服务器。
- 解析器(RESOLVERS),即响应客户端请求、从名称服务器提取信息的程序。解析器必须能够访问至少一台名称服务器,并利用该名称服务器的信息直接回答查询,或利用对其它名称服务器的转介继续追查查询。解析器通常是一个用户程序可直接访问的系统例程;因此解析器与用户程序之间无需协议。
这三个组成部分大致对应于域名系统的三个层次或视图:
- 从用户的角度看,域名系统通过简单的过程调用或操作系统调用访问本地解析器。域名空间由单一棵树构成,用户可以请求树中任何部分的信息。
- 从解析器的角度看,域名系统由数量未知的名称服务器组成。每台名称服务器拥有整个域名树数据的一部分或多部分,但解析器将这些数据库中的每一个都视为本质上静态的。
- 从名称服务器的角度看,域名系统由称为区的独立本地信息集组成。名称服务器本地保存着其中一些区的副本。名称服务器必须定期从本地文件或外部名称服务器中的主副本刷新自己的区。名称服务器必须同时处理来自解析器的查询。
出于性能考虑,实现可以将这些功能耦合在一起。例如,与名称服务器位于同一台机器上的解析器可能共享一个数据库,该数据库由名称服务器管理的区和解析器管理的缓存组成。
3. 域名空间与资源记录
3.1. 名称空间规范与术语
域名空间是一种树状结构。树上的每个节点和叶子都对应一个资源集(可以为空)。域名系统不区分内部节点与叶子的用途,本文档用"节点"(node)一词统称两者。
每个节点都有一个标签(label),长度为 0 到 63 个八位组。兄弟节点不得使用相同的标签,但非兄弟节点可以使用相同标签。有一个标签被保留,即用于根的 null(零长度)标签。
节点的域名是沿从该节点到树根的路径上的标签列表。按惯例,组成域名的标签从左到右书写或阅读,从最具体(最低、离根最远)到最不具体(最高、离根最近)。
在内部,操作域名的程序应当将域名表示为标签序列,其中每个标签由一个长度八位组后跟一个八位组字符串组成。由于所有域名都终止于根,而根的标签是空字符串,因此这些内部表示可以用一个零长度字节来终止域名。
按惯例,域名可以以任意大小写形式存储,但当前所有域名功能的域名比较都以不区分大小写的方式进行,假定使用 ASCII 字符集且高位为零。这意味着你可以自由创建标签为 "A" 的节点或标签为 "a" 的节点,但不能同时作为兄弟节点;你可以用 "a" 或 "A" 引用其中任何一个。当你收到域名或标签时,应当保留其大小写。这一选择的原因是:我们可能有一天需要为新的服务增加完整的二进制域名;现有服务将不会改变。
当用户需要输入域名时,会省略每个标签的长度,标签之间用点(".")分隔。由于完整域名以根标签结尾,这导致打印形式以点结尾。我们利用这一特性来区分:
- 表示完整域名的字符串(通常称为"绝对"名称)。例如,"poneria.ISI.EDU."。
- 表示不完整域名起始标签的字符串,应由本地软件利用对本地域的了解来补全(通常称为"相对"名称)。例如,在 ISI.EDU 域中使用的 "poneria"。
相对名称要么相对于一个众所周知的源点(origin),要么相对于用作搜索列表(search list)的域列表。相对名称主要出现在用户界面(那里的解释因实现而异)和主文件中(那里它们相对于单一的源点域名)。最常见的解释是把根 "." 用作单一源点或搜索列表的成员之一,因此多标签的相对名称通常是省略了末尾点以节省输入的名称。
为简化实现,表示域名的八位组总数(即所有标签八位组与标签长度之和)被限制为 255。
域由域名标识,由域名空间中处于指定该域的域名处或其下方的部分构成。如果一个域包含在另一个域之内,则它是那个域的子域。可以通过查看子域的名称是否以包含它的域名结尾来检验这种关系。例如,A.B.C.D 是 B.C.D、C.D、D 和 " "(根)的子域。
3.2. 管理层面的使用指南
作为一项政策,DNS 技术规范并不强制规定特定的树结构或标签选择规则;其目标是尽可能通用,以便用于构建任意应用。特别是,该系统的设计使名称空间不必按照网络边界、名称服务器等来组织。这样做的理由并不是名称空间不应有隐含语义,而是隐含语义的选择应留待针对手头的问题来决定,并且树的不同部分可以有不同的隐含语义。例如,IN-ADDR.ARPA 域按网络和主机地址组织与分发,因为它的作用是将网络号或主机号转换为名称;NetBIOS 域 [RFC-1001, RFC-1002] 是扁平的,因为这适合该应用。
不过,有一些适用于名称空间中用于主机、邮箱等的"常规"部分的指南,它们将使名称空间更加统一、为增长留出余地,并在软件从旧主机表迁移时最大限度地减少问题。关于树顶层的政策性决定源自 RFC-920。当前关于顶层的政策在 [RFC-1032] 中讨论。MILNET 迁移问题在 [RFC-1031] 中涉及。
那些最终将被划分为多个区的较低层域,应当在域的顶部就提供分叉,以便最终的分解可以在不改名的情况下完成。使用特殊字符、前导数字等的节点标签很可能会破坏依赖更严格命名的旧软件。
3.3. 技术层面的使用指南
在 DNS 被用来为某种对象保存命名信息之前,必须满足两个需求:
- 对象名与域名之间映射的约定。这描述了如何访问关于对象的信息。
- 用于描述对象的 RR 类型与数据格式。
这些规则可以非常简单,也可以相当复杂。很多时候,设计者必须考虑现有格式,并为现有用途规划向上兼容性。可能需要多种映射或多层映射。
对于主机,映射取决于现有主机名语法(它是域名常用文本表示的一个子集),以及用于描述主机地址等的 RR 格式。因为我们还需要从地址到主机名的可靠反向映射,所以还定义了将地址映射到 IN-ADDR.ARPA 域的特殊映射。
对于邮箱,映射稍复杂一些。常见的邮件地址 <local-part>@<mail-domain> 映射为域名的方法是:将 <local-part> 转换为单个标签(无论其中包含多少个点),用域名常用的文本格式(点表示标签分隔)将 <mail-domain> 转换为域名,然后将两者拼接成一个域名。因此,邮箱 HOSTMASTER@SRI-NIC.ARPA 用域名表示为 HOSTMASTER.SRI-NIC.ARPA。要充分理解这一设计背后的原因,还必须考虑邮件交换的方案 [RFC-974]。
普通用户无需关心这些规则的定义,但应当明白,它们通常是多种妥协的结果:与旧用途向上兼容的愿望、不同对象定义之间的相互影响,以及定义规则时不可避免的添加新功能的冲动。DNS 被用来支持某种对象的方式,往往比 DNS 固有的限制更为关键。
3.4. 名称空间示例
下图展示了当前域名空间的一部分,本 RFC 中的许多示例都会用到它。请注意,这棵树只是实际名称空间的一个很小的子集。
|
|
+---------------------+------------------+
| | |
MIL EDU ARPA
| | |
| | |
+-----+-----+ | +------+-----+-----+
| | | | | | |
BRL NOSC DARPA | IN-ADDR SRI-NIC ACC
|
+--------+------------------+---------------+--------+
| | | | |
UCI MIT | UDEL YALE
| ISI
| |
+---+---+ |
| | |
LCS ACHILLES +--+-----+-----+--------+
| | | | | |
XX A C VAXA VENERA Mockapetris
在本例中,根域有三个直接子域:MIL、EDU 和 ARPA。LCS.MIT.EDU 域有一个名为 XX.LCS.MIT.EDU 的直接子域。所有的叶子也都是域。
3.5. 推荐的名称语法
DNS 规范试图在构造域名的规则上尽可能通用。其想法是,任何现有对象的名称都可以以最小的改动表示为域名。然而,在为对象分配域名时,谨慎的用户会选择既满足域名系统规则、又满足该对象任何现有规则(无论是已发布的还是现有程序隐含的)的名称。
例如,在命名邮件域时,用户应当同时满足本文档的规则和 RFC-822 中的规则。在创建新主机名时,应当遵循旧 HOSTS.TXT 的规则。这可以避免旧软件改用域名时出现问题。
以下语法将减少使用域名(例如邮件、TELNET)的许多应用中出现的问题。
<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
请注意,虽然域名中允许使用大写和小写字母,但大小写不具有任何意义。也就是说,拼写相同但大小写不同的两个名称应被视为相同。
标签必须遵循 ARPANET 主机名的规则。它们必须以字母开头,以字母或数字结尾,内部字符只能是字母、数字和连字符。长度也有一些限制。标签必须为 63 个字符或更少。
例如,以下字符串标识互联网中的主机:
A.ISI.EDU XX.LCS.MIT.EDU SRI-NIC.ARPA
3.6. 资源记录
域名标识一个节点。每个节点都有一组资源信息,可以为空。与特定名称关联的资源信息组由若干独立的资源记录(RR)组成。组中 RR 的顺序不重要,名称服务器、解析器或 DNS 的其它部分无需保留该顺序。
当我们谈论特定 RR 时,假定它具有以下组成部分:
owner(所有者)—— RR 所在的域名。
type(类型)—— 一个编码的 16 位值,指定该资源记录国内域名服务商的类型。类型指抽象资源。
本文档使用以下类型:
- A —— 主机地址(a host address)
- CNAME —— 标识别名对应的规范名称(identifies the canonical name of an alias)
- HINFO —— 标识主机使用的 CPU 和操作系统(identifies the CPU and OS used by a host)
- MX —— 标识该域的邮件交换。详见 [RFC-974](identifies a mail exchange for the domain)
- 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(类别)—— 一个编码的 16 位值,标识协议族或协议的一个实例。
本文档使用以下类别:
- IN —— 互联网系统(the Internet system)
- CH —— Chaos 系统(the Chaos system)
TTL —— RR 的生存时间(time to live)。该字段是一个以秒为单位的 32 位整数,主要供解析器缓存 RR 时使用。TTL 描述一个 RR 在被丢弃之前可以缓存多长时间。
RDATA —— 描述资源的、随类型有时也随类别而变的数据:
- A —— 对于 IN 类,是一个 32 位 IP 地址;对于 CH 类,是一个域名后跟一个 16 位八进制 Chaos 地址。
- CNAME —— 一个域名。
- MX —— 一个 16 位优先级值(越小越优先),后跟一个愿意为该所有者域充当邮件交换的主机名。
- NS —— 一个主机名。
- PTR —— 一个域名。
- SOA —— 若干字段。
所有者名称通常是隐含的,而不是构成 RR 的完整组成部分。例如,许多名称服务器在内部为名称空间构建树或散列结构,并把 RR 链接在节点之下。RR 的其余部分是固定的头部(类型、类别、TTL),对所有 RR 一致,以及一个可变的资源描述部分(RDATA),以满足所描述资源的需要。
TTL 字段的含义是一个 RR 可以保存在缓存中的时间上限。该限制不适用于区中的权威数据;权威数据也有超时,但由区的刷新策略控制。TTL 由数据源区的管理员分配。虽然短 TTL 可以最大限度地减少缓存,零 TTL 则禁止缓存,但互联网性能的现实表明,对典型主机而言这些时间应当以天为量级。如果可以预见到变更,可以在变更前降低 TTL 以最大限度地减少变更期间的不一致,然后在变更后恢复到原来的值。
RR 的 RDATA 部分中的数据以二进制字符串和域名的组合形式承载。域名经常被用作 DNS 中其它数据的"指针"。
3.6.1. RR 的文本表示
RR 在 DNS 协议的报文中以二进制形式表示,存储在名称服务器或解析器中时通常以高度编码的形式表示。在本文档中,我们采用类似于主文件的风格来展示 RR 的内容。在这种格式中,大多数 RR 显示为单行,但也可以使用括号来续行。
行首给出 RR 的所有者。如果一行以空白开头,则假定其所有者与前一 RR 相同。为便于阅读,通常还会加入空行。
在所有者之后,列出该 RR 的 TTL、类型和类别。类别和类型使用上面定义的助记符,TTL 是类型字段前的整数。为避免解析歧义,类型和类别的助记符互不重叠,TTL 是整数,类型助记符总是在最后。为清晰起见,示例中经常省略 IN 类别和 TTL 值。
RR 的资源数据或 RDATA 部分则依据该数据的典型表示形式给出。
例如,我们可以把报文中承载的 RR 显示为:
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
MX RR 的 RDATA 部分由一个 16 位数字后跟一个域名组成。地址 RR 使用标准的 IP 地址格式来容纳 32 位互联网地址。
此示例显示六条 RR,分布在三个域名,每个域名两条。
类似地,我们可能看到:
XX.LCS.MIT.EDU. IN A 10.0.0.44
CH A MIT.EDU. 2420
此示例显示 XX.LCS.MIT.EDU 的两个地址,每个地址属于不同的类别。
3.6.2. 别名与规范名称
在现有系统中,主机和其它资源通常有多个名称标识同一资源。例如,名称 C.ISI.EDU 和 USC-ISIC.ARPA 都标识同一台主机。类似地,对于邮箱,许多组织提供多个实际指向同一邮箱的名称;例如 Mockapetris@C.ISI.EDU、Mockapetris@B.ISI.EDU 和 PVM@ISI.EDU 都指向同一个邮箱(尽管其背后的机制有些复杂)。
这些系统大多有这样的概念:等价名称组中的一个名称是规范名称(canonical name)或主名称(primary name),其余都是别名。
域名系统通过规范名称(CNAME)RR 提供这一功能。CNAME RR 将其所有者名称标识为别名,并在 RR 的 RDATA 部分指定相应的规范名称。如果某节点存在 CNAME RR,则不应存在其它数据;这确保规范名称及其别名的数据不可能不同。这一规则还确保缓存的 CNAME 可以直接使用,无需向权威服务器检查其它 RR 类型。
CNAME RR 会在 DNS 软件中引发特殊动作。当名称服务器在与域名关联的资源集中找不到所需的 RR 时,它会检查该资源集是否由一条类别匹配的 CNAME 记录构成。如果是,名称服务器会在响应中包含这条 CNAME 记录,并在 CNAME 记录数据字段指定的域名处重新开始查询。此规则的唯一例外是:匹配 CNAME 类型的查询不会重新开始。
例如,假设一台名称服务器正在处理针对 USC-ISIC.ARPA、请求类型 A 信息的查询,并拥有以下资源记录:
USC-ISIC.ARPA IN CNAME C.ISI.EDU
C.ISI.EDU IN A 10.0.0.52
对类型 A 查询的响应将同时返回这两条 RR,而类型 CNAME 或 * 的查询则应只返回 CNAME。
RR 中指向另一名称的域名应始终指向主名称,而不是别名。这可以避免访问信息时产生额外的间接跳转。例如,上述主机的地址到名称 RR 应为:
52.0.0.10.IN-ADDR.ARPA IN PTR C.ISI.EDU
而不是指向 USC-ISIC.ARPA。当然,根据稳健性原则,域软件在遇到 CNAME 链或 CNAME 环时不应失败;应跟随 CNAME 链,并将 CNAME 环作为错误发出信号。
3.7. 查询
查询是发送给名称服务器以引出响应的消息。在互联网中,查询通过 UDP 数据报或 TCP 连接承载。名称服务器的响应要么回答查询中提出的问题,要么将请求者转介到另一组名称服务器,要么发出某种错误条件的信号。
一般而言,用户不直接生成查询,而是向解析器发出请求,解析器再向名称服务器发送一条或多条查询,并处理可能产生的错误条件和转介。当然,查询中可提出的问题确实会塑造解析器能提供的服务类型。
DNS 查询和响应以标准消息格式承载。消息格式有一个包含若干固定字段的头部(这些字段始终存在),以及四个承载查询参数与 RR 的区段。
头部中最重要的字段是一个称为操作码(opcode)的四位字段,用于区分不同的查询。在可能的 16 个值中,一个(标准查询)属于官方协议,两个(反向查询和状态查询)是可选项,一个(补全查询)已废弃,其余未分配。
四个区段是:
- 问题(Question)—— 承载查询名称和其它查询参数。
- 回答(Answer)—— 承载直接回答查询的 RR。
- 权威(Authority)—— 承载描述其它权威服务器的 RR。可以选择性地携带回答区段中权威数据的 SOA RR。
- 附加(Additional)—— 承载可能有助于使用其它区段 RR 的 RR。
请注意,这些区段的内容随头部操作码而变化,但格式不变。
3.7.1. 标准查询
标准查询指定目标域名(QNAME)、查询类型(QTYPE)和查询类别(QCLASS),并请求与之匹配的 RR。这种类型的查询占 DNS 查询的绝大多数,因此除非另有说明,我们用"查询"一词指标准查询。QTYPE 和 QCLASS 字段各长 16 位,是已定义类型和类别的超集。
QTYPE 字段可以包含:
- <any type> —— 匹配恰好该类型(例如 A、PTR)。
- AXFR —— 特殊的区传送 QTYPE。
- MAILB —— 匹配所有与邮箱相关的 RR(例如 MB 和 MG)。
- * —— 匹配所有 RR 类型。
QCLASS 字段可以包含:
- <any class> —— 匹配恰好该类别(例如 IN、CH)。
- * —— 匹配所有 RR 类别。
名称服务器使用查询域名、QTYPE 和 QCLASS 查找匹配的 RR。除了相关记录之外,名称服务器还可能返回指向拥有所需信息名称服务器的 RR,或返回预期有助于解释相关 RR 的 RR。例如,一台没有请求信息的名称服务器可能知道哪台名称服务器有;一台在相关 RR 中返回域名的名称服务器也可能返回将该域名绑定到地址的 RR。
例如,一个试图向 Mockapetris@ISI.EDU 发送邮件的邮件程序可能会向解析器请求关于 ISI.EDU 的邮件信息,从而产生 QNAME=ISI.EDU、QTYPE=MX、QCLASS=IN 的查询。响应的回答区段将是:
ISI.EDU. MX 10 VENERA.ISI.EDU.
MX 10 VAXA.ISI.EDU.
而附加区段可能是:
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=* 结构在权威性方面需要特殊解释。由于特定名称服务器可能不知道域名系统中可用的所有类别,它永远无法知道自己是否对所有类别都是权威的。因此,对 QCLASS=* 查询的响应永远不可能是权威的。
3.7.2. 反向查询(可选)
名称服务器还可以支持反向查询(inverse queries),将特定资源映射到拥有该资源的域名。例如,标准查询可能将域名映射到 SOA RR,而相应的反向查询可能将 SOA RR 映射回域名。
在名称服务器中,实现该服务是可选的,但所有名称服务器至少必须能够理解反向查询消息并返回"未实现"的错误响应。
域名系统无法保证反向查询的完整性或唯一性,因为域名系统按域名组织,而不是按主机地址或任何其它资源类型组织。反向查询主要用于调试和数据库维护活动。
反向查询可能无法返回正确的 TTL,也不会指明所标识的 RR 是集合中的一个(例如,具有多个地址的主机的一个地址)这类情况。因此,反向查询返回的 RR 绝不应被缓存。
反向查询不是将主机地址映射到主机名的可接受方法;请改用 IN-ADDR.ARPA 域。
[RFC-1035] 中包含对反向查询的详细讨论。
3.8. 状态查询(实验性)
待定义。
3.9. 补全查询(已废弃)
RFC 882 和 883 中描述的可选补全服务已被删除。未来可能出现重新设计的服务,或者这些操作码可能被收回用于其它用途。
4. 名称服务器
4.1. 引言
名称服务器是构成域数据库的信息仓库。数据库被划分为称为区的部分,分布在各名称服务器之间。虽然名称服务器可以有若干可选功能和数据源,但名称服务器的基本任务是使用其区中的数据回答查询。按设计,名称服务器可以以简单的方式回答查询;响应总是可以仅使用本地数据生成,要么包含问题的答案,要么是对"更接近"所需信息的其它名称服务器的转介。
某个区将从多台名称服务器上可用,以确保即使发生主机或通信链路故障也能获得该区。根据行政规定,我们要求每个区至少在两台服务器上可用,许多区拥有比这更多的冗余。
某台名称服务器通常支持一个或多个区,但这只使它拥有域名树一小部分的权威信息。它还可能拥有树其它部分的一些缓存非权威数据。名称服务器会对其查询响应做标记,使请求者能够分辨响应是否来自权威数据。
4.2. 数据库如何划分为区
域数据库以两种方式划分:按类别划分,以及按名称空间中节点之间所作的"切分"(cuts)划分。
类别划分很简单。任何类别的数据库都独立于所有其它类别进行组织、委派和维护。由于按惯例所有类别的名称空间相同,因此各个类别可以视为一组平行的名称空间树。请注意,这些不同的平行类别所挂接在节点上的数据将有所不同。创建新类别最常见的原因是为现有类型提供新的数据格式,或者希望拥有独立管理的现有名称空间版本。
在一个类别内,名称空间中的"切分"可以在任意两个相邻节点之间进行。完成所有切分后,每个连通的名称空间组就是一个独立的区。称该区对连通区域内的所有名称都是权威的。请注意,不同类别的名称空间"切分"可能位于不同位置,名称服务器也可能不同,等等。
这些规则意味着每个区至少拥有一个它对其权威的节点(从而拥有一个域名),并且特定区中的所有节点都是连通的。鉴于树状结构,每个区都有一个最高的节点,它比区中任何其它节点都更接近根。该节点的名称常被用来标识这个区。
将名称空间划分成每个域名一个区,或者所有节点都在一个区中,是可能的,但并不是特别有用。相反,数据库是在特定组织希望接管某个子树控制权的位置进行划分的。一旦组织控制了自己的区,它就可以单方面更改区中的数据、扩展与区相连的新树段、删除现有节点,或在它的区下委派新的子区。
如果组织具有子结构,它可能希望进行进一步的内部划分,以实现名称空间控制的嵌套委派。在某些情况下,这种划分纯粹是为了使数据库维护更方便。
4.2.1. 技术考量
描述一个区的数据有四个主要部分:
- 区中所有节点的权威数据。
- 定义区顶端节点的数据(可以视为权威数据的一部分)。
- 描述已委派子区的数据,即区底部的切分。
- 允许访问子区名称服务器的数据(有时称为"胶水"(glue)数据)。
所有这些数据都以 RR 的形式表示,因此一个区可以用一组 RR 来完整描述。整个区可以通过传送 RR 在名称服务器之间传输,要么由一系列消息承载,要么通过 FTP 传送作为文本表示的主文件。
区的权威数据就是:从区顶端节点向下直到叶子节点或区底边切分上方节点的所有节点所挂接的所有 RR。
虽然逻辑上是权威数据的一部分,但描述区顶端节点的 RR 对区的管理尤为重要。这些 RR 有两种类型:逐条列出该区所有服务器的名称服务器 RR,以及一条描述区管理参数的 SOA RR。
描述区底部切分的 RR 是指明子区服务器的 NS RR。由于切分位于节点之间,这些 RR 不属于区的权威数据,并且应当与子区顶端节点处相应的 RR 完全相同。由于名称服务器总是与区边界相关联,NS RR 只出现在作为某个区顶端节点的节点处。在构成区的数据中,NS RR 出现在区的顶端节点处(它们是权威的)和区底部的切分处(它们不是权威的),但绝不出现在两者之间。
区结构的目标之一是:任何区都拥有与其任何子区名称服务器建立通信所需的全部数据。也就是说,父区拥有访问其子区服务器所需的全部信息。指明子区服务器的 NS RR 往往不足以完成此任务,因为它们指明了服务器,却没有给出其地址。特别是,如果名称服务器的名称本身位于子区中,我们可能面临这样的局面:NS RR 告诉我们,为了获知名称服务器的地址,应该用我们想获知的地址去联系该服务器。为解决这一问题,区中包含一些"胶水"(glue)RR,它们不属于权威数据,是服务器的地址 RR。只有当名称服务器的名称位于切分"下方"时才需要这些 RR,并且它们仅用作转介响应的一部分。
4.2.2. 管理考量
当某个组织想要控制自己的域时,第一步是确定合适的父区,并让父区的所有者同意控制权的委派。虽然就树的哪个位置可以进行委派没有特别的技术限制,但 [RFC-1032] 中讨论了一些涉及顶层组织的管理分组,中层区可以自由制定自己的规则。例如,一所大学可能选择使用单一区,而另一所大学可能选择按专门面向各系或学院的子区来组织。[RFC-1033] 收录了可用的 DNS 软件并讨论了管理程序。
一旦为新子区选定合适的名称,就应要求新所有者证明具备冗余的名称服务器支持。请注意,并不要求区的服务器驻留在拥有该域内名称的主机上。在许多情况下,如果区的服务器广泛分布,而不是位于管理该区的同一组织所控制的物理设施内,则该区对整个互联网将更容易访问。例如,在当前 DNS 中,英国(UK)域的一台名称服务器位于美国。这使美国主机能够获取英国的数据,而无需使用有限的跨大西洋带宽。
作为安装的最后一步,应把使委派生效所需的委派 NS RR 和胶水 RR 添加到父区。两个区的管理员都应确保标记切分两侧的 NS 和胶水 RR 保持一致,并持续保持。
4.3. 名称服务器的内部机制
4.3.1. 查询与响应
名称服务器的主要活动是回答标准查询。查询及其响应都以 [RFC-1035] 中描述的标准消息格式承载。查询包含 QTYPE、QCLASS 和 QNAME,分别描述所需信息的类型与类别以及感兴趣的名称。
名称服务器回答查询的方式取决于它是否以递归模式运行:
- 对服务器而言最简单的模式是非递归,因为它可以仅使用本地信息回答查询:响应包含错误、答案,或对某个"更接近"答案的其它服务器的转介。所有名称服务器必须实现非递归查询。
- 对客户端而言最简单的模式是递归,因为在这种模式下,名称服务器扮演解析器的角色,只返回错误或答案,绝不返回转介。该服务在名称服务器中是可选的,名称服务器还可以选择限制能够使用递归模式的客户端。
递归服务在几种情况下很有帮助:
- 相对简单的请求者,除了问题的直接答案之外无法使用其它任何东西。
- 需要跨越协议或其它边界的请求,可以发送给能够充当中间人的服务器。
- 我们希望集中缓存的网络,而不是为每个客户端设置独立缓存。
如果请求者能够继续追查转介,并且对有助于未来请求的信息感兴趣,则非递归服务是合适的。
递归模式的使用限于客户端和名称服务器都同意使用的情况。该协议通过查询和响应消息中的两个位进行协商:
- 递归可用(recursion available,RA)位由名称服务器在所有响应中设置或清除。如果名称服务器愿意为该客户端提供递归服务,该位为真,无国产邮件系统户端是否请求了递归服务。也就是说,RA 表示可用性而非使用。
- 查询中包含一个称为期望递归(recursion desired,RD)的位。该位指明请求者是否希望对此查询获得递归服务。客户端可以向任何名称服务器请求递归服务,不过它们应当只依赖那些先前发送过 RA 的服务器,或通过 DNS 协议之外的私下协议或其它方式同意提供服务的服务器。
当设置了 RD 的查询到达一台愿意提供递归服务的服务器时,就发生递归模式;客户端可以通过检查响应中 RA 和 RD 是否都置位来验证是否使用了递归模式。请注意,除非通过 RD 请求,名称服务器绝不应执行递归服务,因为这会干扰对名称服务器及其数据库的故障排查。
如果请求了递归服务且该服务可用,对查询的递归响应将是以下之一:
- 查询的答案,可能前面带有一条或多条指明通向答案途中所遇别名的 CNAME RR。
- 指明名称不存在的名称错误。这可能包括指明原始查询名称是不存在名称的别名的 CNAME RR。
- 临时错误指示。
如果未请求递归服务或该服务不可用,非递归响应将是以下之一:
- 指明名称不存在的权威名称错误。
- 临时错误指示。
- 以下内容的某种组合:
- 回答问题的一组 RR,并带有一个指明数据来自区还是缓存的指示;
- 对名称服务器的转介——这些服务器所拥有的区是该名称比发送响应的服务器更近的祖先。
- 名称服务器认为对请求者有用的 RR。
4.3.2. 算法
名称服务器使用的实际算法将取决于本地操作系统和用于存储 RR 的数据结构。以下算法假定 RR 组织在若干树结构中,每个区一棵,另外还有一个缓存树:
- 根据名称服务器是否愿意提供递归服务,在响应中设置或清除"递归可用"的值。如果递归服务可用且查询中的 RD 位请求了该服务,转至步骤 5,否则转至步骤 2。
- 在可用区中搜索 QNAME 的最近祖先区。如果找到这样的区,转至步骤 3,否则转至步骤 4。
- 在区中按标签逐级向下匹配。匹配过程可以以几种方式终止:
- 如果 QNAME 整体匹配,我们就找到了该节点。
- 如果节点处的数据是 CNAME 且 QTYPE 与 CNAME 不匹配,则将 CNAME RR 复制到响应的回答区段,将 QNAME 改为 CNAME RR 中的规范名称,并回到步骤 1。
- 否则,将所有与 QTYPE 匹配的 RR 复制到回答区段并转至步骤 6。
- 如果匹配将使我们的搜索超出权威数据,我们就会遇到转介。当遇到带有沿区底部标记切分的 NS RR 的节点时,就会发生这种情况。
- 将子区的 NS RR 复制到响应的权威区段。将所有可用的地址放入附加区段,如果权威数据或缓存中没有这些地址,则使用胶水 RR。转至步骤 4。
- 如果在某个标签处无法匹配(即相应标签不存在),检查是否存在 "*" 标签。
- 如果 "*" 标签不存在,检查我们正在查找的名称是查询中的原始 QNAME,还是由于 CNAME 而跟随的名称。如果名称是原始的,在响应中设置权威名称错误并退出。否则直接退出。
- 如果 "*" 标签确实存在,则将该节点处的 RR 与 QTYPE 匹配。如果有匹配,将它们复制到回答区段,但将 RR 的所有者设置为 QNAME,而不是带有 "*" 标签的节点。转至步骤 6。
- 如果 QNAME 整体匹配,我们就找到了该节点。
- 开始在缓存中向下匹配。如果在缓存中找到 QNAME,则将挂接在它上面且与 QTYPE 匹配的所有 RR 复制到回答区段。如果权威数据中没有委派,则从缓存中寻找最佳委派,并将其放入权威区段。转至步骤 6。
- 使用本地解析器或其算法副本(参见本文档的解析器部分)回答查询。将结果(包括任何中间 CNAME)存储在响应的回答区段中。
- 仅使用本地数据,尝试将可能对查询的附加区段有用的其它 RR 加入其中。退出。
4.3.3. 通配符
在前面的算法中,对所有者名称以 "*" 标签开头的 RR 给予了特殊处理。这类 RR 称为通配符(wildcards)。通配符 RR 可以视为合成 RR 的指令。当满足适当条件时,名称服务器会创建所有者名称等于查询名称、内容取自通配符 RR 的 RR。
该设施最常用于创建一个区,用于将邮件从互联网转发到其它邮件系统。总体思路是:该区中出现在查询中的任何名称都被假定为存在并具有某些属性,除非存在明确的反证。请注意,这里使用"区"(zone)而非"域"(domain)一词是有意为之;这种默认行为不会跨越区边界传播,尽管子区可能选择通过设置类似的默认行为来达到同样的效果。
通配符 RR 的内容遵循 RR 的常规规则与格式。区中的通配符有一个所有者名称,控制它们将匹配的查询名称。通配符 RR 的所有者名称形式为 "*.<anydomain>",其中 <anydomain> 是任意域名。<anydomain> 不应包含其它 * 标签,并且应当位于该区的权威数据中。通配符可能适用于 <anydomain> 的后代,但不适用于 <anydomain> 本身。另一种看待方式是:"*" 标签总是匹配至少一个完整标签,有时匹配更多,但总是匹配完整的标签。
通配符 RR 不适用于:
- 查询位于另一个区时。也就是说,委派会取消通配符默认行为。
- 当查询名称或位于通配符域与查询名称之间的名称已知存在时。例如,如果通配符 RR 的所有者名称为 "*.X",并且该区还包含挂接在 B.X 上的 RR,则通配符将适用于对名称 Z.X 的查询(假定没有 Z.X 的明确信息),但不适用于 B.X、A.B.X 或 X。
出现在查询名称中的 * 标签没有特殊作用,但可用于测试权威区中是否存在通配符;此类查询是获得包含所有者名称中带 * 的 RR 的响应的唯一方式。此类查询的结果不应被缓存。
请注意,通配符 RR 的内容在用于合成 RR 时不会被修改。
为了说明通配符 RR 的用途,假设一家拥有大型非 IP/TCP 网络的大公司想要创建邮件网关。如果该公司名为 X.COM,具有 IP/TCP 能力的网关机器名为 A.X.COM,那么可能会在 COM 区中输入以下 RR:
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
这将使对任何以 X.COM 结尾的域名的 MX 查询都返回指向 A.X.COM 的 MX RR。需要两条通配符 RR,因为在 A.X.COM 子树中,*.X.COM 通配符的效果被 A.X.COM 的明确数据所抑制。另请注意,X.COM 和 A.X.COM 处的明确 MX 数据是必需的,而且上述 RR 都不会匹配 XX.COM 的查询名称。
4.3.4. 否定响应缓存(可选)
DNS 提供一种可选服务,允许名称服务器分发、解析器缓存带 TTL 的否定结果。例如,名称服务器可以在分发名称错误指示的同时附带一个 TTL,收到此类信息的解析器可以在该 TTL 期间假定该名称不存在,而无需咨询权威数据。类似地,解析器可以发出匹配多种类型的 QTYPE 查询,并缓存其中某些类型不存在的事实。
在实现使用搜索列表的命名简写的系统中,这一功能可能尤为重要,因为一个流行的简写——恰好需要搜索列表靠后位置的某个后缀——每次使用都会产生多个名称错误。
方法是:当响应是权威响应时,名称服务器可以向响应的附加区段添加一条 SOA RR。该 SOA 必须是回答区段中权威数据来源区的 SOA,或在适用时是名称错误来源区的 SOA。SOA 的 MINIMUM 字段控制否定结果可被缓存的时间长度。
请注意,在某些情况下,回答区段可能包含多个所有者名称。在这种情况下,SOA 机制只应针对与 QNAME 匹配的数据使用,因为它是该区段中唯一的权威数据。
名称服务器和解析器绝不应尝试向非权威响应的附加区段添加 SOA,也不应尝试推断权威响应中没有直接陈述的结果。这样做有若干原因,包括:缓存信息通常不足以将 RR 与其区名称对应起来;SOA RR 可能因直接的 SOA 查询而被缓存;以及名称服务器并不需要在权威区段输出 SOA。
该功能是可选的,不过预计未来其改进版本将成为标准协议的一部分。名称服务器不必在所有权威响应中添加 SOA RR,解析器也不必缓存否定结果。两者都是推荐做法。所有解析器和递归名称服务器至少都必须能够在响应中出现 SOA RR 时忽略它。
还提出了一些利用此功能的实验。其思路是:如果已知缓存数据来自特定区,并且获得了该区 SOA 的权威副本,而且该区的 SERIAL 自数据被缓存以来未发生变化,那么缓存数据的 TTL 可以重置为区的 MINIMUM 值(如果该值更小)。提及此用途仅出于规划目的,目前并不推荐。
4.3.5. 区的维护与传送
区管理员的部分职责是维护该区所有权威名称服务器上的区。当不可避免的变更发生时,必须将它们分发给所有名称服务器。虽然这种分发可以通过 FTP 或其它临时程序完成,但首选方法是 DNS 协议的区传送部分。
自动区传送或刷新的通用模型是:其中一台名称服务器是该区的主(master)或主用(primary)服务器。变更在主用服务器处协调,通常通过编辑区的主文件进行。编辑完成后,管理员通知主服务器加载新区。该区的其它非主或从属(secondary)服务器定期(以可选择的间隔)检查变更,并在发生变更时获取新的区副本。
为检测变更,从属服务器只需检查区 SOA 的 SERIAL 字段。除进行任何其它变更外,只要对区作出任何变更,区 SOA 中的 SERIAL 字段总是会被推进。推进可以是简单的递增,也可以基于主文件的写入日期和时间等。其目的是使人们能够通过比较序列号来确定区的两个副本哪个更新。序列号的推进与比较使用序列空间算术,因此区可以更新的速度存在理论上的限制,基本上旧副本必须在序列号覆盖其 32 位范围的一半之前消亡。在实践中,唯一需要注意的是比较操作要正确处理最正与最负 32 位数字之间边界附近的比较。
从属服务器的定期轮询由区 SOA RR 中的参数控制,这些参数设置可接受的最小轮询间隔。这些参数称为 REFRESH、RETRY 和 EXPIRE。每当从属服务器加载新区时,它会等待 REFRESH 秒再向主服务器检查新序列号。如果该检查无法完成,则每 RETRY 秒开始新的检查。该检查是向主服务器发出查询该区 SOA RR 的简单查询。如果从属服务器区副本中的序列号字段等于主服务器返回的序列号,则表示没有发生变更,并重新开始 REFRESH 间隔等待。如果从属服务器发现无法在 EXPIRE 间隔内执行序列号检查,它必须假定自己的区副本已过时并将其丢弃。
当轮询显示区已发生变化时,从属服务器必须通过该区的 AXFR 请求请求区传送。AXFR 可能产生错误(例如被拒绝),但通常由一系列响应消息回答。第一条和最后一条消息必须包含该区顶端权威节点的数据。中间消息承载区中的所有其它 RR,包括权威和非权威 RR。消息流使从属服务器能够构建区的副本。由于准确性至关重要,AXFR 请求必须使用 TCP 或其它可靠协议。
每个从属服务器都必须对主服务器执行以下操作,但也可以选择对其它从属服务器执行这些操作。当主服务器因主机停机或网络问题而不可用,或从属服务器对某个"中间"从属服务器的网络访问优于对主服务器的访问时,该策略可以改善传送过程。
5. 解析器
5.1. 引言
解析器是连接用户程序与域名服务器的程序。在最简单的情况下,解析器以子程序调用、系统调用等形式从用户程序(例如邮件程序、TELNET、FTP)接收请求,并以与本地主机数据格式兼容的形式返回所需信息。
解析器与请求其服务的程序位于同一台机器上,但它可能需要咨询其它主机上的名称服务器。由于解析器可能需要咨询多个名称服务器,或者可能已在本地缓存中拥有请求的信息,解析器完成所需的时间可能相差很大,从几毫秒到几秒不等。
解析器的一个非常重要的目标是消除大多数请求中的网络延迟和名称服务器负载,方法是从其先前结果的缓存中回答这些请求。由此可知,由多个进程、用户、机器等共享的缓存比非共享缓存更高效。
5.2. 客户端与解析器的接口
5.2.1. 典型功能
客户端与解析器的接口受本地主机惯例的影响,但典型的解析器-客户端接口具有三个功能:
- 主机名到主机地址的转换。该功能通常被定义为模仿以前基于 HOSTS.TXT 的功能。给定一个字符串,调用者想要一个或多个 32 位 IP 地址。在 DNS 下,它转换为对类型 A RR 的请求。由于 DNS 不保留 RR 的顺序,如果服务只向客户端返回一个选择,此功能可以选择对返回的地址进行排序或选择"最佳"地址。请注意,建议返回多个地址,但返回单个地址可能是模拟以前 HOSTS.TXT 服务的唯一方式。
- 主机地址到主机名的转换。该功能通常沿用以前功能的形式。给定一个 32 位 IP 地址,调用者想要一个字符串。IP 地址的八位组被反转,用作名称组成部分,并加上后缀 "IN-ADDR.ARPA"。使用类型 PTR 查询获取包含主机主名称的 RR。例如,对 IP 地址 1.2.3.4 对应主机名的请求会查找域名 "4.3.2.1.IN-ADDR.ARPA" 的 PTR RR。
- 通用查找功能。该功能从 DNS 中检索任意信息,在以前的系统中没有对应物。调用者提供 QNAME、QTYPE 和 QCLASS,并希望获得所有匹配的 RR。该功能通常对所有 RR 数据使用 DNS 格式而非本地主机的格式,并返回所有 RR 内容(例如 TTL),而不是带有本地引用约定的已处理形式。
当解析器执行所指示的功能时,它通常有以下结果之一可以回传给客户端:
- 一条或多条给出所请求数据的 RR。在这种情况下,解析器以适当格式返回答案。
- 名称错误(NE)。当被引用的名称不存在时发生。例如,用户可能输错了主机名。
- 数据未找到错误。当被引用的名称存在,但适当类型的数据不存在时发生。例如,对邮箱名称应用主机地址功能会返回此错误,因为该名称存在,但没有地址 RR。
重要的是要注意,主机名与地址之间转换的功能可以将"名称错误"和"数据未找到"错误条件合并为单一类型的错误返回,但通用功能不应如此。原因之一是应用可能先询问某个名称的一种类型信息,随后又向同一名称发出请求询问另一种类型的信息;如果两种错误合并,无用的查询可能会拖慢应用。
5.2.2. 别名
在尝试解析特定请求时,解析器可能会发现所涉名称是一个别名。例如,当解析器找到 CNAME RR 时,它可能会发现为主机名到地址转换给出的名称是别名。如果可能,应从解析器向客户端回传别名条件。
在大多数情况下,解析器在遇到 CNAME 时只需在新名称处重新开始查询。但是,在执行通用功能时,当 CNAME RR 匹配查询类型时,解析器不应继续追查别名。这允许询问别名是否存在的查询。例如,如果查询类型是 CNAME,用户感兴趣的是 CNAME RR 本身,而不是它所指向名称处的 RR。
别名可能出现几种特殊情况。由于效率低下,应避免多层别名,但不应将其作为错误发出信号。应捕获别名环和指向不存在名称的别名,并将错误条件回传给客户端。
5.2.3. 临时故障
在不完美的现实中,所有解析器偶尔都会无法解析特定请求。这种情况可能由以下原因造成:解析器因链路故障或网关问题而与网络其余部分分离,或者较少见的是某个特定域的所有服务器同时发生故障或不可用。
至关重要的是,不应将此类情况作为名称或数据不存在错误发出信号给应用。这种行为会让人恼火,并且当邮件系统使用 DNS 时会造成严重破坏。
虽然在某些情况下可以通过无限期阻塞请求来处理此类临时问题,但这通常不是好的选择,尤其是当客户端是可能转向其它任务的服务器进程时。推荐的解决方案是始终把"临时故障"作为解析器功能可能的结果之一,尽管这可能使对现有 HOSTS.TXT 功能的模拟更加困难。
5.3. 解析器的内部机制
每个解析器实现都使用略有不同的算法,并且通常花在处理各种错误上的逻辑比处理正常情况更多。本节概述推荐的解析器运行基本策略,但把细节留给 [RFC-1035]。
5.3.1. 存根解析器
实现解析器的一种选择是把解析功能从本地机器移出,放入支持递归查询的名称服务器中。这可以为缺乏资源执行解析功能的 PC 提供一种简便的域服务方式,也可以为整个本地网络或组织集中缓存。
剩下的存根(stub)所需的一切只是一份将执行递归请求的名称服务器地址列表。此类解析器大概需要在配置文件中获得这些信息,因为它可能缺乏在域数据库中找到这些信息的复杂能力。用户还需要核实列出的服务器将执行递归服务;名称服务器可以自由地拒绝为任何或所有客户端执行递归服务。用户应咨询本地系统管理员,以找到愿意执行该服务的名称服务器。
此类服务存在一些缺点。由于递归请求可能需要任意长的时间来完成,存根可能难以优化重传间隔,以同时应对丢失的 UDP 数据包和失效的服务器;如果名称服务器把重传解释为新请求,过于热心的存根很容易使其过载。使用 TCP 可能是一个答案,但 TCP 很可能会给主机的处理能力带来与真正的解析器类似的负担。
5.3.2. 资源
除了自身资源外,解析器还可以共享访问本地名称服务器维护的区。这使解析器具有更快访问的优势,但解析器必须小心,绝不让缓存信息覆盖区数据。在本讨论中,"本地信息"(local information)一词指缓存与这类共享区的并集,并理解:当两者都存在时,始终优先使用权威数据而非缓存数据。
以下解析器算法假定所有功能都已转换为通用查找功能,并使用以下数据结构来表示解析器中进行中请求的状态:
SNAME —— 我们正在搜索的域名。
STYPE —— 搜索请求的 QTYPE。
SCLASS —— 搜索请求的 QCLASS。
SLIST —— 描述解析器当前正在尝试查询的名称服务器和区的结构。该结构跟踪解析器当前关于哪些名称服务器持有所需信息的最佳猜测;当到达的信息改变该猜测时对其进行更新。该结构包括相当于区名称的内容、该区已知的名称服务器、这些名称服务器的已知地址,以及可用于提示下一步最值得尝试哪台服务器的历史信息。与区名称等价的是一个匹配计数,即 SNAME 与所查询区从根向下共有的标签数量;它被用作解析器距离 SNAME 有多"近"的度量。
SBELT —— 一个与 SLIST 形式相同的"安全带"(safety belt)结构,从配置文件初始化,列出在解析器没有任何本地信息指导名称服务器选择时应使用的服务器。其匹配计数将为 -1,表示不知道有任何标签匹配。
CACHE —— 存储以前响应结果的结构。由于解析器负责丢弃 TTL 已过期的旧 RR,大多数实现会在 RR 存入缓存时把到达 RR 中指定的间隔转换为某种绝对时间。解析器不是逐个倒计时 TTL,而是在搜索过程中遇到旧 RR 时将其忽略或丢弃,或在定期扫描期间将其丢弃以回收旧 RR 占用的内存。
5.3.3. 算法
顶层算法有四个步骤:
- 查看答案是否在本地信息中,如果是,则将其返回给客户端。
- 找到最佳可咨询的服务器。
- 向它们发送查询,直到其中一个返回响应。
- 分析响应,可以:
- 如果响应回答了问题或包含名称错误,则缓存数据并将其返回给客户端。
- 如果响应包含到其它服务器的更好委派,则缓存委派信息并转至步骤 2。
- 如果响应显示 CNAME 且它不是答案本身,则缓存 CNAME,将 SNAME 改为 CNAME RR 中的规范名称并转至步骤 1。
- 如果响应显示服务器故障或其它异常内容,则从 SLIST 中删除该服务器并回到步骤 3。
步骤 1 在缓存中搜索所需数据。如果数据在缓存中,则假定它对正常使用来说足够好。某些解析器在用户界面上有一个选项,可强制解析器忽略缓存数据并咨询权威服务器。不建议将其作为默认设置。如果解析器可以直接访问名称服务器的区,它应当检查所需数据是否以权威形式存在,如果是,则优先使用权威数据而非缓存数据。
步骤 2 寻找可咨询所需数据的名称服务器。总体策略是查找本地可用的名称服务器 RR,从 SNAME 开始,然后是 SNAME 的父域名、祖父域名,依此向上直至根。因此,如果 SNAME 是 Mockapetris.ISI.EDU,此步骤将查找 Mockapetris.ISI.EDU、然后是 ISI.EDU、然后是 EDU、然后是 .(根)的 NS RR。这些 NS RR 列出 SNAME 处或其之上的区的宿主名。将这些名称复制到 SLIST 中。使用本地数据设置它们的地址。可能发生地址不可用的情况。解析器在这里有很多选择;最佳选择是启动并行的解析器进程寻找地址,同时继续使用可用的地址。显然,设计选择和选项是复杂的,并且取决于本地主机的处理能力。为解析器设计者推荐的优先级是:
- 限定工作量(发送的数据包、启动的并行进程),使请求不会陷入无限循环,也不会引发与其它实现的请求或查询的连锁反应——即使有人错误地配置了某些数据。
- 只要可能就取回答案。
- 避免不必要的传输。
- 尽可能快地获取答案。
如果对 NS RR 的搜索失败,则解析器从安全带 SBELT 初始化 SLIST。基本思路是:当解析器不知道应咨询哪些服务器时,应使用来自配置文件的信息,该文件列出几台预期会有帮助的服务器。虽然有特殊情况,但通常的选择是两台根服务器和主机所在域的两台服务器。各选两台的原因是冗余。根服务器将提供对整个域名空间的最终访问。两台本地服务器将使解析器在本地网络因网关或链路故障而与互联网隔离时,仍能继续解析本地名称。
除服务器名称和地址外,SLIST 数据结构还可以排序,以优先使用最佳服务器,并确保以轮询(round-robin)方式使用所有服务器的所有地址。排序可以是简单地优先选择本地网络上的地址,也可能涉及过去事件的统计,例如以往的响应时间和命中率。
步骤 3 发送查询,直到收到响应。策略是在所有服务器的所有地址之间循环,每次传输之间带有一个超时。在实践中,使用多宿主主机的所有地址非常重要,而过激的重传策略在多个解析器争用同一名称服务器时实际上会拖慢响应,甚至偶尔对单个解析器也是如此。SLIST 通常包含控制超时和跟踪先前传输的数据值。
步骤 4 涉及分析响应。解析器在解析响应时应高度多疑。它还应当使用响应中的 ID 字段检查响应是否与其发送的查询匹配。
理想的答案来自对查询权威的服务器,它要么给出所需数据,要么给出名称错误。数据被回传给用户,并在其 TTL 大于零时存入缓存以供将来使用。
如果响应显示委派,解析器应当检查该委派是否比 SLIST 中的服务器更"接近"答案。这可以通过比较 SLIST 中的匹配计数与根据 SNAME 和委派中的 NS RR 计算出的匹配计数来完成。如果不是,则响应是伪造的,应当忽略。如果委派有效,则应缓存 NS 委派 RR 和任何服务器的地址 RR。将这些名称服务器记入 SLIST,并重新开始搜索。
如果响应包含 CNAME,则在 CNAME 处重新开始搜索,除非响应具有规范名称的数据,或者 CNAME 本身就是答案。
细节和实现提示可在 [RFC-1035] 中找到。
6. 一个场景示例
在我们的示例域名空间中,假设我们希望对根、MIL、EDU、MIT.EDU 和 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
在本例中,权威名称服务器以括号形式显示在域名树中它接管控制权的位置。
因此,根名称服务器位于 C.ISI.EDU、SRI-NIC.ARPA 和 A.ISI.EDU 上。MIL 域由 SRI-NIC.ARPA 和 A.ISI.EDU 提供服务。EDU 域由 SRI-NIC.ARPA 和 C.ISI.EDU 提供服务。请注意,服务器可能拥有连续或不连续的区。在此场景中,C.ISI.EDU 在根域和 EDU 域拥有连续的区。A.ISI.EDU 在根域和 MIL 域拥有连续的区,但还在 ISI.EDU 拥有一个不连续的区。
6.1. C.ISI.EDU 名称服务器
C.ISI.EDU 是 IN 类根域、MIL 域和 EDU 域的名称服务器,并将拥有这些域的区。根域的区数据可能是:
. 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
此数据按主文件中的形式表示。大多数 RR 是单行条目;这里唯一的例外是 SOA RR,它使用 "(" 开始一条多行 RR,用 ")" 表示多行 RR 的结束。由于区中所有 RR 的类别必须相同,区中只有第一条 RR 需要指明类别。当名称服务器加载区时,它会强制所有权威 RR 的 TTL 至少为 SOA 的 MINIMUM 字段值,这里是 86400 秒,即一天。标记 MIL 和 EDU 域委派的 NS RR,连同服务器主机地址的胶水 RR,不属于该区的权威数据,因此具有明确的 TTL。
根节点挂接了四条 RR:描述根区的 SOA 和列出根名称服务器的三条 NS RR。SOA RR 中的数据描述该区的管理。区数据维护在主机 SRI-NIC.ARPA 上,该区的责任人(responsible party)是 HOSTMASTER@SRI-NIC.ARPA。SOA 中的一个关键项是 86400 秒的最小 TTL,这意味着区中所有权威数据的 TTL 至少为该值,尽管可以明确指定更高的值。
MIL 和 EDU 域的 NS RR 标记根区与 MIL 和 EDU 区之间的边界。请注意,在本例中,较低层的区碰巧由也支持根区的名称服务器提供支持。
EDU 区的主文件可以相对于源点 EDU 来表述。EDU 域的区数据可能是:
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
请注意此处相对名称的使用。ISI.EDU. 的所有者名称用相对名称表述,两条名称服务器 RR 的内容也是如此。相对和绝对域名可以在主文件中自由混用。
6.2. 标准查询示例
以下查询和响应说明名称服务器的行为。除非另有说明,查询的头部不包含"期望递归"(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> |
+---------------------------------------------------+
C.ISI.EDU 的响应将是:
+---------------------------------------------------+
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> |
+---------------------------------------------------+
响应的头部与查询的头部相似,不同之处在于:RESPONSE 位置位,表示该消息是响应而非查询;"权威回答"(AA)位置位,表示回答区段中的地址 RR 来自权威数据。响应的问题区段与查询的问题区段相匹配。
如果将同样的查询发送到另一台对 SRI-NIC.ARPA 不权威的服务器,响应可能是:
+---------------------------------------------------+
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> |
+---------------------------------------------------+
此响应与之前的响应有两个不同之处:头部未设置 AA,且 TTL 不同。由此推断,数据并非来自区,而是来自缓存。权威 TTL 与此处 TTL 的差异是由于数据在缓存中老化所致。回答区段中 RR 顺序的差异并不重要。
6.2.2. QNAME=SRI-NIC.ARPA,QTYPE=*
与上一个类似的查询,但使用 QTYPE=*,将从 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> |
+---------------------------------------------------+
如果将类似的查询发送到两台对 SRI-NIC.ARPA 不权威的名称服务器,响应可能是:
+---------------------------------------------------+
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> |
+---------------------------------------------------+
以及
+---------------------------------------------------+
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> |
+---------------------------------------------------+
这两个答案都没有设置 AA,因此两个响应都不来自权威数据。不同的内容和不同的 TTL 表明两台服务器在不同时间缓存了数据,第一台服务器缓存了 QTYPE=A 查询的响应,第二台缓存了 HINFO 查询的响应。
6.2.3. QNAME=SRI-NIC.ARPA,QTYPE=MX
这种类型的查询可能来自试图查找邮件目的地 HOSTMASTER@SRI-NIC.ARPA 路由信息的邮件程序。C.ISI.EDU 的响应将是:
+---------------------------------------------------+
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 |
+---------------------------------------------------+
此响应的回答区段包含 MX RR。附加区段包含地址 RR,因为 C.ISI.EDU 的名称服务器猜测请求者需要这些地址来正确使用 MX 携带的信息。
6.2.4. QNAME=SRI-NIC.ARPA,QTYPE=NS
C.ISI.EDU 将用以下内容回复此查询:
+---------------------------------------------------+
Header | OPCODE=SQUERY, RESPONSE, AA |
+---------------------------------------------------+
Question | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=NS |
+---------------------------------------------------+
Answer | <empty> |
+---------------------------------------------------+
Authority | <empty> |
+---------------------------------------------------+
Additional | <empty> |
+---------------------------------------------------+
响应与查询之间的唯一区别是头部中的 AA 和 RESPONSE 位。对此响应的解释是:服务器对该名称是权威的,名称存在,但那里没有类型为 NS 的 RR。
6.2.5. QNAME=SIR-NIC.ARPA,QTYPE=A
如果用户输错了主机名,我们可能会看到这种类型的查询。C.ISI.EDU 将用以下内容回答:
+---------------------------------------------------+
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> |
+---------------------------------------------------+
此响应表明该名称不存在。此条件在头部的响应码(RCODE)部分发出信号。
权威区段中的 SOA RR 是可选否定缓存信息,它允许使用此响应的解析器假定该名称在 SOA MINIMUM(86400)秒内不存在。
6.2.6. QNAME=BRL.MIL,QTYPE=A
如果将此查询发送到 C.ISI.EDU,响应将是:
+---------------------------------------------------+
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 |
+---------------------------------------------------+
此响应的回答区段为空,但不是权威响应,因此它是一个转介。C.ISI.EDU 上的名称服务器意识到自己对 MIL 域不权威,因此将请求者转介到 A.ISI.EDU 和 SRI-NIC.ARPA 上的服务器,它知道这些服务器对 MIL 域是权威的。
6.2.7. QNAME=USC-ISIC.ARPA,QTYPE=A
A.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> |
+---------------------------------------------------+
请注意,头部中的 AA 位保证与 QNAME 匹配的数据是权威的,但并未说明 C.ISI.EDU 的数据是否权威。之所以能给出如此完整的响应,是因为 A.ISI.EDU 恰好对 USC-ISIC.ARPA 所在的 ARPA 域和 C.ISI.EDU 数据所在的 ISI.EDU 域都是权威的。
如果将同样的查询发送到 C.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. |
+---------------------------------------------------+
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 |
+---------------------------------------------------+
该响应包含对别名 USC-ISIC.ARPA 的权威回答,外加对 ISI.EDU 名称服务器的转介。鉴于查询针对的是被询问名称服务器的主机名,这种响应不太可能出现,但对于其它别名则会很常见。
6.2.8. QNAME=USC-ISIC.ARPA,QTYPE=CNAME
如果将此查询发送到 A.ISI.EDU 或 C.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. |
+---------------------------------------------------+
Authority | <empty> |
+---------------------------------------------------+
Additional | <empty> |
+---------------------------------------------------+
由于 QTYPE=CNAME,CNAME RR 本身回答了查询,名称服务器不会尝试为 C.ISI.EDU 查找任何内容。(除非是为了附加区段。)
6.3. 解析示例
以下示例说明解析器必须为其客户端执行的操作。我们假定解析器在无缓存的情况下启动,就像系统启动后的情况。我们进一步假定该系统不是数据中的主机之一,该主机位于网络 26 的某处,并且其安全带(SBELT)数据结构包含以下信息:
Match count = -1
SRI-NIC.ARPA. 26.0.0.73 10.0.0.51
A.ISI.EDU. 26.3.0.103
该信息指定要尝试的服务器、它们的地址以及 -1 的匹配计数,表示这些服务器距离目标不太近。请注意,-1 并不是要作为准确的接近程度度量,只是一个使算法后续阶段能够工作的值。
以下示例说明缓存的使用,因此每个示例都假定先前的请求已经完成。
6.3.1. 解析 ISI.EDU 的 MX 记录
假设解析器收到的第一个请求来自本地邮件程序,它有寄往 PVM@ISI.EDU 的邮件。邮件程序随后可能请求域名 ISI.EDU 的类型 MX RR。
解析器会在其缓存中查找 ISI.EDU 处的 MX RR,但空的缓存毫无帮助。解析器会认识到它需要查询外部服务器,并尝试确定最佳可查询服务器。该搜索会查找 ISI.EDU、EDU 和根域的 NS RR。这些缓存搜索也会失败。作为最后的手段,解析器将使用 SBELT 的信息,将其复制到 SLIST 结构中。
此时,解析器需要从三个可用地址中选择一个来尝试。鉴于解析器位于网络 26 上,它应当选择 26.0.0.73 或 26.3.0.103 作为首选。然后它会发出如下形式的查询:
+---------------------------------------------------+
Header | OPCODE=SQUERY |
+---------------------------------------------------+
Question | QNAME=ISI.EDU., QCLASS=IN, QTYPE=MX |
+---------------------------------------------------+
Answer | <empty> |
+---------------------------------------------------+
Authority | <empty> |
+---------------------------------------------------+
Additional | <empty> |
+---------------------------------------------------+
解析器随后会等待查询的响应或超时。如果超时发生,它会尝试不同的服务器,然后是同一服务器的不同地址,最后重试已尝试过的地址。它最终可能收到来自 SRI-NIC.ARPA 的回复:
+---------------------------------------------------+
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 |
+---------------------------------------------------+
解析器会注意到,响应中的信息给出了比其现有 SLIST 更接近 ISI.EDU 的委派(因为它匹配三个标签)。解析器随后会缓存此响应中的信息,并用它建立新的 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
A.ISI.EDU 同时出现在此列表和之前的列表中,但这纯属巧合。解析器将再次开始发送并等待响应。最终它会得到答案:
+---------------------------------------------------+
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 |
+---------------------------------------------------+
解析器会将此信息添加到缓存中,并将 MX RR 返回给客户端。
6.3.2. 获取地址 26.6.0.65 的主机名
解析器会将其转换为对 65.0.6.26.IN-ADDR.ARPA 的 PTR RR 请求。该信息不在缓存中,因此解析器会寻找可咨询的外部服务器。没有服务器匹配,因此它将再次使用 SBELT。(请注意,ISI.EDU 域的服务器在缓存中,但 ISI.EDU 不是 65.0.6.26.IN-ADDR.ARPA 的祖先,因此使用 SBELT。)
由于此请求位于 SBELT 中两台服务器的权威数据之内,最终其中一台会返回:
+---------------------------------------------------+
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 的主机地址
此请求将转换为对 poneria.ISI.EDU 的类型 A 请求。解析器不会找到该名称的任何缓存数据,但在寻找可咨询的外部服务器时,会在缓存中找到 ISI.EDU 的 NS RR。利用这些数据,它将构建如下形式的 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
A.ISI.EDU 被列在最前面,因为假定解析器按偏好对选择排序,而 A.ISI.EDU 在同一网络上。
其中一台服务器将回答查询。
7. 参考文献与参考书目
- [Dyer 87] Dyer, S. 与 F. Hsu, 《Hesiod》, 雅典娜计划技术方案——名称服务(Project Athena Technical Plan - Name Service), 1987 年 4 月, 1.9 版。
描述 Hesiod 名称服务的基本原理。 - [IEN-116] J. Postel, 《互联网名称服务器》(Internet Name Server), IEN-116, USC/信息科学研究所(USC/Information Sciences Institute), 1979 年 8 月。
一种已被域名系统取代、但仍在使用的名称服务。 - [Quarterman 86] Quarterman, J. 与 J. Hoskins, 《值得关注的计算网络》(Notable Computer Networks), Communications of the ACM, 1986 年 10 月, 第 29 卷第 10 期。
- [RFC-742] K. Harrenstien, 《NAME/FINGER》, RFC-742, 网络信息中心(Network Information Center), SRI International, 1977 年 12 月。
- [RFC-768] J. Postel, 《用户数据报协议》(User Datagram Protocol), RFC-768, USC/信息科学研究所, 1980 年 8 月。
- [RFC-793] J. Postel, 《传输控制协议》(Transmission Control Protocol), RFC-793, USC/信息科学研究所, 1981 年 9 月。
- [RFC-799] D. Mills, 《互联网名称域》(Internet Name Domains), RFC-799, COMSAT, 1981 年 9 月。
建议为互联网引入层级结构以取代扁平名称空间。 - [RFC-805] J. Postel, 《计算机邮件会议纪要》(Computer Mail Meeting Notes), RFC-805, USC/信息科学研究所, 1982 年 2 月。
- [RFC-810] E. Feinler, K. Harrenstien, Z. Su 与 V. White, 《DOD 互联网主机表规范》(DOD Internet Host Table Specification), RFC-810, 网络信息中心, SRI International, 1982 年 3 月。
已废弃。参见 RFC-952。 - [RFC-811] K. Harrenstien, V. White 与 E. Feinler, 《主机名服务器》(Hostnames Server), RFC-811, 网络信息中心, SRI International, 1982 年 3 月。
已废弃。参见 RFC-953。 - [RFC-812] K. Harrenstien 与 V. White, 《NICNAME/WHOIS》, RFC-812, 网络信息中心, SRI International, 1982 年 3 月。
- [RFC-819] Z. Su 与 J. Postel, 《面向互联网用户应用的域名命名约定》(The Domain Naming Convention for Internet User Applications), RFC-819, 网络信息中心, SRI International, 1982 年 8 月。
关于域名系统设计的早期构想。当前实现已完全不同。 - [RFC-821] J. Postel, 《简单邮件传输协议》(Simple Mail Transfer Protocol), RFC-821, USC/信息科学研究所, 1980 年 8 月。
- [RFC-830] Z. Su, 《用于互联网名称服务的分布式系统》(A Distributed System for Internet Name Service), RFC-830, 网络信息中心, SRI International, 1982 年 10 月。
关于域名系统设计的早期构想。当前实现已完全不同。 - [RFC-882] P. Mockapetris, 《域名——概念与设施》(Domain names - Concepts and Facilities), RFC-882, USC/信息科学研究所, 1983 年 11 月。
已被本备忘录取代。 - [RFC-883] P. Mockapetris, 《域名——实现与规范》(Domain names - Implementation and Specification), RFC-883, USC/信息科学研究所, 1983 年 11 月。
已被本备忘录取代。 - [RFC-920] J. Postel 与 J. Reynolds, 《域需求》(Domain Requirements), RFC-920, USC/信息科学研究所, 1984 年 10 月。
解释顶级域的命名方案。 - [RFC-952] K. Harrenstien, M. Stahl, E. Feinler, 《DoD 互联网主机表规范》(DoD Internet Host Table Specification), RFC-952, SRI, 1985 年 10 月。
规定 HOSTS.TXT(被 DNS 取代的主机/地址表)的格式。 - [RFC-953] K. Harrenstien, M. Stahl, E. Feinler, 《HOSTNAME 服务器》(HOSTNAME Server), RFC-953, SRI, 1985 年 10 月。
该 RFC 包含主机名服务器协议的官方规范,该协议已被 DNS 取代。这一基于 TCP 的协议访问以 RFC-952 格式存储的信息,用于获取主机表的副本。 - [RFC-973] P. Mockapetris, 《域名系统变更与观察》(Domain System Changes and Observations), RFC-973, USC/信息科学研究所, 1986 年 1 月。
描述对 RFC-882 和 RFC-883 的变更及其原因。现已废弃。 - [RFC-974] C. Partridge, 《邮件路由与域名系统》(Mail routing and the domain system), RFC-974, CSNET CIC BBN Labs, 1986 年 1 月。
描述从基于 HOSTS.TXT 的邮件寻址到与域名系统配合使用的更强大的 MX 系统的过渡。 - [RFC-1001] NetBIOS 工作组, 《在 TCP/UDP 传输之上的 NetBIOS 服务协议标准:概念与方法》(Protocol standard for a NetBIOS service on a TCP/UDP transport: Concepts and Methods), RFC-1001, 1987 年 3 月。
该 RFC 与 RFC-1002 是 TCP/IP 之上 NETBIOS 的初步设计,提议把 NetBIOS 名称服务建立在 DNS 之上。 - [RFC-1002] NetBIOS 工作组, 《在 TCP/UDP 传输之上的 NetBIOS 服务协议标准:详细规范》(Protocol standard for a NetBIOS service on a TCP/UDP transport: Detailed Specifications), RFC-1002, 1987 年 3 月。
- [RFC-1010] J. Reynolds 与 J. Postel, 《分配编号》(Assigned Numbers), RFC-1010, USC/信息科学研究所, 1987 年 5 月。
包含主机名、操作系统等的套接字号与助记符。 - [RFC-1031] W. Lazear, 《MILNET 名称域过渡》(MILNET Name Domain Transition), RFC-1031, 1987 年 11 月。
描述把 MILNET 转换到 DNS 的计划。 - [RFC-1032] M. K. Stahl, 《建立域——管理员指南》(Establishing a Domain - Guidelines for Administrators), RFC-1032, 1987 年 11 月。
描述 NIC 用于管理顶级域和委派子区的注册政策。 - [RFC-1033] M. K. Lottor, 《域管理员操作指南》(Domain Administrators Operations Guide), RFC-1033, 1987 年 11 月。
面向域管理员的操作手册。 - [Solomon 82] M. Solomon, L. Landweber 与 D. Neuhengen, 《CSNET 名称服务器》(The CSNET Name Server), Computer Networks, 第 6 卷第 3 期, 1982 年 7 月。
描述一个独立于 DNS 的 CSNET 名称服务以及 DNS 在 CSNET 中的使用。
索引
| 术语 | 页码 |
|---|---|
| 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 |
| 胶水 RR(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 |
