根据RFC1035,对于DNS服务器,递归解析时用53/UDP,区传输因需要可靠传输,必须使用53/TCP,DNS服务器的标准实现必须同时支持53/TCP和53/UDP。
RFC 1035中还指出,53/UDP上的UDP数据区(不包括UDP首部)不得超过512字节,发送时如果超过512字节,将被截断成512字节,同时DNS协议Flags字段Truncated位置位,53/TCP上的数据区最前面是big-endian序的2字节长度域,不包括自身这2字节,指明了后续数据长度。
当DNS响应数据大于512字节的时候,数据只返回512字节,剩余的数据将被丢弃,这个时候名字解析器通常使用TCP重发原来的查询请求,它将允许返回的响应超过512个字节。
EDNS0(Extension Mechanisms for DNS Version 0)是DNS在RFC1035基础上对DNS协议的扩展。DNS 的扩展机制(在RFC2671中定义为 EDNS0)允许 DNS 请求者公布其 UDP 数据包的大小,并且更便于传输大于 512 字节(对于UDP数据包大小的原始 DNS 限制RFC 1035)的数据包。DNS服务器通过UDP传输层接收请求时,它对来自OPT资源记录(RR)的请求者的UDP数据包大小进行标识,测量其响应,以包含请求者指定的最大 UDP 数据包大小中允许的多个资源记录。
简单来说,EDNS就是在遵循已有的DNS消息格式的基础上增加一些字段,来支持更多的DNS请求业务,RFC2671中指出EDNS被提出来的几个理由:
(1)扩展RCODE,由原来的4位增加到12位;
(2)只为标示domain类型的标签分配了两位,现在已经用掉了两位(00标示字符串类型,11表示压缩类型),后面如果有更多的标签类型则无法支持;
(3)扩展DNS使用UDP传输时的最大报文限制,可以超过512字节;
备注:edns0-client-subnet是google提交的一份关于edns0的扩展。
为了保持向后兼容性,更改已有的DNS协议格式是不可能的,因此需要在DNS协议的数据部分做文章,因此EDNS中引入了一种新的伪资源记录OPT,之所以叫做伪资源记录是因为它不包含任何DNS数据,OPT RR不能被cache、不能被转发、不能被存储在zone文件中,OPT被放在DNS通信双方(request和responsor)DNS消息的Additional section中。
(1)增加OPT RR;
(2)交互流程:
客户端发起DNS请求,在Additional部分增加OPT RR;
服务器端解析并记录下客户端能够处理的最大UDP报文的大小;
服务器端生成相应报文,若大于最大值,则置truncated位,否则可发送大于512且小于最大值报文;
#dig www.baidu.com +bufsize=2048
00 (NAME:root)
00 29 (TYPE:OPT=41)
08 00 (CLASS=UDP PLOAD SIZE=2048)
00 (Higher bits in extended RCODE)00(EDNS0 version:0)00 00(Z或flags)-TTL(4字节)
00 00(RDLENGTH=0)
#dig www.baidu.com +subnet=1.1.1.1
00 (NAME:<root>)
00 29 (TYPE: 0x29=41 OPT)
10 00 (CLASS=UDP payload size:4096)
00 (Higher bits in extended RCODE)00(EDNS0 version:0)00 00(Z或flags)-TTL(4字节)
00 0c(RDLENGTH=12)
00 08(Option Code:0x0008表示client subnet)
00 08(Option Length=8)
00 01 (family)
20 (source netmask)00 (scope netmask)
01 01 01 01(client subnet=32位4字节)
EDNS0
http://zhaotao110.blog.sohu.com/245807584.html
http://www.cnblogs.com/cobbliu/p/3188632.html
RFC2671
https://tools.ietf.org/html/rfc2671