域名系统(DNS)是一种用于TCP / IP应用程序的分布式数据库,它提供主机名字和IP地
址之间互相转换及有关电子邮件的选路信息。
从应用角度上,对DNS的访问是通过一个地址解析器(resolver)来完成的。在UNIX主机中,该解析器主要通过两个库函数gethostbyname(3)和gethostbyaddr(3)来访问。前者接收主机名字返回 IP 地址,而后者接收 IP 地址来寻找主机名字。
1、因为IP地址是固定长度的,IPv4是32位,IPv6是128位,而域名是变长的,不便于计算机处理。
2.、IP地址对于用户来说不方便记忆,但域名便于用户使用,例如www.baidu.com这是百度的域名。
从理论上讲,整个因特网可以只使用一个域名服务器,使它装入因特网上所有的主机名,并回答所有对IP地址的查询。然而这种做法并不可取。因为因特网规模很大,这样的域名服务器肯定会因过负荷而无法正常工作,而且一旦域名服务器出现故障,整个因特网就会瘫痪。因此,早在1983年因特网就开始采用层次树状结构的命名方法,并使用分布式的域名系统DNS。
为了方便管理使用,采用了层次树状结构的命名方法,就像全球邮政系统和电话系统那样。采用这种命名方法,任何一个连接在因特网上的主机或路由器,都有一个唯一的层次结构的名字,即域名(domain name)。这里,“域”(domain)是名字空间中一个可被管理的划分。域还可以划分为子域,而子域还可继续划分为子域的子域,这样就形成了顶级域、二级域、三级域,等等。
每一个域名都是由标号(label)序列组成,而各标号之间用点隔开(请注意,是小数点“.”,不是中文的句号“。”)。例如下面的域名:
DNS规定,域名中标号都有英文字母和数据构成,每一个标号不超过63个字符,也不区分大小写字母(CCTV和cctv在域名中是等效的)。级别最低的域名写在最左边,级别最高的域名写在最右边。由多个标号组成的完整域名总共不超过255个字符。DNS既不规定一个域名需要包含多少个下级域名,也不规定每一级的域名代表什么意思。各级域名由其上一级的域名管理机构管理,而最高的顶级域名则由ICANN进行管理。用这种方法可使每一个域名在整个因特网范围内是唯一的,并且也容易设计出一种查找域名的机制。
需要注意的是,域名只是个逻辑概念,并不代表计算机所在的物理地点。变长的域名和使用有助记忆的字符串,是为了便于人来使用。而IP地址是定长的32位二进制数字则非常便于机器进行处理。这里需要注意,域名中的“点”和点分十进制IP地址中的“点”并无一一对应的关系。点分十进制IP地址中一定是包含三个“点”,但每一个域名中“点”的数目则不一定正好是三个。
域名服务数结构图
从理论上讲,可以让每一级的域名都有一个相对应的域名服务器,使所有的域名服务器构成和图“域名服务器树”的结构。但这样做会使域名服务器的数量太多,使域名系统的运行效率降低。因此DNS就采用划分区的办法来解决这个问题。
一个服务器所负责管辖的(或有权限的)范围叫做区(zone)。各单位根据具体情况来划分自己管辖范围的区。但在一个区中的所有节点必须是能够连通的。每一个区设置相应的权限域名服务器(authoritative name server),用来保存该区中的所有主机的域名到IP地址的映射。总之,DNS服务器的管辖范围不是以“域”为单位,而是以“区”为单位。区是DNS服务器实际管辖的范围。区可能等于或小于域,但一定不可能大于域。区是域的子集。
DNS定义了一个用于查询和响应的报文格式:
该报文由12个字节的首部和4个长度可变的字段组成。
标识字段由客户程序设置并由服务器返回结果。客户程序通过它来确定响应与查询是否匹配。
我们从最左位开始依次介绍各子字段:
随后的4个16bit 字段说明最后4个变长字段中包含的条目数。对于查询报文,问题数通常是1,而其他3项则为0。类似地,对于应答报文,回答数至少是1,剩下的两项可以是0或非0。
注意到DNS名字服务器使用的熟知端口号无论对UDP还是TCP都是53。这意味着DNS均
支持UDP和TCP访问,但我们使用tcpdump观察的所有例子都是采用UDP。那么这两种协议
都在什么情况下采用以及采用的理由都是什么呢?
当名字解析器发出一个查询请求,并且返回响应中的TC(删减标志)比特被设置为1时,
它就意味着响应的长度超过了512个字节,而仅返回前512个字节。在遇到这种情况时,名字
解析器通常使用TCP重发原来的查询请求,它将允许返回的响应超过512个字节(回想UDP数据报的最大长度)。既然TCP能将用户的数据流分为一些报文段,它就能用多个报文段来传送任意长度的用户数据。
此外,当一个域的辅助名字服务器在启动时,将从该域的主名字服务器执行区域传送。
我们也说过辅助服务器将定时(通常是3小时)向主服务器进行查询以便了解主服务器数据是
否发生变动。如果有变动,将执行一次区域传送。区域传送将使用TCP,因为这里传送的数
据远比一个查询或响应多得多。
既然DNS主要使用UDP,无论是名字解析器还是名字服务器都必须自己处理超时和重传。
此外,不像其他的使用UDP的nternet应用(TFTP、BOOTP和SNMP),大部分操作集中在局
域网上,DNS查询和响应通常经过广域网。分组丢失率和往返时间的不确定性在广域网上比
局域网上更大。这样对于DNS客户程序,一个好的重传和超时程序就显得更重要了。
主机向本地域名服务器的查询一般都是采用递归查询(recursive query)。所谓递归查询就是:如果主机所询问的本地域名服务器不知道被查询域名的IP地址,那么本地域名服务器就以DNS客户的身份,向其他根域名服务器继续发出查询请求报文(即替该主机继续查询),而不是让该主机自己进行下一步的查询。因此,递归查询返回的查询结果或者是所要查询的IP地址,或者是报错,表示无法查询到所需的IP地址。
本地域名服务器向根域名服务器的查询通常是采用迭代查询(iterativequery)。迭代查询的特点是这样的:当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的IP地址,要么告诉本地域名服务器:“你下一步应当向哪一个域名服务器进行查询”。然后让本地域名服务器进行后续的查询(而不是替本地域名服务器进行后续的查询)。根域名服务器通常是把自己知道的顶级域名服务器的IP地址告诉本地域名服务器,让本地域名服务器再向顶级域名服务器查询。顶级域名服务器在收到本地域名服务器的查询请求后,要么给出所要查询的IP地址,要么告诉本地域名服务器下一步应当向哪一个权限域名服务器进行查询,本地域名服务器就这样进行迭代查询。最后,知道了所要解析的域名的IP地址,然后把这个结果返回给发起查询的主机。当然,本地域名服务器也可以采用递归查询,这取决于最初的查询请求报文的设置是要求使用哪一种查询方式
假定域名为m.xyz.com的主机想知道另一个主机(域名为y.abc.com)的IP地址。例如,主机m.xyz.com打算发送邮件给主机y.abc.com。这时就必须知道主机y.abc.com的IP地址,其查询步骤如下所示:
8个步骤总共要使用8个UDP用户数据报的报文。