IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    DNS编程开发(4)—DNS协议格式

    cjhust发表于 2014-12-18 20:07:44
    love 0

    1、知识百科

    我们通常使用机器的域名来访问这台机器,而不直接使用其IP地址,比如访问因特网上的各种网站。那么如何将机器的域名转换成IP地址呢?这就需要使用域名查询服务,域名查询服务有很多种实现方式,比如NIS(Network Information Service,网络信息服务)、DNS和本地静态文件等。

    DNS是一套分布式的域名服务系统,每个DNS服务器上都存放着大量的机器名和IP地址的映射,并且是动态更新的,众多网络客户端程序都使用DNS协议来向DNS服务器查询目标主机的IP地址。

    查询过程一般是:客户向DNS服务器的53端口发送UDP/TCP报文,DNS服务器收到后进行处理,并把结果记录仍以UDP/TCP报文的形式返回过来。

    2、协议格式

    clip_image002

    备注:每个DNS请求和响应都包括5个部分,Header固定12个字节,Header的字段QDcount、ANcount、NScount和ARcount决定了是否有Question、Answer、Authority和Addition等阶段。

    2.1 Header

    clip_image002[4]

    (1)ID:长度为16位,是一个用户发送查询的时候定义的随机数,当服务器返回结果的时候,返回包的ID与用户发送的一致;(客户端可以区分不同的请求应答)

    (2)QR:长度1位,值0是请求,1是应答;

    Opcode:长度4位,值0是标准查询(QUERY),1是反向查询(IQUERY),2是服务器状态查询(STATUS),3-15是保留值暂未使用;

    AA:长度1位,授权应答(Authoritative Answer),这个比特位在应答的时候才有意义,指出给出应答的服务器是查询域名的授权解析服务器;

    TC:长度1位,截断(TrunCation),用来指出报文比允许的长度还要长,导致被截断;

    RD:长度1位,期望递归(Recursion Desired),这个比特位被请求设置,应答的时候使用的相同的值返回,如果设置了RD,就建议域名服务器进行递归解析,递归查询的支持是可选的;

    RA:长度1位,支持递归(Recursion Available),这个比特位在应答中设置或取消,用来代表服务器是否支持递归查询;

    Z:长度3位,保留值,暂未使用,在所有请求和应答报文中必须设置为0;

    RCode:长度4位,应答码,类似http的stateCode一样,值0没有错误、1格式错误(Format Error)、2服务器错误(Server Failure)、3名字错误(Name Error)、4服务器不支持(Not Implemented)、5拒绝(Refused,由于设置的策略拒绝给出应答)和6-15(保留值,暂未使用);

    (3)QDCount(Questions):长度16位,报文请求段中的问题记录数;

    (4)NCount(Answer RRs):长度16位,报文回答段中的回答记录数;

    (5)NSCOUNT(Authority RRs):长度16位,报文授权段中的授权记录数;

    (6)ARCOUNT(Additional RRs):长度16位,报文附加段中的附加记录数;

    2.2 Question

    clip_image002[10]

    (1)QNAME:域名被编码为一些labels序列,每个labels包含一个字节表示后续字符串长度,以及这个字符串,以0长度和空字符串来表示域名结束,注意这个字段可能为奇数字节,不需要进行边界填充对齐;(不定长字段,格式为长度(1字节)+N字节内容+长度为0)

    (2)QTYPE:2个字节表示查询类型,取值可以为任何可用的类型值,以及通配码来表示所有的资源记录;

    //查询的资源记录类型

    enum QueryType

    {

    A=0×01, //指定计算机IP地址,AAAA是IPV6的地址?

    NS=0×02, //指定用于命名区域的 DNS 名称服务器

    MD=0×03, //指定邮件接收站(此类型已经过时了,使用MX代替)

    MF=0×04, //指定邮件中转站(此类型已经过时了,使用MX代替)

    CNAME=0×05, //指定用于别名的规范名称

    SOA=0×06, //指定用于 DNS区域的“起始授权机构”

    MB=0×07, //指定邮箱域名

    MG=0×08, //指定邮件组成员

    MR=0×09, //指定邮件重命名域名

    NULL=0x0A, //指定空的资源记录

    WKS=0x0B, //描述已知服务

    PTR=0x0C, //如果查询是IP地址,则指定计算机名;否则指定指向其它信息的指针

    HINFO=0x0D, //指定计算机 CPU 以及操作系统类型

    MINFO=0x0E, //指定邮箱或邮件列表信息

    MX=0x0F, //指定邮件交换器

    TXT=0×10, //指定文本信息

    UINFO=0×64, //指定用户信息

    UID=0×65, //指定用户标识符

    GID=0×66, //指定组名的组标识符

    ANY=0xFF //指定所有数据类型

    };

    (3)QCLASS:2个字节表示查询的协议类,比如,IN代表Internet;

    //指定信息的协议组

    enum QueryClass

    {

    IN=0×01, //指定 Internet 类别

    CSNET=0×02, //指定 CSNET 类别(已过时)

    CHAOS=0×03, //指定 Chaos 类别

    HESIOD=0×04, //指定 MIT Athena Hesiod 类别

    ANY=0xFF //指定任何以前列出的通配符

    };

    2.3 Resource Record

    clip_image002[12]

    (1)NAME:2字节,资源记录包含的域名;(4个字节被压缩成2个字节,一般以c0开头)

    (2)QTYPE:2字节,表示资源记录的类型如A、CNAME、NS等,指出RDATA数据的含义;

    (3)QCLASS:2字节,表示RDATA的类比如IN等;

    (4)TTL:4字节,表示资源记录可以缓存的时间,0代表只能被传输,但是不能被缓存;

    (5)RDLENGTH:2字节,表示RDATA的长度;

    (6)RDATA:不定长,表示记录,格式与TYPE和CLASS有关,比如TYPE是A,CLASS 是 IN,那么RDATA就是一个4个字节的ARPA网络地址;

    2.4 报文压缩

    为了减小报文,域名系统使用一种压缩方法来消除报文中域名的重复,使用这种方法,后面重复出现的域名或者labels被替换为指向之前出现位置的指针。

    前两个比特位都为1,因为lablels限制为不多于63个字节,所以label的前两位一定为0,这样就可以让指针与label进行区分(10 和 01 组合保留,以便日后使用),偏移值(OFFSET)0表示从报文开始的字节指针,偏移量为0表示ID字段的第一个字节(即都以c0开头)。

    指针只能在域名不是特殊格式的时候使用,否则域名服务器或解析器需要知道资源记录的格式。

    如果报文中的域名需要计算长度,并且使用了压缩算法,那么应该使用压缩后的长度,而不是压缩前的长度。

    程序可以自由选择是否使用指针,虽然这回降低报文的容量,而且很容易产生截断。不过所有的程序都应该能够理解收到的报文中包含的指针。

    2.5 传输(UDP/TCP)

    DNS报文以数据报UDP或者字节流TCP进行传输。字节流可以用来任何的DNS的传输,数据报可以减少代价提高传输性能,区域刷新必须使用TCP,因为需要一个可靠的传输,因特网中DNS支持端口53的TCP[RFC-793]和端口53的UDP [RFC-768]传输。

    (1)使用UDP:消息通过UDP的53端口进行传输;

    UDP传输的消息严格要求限制在512字节内(不包括IP和UDP头),长报文被截断,同时置报文头的TC标志位;

    UDP不能用于区域传输,主要用在标准的域名查询,报文通过UDP可能会丢失,所以重传机制是需要的,请求和应答可能在网络中或者服务器处理的时候被重新排序,所以解析客户端不能依赖请求的发送顺序;

    UDP的最优重传策略会因为网络的性能,客户的需要而不同,但是下面是推荐的:

    客户端在对一台固定的服务器重试之前,尝试一下其他的服务器;

    如果可能的话,重传的时间间隔需要建立在统计分析数据的基础上,太快的重试可能因为量太大导致服务器响应慢,建议的重试时间为2-5秒;

    (2)使用TCP:通过TCP发送的报文使用53端口,报文的前面有个字节表示后面报文的长度,长度不包括自己占用的2个字节,这个长度使得底层收取完整的报文后在交给上层处理。很多连接管理策略如下:

    服务器不能阻塞其他传输TCP数据的请求;

    服务器需要支持多连接;

    服务器要等客户端主动关闭连接,除非所有的数据都已经传输完了;

    如果服务器想关闭没有通讯的连接来释放资源,那么需要等待大约2分钟的时间。特别是要等SOA和AXFR(刷新操作中)在一个连接上传输完,服务器关闭连接的时候可以单方面的关闭,或者直接reset掉连接;

    3、常用公共DNS

    3.1 谷歌DNS

    主DNS:8.8.8.8

    辅DNS:8.8.4.4

    3.2 114DNS

    主DNS:114.114.114.114

    辅DNS:114.114.115.115

    3.3 阿里DNS

    主DNS:223.5.5.5

    辅DNS:223.6.6.6

    3.4 360DNS

    主DNS:101.226.4.6

    辅DNS:123.125.82.6

    4、参考资料

    DNS协议格式:

    http://lcx.cc/?i=1247

    http://09105106.blog.163.com/blog/static/2483578201342584441807/

    EDNS:

    http://www.cnblogs.com/cobbliu/p/3188632.html



沪ICP备19023445号-2号
友情链接