mirror of
https://github.com/correl/SleekXMPP.git
synced 2024-11-27 19:19:54 +00:00
Add support for querying and connecting to IPv6 addresses.
Tested using servers provided by Florian Jensen (flosoft.biz) during the 2012 FOSDEM XMPP Summit. Fixes issue #94.
This commit is contained in:
parent
952260b423
commit
1a272fd276
2 changed files with 51 additions and 7 deletions
|
@ -166,8 +166,10 @@ class ClientXMPP(BaseXMPP):
|
||||||
try:
|
try:
|
||||||
record = "_xmpp-client._tcp.%s" % domain
|
record = "_xmpp-client._tcp.%s" % domain
|
||||||
answers = []
|
answers = []
|
||||||
|
log.debug("Querying SRV records for %s" % domain)
|
||||||
for answer in dns.resolver.query(record, dns.rdatatype.SRV):
|
for answer in dns.resolver.query(record, dns.rdatatype.SRV):
|
||||||
address = (answer.target.to_text()[:-1], answer.port)
|
address = (answer.target.to_text()[:-1], answer.port)
|
||||||
|
log.debug("Found SRV record: %s", address)
|
||||||
answers.append((address, answer.priority, answer.weight))
|
answers.append((address, answer.priority, answer.weight))
|
||||||
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
|
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
|
||||||
log.warning("No SRV records for %s", domain)
|
log.warning("No SRV records for %s", domain)
|
||||||
|
@ -179,7 +181,7 @@ class ClientXMPP(BaseXMPP):
|
||||||
return answers
|
return answers
|
||||||
else:
|
else:
|
||||||
log.warning("dnspython is not installed -- " + \
|
log.warning("dnspython is not installed -- " + \
|
||||||
"relying on OS A record resolution")
|
"relying on OS A/AAAA record resolution")
|
||||||
return [((domain, port), 0, 0)]
|
return [((domain, port), 0, 0)]
|
||||||
|
|
||||||
def register_feature(self, name, handler, restart=False, order=5000):
|
def register_feature(self, name, handler, restart=False, order=5000):
|
||||||
|
|
|
@ -397,7 +397,25 @@ class XMLStream(object):
|
||||||
if self.default_domain:
|
if self.default_domain:
|
||||||
self.address = self.pick_dns_answer(self.default_domain,
|
self.address = self.pick_dns_answer(self.default_domain,
|
||||||
self.address[1])
|
self.address[1])
|
||||||
self.socket = self.socket_class(Socket.AF_INET, Socket.SOCK_STREAM)
|
|
||||||
|
try:
|
||||||
|
# Look for IPv6 addresses, in addition to IPv4
|
||||||
|
for res in Socket.getaddrinfo(self.address[0],
|
||||||
|
int(self.address[1]),
|
||||||
|
0,
|
||||||
|
Socket.SOCK_STREAM):
|
||||||
|
log.debug("Trying: %s", res[-1])
|
||||||
|
af, sock_type, proto, canonical, sock_addr = res
|
||||||
|
try:
|
||||||
|
self.socket = self.socket_class(af, sock_type, proto)
|
||||||
|
break
|
||||||
|
except Socket.error:
|
||||||
|
log.debug("Could not open IPv%s socket." % proto)
|
||||||
|
except Socket.gaierror:
|
||||||
|
log.warning("Socket could not be opened, wrong IP versions.")
|
||||||
|
self.stop.set()
|
||||||
|
return False
|
||||||
|
|
||||||
self.configure_socket()
|
self.configure_socket()
|
||||||
|
|
||||||
if self.reconnect_delay is None:
|
if self.reconnect_delay is None:
|
||||||
|
@ -839,20 +857,44 @@ class XMLStream(object):
|
||||||
resolver = dns.resolver.get_default_resolver()
|
resolver = dns.resolver.get_default_resolver()
|
||||||
self.configure_dns(resolver, domain=domain, port=port)
|
self.configure_dns(resolver, domain=domain, port=port)
|
||||||
|
|
||||||
|
v4_answers = []
|
||||||
|
v6_answers = []
|
||||||
|
answers = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
answers = resolver.query(domain, dns.rdatatype.A)
|
log.debug("Querying A records for %s" % domain)
|
||||||
|
v4_answers = resolver.query(domain, dns.rdatatype.A)
|
||||||
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
|
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
|
||||||
log.warning("No A records for %s", domain)
|
log.warning("No A records for %s", domain)
|
||||||
return [((domain, port), 0, 0)]
|
v4_answers = [((domain, port), 0, 0)]
|
||||||
except dns.exception.Timeout:
|
except dns.exception.Timeout:
|
||||||
log.warning("DNS resolution timed out " + \
|
log.warning("DNS resolution timed out " + \
|
||||||
"for A record of %s", domain)
|
"for A record of %s", domain)
|
||||||
return [((domain, port), 0, 0)]
|
v4_answers = [((domain, port), 0, 0)]
|
||||||
else:
|
else:
|
||||||
return [((ans.address, port), 0, 0) for ans in answers]
|
for ans in v4_answers:
|
||||||
|
log.debug("Found A record: %s", ans[0])
|
||||||
|
answers.append(((ans.address, port), 0, 0))
|
||||||
|
|
||||||
|
try:
|
||||||
|
log.debug("Querying AAAA records for %s" % domain)
|
||||||
|
v6_answers = resolver.query(domain, dns.rdatatype.AAAA)
|
||||||
|
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
|
||||||
|
log.warning("No A records for %s", domain)
|
||||||
|
v6_answers = [((domain, port), 0, 0)]
|
||||||
|
except dns.exception.Timeout:
|
||||||
|
log.warning("DNS resolution timed out " + \
|
||||||
|
"for A record of %s", domain)
|
||||||
|
v6_answers = [((domain, port), 0, 0)]
|
||||||
|
else:
|
||||||
|
for ans in v6_answers:
|
||||||
|
log.debug("Found AAAA record: %s", ans[0])
|
||||||
|
answers.append(((ans.address, port), 0, 0))
|
||||||
|
|
||||||
|
return answers
|
||||||
else:
|
else:
|
||||||
log.warning("dnspython is not installed -- " + \
|
log.warning("dnspython is not installed -- " + \
|
||||||
"relying on OS A record resolution")
|
"relying on OS A/AAAA record resolution")
|
||||||
self.configure_dns(None, domain=domain, port=port)
|
self.configure_dns(None, domain=domain, port=port)
|
||||||
return [((domain, port), 0, 0)]
|
return [((domain, port), 0, 0)]
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue