Dns twisted.names.client是否可以强制返回ipv4地址?(不修改resolv.conf或ETH设备)
我遇到的问题是,因为我的以太网接口上启用了IPv6,所以主机名解析有时会在我不需要IPv6时产生IPv6结果 是否可以让twisted.names.client仅返回ipv4地址,而不更改操作系统/名称解析/以太网配置 示例代码:Dns twisted.names.client是否可以强制返回ipv4地址?(不修改resolv.conf或ETH设备),dns,twisted,ipv4,names,Dns,Twisted,Ipv4,Names,我遇到的问题是,因为我的以太网接口上启用了IPv6,所以主机名解析有时会在我不需要IPv6时产生IPv6结果 是否可以让twisted.names.client仅返回ipv4地址,而不更改操作系统/名称解析/以太网配置 示例代码: #!/usr/bin/python from twisted.internet import defer, reactor from twisted.names import client def got_arg(*args): print 'got_ar
#!/usr/bin/python
from twisted.internet import defer, reactor
from twisted.names import client
def got_arg(*args):
print 'got_arg',args
def get_arg(arg):
d = client.getHostByName('www.google.com').addCallback(got_arg)
if __name__ == '__main__':
get_arg('www.google.com')
reactor.run()
这段代码总是在我的Linux设备上为我提供一个ipv6地址:
got_arg ('2001:4860:4001:800::1010',)
我希望能够强制ipv4查找,而不必修改下面的任何内容。有什么想法吗?由于不需要强制,至少有一个dict或tuple,其结果由ipv4/ipv6分解就好了 我知道了。。您必须使用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的掩码来确定哪些记录要遍历树,那么这会更友好。IPv4(a)或IPv6(AAAA)记录可能会返回,无论您是否有分配了IPv6地址的接口。Twisted Names只返回您查询的名称服务器的结果。名称服务器通常不会根据您的地址更改其响应。所以这是一个需要解决的更普遍的问题,而不仅仅是一个适用于拥有IPv6地址的人的问题。