易栈 · 一盏

塞外秋来,衡阳雁去

使用UDP的协议:DNS、TFTP、BOOTP

一、DNS:域名系统

把DNS归到“使用UDP的协议”其实不是十分准确。一般情况下DNS客户端和DNS服务器使用UDP进行交互。但是当应答报文的长度超过512字节时,DNS服务器会告诉DNS客户端使用TCP重发原来的请求,从而用TCP来传输超过512字节的报文

域名系统(DNS)是一种用于TCP/IP应用程序的分布式数据库,它提供主机名字和IP地址之间的转换及有关电子邮件的选路信息。UNIX中提供两个库函数gethostbyname和gethostbyaddr来调用本机的地址解析器(resolver)向网络上的DNS服务器查询。

DNS的名字空间是一颗命名树。命名树上每个节点用一个字符串来标识,例如com、edu和org等。一个节点的完整域名是将从该节点到根节点的节点标识用点“.”串联起来。命名树的根节点是未命名的,所以完整域名最后都以点“.”结尾。以点“.”结尾的域名称为绝对域名或者完全合格的域名FQDN(Full Qualified Domain Name)。

命名树的层次结构为“命名树根->顶级域->第二级域->…”,详见书中图14-1。顶级域被分成三个部分:

  • 特殊域:arpa,用于从IP地址到域名的转换。我们熟知的DNS的功能是通过域名获取IP地址,但是如果我们想知道IP地址对应的域名呢?一种方案是遍历命名树,但这样代价太高了。而arpa方案是:每个IP都有一个对应的arpa域名,例如IP地址140.252.13.33的arpa域名为33.13.252.140.in-addr.arpa,通过arpa域名可以查到140.252.13.33对应的域名。arpa相当于域名数据库的反向索引。
  • 普通域:3字符。包括用于商业组织的com,用于教育机构的edu,用于组织机构的org等。
  • 国家域:2字符。基于ISO标准国家代码,例如中国的代码是cn,即国家域为cn。

一个独立管理的命名子树称为一个区域(zone),一个区域下可以划分更多小区域。网络信息中心NIC负责分配顶级域和委派其他指定地区域的授权机构。一旦一个区域的授权机构被委派后,由它负责向该区域提供多个名字服务器。

域名数据分布在多个名字服务器上,当一个名字服务器没有请求的信息时,它会向其他名字服务器请求。并不是每个名字服务器都知道怎样和其他名字服务器联系,但是每个名字服务器都必须知道怎么和根名字服务器联系(即知道根服务器的IP地址)。根服务器知道所有二级域中授权名字服务器的名字和IP地址。当名字服务器向根服务器请求时,根服务器会告诉它与另一个名字服务器联系。

DNS报文有查询报文应答报文,两者的格式一样,只是填充的值不一样。这里不介绍报文的具体格式,只介绍其中的标志字段和类型字段。

1、标志字段

  • AA:“授权回答”标志。表示应答是来自授权名字服务器,而不是来自名字服务器的高速缓存。名字服务器会把向其他名字服务器查询到的内容存在高速缓存中,下次收到请求不用向其他名字服务器重复请求,而直接用高速缓冲的信息返回,这种应答就不会置位AA标志。
  • RD:“期望递归”标志。这个标志告诉服务器必须要处理完这个查询,如果服务器中没有请求所需要的信息,他要负责向别的服务器递归查询,直到获取到结果。如果没有设置这个标志,当服务器没有请求所需要的信息时,它只是返回能解答该查询的其它名字服务器列表。不应该向根名字服务器发出期望递归的查询,它们仅用来查找其他授权名字服务器的地址。

2、类型字段

对于查询报文来说,类型字段表示要查询的内容。对于应答报文,类型字段表示返回的应答的类型。应答报文中可能有多个应答纪录,每个纪录都有自己的类型字段。

  • A:IP地址。这是最常见的查询类型,用于查询域名对应的IP地址。
  • PTR:指针纪录。用于查询IP地址对应的域名。原理见前面对arpa的解释。
  • CNAME:规范名字。有时候一个域名太复杂了,可以给用户提供一个较为简单易于记忆的别名。原始的那个复杂的域名就是这个别名对应的规范名字。
  • MX:邮件交换纪录。表示域名对应的邮件服务器,例如要往user@foo.com发邮件时,会通过域名foo.com获取MX纪录,然后把邮件发往MX纪录指定的邮件服务器。
  • NS:名字服务器。表示一个域的授权名字服务器。前面说到,名字服务器没有请求所需要的信息时,会向根服务器请求,这时根服务器会返回能够解答这个请求的授权名字服务器列表,应答类型为NS。

二、TFTP:简单文件传送协议

TFTP支持客户端从服务器读文件和往服务器写文件,最初用于通过网络来引导无盘系统。

TFTP是一种停止等待协议:数据发送方(可能是客户端也可能是服务器,视乎当前是在读文件还是写文件)发送完一个数据分组后,先等待对方返回ACK确认,然后再接着发下一个数据分组。由于使用了不可靠的UDP,所以TFTP需要自己实现超时与重传机制来避免分组丢失。同时为了避免分片,TFTP每个数据分组只发不超过512字节的数据。

TFTP服务器使用UDP知名端口69,但是服务器并不用这个端口来收发所有数据。服务器收到来自客户端的读/写请求之后,会申请一个未使用的端口,用这个新端口来给客户端发送第一个ACK。客户端接收到ACK后必须探测到这个新端口,并把之后的所有数据都发往新端口。这种处理避免了读写数据量大时,端口占用时间太长导致的服务器响应不及时问题,提高了并发性

三、BOOTP:引导程序协议

BOOTP用于无盘主机进行系统引导时,获取IP地址、主机名和引导文件名等信息。BOOTP是DHCP协议的前身,所以两者很多细节(包括以下讲述到的)都是相同的。

BOOTP有两个知名端口:服务器为67,客户端为68。很多协议都只规定了服务器端口,为什么BOOTP还需要规定客户端端口呢?因为客户端进行系统引导时通常还没有IP地址,所以服务器的应答是通过广播来发送的,所以客户端端口必须是一个已知端口。由于应答是通过广播发送,每个客户端都会收到所有应答,客户端是通过应答中的会话标识字段来判断该应答是否是发给自己的。

本文链接:易栈 - 使用UDP的协议:DNS、TFTP、BOOTP