add one_rr_per_rrset mode switch to methods which parse messages from wire format
authorBob Halley <halley@dnspython.org>
Mon, 30 Mar 2009 22:58:26 +0000 (22:58 +0000)
committerBob Halley <halley@dnspython.org>
Mon, 30 Mar 2009 22:58:26 +0000 (22:58 +0000)
ChangeLog
dns/message.py
dns/query.py

index 32f2c8cd9884eb82b450604632f1d6cc9b6f2e6f..2fdf4f93e8fa896b69a7d8d841a9190a2af2d847 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-03-30  Bob Halley  <halley@dnspython.org>
+
+       * Add "one_rr_per_rrset" mode switch to methods which parse
+         messages from wire format (e.g. dns.message.from_wire(),
+         dns.query.udp(), dns.query.tcp()).  If set, each RR read is
+         placed in its own RRset (instead of being coalesced).
+
 2009-03-30  Bob Halley  <halley@dnspython.org>
 
        * Added EDNS option support.
index 4786bedd7e78eb03290751cdbb53589ccb2300a4..9afbd3d0446642776e9bf324b82ff37269d520c8 100644 (file)
@@ -553,18 +553,22 @@ class _WireReader(object):
     @type current: int
     @ivar updating: Is the message a dynamic update?
     @type updating: bool
+    @ivar one_rr_per_rrset: Put each RR into its own RRset?
+    @type one_rr_per_rrset: bool
     @ivar zone_rdclass: The class of the zone in messages which are
     DNS dynamic updates.
     @type zone_rdclass: int
     """
 
-    def __init__(self, wire, message, question_only=False):
+    def __init__(self, wire, message, question_only=False,
+                 one_rr_per_rrset=False):
         self.wire = wire
         self.message = message
         self.current = 0
         self.updating = False
         self.zone_rdclass = dns.rdataclass.IN
         self.question_only = question_only
+        self.one_rr_per_rrset = one_rr_per_rrset
 
     def _get_question(self, qcount):
         """Read the next I{qcount} records from the wire data and add them to
@@ -598,7 +602,7 @@ class _WireReader(object):
         @param count: the number of records to read
         @type count: int"""
 
-        if self.updating:
+        if self.updating or self.one_rr_per_rrset:
             force_unique = True
         else:
             force_unique = False
@@ -709,7 +713,7 @@ class _WireReader(object):
 
 def from_wire(wire, keyring=None, request_mac='', xfr=False, origin=None,
               tsig_ctx = None, multi = False, first = True,
-              question_only = False):
+              question_only = False, one_rr_per_rrset = False):
     """Convert a DNS wire format message into a message
     object.
 
@@ -733,6 +737,8 @@ def from_wire(wire, keyring=None, request_mac='', xfr=False, origin=None,
     @type first: bool
     @param question_only: Read only up to the end of the question section?
     @type question_only: bool
+    @param one_rr_per_rrset: Put each RR into its own RRset
+    @type one_rr_per_rrset: bool
     @raises ShortHeader: The message is less than 12 octets long.
     @raises TrailingJunk: There were octets in the message past the end
     of the proper DNS message.
@@ -751,7 +757,7 @@ def from_wire(wire, keyring=None, request_mac='', xfr=False, origin=None,
     m.multi = multi
     m.first = first
 
-    reader = _WireReader(wire, m, question_only)
+    reader = _WireReader(wire, m, question_only, one_rr_per_rrset)
     reader.read()
 
     return m
index c6f1f6524736d1e4c61189dc39dc241fa9625895..7e305ce140e7502d914ea67716350f8a67c38696 100644 (file)
@@ -73,7 +73,7 @@ def _wait_for_writable(s, expiration):
     _wait_for([], [s], [s], expiration)
 
 def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,
-        ignore_unexpected=False):
+        ignore_unexpected=False, one_rr_per_rrset=False):
     """Return the response obtained after sending a query via UDP.
 
     @param q: the query
@@ -97,7 +97,10 @@ def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,
     @type source_port: int
     @param ignore_unexpected: If True, ignore responses from unexpected
     sources.  The default is False.
-    @type ignore_unexpected: bool"""
+    @type ignore_unexpected: bool
+    @param one_rr_per_rrset: Put each RR into its own RRset
+    @type one_rr_per_rrset: bool
+    """
 
     wire = q.to_wire()
     if af is None:
@@ -134,7 +137,8 @@ def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,
                                                                 destination)
     finally:
         s.close()
-    r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac)
+    r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
+                              one_rr_per_rrset=one_rr_per_rrset)
     if not q.is_response(r):
         raise BadResponse
     return r
@@ -176,7 +180,8 @@ def _connect(s, address):
                v[0] != errno.EALREADY:
             raise ty, v
 
-def tcp(q, where, timeout=None, port=53, af=None, source=None, source_port=0):
+def tcp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,
+        one_rr_per_rrset=False):
     """Return the response obtained after sending a query via TCP.
 
     @param q: the query
@@ -197,7 +202,10 @@ def tcp(q, where, timeout=None, port=53, af=None, source=None, source_port=0):
     @type source: string
     @param source_port: The port from which to send the message.
     The default is 0.
-    @type source_port: int"""
+    @type source_port: int
+    @param one_rr_per_rrset: Put each RR into its own RRset
+    @type one_rr_per_rrset: bool
+    """
 
     wire = q.to_wire()
     if af is None:
@@ -233,7 +241,8 @@ def tcp(q, where, timeout=None, port=53, af=None, source=None, source_port=0):
         wire = _net_read(s, l, expiration)
     finally:
         s.close()
-    r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac)
+    r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
+                              one_rr_per_rrset=one_rr_per_rrset)
     if not q.is_response(r):
         raise BadResponse
     return r