总体而言, 早期 DNS 协议是个比较简单的协议。受限于 UDP 大小和数据量, 基于 UDP 的 DNS 协议限制了包大小,并且采用二进制编码方式力求减少数据量占用。

二进制编码方式相比文本方式(例如HTTP、SIP、SMTP等)最明显的缺点就是不直观,再用一些技巧减少数据量,DNS 协议在定义、实现方面总显得有些弯弯绕绕。

本文记录了这些古怪的编码方式,方便以后查找,并帮助后续的开发者不会被代码给绕晕。作为我个人来说,还是尽快忘记这些吧。

这种方式应用很普遍,以“0xc0”标记开始,加上一个字节的 offset,进行消息包内的寻址即可。如下图所示:

这种方式比较直接,占用数据量也相对大一些,将域名完整信息存在数据包中。如下图所示:

需要说明的是:并不是直接将所有字符存进去就 OK 了。对于域名数据,以“.”符号分割成几个单元,每个单元数据采用 “length + value” 方式进行编码,最后以0x00结束编码。以上述数据为例:

这种方式其实就是综合了上述两种方式。以直接编码方式开始,然后以压缩(偏移)编码方式结尾。如下图所示: