DNS数据包封装接口
Header section format
https://datatracker.ietf.org/doc/html/rfc1035#section-4.1.1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- ID[16b] 查询ID或者响应ID
- QR[1b]
- 0 表示是查询请求
- 1 标识是返回数据
- Opcode[4b]
- 0 (QUERY): 标准查询,这是最常见的操作类型,用于执行基本的域名解析。
- 1 (IQUERY): 反向查询(已废弃,不再使用)。
- 2 (STATUS): 服务器状态请求(也很少使用)。
- 3-15保留
- AA[1b] 是否权威应答
- 0 表示可以从缓存去数据,
- 1表示是权威服务器返回数据。
- TC[1b] 传输截断标志位
- RD[1b] 是否递归查询
- RA[1b] 是否支持递归
- Z[3b] 保留位
- RCODE[4b]
- 0 无错误条件
- 1 格式错误,名称服务器无法解释查询。
- 2 服务器故障,由于名称服务器出现问题,名称服务器无法处理此查询。
- 3 名称错误,此代码仅对权威名称服务器的响应有意义,表示查询中引用的域名不存在。
- 4 未实现,名称服务器不支持所请求的查询类型。
- 5 拒绝,名称服务器出于策略原因拒绝执行指定操作。例如,名称服务器可能不希望向特定请求者提供信息,或者名称服务器可能不希望对特定数据执行特定操作(例如区域传输)。
- 6-15 保留以备将来使用。
- QDCOUNT[16b] 查询记录数
- ANCOUNT[16b] 应答记录数
- NSCOUNT[16b] NS记录数
- ARCOUNT[16b] 额外记录数
Question section format
https://datatracker.ietf.org/doc/html/rfc1035#section-4.1.2
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ QNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- QNAME: 变长 字节长度 + 字符数据 如果下字节为0则结束否则要循环
- QTYPE类型:https://datatracker.ietf.org/doc/html/rfc1035#section-3.2.2
- QCLASS类型:https://datatracker.ietf.org/doc/html/rfc1035#section-3.2.4
请求封装示例:
184, 105, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 7, 97, 108, 105, 98, 97, 98, 97, 3, 99, 111, 109, 0, 0, 1, 0, 1
- 头部分(固定12位,参考文档说明): 184, 105, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0
- 域名部分: (变长[字符长度,字符数据])
- 7, 97, 108, 105, 98, 97, 98, 97,
- 3, 99, 111, 109,
- 0, 结束标志位
- QTYPE(查询类型): 0, 1,
- QCLASS:(网络类型) 0, 1, 0, 1,
Resource record format
https://datatracker.ietf.org/doc/html/rfc1035#section-4.1.3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
/ NAME /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/ RDATA /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- 前字段与请求段类似
- TTLI(32b): dns的生存周期返回数据的长度
- RDLENGTH (16b): RDATA的长度。
- RDATA (RDLENGTH byte): 实际数据, RDATA与NAME 可能会有数据压缩。
详细的实现步骤请参考 Dart(flutter) 代码
DOH(Dns over https)
通过https进行dns查询 rfc文件格式是https://datatracker.ietf.org/doc/html/rfc8484
GET
:method = GET
:scheme = https
:authority = dnsserver.example.net
:path = /dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application/dns-message
- dns 中的参数使用 base64url 原始的dns二进制message
POST
:method = POST
:scheme = https
:authority = dnsserver.example.net
:path = /dns-query
accept = application/dns-message
content-type = application/dns-message
content-length = 33
<33 bytes represented by the following hex encoding>
00 00 01 00 00 01 00 00 00 00 00 00 03 77 77 77
07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00
01
DOT(Dns over TCP)
通过TCP协议进行dns查询的方式 目前 移动设备基本都是支持,在安卓叫(私密DNS)