summaryrefslogtreecommitdiff
path: root/sleekxmpp/xmlstream/xmlstream.py
diff options
context:
space:
mode:
authorLance Stout <lancestout@gmail.com>2012-02-09 21:28:28 -0800
committerLance Stout <lancestout@gmail.com>2012-02-09 21:28:28 -0800
commit1a272fd276fd5ab16506b205fcc75ba581873bc6 (patch)
treef2ab29fd56548d3f3b35821dd9274baa56dd2841 /sleekxmpp/xmlstream/xmlstream.py
parent952260b423e628ab9a68ca52d09b6330c7508c62 (diff)
downloadslixmpp-1a272fd276fd5ab16506b205fcc75ba581873bc6.tar.gz
slixmpp-1a272fd276fd5ab16506b205fcc75ba581873bc6.tar.bz2
slixmpp-1a272fd276fd5ab16506b205fcc75ba581873bc6.tar.xz
slixmpp-1a272fd276fd5ab16506b205fcc75ba581873bc6.zip
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.
Diffstat (limited to 'sleekxmpp/xmlstream/xmlstream.py')
-rw-r--r--sleekxmpp/xmlstream/xmlstream.py54
1 files changed, 48 insertions, 6 deletions
diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py
index 3a2cafc4..fe8f1bf3 100644
--- a/sleekxmpp/xmlstream/xmlstream.py
+++ b/sleekxmpp/xmlstream/xmlstream.py
@@ -397,7 +397,25 @@ class XMLStream(object):
if self.default_domain:
self.address = self.pick_dns_answer(self.default_domain,
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()
if self.reconnect_delay is None:
@@ -839,20 +857,44 @@ class XMLStream(object):
resolver = dns.resolver.get_default_resolver()
self.configure_dns(resolver, domain=domain, port=port)
+ v4_answers = []
+ v6_answers = []
+ answers = []
+
+ try:
+ log.debug("Querying A records for %s" % domain)
+ v4_answers = resolver.query(domain, dns.rdatatype.A)
+ except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
+ log.warning("No A records for %s", domain)
+ v4_answers = [((domain, port), 0, 0)]
+ except dns.exception.Timeout:
+ log.warning("DNS resolution timed out " + \
+ "for A record of %s", domain)
+ v4_answers = [((domain, port), 0, 0)]
+ else:
+ for ans in v4_answers:
+ log.debug("Found A record: %s", ans[0])
+ answers.append(((ans.address, port), 0, 0))
+
try:
- answers = resolver.query(domain, dns.rdatatype.A)
+ 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)
- return [((domain, port), 0, 0)]
+ v6_answers = [((domain, port), 0, 0)]
except dns.exception.Timeout:
log.warning("DNS resolution timed out " + \
"for A record of %s", domain)
- return [((domain, port), 0, 0)]
+ v6_answers = [((domain, port), 0, 0)]
else:
- return [((ans.address, port), 0, 0) for ans in answers]
+ for ans in v6_answers:
+ log.debug("Found AAAA record: %s", ans[0])
+ answers.append(((ans.address, port), 0, 0))
+
+ return answers
else:
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)
return [((domain, port), 0, 0)]