标签归档:协议

DNS协议及DNS客户端的实现

DNS(Domain Name System)是一个提供域名解析服务的分布式系统,主要功能是完成域名与其对应的IP地址之间的相互转换。网络中提供DNS服务的主机叫做DNS服务器,而向DNS服务器发起查询请求的主机叫做DNS客户端,客户端与服务器之间通过DNS协议这一种应用层协议来相互通信并交换数据。

DNS协议建立在UDP或TCP协议之上,DNS服务器开放UDP:53端口和TCP:53端口监听客户端发来的请求。一般情况下客户端通过UDP协议封装请求报文,服务器也用UDP协议封装回应报文;由于广域网中不适合传输过大的UDP数据包,因此规定当封装了DNS回应的UDP数据包长度可能超过512字节时,客户端应该使用TCP协议连接DNS服务器并传输请求和回应,具体包括以下两种情况:(1)客户端认为UDP回应包长度可能超过512字节,主动使用TCP协议;(2)客户端第一次使用UDP协议发送DNS请求,服务端发现UDP回应包会超过512字节,截断UDP包中的回应报文,并在回应报文中为TC字段置1以通知客户端该报文已经被截断,客户端收到之后再发起一次TCP请求。

DNS数据报由头部和记录部分组成,其中请求报文只有问题部分,而回应报文可以有问题部分、回答部分、授权部分和附加部分。
net

DNS头部包含了标识、标志以及各个记录部分的记录个数。net_dns_header

其中标识字段用于确定请求会话,DNS服务保证请求和其对应的回应报文中标识字段的值是相等的。标志字段被分成若干子字段,用于标识数据包的各个属性。DNS头部的C语言结构可以表示如下:

问题部分由问题记录组成,资源部分、授权部分和附加部分由资源记录组成,问题记录和资源记录的结构是不一样的。
问题记录的格式如下图所示
net_a_record
查询名字是将要查询的域名,域名是一个由圆点分为若干节的字符串,这里的名字也由若干节组成,每一节第一个字节是这一个节中包含字符的长度。如下图
net_query_name

查询类型一般是A(地址)记录,表示把域名转换为32位的IPv4地址。全部的查询类型如下所示

查询类别一般都为1(Internet)。

资源记录的格式如下图所示
net_res_record
其中前三个字段与问题记录一致。生存时间表示该DNS回应记录可以在主机缓存中生存的时间,以秒为单位。资源数据长度是紧随其后的资源数据的长度,资源数据的具体内容与域类型字段有关,在只考虑A类型的时候这里的记录是一个32位的IP地址。

为了使DNS报文尽可能短,DNS协议对于可能重复出现的域名节采取压缩策略,因此通常情况下在一个报文中不会存有完全相同的域名节。当出现重复的域名节时,域名节的第一个字节将不是这个节的字符长度,而是以11开头的一个指针,指向该节在报文中第一次出现的位置。
net_pointer

下面是一个用UDP协议实现的DNS客户端类(没有实现TCP方式),测试Demo运行结果如图所示

dns_resolver


最新的相关文章

DNS:域名系统(一)
DNS:域名系统(二)