今天我花了几个小时试图弄清楚为什么我自己在浏览器中实现的 DIG 套接字级别不能持续工作。我成功地通过 UDP 发送了一个 DNS 数据包,但收到的响应却没有答案部分。它有时会工作,但随后会突然停止工作,没有任何代码更改。在拉出 Wireshark 后,我看到了以下两幅图像(一幅是通过 Dig 成功的,另一幅是由我的网络应用程序执行的,没有成功)。
答案1
我注意到的关键是那一位表示是否需要递归。http://www.ietf.org/rfc/rfc1035.txt以及 RFC 1035 第 25 页:
Recursion Desired - this bit may be set in a query and is copied into the response.
If RD is set, it directs the name server to pursue the query recursively.
Recursive query support is optional."
起初,我并不认为这个位是问题的根源,因为有时即使没有设置该位(即,递归时为 0),我也会收到正确的响应。解释是,如果解析器缓存了结果,即使递归时为 0,它也会返回该结果。
在命令行上进行一些尝试之后,我通过传递“+norecurse”标志来模拟使用 Dig 的行为:
$ dig mx google.com @8.8.8.8 +norecurse
; <<>> DiG 9.8.3-P1 <<>> mx google.com @8.8.8.8 +norecurse
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62530
;; flags: qr ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;google.com. IN MX
;; Query time: 50 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Dec 24 19:52:23 2012
;; MSG SIZE rcvd: 28
然后我删除了 +norecurse,一切正常!
教训:如果您没有看到 DNS 请求的任何答案部分,请检查您是否正在执行递归查询。很可能您没有执行递归查询,并且您正在查询的解析器没有缓存结果,因此您什么也得不到。