在进行DNS源码解析前我还行讲解一些DNS的基础知识。这个是以后代码讲解需要用到的这些知识。先介绍一下DNS数据包的组成部分如下图
Header ID 请求客户端设置的16位标示,服务器给出应答的时候会带相同的标示字段回来,这样请求客户端就可以区分不同的请求应答了。 QR 1个比特位用来区分是请求(0)还是应答(1)。 OPCODE 4个比特位用来设置查询的种类,应答的时候会带相同值,可用的值如下: 0 标准查询 (QUERY) 1 反向查询 (IQUERY) 2 服务器状态查询 (STATUS) 3-15 保留值,暂时未使用 AA 授权应答(Authoritative Answer) - 这个比特位在应答的时候才有意义,指出给出应答的服务器是查询域名的授权解析服务器。 注意因为别名的存在,应答可能存在多个主域名,这个AA位对应请求名,或者应答中的第一个主域名。 TC 截断(TrunCation) - 用来指出报文比允许的长度还要长,导致被截断。 RD 期望递归(Recursion Desired) - 这个比特位被请求设置,应答的时候使用的相同的值返回。如果设置了RD,就建议域名服务器进行递归解析,递归查询的支持是可选的。 RA 支持递归(Recursion Available) - 这个比特位在应答中设置或取消,用来代表服务器是否支持递归查询。 Z 保留值,暂时未使用。在所有的请求和应答报文中必须置为0。 RCODE 应答码(Response code) - 这4个比特位在应答报文中设置,代表的含义如下: 0 没有错误。 1 报文格式错误(Format error) - 服务器不能理解请求的报文。 2 服务器失败(Server failure) - 因为服务器的原因导致没办法处理这个请求。 3 名字错误(Name Error) - 只有对授权域名解析服务器有意义,指出解析的域名不存在。 4 没有实现(Not Implemented) - 域名服务器不支持查询类型。 5 拒绝(Refused) - 服务器由于设置的策略拒绝给出应答。比如,服务器不希望对某些请求者给出应答,或者服务器不希望进行某些操作(比如区域传送zone transfer)。 6-15 保留值,暂时未使用。 QDCOUNT 无符号16位整数表示报文请求段中的问题记录数。 ANCOUNT 无符号16位整数表示报文回答段中的回答记录数。 NSCOUNT 无符号16位整数表示报文授权段中的授权记录数。 ARCOUNT 无符号16位整数表示报文附加段中的附加记录数。Question Question是重点需要讲解的,它是请求的主体 QNAME 域名被编码为一些labels序列,每个labels包含一个字节表示后续字符串长度,以及这个字符串,以0长度和空字符串来表示域名结束。注意这个字段可能为奇数字节,不需要进行边界填充对齐。 QTYPE 2个字节表示查询类型,.取值可以为任何可用的类型值,以及通配码来表示所有的资源记录。 A=0x01, //指定计算机 IP 地址。NS=0x02, //指定用于命名区域的 DNS 名称服务器。
MD=0x03, //指定邮件接收站(此类型已经过时了,使用MX代替)
MF=0x04, //指定邮件中转站(此类型已经过时了,使用MX代替)
CNAME=0x05, //指定用于别名的规范名称。
SOA=0x06, //指定用于 DNS 区域的“起始授权机构”。
MB=0x07, //指定邮箱域名。
MG=0x08, //指定邮件组成员。
MR=0x09, //指定邮件重命名域名。
NULL=0x0A, //指定空的资源记录
WKS=0x0B, //描述已知服务。
PTR=0x0C, //如果查询是 IP 地址,则指定计算机名;否则指定指向其它信息的指针。
HINFO=0x0D, //指定计算机 CPU 以及操作系统类型。
MINFO=0x0E, //指定邮箱或邮件列表信息。
MX=0x0F, //指定邮件交换器。
TXT=0x10, //指定文本信息。
AAAA=0x1c,//IPV6资源记录。
UINFO=0x64, //指定用户信息。
UID=0x65, //指定用户标识符。
GID=0x66, //指定组名的组标识符。
ANY=0xFF //指定所有数据类型。
QCLASS 2个字节表示查询的协议类,比如,IN代表Internet。 IN=0x01, //指定 Internet 类别。
CSNET=0x02, //指定 CSNET 类别。(已过时)
CHAOS=0x03, //指定 Chaos 类别。
HESIOD=0x04,//指定 MIT Athena Hesiod 类别。
ANY=0xFF //指定任何以前列出的通配符。
Answer Answer是资源应答,所有的RRs(Resource Records)都具有相同的顶级字段格式定义:owner TTL CLASS TYPE RDATA。主要包括 NAME 资源记录包含的域名 TYPE 2个字节表示资源记录的类型,指出RDATA数据的含义,主要有十几种类型: A:主机地址 主机地址(A) 资源记录。将 DNS 域名映射到Internet 协议(IP) 版本4 的32 位地址中 AAAA:IPv6主机地址 IPv6 主机地址(AAAA) 资源记录。将DNS 域名映射到 Internet 协议(IP) 版本6 的128 位地址中 NS:权威名称服务器 MD:邮件目的地(被废弃,使用MX) MF:邮件转发器(被废弃,使用MX) CNAME:别名的正则名称 SOA:标记权威区域的开始 MB:邮箱域名(试验) MG:邮件组成员(试验) MR:邮件重新命名域名(试验) NULL:空RR(试验) WKS:众所周知的业务描述 PTR:域名指针 HINFO:主机信息 MINFO:邮箱或邮件列表信息 MX:邮件交换 邮件交换器(MX) 资源记录如mail_exchanger_host中指定的那样,为邮件交换器主机提供邮件路由 TXT:文本字符串 CLASS 2个字节表示RDATA的类,主要有四种类型:IN(Internet类) CS(CSNET类)、CH(CHAOS类)、HS(Hesiod)很少使用 TTL 4字节无符号整数表示资源记录可以缓存的时间。0代表只能被传输,但是不能被缓存。 RDLENGTH 2个字节无符号整数表示RDATA的长度 RDATA 不定长字符串来表示记录,格式根TYPE和CLASS有关。比如,TYPE是A,CLASS 是 IN,那么RDATA就是一个4个字节的ARPA网络地址。 这个为以后源码讲解做好理论基础。