dnspython вызывает NoAnswer, несмотря на ответ на запрос
Когда я использую dnspython для запроса к NS-серверу авторитетного сервера имен, возникает исключение NoAnswer, несмотря на тот факт, что мой захват пакета показывает, что был получен правильный ответ.
Пример: спросите у j.gtld-servers.net (192.48.79.30) NS-записи для stackru.com
>>> import dns.resolver
>>> r = dns.resolver.Resolver()
>>> r.nameservers = ['192.48.79.30']
>>> for answer in r.query('stackru.com', 'NS'):
... print answer.to_text()
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/dns/resolver.py", line 905, in query
raise_on_no_answer)
File "/usr/local/lib/python2.7/dist-packages/dns/resolver.py", line 142, in __init__
raise NoAnswer
dns.resolver.NoAnswer
>>>
Wireshark показывает, что ответ действительно вернулся:
Frame 2: 157 bytes on wire (1256 bits), 157 bytes captured (1256 bits)
Ethernet II, Src: xxxxxxxxxxxxxx (xx:xx:xx:xx:xx:xx), Dst: xxxxxxxxxxxxx (xx:xx:xx:xx:xx:xx)
Internet Protocol Version 4, Src: 192.48.79.30 (192.48.79.30), Dst: xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)
User Datagram Protocol, Src Port: domain (53), Dst Port: 55100 (55100)
Domain Name System (response)
[Request In: 1]
[Time: 0.278279000 seconds]
Transaction ID: 0xb6f5
Flags: 0x8100 (Standard query response, No error)
Questions: 1
Answer RRs: 0
Authority RRs: 2
Additional RRs: 2
Queries
Authoritative nameservers
stackru.com: type NS, class IN, ns ns1.serverfault.com
stackru.com: type NS, class IN, ns ns2.serverfault.com
Additional records
ns1.serverfault.com: type A, class IN, addr 198.252.206.80
ns2.serverfault.com: type A, class IN, addr 198.252.206.81
Запрос с dig @192.48.79.30 stackru.com ns
успешно и дает тот же ответ, показанный в захвате пакета выше.
Что интересно, host -t NS stackru.com 192.48.79.30
дает сбой с ответом "stackru.com не имеет записи NS", и в этом случае перехват пакета еще раз показывает, что ответ получен.
Почему dnspython неправильно обрабатывает ответ на этот запрос?
2 ответа
Боб Галли (сопровождающий dnspython) дал следующий ответ. Это не ошибка. Я должен использовать dns.query.udp()
вместо.
Вероятно, вам следует использовать dns.query.udp(), если вы запрашиваете авторитетный сервер. Запрос dns.resolver.Resolver предназначен для перехода на рекурсивный сервер. С точки зрения решателя, NoAnswer - это правильная вещь, потому что ответ - это делегирование, а не "ответ".
$ dig @192.48.79.30 stackru.com. ns
; <<>> DiG 9.8.3-P1 <<>> @192.48.79.30 stackru.com. ns
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31192
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 2
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;stackru.com. IN NS
;; AUTHORITY SECTION:
stackru.com. 172800 IN NS ns1.serverfault.com.
stackru.com. 172800 IN NS ns2.serverfault.com.
;; ADDITIONAL SECTION:
ns1.serverfault.com. 172800 IN A 198.252.206.80
ns2.serverfault.com. 172800 IN A 198.252.206.81
;; Query time: 293 msec
;; SERVER: 192.48.79.30#53(192.48.79.30)
;; WHEN: Sat Dec 7 15:48:48 2013
;; MSG SIZE rcvd: 115
Я могу подтвердить ту же проблему с Python 3.3 и dnspython 1.11.1 под FreeBSD 9.1
Кажется, это ошибка, вы пытались связаться с автором на http://www.dnspython.org/?