私はこれを理解しました.. client.lookupAllRecords を使用してから、返されるレコードのタイプをテストする必要があります..
#!/usr/bin/python
from twisted.internet import defer, reactor
from twisted.names import client, dns
def got_arg(*args):
for a in args[0][0]:
if a.payload.TYPE == dns.A:
print 'A - ipv4',a.payload
elif a.payload.TYPE == dns.AAAA:
print 'AAAA - ipv6',a.payload
def get_arg(arg):
d = client.lookupAllRecords('www.google.com').addCallback(got_arg)
if __name__ == '__main__':
get_arg('www.google.com')
reactor.run()
編集
私は、この解決策が不十分であることを認識しています。特に、レコードの最初のバッチに別のアドレスを指す単一の CNAME しか含まれていない場合..
これは、 twisted.names.common.extractRecord() が最初に ipv6 アドレスを探し、すぐにそれらを返すためです。この動作をオーバーライドする明白なメカニズムはありません。
そこで、醜いモンキー パッチを作成して ipv6 アドレスのチェーンを解決しようとさえしないように、これに対するハックなソリューションをまとめました。
#!/usr/bin/python
import socket
from twisted.names import dns
from twisted.names import common
def myExtractRecord(resolver, name, answers, level=10):
if not level:
return None
for r in answers:
if r.name == name and r.type == dns.A:
return socket.inet_ntop(socket.AF_INET, r.payload.address)
for r in answers:
if r.name == name and r.type == dns.CNAME:
result = myExtractRecord(
resolver, r.payload.name, answers, level - 1)
if not result:
return resolver.getHostByName(
str(r.payload.name), effort=level - 1)
return result
# No answers, but maybe there's a hint at who we should be asking about
# this
for r in answers:
if r.type == dns.NS:
from twisted.names import client
r = client.Resolver(servers=[(str(r.payload.name), dns.PORT)])
return r.lookupAddress(str(name)
).addCallback(
lambda (ans, auth, add):
myExtractRecord(r, name, ans + auth + add, level - 1))
common.extractRecord = myExtractRecord
私はそれを dnsclient.py に入れて、メインのプログラムで次のように使用します。
from twisted.names import client
import dnsclient
これに対するよりエレガントな解決策があれば、私はすべて耳にします。getHostByName が dns.A,dns.AAAA,dns.A && dns.AAAA のマスクを受け入れて、どのレコードのツリーをたどるかを判断する場合、これはより友好的だと思います。