2. 引言 (Introduction)
2. 引言 (Introduction)
2.1. 概述 (Overview)
域名 (domain name) 的目标是提供一种命名资源的机制, 使这些名称能够在不同主机, 网络, 协议族, 互联网以及管理组织中使用.
从用户角度看, 域名可以作为本地代理的参数使用. 这个本地代理称为解析器 (resolver), 它会取回与域名相关联的信息. 因此, 用户可以请求某个特定域名对应的主机地址或邮件信息. 为了让用户能够请求特定类型的信息, 需要把相应的查询类型与域名一起传给解析器. 对用户而言, 域树是一个单一的信息空间; 解析器负责隐藏数据在各个名称服务器 (name server) 之间分布的事实.
从解析器角度看, 构成域空间的数据库分布在多个名称服务器中. 域空间的不同部分存放在不同名称服务器里, 尽管某个具体数据项通常会在两个或更多名称服务器中冗余保存. 解析器至少从已知一个名称服务器开始. 当解析器处理用户查询时, 它会向已知名称服务器询问信息; 作为回应, 解析器要么收到所需信息, 要么收到指向另一个名称服务器的引用 (referral). 通过这些引用, 解析器逐步了解其他名称服务器的身份和内容. 解析器负责处理域空间的分布, 并在名称服务器故障时通过查询其他服务器上的冗余数据库来处理故障影响.
名称服务器管理两类数据. 第一类数据保存在称为区域 (zone) 的集合中; 每个区域都是域空间某个特定"修剪后"子树的完整数据库. 这类数据称为权威数据 (authoritative data). 名称服务器会定期检查其区域是否为最新, 如果不是, 就从本地或另一个名称服务器保存的主文件 (master file) 中取得更新区域的新副本. 第二类数据是本地解析器获得的缓存数据 (cached data). 这类数据可能不完整, 但当非本地数据被反复访问时, 它能提升检索过程的性能. 缓存数据最终会通过超时机制丢弃.
这种功能结构把用户接口, 故障恢复和分布问题隔离在解析器中, 并把数据库更新和刷新问题隔离在名称服务器中.
2.2. 常见配置 (Common configurations)
一台主机可以用多种方式参与域名系统, 取决于该主机是否运行从域系统取回信息的程序, 是否运行应答其他主机查询的名称服务器, 或者同时组合这些功能. 最简单, 也可能最典型的配置如下:
Local Host | Foreign
|
+---------+ +----------+ | +--------+
| | user queries | |queries | | |
| User |-------------->| |---------|->|Foreign |
| Program | | Resolver | | | Name |
| |<--------------| |<--------|--| Server |
| | user responses| |responses| | |
+---------+ +----------+ | +--------+
| A |
cache additions | | references |
V | |
+----------+ |
| cache | |
+----------+ |
用户程序通过解析器与域名空间交互; 用户查询和用户响应的格式取决于主机及其操作系统. 用户查询通常是操作系统调用, 解析器及其缓存通常是主机操作系统的一部分. 能力较弱的主机可以选择把解析器实现为子例程, 链接到每个需要其服务的程序中. 解析器使用向外部名称服务器发出的查询以及本地缓存取得的信息来回答用户查询.
注意, 为了回答一个特定用户查询, 解析器可能必须向多个不同的外部名称服务器发出多个查询. 因此, 解析一个用户查询可能涉及多次网络访问, 并耗费任意长度的时间. 发往外部名称服务器的查询及其对应响应具有本文档描述的标准格式, 并且可以作为数据报传输.
根据能力不同, 名称服务器可以是专用机器上的独立程序, 也可以是大型分时主机上的一个或多个进程. 一个简单配置可能如下:
Local Host | Foreign
|
+---------+ |
/ /| |
+---------+ | +----------+ | +--------+
| | | | |responses| | |
| | | | Name |---------|->|Foreign |
| Master |-------------->| Server | | |Resolver|
| files | | | |<--------|--| |
| |/ | | queries | +--------+
+---------+ +----------+ |
在这里, 主名称服务器 (primary name server) 通过从本地文件系统读取主文件获取一个或多个区域的信息, 并回答外部解析器发来的关于这些区域的查询.
DNS 要求所有区域都由多个名称服务器冗余支持. 指定的辅助服务器 (secondary server) 可以使用 DNS 的区域传送协议 (zone transfer protocol) 从主服务器获取区域, 并检查更新. 这种配置如下:
Local Host | Foreign
|
+---------+ |
/ /| |
+---------+ | +----------+ | +--------+
| | | | |responses| | |
| | | | Name |---------|->|Foreign |
| Master |-------------->| Server | | |Resolver|
| files | | | |<--------|--| |
| |/ | | queries | +--------+
+---------+ +----------+ |
A |maintenance | +--------+
| +------------|->| |
| queries | |Foreign |
| | | Name |
+------------------|--| Server |
maintenance responses | +--------+
在这种配置中, 名称服务器会定期与外部名称服务器建立虚电路, 以获取某个区域的副本, 或检查现有副本是否未发生变化. 为这些维护活动发送的消息遵循与查询和响应相同的形式, 但消息序列略有不同.
支持域名系统全部方面的主机中的信息流如下:
Local Host | Foreign
|
+---------+ +----------+ | +--------+
| | user queries | |queries | | |
| User |-------------->| |---------|->|Foreign |
| Program | | Resolver | | | Name |
| |<--------------| |<--------|--| Server |
| | user responses| |responses| | |
+---------+ +----------+ | +--------+
| A |
cache additions | | references |
V | |
+----------+ |
| Shared | |
| database | |
+----------+ |
A | |
+---------+ refreshes | | references |
/ /| | V |
+---------+ | +----------+ | +--------+
| | | | |responses| | |
| | | | Name |---------|->|Foreign |
| Master |-------------->| Server | | |Resolver|
| files | | | |<--------|--| |
| |/ | | queries | +--------+
+---------+ +----------+ |
A |maintenance | +--------+
| +------------|->| |
| queries | |Foreign |
| | | Name |
+------------------|--| Server |
maintenance responses | +--------+
共享数据库保存本地名称服务器和解析器的域空间数据. 共享数据库的内容通常是名称服务器通过周期性刷新操作维护的权威数据, 以及此前解析器请求得到的缓存数据的混合. 域数据的结构以及名称服务器与解析器之间同步的必要性, 决定了该数据库的一般特征, 但实际格式由本地实现者决定.
也可以调整信息流, 让一组主机协同优化活动. 有时这样做是为了卸载能力较弱的主机, 使其不必实现完整解析器. 这适用于 PC 或希望尽量减少新增网络代码的主机. 这种方案还可以让一组主机共享少量缓存, 而不是维护大量独立缓存; 其前提是集中式缓存会有更高命中率. 在这两种情况下, 解析器会被存根解析器 (stub resolver) 取代, 存根解析器作为前端, 连接到一个或多个已知能够提供递归服务的名称服务器中的递归服务器:
Local Hosts | Foreign
|
+---------+ |
| | responses |
| Stub |<--------------------+ |
| Resolver| | |
| |----------------+ | |
+---------+ recursive | | |
queries | | |
V | |
+---------+ recursive +----------+ | +--------+
| | queries | |queries | | |
| Stub |-------------->| Recursive|---------|->|Foreign |
| Resolver| | Server | | | Name |
| |<--------------| |<--------|--| Server |
+---------+ responses | |responses| | |
+----------+ | +--------+
| Central | |
| cache | |
+----------+ |
无论采用哪种方式, 都要注意域组件在可能时始终会为了可靠性而复制.
2.3. 约定 (Conventions)
域系统有若干约定, 用来处理低层但基础的问题. 尽管实现者可以在自己的系统内部违反这些约定, 但在其他主机能够观察到的所有行为中, 必须遵守这些约定.
2.3.1. 首选名称语法 (Preferred name syntax)
DNS 规范在构造域名的规则上尽可能保持通用. 其思想是, 任何现有对象的名称都应当能以最少改动表达为域名.
然而, 当为对象分配域名时, 谨慎的用户会选择同时满足域系统规则和对象已有规则的名称, 无论这些规则是公开发布的, 还是由现有程序隐含规定的.
例如, 命名邮件域时, 用户应同时满足本备忘录中的规则和 RFC-822 中的规则. 创建新主机名时, 应遵循 HOSTS.TXT 的旧规则. 这样可以避免旧软件转换为使用域名时出现问题.
以下语法会让许多使用域名的应用程序遇到更少问题, 例如 mail 和 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
注意, 域名中允许使用大写和小写字母, 但大小写不具有语义差异. 也就是说, 拼写相同但大小写不同的两个名称应被视为相同.
标签 (label) 必须遵循 ARPANET 主机名规则. 标签必须以字母开头, 以字母或数字结尾, 内部字符只能是字母, 数字和连字符. 长度也有限制. 标签长度必须不超过 63 个字符.
例如, 以下字符串标识 Internet 中的主机:
A.ISI.EDU XX.LCS.MIT.EDU SRI-NIC.ARPA
2.3.2. 数据传输顺序 (Data Transmission Order)
本文档描述的头部和数据的传输顺序精确到八位组 (octet) 级别. 每当图中展示一组八位组时, 这些八位组的传输顺序就是英语中正常阅读它们的顺序. 例如在下图中, 八位组按编号顺序传输.
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 1 | 2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 3 | 4 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 5 | 6 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
当一个八位组表示数值时, 图中最左边的位是高阶位或最高有效位. 也就是说, 标记为 0 的位是最高有效位. 例如, 下图表示十进制值 170.
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|1 0 1 0 1 0 1 0|
+-+-+-+-+-+-+-+-+
类似地, 当多八位组字段表示数值时, 整个字段最左边的位是最高有效位. 传输多八位组数量时, 最高有效八位组首先传输.
2.3.3. 字符大小写 (Character Case)
对于 DNS 中属于正式协议的所有部分, 字符串之间的所有比较, 例如标签和域名, 都以大小写不敏感方式进行. 目前, 这条规则在整个域系统中无例外地生效. 不过, 未来在当前用法之外的扩展可能需要使用名称中的完整二进制八位组能力, 因此应避免试图把域名存储为 7 位 ASCII, 或使用特殊字节终止标签等做法.
当数据进入域系统时, 应尽可能保留其原始大小写. 在某些情况下无法做到这一点. 例如, 如果数据库中存储了两个 RR, 一个位于 x.y, 一个位于 X.Y, 它们实际上存放在数据库的同一位置, 因此只能保留一种大小写形式. 基本规则是: 只有当数据用于定义数据库结构时才可以丢弃大小写; 如果两个名称按大小写不敏感方式比较相同, 则它们是同一个名称.
必须尽量减少大小写敏感数据的丢失. 因此, 虽然 x.y 和 X.Y 的数据都可以存储在单一位置 x.y 或 X.Y 下, 但 a.x 和 B.X 的数据绝不会存储在 A.x, A.X, b.x 或 b.X 下. 一般而言, 这会保留域名第一个标签的大小写, 但会强制内部节点标签标准化.
如果系统区分大小写, 将数据输入域数据库的系统管理员应注意以大小写一致的方式向域系统表示其提供的数据. 域系统中的数据分发系统会确保一致表示得到保留.
2.3.4. 大小限制 (Size limits)
DNS 中各种对象和参数都有大小限制. 它们列在下面. 其中一些限制很容易改变, 另一些则更基础.
| 对象 (Object) | 限制 (Limit) |
|---|---|
| labels | 63 个八位组或更少 |
| names | 255 个八位组或更少 |
| TTL | 有符号 32 位数的正值 |
| UDP messages | 512 个八位组或更少 |