summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Halley <halley@dnspython.org>2005-09-02 05:23:18 +0000
committerBob Halley <halley@dnspython.org>2005-09-02 05:23:18 +0000
commitd33a7f336c7637f5f6b86e8be8463e180d5a729f (patch)
tree83d7e2cdaf532662ec8851bbe88597c247e0b525
parent0865574e6da791d7360dd4a6f9d4267a1b81596d (diff)
downloaddnspython-d33a7f336c7637f5f6b86e8be8463e180d5a729f.tar.gz
make sending queries via IPv6 work
Original author: Bob Halley <halley@dnspython.org> Date: 2004-08-04 09:10:14
-rw-r--r--ChangeLog15
-rw-r--r--dns/inet.py18
-rw-r--r--dns/query.py54
3 files changed, 77 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 14b81fa..ea21348 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2004-08-04 Bob Halley <halley@nominum.com>
+
+ * dns/query.py: sending queries to a nameserver via IPv6 now
+ works.
+
+ * dns/inet.py (af_for_address): Add af_for_address(), which looks
+ at a textual-form address and attempts to determine which address
+ family it is.
+
+ * dns/query.py: the default for the 'af' parameter of the udp(),
+ tcp(), and xfr() functions has been changed from AF_INET to None,
+ which causes dns.inet.af_for_address() to be used to determine the
+ address family. If dns.inet.af_for_address() can't figure it out,
+ we fall back to AF_INET and hope for the best.
+
2004-07-31 Bob Halley <halley@dnspython.org>
* dns/rdtypes/ANY/NSEC.py (NSEC.from_text): The NSEC text format
diff --git a/dns/inet.py b/dns/inet.py
index e8e3092..c12dbbf 100644
--- a/dns/inet.py
+++ b/dns/inet.py
@@ -70,3 +70,21 @@ def inet_ntop(family, address):
return dns.ipv6.inet_ntoa(address)
else:
raise NotImplementedError
+
+def af_for_address(text):
+ """Determine the address family of a textual-form network address.
+
+ @param text: the textual address
+ @type text: string
+ @raises ValueError: the address family cannot be determined from the input.
+ @rtype int
+ """
+ try:
+ junk = dns.ipv4.inet_aton(text)
+ return AF_INET
+ except:
+ try:
+ junk = dns.ipv6.inet_aton(text)
+ return AF_INET6
+ except:
+ raise ValueError
diff --git a/dns/query.py b/dns/query.py
index d0e04d8..d5f86fb 100644
--- a/dns/query.py
+++ b/dns/query.py
@@ -25,6 +25,7 @@ import sys
import time
import dns.exception
+import dns.inet
import dns.name
import dns.message
import dns.rdataclass
@@ -64,7 +65,7 @@ def _wait_for_readable(s, expiration):
def _wait_for_writable(s, expiration):
_wait_for([], [s], [s], expiration)
-def udp(q, where, timeout=None, port=53, af=socket.AF_INET):
+def udp(q, where, timeout=None, port=53, af=None):
"""Return the response obtained after sending a query via UDP.
@param q: the query
@@ -76,22 +77,33 @@ def udp(q, where, timeout=None, port=53, af=socket.AF_INET):
@type timeout: float
@param port: The port to which to send the message. The default is 53.
@type port: int
- @param af: the address family to use. The default is socket.AF_INET.
+ @param af: the address family to use. The default is None, which
+ causes the address family to use to be inferred from the form of of where.
+ If the inference attempt fails, AF_INET is used.
@type af: int
@rtype: dns.message.Message object"""
wire = q.to_wire()
+ if af is None:
+ try:
+ af = dns.inet.af_for_address(where)
+ except:
+ af = dns.inet.AF_INET
+ if af == dns.inet.AF_INET:
+ destination = (where, port)
+ elif af == dns.inet.AF_INET6:
+ destination = (where, port, 0, 0)
s = socket.socket(af, socket.SOCK_DGRAM, 0)
try:
expiration = _compute_expiration(timeout)
s.setblocking(0)
_wait_for_writable(s, expiration)
- s.sendto(wire, (where, port))
+ s.sendto(wire, destination)
_wait_for_readable(s, expiration)
(wire, from_address) = s.recvfrom(65535)
finally:
s.close()
- if from_address != (where, port):
+ if from_address != destination:
raise UnexpectedSource
r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac)
if not q.is_response(r):
@@ -133,7 +145,7 @@ def _connect(s, address):
if v[0] != errno.EINPROGRESS and v[0] != errno.EWOULDBLOCK:
raise ty, v
-def tcp(q, where, timeout=None, port=53, af=socket.AF_INET):
+def tcp(q, where, timeout=None, port=53, af=None):
"""Return the response obtained after sending a query via TCP.
@param q: the query
@@ -145,16 +157,27 @@ def tcp(q, where, timeout=None, port=53, af=socket.AF_INET):
@type timeout: float
@param port: The port to which to send the message. The default is 53.
@type port: int
- @param af: the address family to use. The default is socket.AF_INET.
+ @param af: the address family to use. The default is None, which
+ causes the address family to use to be inferred from the form of of where.
+ If the inference attempt fails, AF_INET is used.
@type af: int
@rtype: dns.message.Message object"""
wire = q.to_wire()
+ if af is None:
+ try:
+ af = dns.inet.af_for_address(where)
+ except:
+ af = dns.inet.AF_INET
+ if af == dns.inet.AF_INET:
+ destination = (where, port)
+ elif af == dns.inet.AF_INET6:
+ destination = (where, port, 0, 0)
s = socket.socket(af, socket.SOCK_STREAM, 0)
try:
expiration = _compute_expiration(timeout)
s.setblocking(0)
- _connect(s, (where, port))
+ _connect(s, destination)
l = len(wire)
@@ -175,7 +198,7 @@ def tcp(q, where, timeout=None, port=53, af=socket.AF_INET):
def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN,
timeout=None, port=53, keyring=None, keyname=None, relativize=True,
- af=socket.AF_INET, lifetime=None):
+ af=None, lifetime=None):
"""Return a generator for the responses to a zone transfer.
@param where: where to send the message
@@ -200,7 +223,9 @@ def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN,
@param relativize: If True, all names in the zone will be relativized to
the zone origin.
@type relativize: bool
- @param af: the address family to use. The default is socket.AF_INET.
+ @param af: the address family to use. The default is None, which
+ causes the address family to use to be inferred from the form of of where.
+ If the inference attempt fails, AF_INET is used.
@type af: int
@param lifetime: The total number of seconds to spend doing the transfer.
If None, the default, then there is no limit on the time the transfer may
@@ -214,9 +239,18 @@ def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN,
if not keyring is None:
q.use_tsig(keyring, keyname)
wire = q.to_wire()
+ if af is None:
+ try:
+ af = dns.inet.af_for_address(where)
+ except:
+ af = dns.inet.AF_INET
+ if af == dns.inet.AF_INET:
+ destination = (where, port)
+ elif af == dns.inet.AF_INET6:
+ destination = (where, port, 0, 0)
s = socket.socket(af, socket.SOCK_STREAM, 0)
expiration = _compute_expiration(lifetime)
- _connect(s, (where, port))
+ _connect(s, destination)
l = len(wire)
tcpmsg = struct.pack("!H", l) + wire
_net_write(s, tcpmsg, expiration)