]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
Add to_digestable() methods to rdata classes
authorBob Halley <halley@nominum.com>
Fri, 19 Jun 2009 10:57:39 +0000 (11:57 +0100)
committerBob Halley <halley@nominum.com>
Fri, 19 Jun 2009 10:57:39 +0000 (11:57 +0100)
ChangeLog
dns/rdata.py
dns/rdtypes/ANY/AFSDB.py
dns/rdtypes/ANY/DNAME.py
dns/rdtypes/ANY/NXT.py
dns/rdtypes/ANY/RP.py
dns/rdtypes/ANY/RT.py
dns/rdtypes/ANY/SIG.py
dns/rdtypes/ANY/SOA.py
dns/rdtypes/mxbase.py
dns/rdtypes/nsbase.py

index 0b26bb79aae51d32f46de2fabde8ed3a5289fb2d..48a5b43547ff133200865c6303161ec7f153bbe4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 2009-06-19  Bob Halley  <halley@dnspython.org>
 
-       * Added support for the HIP RR type.
+        * Added a to_digestable() method to rdata classes; it returns the
+         digestable form (i.e. DNSSEC canonical form) of the rdata.  For
+         most rdata types this is the same uncompressed wire form.  For
+         certain older DNS RR types, however, domain names in the rdata
+         are downcased.
+
+2009-06-19  Bob Halley  <halley@dnspython.org>
+
+        * Added support for the HIP RR type.
 
 2009-06-18  Bob Halley  <halley@dnspython.org>
 
-       * Added support for the DLV RR type.
+        * Added support for the DLV RR type.
 
 2009-06-18  Bob Halley  <halley@dnspython.org>
 
-       * Added various DNSSEC related constants (e.g. algorithm identifiers,
-         flag values).
+        * Added various DNSSEC related constants (e.g. algorithm identifiers,
+          flag values).
 
 2009-06-18  Bob Halley  <halley@dnspython.org>
 
-       * dns/tsig.py: Added support for BADTRUNC result code.
+        * dns/tsig.py: Added support for BADTRUNC result code.
 
 2009-06-18  Bob Halley  <halley@dnspython.org>
 
-       * dns/query.py (udp): When checking that addresses are the same,
-         use the binary form of the address in the comparison.  This
-         ensures that we don't treat addresses as different if they have
-         equivalent but differing textual representations.  E.g. "1:00::1"
-         and "1::1" represent the same address but are not textually equal.
-         Thanks to Kim Davies for reporting this bug.
+        * dns/query.py (udp): When checking that addresses are the same,
+          use the binary form of the address in the comparison.  This
+          ensures that we don't treat addresses as different if they have
+          equivalent but differing textual representations.  E.g. "1:00::1"
+          and "1::1" represent the same address but are not textually equal.
+          Thanks to Kim Davies for reporting this bug.
 
 2009-06-18  Bob Halley  <halley@dnspython.org>
 
-       * The resolver's query() method now has an optional 'source' parameter,
-         allowing the source IP address to be specified.  Thanks to
-         Alexander Lind for suggesting the change and sending a patch.
+        * The resolver's query() method now has an optional 'source' parameter,
+          allowing the source IP address to be specified.  Thanks to
+          Alexander Lind for suggesting the change and sending a patch.
 
 2009-06-18  Bob Halley  <halley@dnspython.org>
 
-       * Added NSEC3 and NSEC3PARAM support.
+        * Added NSEC3 and NSEC3PARAM support.
 
 2009-06-17  Bob Halley  <halley@dnspython.org>
 
-       * Fixed NSEC.to_text(), which was only printing the last window.
-         Thanks to Brian Wellington for finding the problem and fixing it.
+        * Fixed NSEC.to_text(), which was only printing the last window.
+          Thanks to Brian Wellington for finding the problem and fixing it.
 
 2009-03-30  Bob Halley  <halley@dnspython.org>
 
-       * dns/query.py (xfr): Allow UDP IXFRs.  Use "one_rr_per_rrset" mode when
-         doing IXFR.
+        * dns/query.py (xfr): Allow UDP IXFRs.  Use "one_rr_per_rrset" mode when
+          doing IXFR.
 
 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).
+        * 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.
+        * Added EDNS option support.
 
 2008-10-16  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdtypes/ANY/DS.py: The from_text() parser for DS RRs did not
-         allow multiple Base64 chunks.  Thanks to Rakesh Banka for
-         finding this bug and submitting a patch.
+        * dns/rdtypes/ANY/DS.py: The from_text() parser for DS RRs did not
+          allow multiple Base64 chunks.  Thanks to Rakesh Banka for
+          finding this bug and submitting a patch.
 
 2008-10-08  Bob Halley  <halley@dnspython.org>
 
-       * Add entropy module.
+        * Add entropy module.
 
-       * When validating TSIGs, we need to use the absolute name.
+        * When validating TSIGs, we need to use the absolute name.
 
 2008-06-03  Bob Halley  <halley@dnspython.org>
 
-       * dns/message.py (Message.set_rcode): The mask used preserved the
-         extended rcode, instead of everything else in ednsflags.
+        * dns/message.py (Message.set_rcode): The mask used preserved the
+          extended rcode, instead of everything else in ednsflags.
 
-       * dns/message.py (Message.use_edns): ednsflags was not kept
-         coherent with the specified edns version.
+        * dns/message.py (Message.use_edns): ednsflags was not kept
+          coherent with the specified edns version.
 
 2008-02-06  Bob Halley  <halley@dnspython.org>
 
-       * dns/ipv6.py (inet_aton):  We could raise an exception other than
-         dns.exception.SyntaxError in some cases.
+        * dns/ipv6.py (inet_aton):  We could raise an exception other than
+          dns.exception.SyntaxError in some cases.
 
-       * dns/tsig.py: Raise an exception when the peer has set a non-zero
-         TSIG error.
+        * dns/tsig.py: Raise an exception when the peer has set a non-zero
+          TSIG error.
 
 2007-11-25  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.6.0 released)
+        * (Version 1.6.0 released)
 
 2007-11-25  Bob Halley  <halley@dnspython.org>
 
-       * dns/query.py (_wait_for): if select() raises an exception due to
-         EINTR, we should just select() again.
+        * dns/query.py (_wait_for): if select() raises an exception due to
+          EINTR, we should just select() again.
 
 2007-06-13  Bob Halley  <halley@dnspython.org>
 
-       * dns/inet.py: Added is_multicast().
+        * dns/inet.py: Added is_multicast().
 
-       * dns/query.py (udp):  If the queried address is a multicast address, then
-         don't check that the address of the response is the same as the address
-         queried.
+        * dns/query.py (udp):  If the queried address is a multicast address, then
+          don't check that the address of the response is the same as the address
+          queried.
 
 2007-05-24  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdtypes/IN/NAPTR.py: NAPTR comparisons didn't compare the
-         preference field due to a typo.
+        * dns/rdtypes/IN/NAPTR.py: NAPTR comparisons didn't compare the
+          preference field due to a typo.
 
 2007-02-07  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py: Integrate code submitted by Paul Marks to
-         determine whether a Windows NIC is enabled.  The way dnspython
-         used to do this does not work on Windows Vista.
+        * dns/resolver.py: Integrate code submitted by Paul Marks to
+          determine whether a Windows NIC is enabled.  The way dnspython
+          used to do this does not work on Windows Vista.
 
 2006-12-10  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.5.0 released)
-       
+        * (Version 1.5.0 released)
+
 2006-11-03  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdtypes/IN/DHCID.py: Added support for the DHCID RR type.
+        * dns/rdtypes/IN/DHCID.py: Added support for the DHCID RR type.
 
 2006-11-02  Bob Halley  <halley@dnspython.org>
 
-       * dns/query.py (udp): Messages from unexpected sources can now be
-         ignored by setting ignore_unexpected to True.
+        * dns/query.py (udp): Messages from unexpected sources can now be
+          ignored by setting ignore_unexpected to True.
 
 2006-10-31  Bob Halley  <halley@dnspython.org>
 
-       * dns/query.py (udp): When raising UnexpectedSource, add more
-         detail about what went wrong to the exception.
+        * dns/query.py (udp): When raising UnexpectedSource, add more
+          detail about what went wrong to the exception.
 
 2006-09-22  Bob Halley  <halley@dnspython.org>
 
-       * dns/message.py (Message.use_edns): add reasonable defaults for
-         the ednsflags, payload, and request_payload parameters.
+        * dns/message.py (Message.use_edns): add reasonable defaults for
+          the ednsflags, payload, and request_payload parameters.
 
-       * dns/message.py (Message.want_dnssec): add a convenience method for
-         enabling/disabling the "DNSSEC desired" flag in requests.
+        * dns/message.py (Message.want_dnssec): add a convenience method for
+          enabling/disabling the "DNSSEC desired" flag in requests.
 
-       * dns/message.py (make_query): add "use_edns" and "want_dnssec"
-         parameters.
+        * dns/message.py (make_query): add "use_edns" and "want_dnssec"
+          parameters.
 
 2006-08-17  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py (Resolver.read_resolv_conf): If /etc/resolv.conf
-         doesn't exist, just use the default resolver configuration (i.e.
-         the same thing we would have used if resolv.conf had existed and
-         been empty).
+        * dns/resolver.py (Resolver.read_resolv_conf): If /etc/resolv.conf
+          doesn't exist, just use the default resolver configuration (i.e.
+          the same thing we would have used if resolv.conf had existed and
+          been empty).
 
 2006-07-26  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py (Resolver._config_win32_fromkey): fix
-         cut-and-paste error where we passed the wrong variable to
-         self._config_win32_search().  Thanks to David Arnold for finding
-         the bug and submitting a patch.
+        * dns/resolver.py (Resolver._config_win32_fromkey): fix
+          cut-and-paste error where we passed the wrong variable to
+          self._config_win32_search().  Thanks to David Arnold for finding
+          the bug and submitting a patch.
 
 2006-07-20  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py (Answer): Add more support for the sequence
-         protocol, forwarding requests to the answer object's rrset.
-         E.g. "for a in answer" is equivalent to "for a in answer.rrset",
-         "answer[i]" is equivalent to "answer.rrset[i]", and
-         "answer[i:j]" is equivalent to "answer.rrset[i:j]".
+        * dns/resolver.py (Answer): Add more support for the sequence
+          protocol, forwarding requests to the answer object's rrset.
+          E.g. "for a in answer" is equivalent to "for a in answer.rrset",
+          "answer[i]" is equivalent to "answer.rrset[i]", and
+          "answer[i:j]" is equivalent to "answer.rrset[i:j]".
 
 2006-07-19  Bob Halley  <halley@dnspython.org>
 
-       * dns/query.py (xfr): Add IXFR support.
+        * dns/query.py (xfr): Add IXFR support.
 
 2006-06-22  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdtypes/IN/IPSECKEY.py: Added support for the IPSECKEY RR type.
+        * dns/rdtypes/IN/IPSECKEY.py: Added support for the IPSECKEY RR type.
 
 2006-06-21  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdtypes/ANY/SPF.py: Added support for the SPF RR type.
+        * dns/rdtypes/ANY/SPF.py: Added support for the SPF RR type.
 
 2006-06-02  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.4.0 released)
+        * (Version 1.4.0 released)
 
 2006-04-25  Bob Halley  <halley@dnspython.org>
 
-       * dns/rrset.py (RRset.to_rdataset): Added a convenience method
-         to convert an rrset into an rdataset.
+        * dns/rrset.py (RRset.to_rdataset): Added a convenience method
+          to convert an rrset into an rdataset.
 
 2006-03-27  Bob Halley  <halley@dnspython.org>
 
-       * Added dns.e164.query().  This function can be used to look for
-         NAPTR RRs for a specified number in several domains, e.g.:
+        * Added dns.e164.query().  This function can be used to look for
+          NAPTR RRs for a specified number in several domains, e.g.:
 
-               dns.e164.query('16505551212',
-                              ['e164.dnspython.org.', 'e164.arpa.'])
+                dns.e164.query('16505551212',
+                               ['e164.dnspython.org.', 'e164.arpa.'])
 
 2006-03-26  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py (Resolver.query): The resolver deleted from
-         a list while iterating it, which makes the iterator unhappy.
+        * dns/resolver.py (Resolver.query): The resolver deleted from
+          a list while iterating it, which makes the iterator unhappy.
 
 2006-03-17  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py (Resolver.query): The resolver needlessly
-         delayed responses for successful queries.
+        * dns/resolver.py (Resolver.query): The resolver needlessly
+          delayed responses for successful queries.
 
 2006-01-18  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdata.py: added a validate() method to the rdata class.  If
-         you change an rdata by assigning to its fields, it is a good
-         idea to call validate() when you are done making changes.
-         For example, if 'r' is an MX record and then you execute:
+        * dns/rdata.py: added a validate() method to the rdata class.  If
+          you change an rdata by assigning to its fields, it is a good
+          idea to call validate() when you are done making changes.
+          For example, if 'r' is an MX record and then you execute:
 
-               r.preference = 100000   # invalid, because > 65535
-               r.validate()
+                r.preference = 100000   # invalid, because > 65535
+                r.validate()
 
-         The validation will fail and an exception will be raised.
+          The validation will fail and an exception will be raised.
 
 2006-01-11  Bob Halley  <halley@dnspython.org>
 
-       * dns/ttl.py: TTLs are now bounds checked to be within the closed
-         interval [0, 2^31 - 1].
+        * dns/ttl.py: TTLs are now bounds checked to be within the closed
+          interval [0, 2^31 - 1].
 
-       * The BIND 8 TTL syntax is now accepted in the SOA refresh, retry,
-         expire, and minimum fields, and in the original_ttl field of
-         SIG and RRSIG records.
+        * The BIND 8 TTL syntax is now accepted in the SOA refresh, retry,
+          expire, and minimum fields, and in the original_ttl field of
+          SIG and RRSIG records.
 
 2006-01-04  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py: The windows registry irritatingly changes the
-         list element delimiter in between ' ' and ',' (and vice-versa)
-         in various versions of windows.  We now cope by always looking
-         for either one (' ' first).
+        * dns/resolver.py: The windows registry irritatingly changes the
+          list element delimiter in between ' ' and ',' (and vice-versa)
+          in various versions of windows.  We now cope by always looking
+          for either one (' ' first).
 
 2005-12-27  Bob Halley  <halley@dnspython.org>
 
-       * dns/e164.py: Added routines to convert between E.164 numbers and
-         their ENUM domain name equivalents.
+        * dns/e164.py: Added routines to convert between E.164 numbers and
+          their ENUM domain name equivalents.
 
-       * dns/reversename.py: Added routines to convert between IPv4 and
-         IPv6 addresses and their DNS reverse-map equivalents.
+        * dns/reversename.py: Added routines to convert between IPv4 and
+          IPv6 addresses and their DNS reverse-map equivalents.
 
 2005-12-18  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdtypes/ANY/LOC.py (_tuple_to_float): The sign was lost when
-         converting a tuple into a float, which broke conversions of
-         south latitudes and west longitudes.
+        * dns/rdtypes/ANY/LOC.py (_tuple_to_float): The sign was lost when
+          converting a tuple into a float, which broke conversions of
+          south latitudes and west longitudes.
 
 2005-11-17  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py: The 'origin' parameter to from_text() and from_file()
-         is now optional.  If not specified, dnspython will use the
-         first $ORIGIN in the text as the zone's origin.
+        * dns/zone.py: The 'origin' parameter to from_text() and from_file()
+          is now optional.  If not specified, dnspython will use the
+          first $ORIGIN in the text as the zone's origin.
 
-       * dns/zone.py: Sanity checks of the zone's origin node can now
-         be disabled.
+        * dns/zone.py: Sanity checks of the zone's origin node can now
+          be disabled.
 
 2005-11-12  Bob Halley  <halley@dnspython.org>
 
-       * dns/name.py: Preliminary Unicode support has been added for
-         domain names.  Running dns.name.from_text() on a Unicode string
-         will now encode each label using the IDN ACE encoding.  The
-         to_unicode() method may be used to convert a dns.name.Name with
-         IDN ACE labels back into a Unicode string.  This functionality
-         requires Python 2.3 or greater.
+        * dns/name.py: Preliminary Unicode support has been added for
+          domain names.  Running dns.name.from_text() on a Unicode string
+          will now encode each label using the IDN ACE encoding.  The
+          to_unicode() method may be used to convert a dns.name.Name with
+          IDN ACE labels back into a Unicode string.  This functionality
+          requires Python 2.3 or greater.
 
 2005-10-31  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.3.5 released)
+        * (Version 1.3.5 released)
 
 2005-10-12  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py: Zone.iterate_rdatasets() and Zone.iterate_rdatas()
-         did not have a default rdtype of dns.rdatatype.ANY as their
-         docstrings said they did.  They do now.
+        * dns/zone.py: Zone.iterate_rdatasets() and Zone.iterate_rdatas()
+          did not have a default rdtype of dns.rdatatype.ANY as their
+          docstrings said they did.  They do now.
 
 2005-10-06  Bob Halley  <halley@dnspython.org>
 
-       * dns/name.py: Added the parent() method, which returns the
-         parent of a name.
+        * dns/name.py: Added the parent() method, which returns the
+          parent of a name.
 
 2005-10-01  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py: Added zone_for_name() helper, which returns
-         the name of the zone which contains the specified name.
+        * dns/resolver.py: Added zone_for_name() helper, which returns
+          the name of the zone which contains the specified name.
 
-       * dns/resolver.py: Added get_default_resolver(), which returns
-         the default resolver, initializing it if necessary.
+        * dns/resolver.py: Added get_default_resolver(), which returns
+          the default resolver, initializing it if necessary.
 
 2005-09-29  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py (Resolver._compute_timeout): If time goes
-         backwards a little bit, ignore it.
+        * dns/resolver.py (Resolver._compute_timeout): If time goes
+          backwards a little bit, ignore it.
 
 2005-07-31  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.3.4 released)
+        * (Version 1.3.4 released)
 
 2005-07-31  Bob Halley  <halley@dnspython.org>
 
-       * dns/message.py (make_response): Trying to respond to a response
-         threw a NameError while trying to throw a FormErr since it used
-         the wrong name for the FormErr exception.
+        * dns/message.py (make_response): Trying to respond to a response
+          threw a NameError while trying to throw a FormErr since it used
+          the wrong name for the FormErr exception.
 
-       * dns/query.py (_connect): We needed to ignore EALREADY too.
+        * dns/query.py (_connect): We needed to ignore EALREADY too.
 
-       * dns/query.py: Optional "source" and "source_port" parameters
-         have been added to udp(), tcp(), and xfr().  Thanks to Ralf
-         Weber for suggesting the change and providing a patch.
+        * dns/query.py: Optional "source" and "source_port" parameters
+          have been added to udp(), tcp(), and xfr().  Thanks to Ralf
+          Weber for suggesting the change and providing a patch.
 
 2005-06-05  Bob Halley  <halley@dnspython.org>
 
-       * dns/query.py: The requirement that the "where" parameter be
-         an IPv4 or IPv6 address is now documented.
+        * dns/query.py: The requirement that the "where" parameter be
+          an IPv4 or IPv6 address is now documented.
 
 2005-06-04  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py: The resolver now does exponential backoff
-         each time it runs through all of the nameservers.
+        * dns/resolver.py: The resolver now does exponential backoff
+          each time it runs through all of the nameservers.
 
-       * dns/resolver.py: rcodes which indicate a nameserver is likely
-         to be a "permanent failure" for a query cause the nameserver
-         to be removed from the mix for that query.
+        * dns/resolver.py: rcodes which indicate a nameserver is likely
+          to be a "permanent failure" for a query cause the nameserver
+          to be removed from the mix for that query.
 
 2005-01-30  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.3.3 released)
+        * (Version 1.3.3 released)
 
 2004-10-25  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdtypes/ANY/TXT.py (TXT.from_text): The masterfile parser
-       incorrectly rejected TXT records where a value was not quoted.
+        * dns/rdtypes/ANY/TXT.py (TXT.from_text): The masterfile parser
+        incorrectly rejected TXT records where a value was not quoted.
 
 2004-10-11  Bob Halley  <halley@dnspython.org>
 
-       * dns/message.py: Added make_response(), which creates a skeletal
-       response for the specified query.  Added opcode() and set_opcode()
-       convenience methods to the Message class.  Added the request_payload
-       attribute to the Message class.
+        * dns/message.py: Added make_response(), which creates a skeletal
+        response for the specified query.  Added opcode() and set_opcode()
+        convenience methods to the Message class.  Added the request_payload
+        attribute to the Message class.
 
 2004-10-10  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py (from_xfr): dns.zone.from_xfr() in relativization
-       mode incorrectly set zone.origin to the empty name.
+        * dns/zone.py (from_xfr): dns.zone.from_xfr() in relativization
+        mode incorrectly set zone.origin to the empty name.
 
 2004-09-02  Bob Halley  <halley@dnspython.org>
 
-       * dns/name.py (Name.to_wire): The 'file' parameter to
-       Name.to_wire() is now optional; if omitted, the wire form will
-       be returned as the value of the function.
+        * dns/name.py (Name.to_wire): The 'file' parameter to
+        Name.to_wire() is now optional; if omitted, the wire form will
+        be returned as the value of the function.
 
 2004-08-14  Bob Halley  <halley@dnspython.org>
 
-       * dns/message.py (Message.find_rrset): find_rrset() now uses an
-       index, vastly improving the from_wire() performance of large
-       messages such as zone transfers.
+        * dns/message.py (Message.find_rrset): find_rrset() now uses an
+        index, vastly improving the from_wire() performance of large
+        messages such as zone transfers.
 
 2004-08-07  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.3.2 released)
+        * (Version 1.3.2 released)
 
 2004-08-04  Bob Halley  <halley@dnspython.org>
 
-       * 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: 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.
+        * 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
-       does not allow specifying types by number, so we shouldn't either.
+        * dns/rdtypes/ANY/NSEC.py (NSEC.from_text): The NSEC text format
+        does not allow specifying types by number, so we shouldn't either.
 
-       * dns/renderer.py: the renderer module didn't import random,
-       causing an exception to be raised if a query id wasn't provided
-       when a Renderer was created.
+        * dns/renderer.py: the renderer module didn't import random,
+        causing an exception to be raised if a query id wasn't provided
+        when a Renderer was created.
 
-       * dns/resolver.py (Resolver.query): the resolver wasn't catching
-       dns.exception.Timeout, so a timeout erroneously caused the whole
-       resolution to fail instead of just going on to the next server.
+        * dns/resolver.py (Resolver.query): the resolver wasn't catching
+        dns.exception.Timeout, so a timeout erroneously caused the whole
+        resolution to fail instead of just going on to the next server.
 
 2004-06-16  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdtypes/ANY/LOC.py (LOC.from_text): LOC milliseconds values
-       were converted incorrectly if the length of the milliseconds
-       string was less than 3.
+        * dns/rdtypes/ANY/LOC.py (LOC.from_text): LOC milliseconds values
+        were converted incorrectly if the length of the milliseconds
+        string was less than 3.
 
 2004-06-06  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.3.1 released)
+        * (Version 1.3.1 released)
 
 2004-05-22  Bob Halley  <halley@dnspython.org>
 
-       * dns/update.py (Update.delete): We erroneously specified a
-       "deleting" value of dns.rdatatype.NONE instead of
-       dns.rdataclass.NONE when the thing being deleted was either an
-       Rdataset instance or an Rdata instance.
+        * dns/update.py (Update.delete): We erroneously specified a
+        "deleting" value of dns.rdatatype.NONE instead of
+        dns.rdataclass.NONE when the thing being deleted was either an
+        Rdataset instance or an Rdata instance.
 
-       * dns/rdtypes/ANY/SSHFP.py: Added support for the proposed SSHFP
-       RR type.
+        * dns/rdtypes/ANY/SSHFP.py: Added support for the proposed SSHFP
+        RR type.
 
 2004-05-14  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdata.py (from_text): The masterfile reader did not
-       accept the unknown RR syntax when used with a known RR type.
+        * dns/rdata.py (from_text): The masterfile reader did not
+        accept the unknown RR syntax when used with a known RR type.
 
 2004-05-08  Bob Halley  <halley@dnspython.org>
 
-       * dns/name.py (from_text): dns.name.from_text() did not raise
-       an exception if a backslash escape ended prematurely.
+        * dns/name.py (from_text): dns.name.from_text() did not raise
+        an exception if a backslash escape ended prematurely.
 
 2004-04-09  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py (_MasterReader._rr_line): The masterfile reader
-       erroneously treated lines starting with leading whitespace but
-       not having any RR definition as an error.  It now treats
-       them like a blank line (which is not an error).
+        * dns/zone.py (_MasterReader._rr_line): The masterfile reader
+        erroneously treated lines starting with leading whitespace but
+        not having any RR definition as an error.  It now treats
+        them like a blank line (which is not an error).
 
 2004-04-01  Bob Halley  <halley@dnspython.org>
-       
-       * (Version 1.3.0 released)
+
+        * (Version 1.3.0 released)
 
 2004-03-19  Bob Halley  <halley@dnspython.org>
 
-       * Added support for new DNSSEC types RRSIG, NSEC, and DNSKEY.
+        * Added support for new DNSSEC types RRSIG, NSEC, and DNSKEY.
 
 2004-01-16  Bob Halley  <halley@dnspython.org>
 
-       * dns/query.py (_connect): Windows returns EWOULDBLOCK instead
-       of EINPROGRESS when trying to connect a nonblocking socket.
+        * dns/query.py (_connect): Windows returns EWOULDBLOCK instead
+        of EINPROGRESS when trying to connect a nonblocking socket.
 
 2003-11-13  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdtypes/ANY/LOC.py (LOC.to_wire): We encoded and decoded LOC
-       incorrectly, since we were interpreting the values of altitiude,
-       size, hprec, and vprec in meters instead of centimeters.
+        * dns/rdtypes/ANY/LOC.py (LOC.to_wire): We encoded and decoded LOC
+        incorrectly, since we were interpreting the values of altitiude,
+        size, hprec, and vprec in meters instead of centimeters.
 
-       * dns/rdtypes/IN/WKS.py (WKS.from_wire): The WKS protocol value is
-       encoded with just one octet, not two!
+        * dns/rdtypes/IN/WKS.py (WKS.from_wire): The WKS protocol value is
+        encoded with just one octet, not two!
 
 2003-11-09  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py (Cache.maybe_clean): The cleaner deleted items
-       from the dictionary while iterating it, causing a RuntimeError
-       to be raised.  Thanks to Mark R. Levinson for the bug report,
-       regression test, and fix.
+        * dns/resolver.py (Cache.maybe_clean): The cleaner deleted items
+        from the dictionary while iterating it, causing a RuntimeError
+        to be raised.  Thanks to Mark R. Levinson for the bug report,
+        regression test, and fix.
 
 2003-11-07  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.2.0 released)
+        * (Version 1.2.0 released)
 
 2003-11-03  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py (_MasterReader.read): The saved_state now includes
-       the default TTL.
+        * dns/zone.py (_MasterReader.read): The saved_state now includes
+        the default TTL.
 
 2003-11-01  Bob Halley  <halley@dnspython.org>
 
-       * dns/tokenizer.py (Tokenizer.get): The tokenizer didn't
-       handle escaped delimiters.
+        * dns/tokenizer.py (Tokenizer.get): The tokenizer didn't
+        handle escaped delimiters.
 
 2003-10-27  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py (Resolver.read_resolv_conf): If no nameservers
-       are configured in /etc/resolv.conf, the default nameserver
-       list should be ['127.0.0.1'].
+        * dns/resolver.py (Resolver.read_resolv_conf): If no nameservers
+        are configured in /etc/resolv.conf, the default nameserver
+        list should be ['127.0.0.1'].
 
 2003-09-08  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py (Resolver._config_win32_fromkey): We didn't
-       catch WindowsError, which can happen if a key is not defined
-       in the registry.
+        * dns/resolver.py (Resolver._config_win32_fromkey): We didn't
+        catch WindowsError, which can happen if a key is not defined
+        in the registry.
 
 2003-09-06  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.2.0b1 released)
-       
+        * (Version 1.2.0b1 released)
+
 2003-09-05  Bob Halley  <halley@dnspython.org>
 
-       * dns/query.py: Timeout support has been overhauled to provide
-       timeouts under Python 2.2 as well as 2.3, and to provide more
-       accurate expiration.
+        * dns/query.py: Timeout support has been overhauled to provide
+        timeouts under Python 2.2 as well as 2.3, and to provide more
+        accurate expiration.
 
 2003-08-30  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py: dns.exception.SyntaxError is raised for unknown
-       master file directives.
+        * dns/zone.py: dns.exception.SyntaxError is raised for unknown
+        master file directives.
 
 2003-08-28  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py: $INCLUDE processing is now enabled/disabled using
-       the allow_include parameter.  The default is to process $INCLUDE
-       for from_file(), and to disallow $INCLUDE for from_text().  The
-       master reader now calls zone.check_origin_node() by default after
-       the zone has been read.  find_rdataset() called get_node() instead
-       of find_node(), which result in an incorrect exception.  The
-       relativization state of a zone is now remembered and applied
-       consistently when looking up names.  from_xfr() now supports
-       relativization like the _MasterReader.
+        * dns/zone.py: $INCLUDE processing is now enabled/disabled using
+        the allow_include parameter.  The default is to process $INCLUDE
+        for from_file(), and to disallow $INCLUDE for from_text().  The
+        master reader now calls zone.check_origin_node() by default after
+        the zone has been read.  find_rdataset() called get_node() instead
+        of find_node(), which result in an incorrect exception.  The
+        relativization state of a zone is now remembered and applied
+        consistently when looking up names.  from_xfr() now supports
+        relativization like the _MasterReader.
 
 2003-08-22  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py: The _MasterReader now understands $INCLUDE.
+        * dns/zone.py: The _MasterReader now understands $INCLUDE.
 
 2003-08-12  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py: The _MasterReader now specifies the file and line
-       number when a syntax error occurs.  The BIND 8 TTL format is now
-       understood when loading a zone, though it will never be emitted.
-       The from_file() function didn't pass the zone_factory parameter
-       to from_text().
+        * dns/zone.py: The _MasterReader now specifies the file and line
+        number when a syntax error occurs.  The BIND 8 TTL format is now
+        understood when loading a zone, though it will never be emitted.
+        The from_file() function didn't pass the zone_factory parameter
+        to from_text().
 
 2003-08-10  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.1.0 released)
+        * (Version 1.1.0 released)
 
 2003-08-07  Bob Halley  <halley@dnspython.org>
 
-       * dns/update.py (Update._add): A typo meant that _add would
-       fail if the thing being added was an Rdata object (as
-       opposed to an Rdataset or the textual form of an Rdata).
+        * dns/update.py (Update._add): A typo meant that _add would
+        fail if the thing being added was an Rdata object (as
+        opposed to an Rdataset or the textual form of an Rdata).
 
 2003-08-05  Bob Halley  <halley@dnspython.org>
 
-       * dns/set.py: the simple Set class has been moved to its
-       own module, and augmented to support more set operations.
+        * dns/set.py: the simple Set class has been moved to its
+        own module, and augmented to support more set operations.
 
 2003-08-04  Bob Halley  <halley@dnspython.org>
 
-       * Node and all rdata types have been "slotted".  This speeds
-       things up a little and reduces memory usage noticeably.
+        * Node and all rdata types have been "slotted".  This speeds
+        things up a little and reduces memory usage noticeably.
 
 2003-08-02  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.1.0c1 released)
+        * (Version 1.1.0c1 released)
 
 2003-08-02  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdataset.py: SimpleSets now support more set options.
-       
-       * dns/message.py: Added the get_rrset() method.  from_file() now
-       allows Unicode filenames and turns on universal newline support if
-       it opens the file itself.
+        * dns/rdataset.py: SimpleSets now support more set options.
+
+        * dns/message.py: Added the get_rrset() method.  from_file() now
+        allows Unicode filenames and turns on universal newline support if
+        it opens the file itself.
 
-       * dns/node.py: Added the delete_rdataset() and replace_rdataset()
-       methods.
+        * dns/node.py: Added the delete_rdataset() and replace_rdataset()
+        methods.
 
-       * dns/zone.py: Added the delete_node(), delete_rdataset(), and
-       replace_rdataset() methods.  from_file() now allows Unicode
-       filenames and turns on universal newline support if it opens the
-       file itself.  Added a to_file() method.
+        * dns/zone.py: Added the delete_node(), delete_rdataset(), and
+        replace_rdataset() methods.  from_file() now allows Unicode
+        filenames and turns on universal newline support if it opens the
+        file itself.  Added a to_file() method.
 
 2003-08-01  Bob Halley  <halley@dnspython.org>
 
-       * dns/opcode.py: Opcode from/to text converters now understand
-       numeric opcodes.  The to_text() method will return a numeric opcode
-       string if it doesn't know a text name for the opcode.
-       
-       * dns/message.py: Added set_rcode().  Fixed code where ednsflags
-       wasn't treated as a long.
+        * dns/opcode.py: Opcode from/to text converters now understand
+        numeric opcodes.  The to_text() method will return a numeric opcode
+        string if it doesn't know a text name for the opcode.
+
+        * dns/message.py: Added set_rcode().  Fixed code where ednsflags
+        wasn't treated as a long.
 
-       * dns/rcode.py: ednsflags wasn't treated as a long.  Rcode from/to
-       text converters now understand numeric rcodes.  The to_text()
-       method will return a numeric rcode string if it doesn't know
-       a text name for the rcode.
+        * dns/rcode.py: ednsflags wasn't treated as a long.  Rcode from/to
+        text converters now understand numeric rcodes.  The to_text()
+        method will return a numeric rcode string if it doesn't know
+        a text name for the rcode.
 
-       * examples/reverse.py: Added a new example program that builds a
-       reverse (address-to-name) mapping table from the name-to-address
-       mapping specified by A RRs in zone files.
+        * examples/reverse.py: Added a new example program that builds a
+        reverse (address-to-name) mapping table from the name-to-address
+        mapping specified by A RRs in zone files.
 
-       * dns/node.py: Added get_rdataset() method.
+        * dns/node.py: Added get_rdataset() method.
 
-       * dns/zone.py: Added get_rdataset() and get_rrset() methods.  Added
-       iterate_rdatas().
+        * dns/zone.py: Added get_rdataset() and get_rrset() methods.  Added
+        iterate_rdatas().
 
 2003-07-31  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py: Added the iterate_rdatasets() method which returns
-       a generator which yields (name, rdataset) tuples for all the
-       rdatasets in the zone matching the specified rdatatype.
+        * dns/zone.py: Added the iterate_rdatasets() method which returns
+        a generator which yields (name, rdataset) tuples for all the
+        rdatasets in the zone matching the specified rdatatype.
 
 2003-07-30  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.1.0b2 released)
+        * (Version 1.1.0b2 released)
 
 2003-07-30  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py: Added find_rrset() and find_rdataset() convenience
-       methods.  They let you retrieve rdata with the specified name
-       and type in one call.
+        * dns/zone.py: Added find_rrset() and find_rdataset() convenience
+        methods.  They let you retrieve rdata with the specified name
+        and type in one call.
 
-       * dns/node.py: Nodes no longer have names; owner names are
-       associated with nodes in the Zone object's nodes dictionary.
+        * dns/node.py: Nodes no longer have names; owner names are
+        associated with nodes in the Zone object's nodes dictionary.
 
-       * dns/zone.py: Zone objects now implement more of the standard
-       mapping interface.  __iter__ has been changed to iterate the keys
-       rather than values to match the standard mapping interface's
-       behavior.
+        * dns/zone.py: Zone objects now implement more of the standard
+        mapping interface.  __iter__ has been changed to iterate the keys
+        rather than values to match the standard mapping interface's
+        behavior.
 
 2003-07-20  Bob Halley  <halley@dnspython.org>
 
-       * dns/ipv6.py (inet_ntoa): Handle embedded IPv4 addresses.
+        * dns/ipv6.py (inet_ntoa): Handle embedded IPv4 addresses.
 
 2003-07-19  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.1.0b1 released)
+        * (Version 1.1.0b1 released)
 
 2003-07-18  Bob Halley  <halley@dnspython.org>
 
-       * dns/tsig.py: The TSIG validation of TCP streams where not
-       every message is signed now works correctly.
+        * dns/tsig.py: The TSIG validation of TCP streams where not
+        every message is signed now works correctly.
 
-       * dns/zone.py: Zones can now be compared for equality and
-       inequality.  If the other object in the comparison is also
-       a zone, then "the right thing" happens; i.e. the zones are
-       equal iff.: they have the same rdclass, origin, and nodes.
+        * dns/zone.py: Zones can now be compared for equality and
+        inequality.  If the other object in the comparison is also
+        a zone, then "the right thing" happens; i.e. the zones are
+        equal iff.: they have the same rdclass, origin, and nodes.
 
 2003-07-17  Bob Halley  <halley@dnspython.org>
 
-       * dns/message.py (Message.use_tsig): The method now allows for
-       greater control over the various fields in the generated signature
-       (e.g. fudge).
-       (_WireReader._get_section): UnknownTSIGKey is now raised if an
-       unknown key is encountered, or if a signed message has no keyring.
+        * dns/message.py (Message.use_tsig): The method now allows for
+        greater control over the various fields in the generated signature
+        (e.g. fudge).
+        (_WireReader._get_section): UnknownTSIGKey is now raised if an
+        unknown key is encountered, or if a signed message has no keyring.
 
 2003-07-16  Bob Halley  <halley@dnspython.org>
 
-       * dns/tokenizer.py (Tokenizer._get_char): get_char and unget_char
-       have been renamed to _get_char and _unget_char since they are not
-       useful to clients of the tokenizer.
+        * dns/tokenizer.py (Tokenizer._get_char): get_char and unget_char
+        have been renamed to _get_char and _unget_char since they are not
+        useful to clients of the tokenizer.
 
 2003-07-15  Bob Halley  <halley@dnspython.org>
 
-       * dns/zone.py (_MasterReader._rr_line): owner names were being
-       unconditionally relativized; it makes much more sense for them
-       to be relativized according to the relativization setting of
-       the reader.
+        * dns/zone.py (_MasterReader._rr_line): owner names were being
+        unconditionally relativized; it makes much more sense for them
+        to be relativized according to the relativization setting of
+        the reader.
 
 2003-07-12  Bob Halley  <halley@dnspython.org>
 
-       * dns/resolver.py (Resolver.read_resolv_conf): The resolv.conf
-       parser did not allow blank / whitespace-only lines, nor did it
-       allow comments.  Both are now supported.
+        * dns/resolver.py (Resolver.read_resolv_conf): The resolv.conf
+        parser did not allow blank / whitespace-only lines, nor did it
+        allow comments.  Both are now supported.
 
 2003-07-11  Bob Halley  <halley@dnspython.org>
 
-       * dns/name.py (Name.to_digestable): to_digestable() now
-       requires an origin to be specified if the name is relative.
-       It will raise NeedAbsoluteNameOrOrigin if the name is
-       relative and there is either no origin or the origin is
-       itself relative.
-       (Name.split): returned the wrong answer if depth was 0 or depth
-       was the length of the name.  split() now does bounds checking
-       on depth, and raises ValueError if depth < 0 or depth > the length
-       of the name.
+        * dns/name.py (Name.to_digestable): to_digestable() now
+        requires an origin to be specified if the name is relative.
+        It will raise NeedAbsoluteNameOrOrigin if the name is
+        relative and there is either no origin or the origin is
+        itself relative.
+        (Name.split): returned the wrong answer if depth was 0 or depth
+        was the length of the name.  split() now does bounds checking
+        on depth, and raises ValueError if depth < 0 or depth > the length
+        of the name.
 
 2003-07-10  Bob Halley  <halley@dnspython.org>
 
-       * dns/ipv6.py (inet_ntoa): The routine now minimizes its output
-       strings.  E.g. the IPv6 address
-       "0000:0000:0000:0000:0000:0000:0000:0001" is minimized to "::1".
-       We do not, however, make any effort to display embedded IPv4
-       addresses in the dot-quad notation.
+        * dns/ipv6.py (inet_ntoa): The routine now minimizes its output
+        strings.  E.g. the IPv6 address
+        "0000:0000:0000:0000:0000:0000:0000:0001" is minimized to "::1".
+        We do not, however, make any effort to display embedded IPv4
+        addresses in the dot-quad notation.
 
 2003-07-09  Bob Halley  <halley@dnspython.org>
 
-       * dns/inet.py: We now supply our own AF_INET and AF_INET6
-       constants since AF_INET6 may not always be available.  If the
-       socket module has AF_INET6, we will use it.  If not, we will
-       use our own value for the constant.
+        * dns/inet.py: We now supply our own AF_INET and AF_INET6
+        constants since AF_INET6 may not always be available.  If the
+        socket module has AF_INET6, we will use it.  If not, we will
+        use our own value for the constant.
 
-       * dns/query.py: the functions now take an optional af argument
-       specifying the address family to use when creating the socket.
+        * dns/query.py: the functions now take an optional af argument
+        specifying the address family to use when creating the socket.
 
-       * dns/rdatatype.py (is_metatype): a typo caused the function
-       return true only for type OPT.
+        * dns/rdatatype.py (is_metatype): a typo caused the function
+        return true only for type OPT.
+
+        * dns/message.py: message section list elements are now RRsets
+        instead of Nodes.  This API change makes processing messages
+        easier for many applications.
 
-       * dns/message.py: message section list elements are now RRsets
-       instead of Nodes.  This API change makes processing messages
-       easier for many applications.
-       
 2003-07-07  Bob Halley  <halley@dnspython.org>
 
-       * dns/rrset.py: added.  An RRset is a named rdataset.
+        * dns/rrset.py: added.  An RRset is a named rdataset.
+
+        * dns/rdataset.py (Rdataset.__eq__): rdatasets may now be compared
+        for equality and inequality with other objects.  Rdataset instance
+        variables are now slotted.
 
-       * dns/rdataset.py (Rdataset.__eq__): rdatasets may now be compared
-       for equality and inequality with other objects.  Rdataset instance
-       variables are now slotted.
-       
-       * dns/message.py: The wire format and text format readers are now
-       classes.  Variables related to reader state have been moved out
-       of the message class.
+        * dns/message.py: The wire format and text format readers are now
+        classes.  Variables related to reader state have been moved out
+        of the message class.
 
 2003-07-06  Bob Halley  <halley@dnspython.org>
 
-       * dns/name.py (from_text): '@' was not interpreted as the empty
-       name.
+        * dns/name.py (from_text): '@' was not interpreted as the empty
+        name.
+
+        * dns/zone.py: the master file reader derelativized names in rdata
+        relative to the zone's origin, not relative to the current origin.
+        The reader now deals with relativization in two steps.  The rdata
+        is read and derelativized using the current origin.  The rdata's
+        relativity is then chosen using the zone origin and the relativize
+        boolean.  Here's an example.
 
-       * dns/zone.py: the master file reader derelativized names in rdata
-       relative to the zone's origin, not relative to the current origin.
-       The reader now deals with relativization in two steps.  The rdata
-       is read and derelativized using the current origin.  The rdata's
-       relativity is then chosen using the zone origin and the relativize
-       boolean.  Here's an example.
+                $ORIGIN foo.example.
+                $TTL 300
+                bar MX 0 blaz
 
-               $ORIGIN foo.example.
-               $TTL 300
-               bar MX 0 blaz
+        If the zone origin is example., and relativization is on, then
+        This fragment will become:
 
-       If the zone origin is example., and relativization is on, then
-       This fragment will become:
+                bar.foo.example. 300 IN MX 0 blaz.foo.example.
 
-               bar.foo.example. 300 IN MX 0 blaz.foo.example.
+        after the first step (derelativization to current origin), and
 
-       after the first step (derelativization to current origin), and
+                bar.foo 300 IN MX 0 blaz.foo
 
-               bar.foo 300 IN MX 0 blaz.foo
+        after the second step (relativiation to zone origin).
 
-       after the second step (relativiation to zone origin).
-       
-       * dns/namedict.py: added.
+        * dns/namedict.py: added.
 
-       * dns/zone.py: The master file reader has been made into its
-       own class.  Reader-related instance variables have been moved
-       form the zone class into the reader class.
-       
-       * dns/zone.py: Add node_factory class attribute.  An application
-       can now subclass Zone and Node and have a zone whose nodes are of
-       the subclassed Node type.  The from_text(), from_file(), and
-       from_xfr() algorithms now take an optional zone_factory argument.
-       This allows the algorithms to be used to create zones whose class
-       is a subclass of Zone.
+        * dns/zone.py: The master file reader has been made into its
+        own class.  Reader-related instance variables have been moved
+        form the zone class into the reader class.
+
+        * dns/zone.py: Add node_factory class attribute.  An application
+        can now subclass Zone and Node and have a zone whose nodes are of
+        the subclassed Node type.  The from_text(), from_file(), and
+        from_xfr() algorithms now take an optional zone_factory argument.
+        This allows the algorithms to be used to create zones whose class
+        is a subclass of Zone.
 
 
 2003-07-04  Bob Halley  <halley@dnspython.org>
 
-       * dns/renderer.py: added new wire format rendering module and
-       converted message.py to use it.  Applications which want
-       fine-grained control over the conversion to wire format may call
-       the renderer directy, instead of having it called on their behalf
-       by the message code.
+        * dns/renderer.py: added new wire format rendering module and
+        converted message.py to use it.  Applications which want
+        fine-grained control over the conversion to wire format may call
+        the renderer directy, instead of having it called on their behalf
+        by the message code.
 
 2003-07-02  Bob Halley  <halley@dnspython.org>
 
-       * dns/name.py (_validate_labels): The NameTooLong test was
-       incorrect.
+        * dns/name.py (_validate_labels): The NameTooLong test was
+        incorrect.
 
-       * dns/message.py (Message.to_wire): dns.exception.TooBig is
-       now raised if the wire encoding exceeds the specified
-       maximum size.
+        * dns/message.py (Message.to_wire): dns.exception.TooBig is
+        now raised if the wire encoding exceeds the specified
+        maximum size.
 
 2003-07-01  Bob Halley  <halley@dnspython.org>
 
-       * dns/message.py: EDNS encoding was broken.  from_text()
-       didn't parse rcodes, flags, or eflags correctly.  Comparing
-       messages with other types of objects didn't work.
+        * dns/message.py: EDNS encoding was broken.  from_text()
+        didn't parse rcodes, flags, or eflags correctly.  Comparing
+        messages with other types of objects didn't work.
 
 2003-06-30  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.0.0 released)
+        * (Version 1.0.0 released)
 
 2003-06-30  Bob Halley  <halley@dnspython.org>
 
-       * dns/rdata.py: Rdatas now implement rich comparisons instead of
-       __cmp__.
+        * dns/rdata.py: Rdatas now implement rich comparisons instead of
+        __cmp__.
 
-       * dns/name.py: Names now implement rich comparisons instead of
-       __cmp__.
+        * dns/name.py: Names now implement rich comparisons instead of
+        __cmp__.
 
-       * dns/inet.py (inet_ntop): Always use our code, since the code
-       in the socket module doesn't support AF_INET6 conversions if
-       IPv6 sockets are not available on the system.
+        * dns/inet.py (inet_ntop): Always use our code, since the code
+        in the socket module doesn't support AF_INET6 conversions if
+        IPv6 sockets are not available on the system.
 
-       * dns/resolver.py (Answer.__init__): A dangling CNAME chain was
-       not raising NoAnswer.
+        * dns/resolver.py (Answer.__init__): A dangling CNAME chain was
+        not raising NoAnswer.
 
-       * Added a simple resolver Cache class.
+        * Added a simple resolver Cache class.
 
-       * Added an expiration attribute to answer instances.
+        * Added an expiration attribute to answer instances.
 
 2003-06-24  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.0.0b3 released)
+        * (Version 1.0.0b3 released)
 
 2003-06-24  Bob Halley  <halley@dnspython.org>
 
-       * Renamed module "DNS" to "dns" to avoid conflicting with
-       PyDNS.
+        * Renamed module "DNS" to "dns" to avoid conflicting with
+        PyDNS.
 
 2003-06-23  Bob Halley  <halley@dnspython.org>
 
-       * The from_text() relativization controls now work the same way as
-       the to_text() controls.
+        * The from_text() relativization controls now work the same way as
+        the to_text() controls.
 
-       * DNS/rdata.py: The parsing of generic rdata was broken.
+        * DNS/rdata.py: The parsing of generic rdata was broken.
 
 2003-06-21  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.0.0b2 released)
+        * (Version 1.0.0b2 released)
 
 2003-06-21  Bob Halley  <halley@dnspython.org>
 
-       * The Python 2.2 socket.inet_aton() doesn't seem to like
-       '255.255.255.255'.  We work around this.
+        * The Python 2.2 socket.inet_aton() doesn't seem to like
+        '255.255.255.255'.  We work around this.
+
+        * Fixed bugs in rdata to_wire() and from_wire() routines of a few
+        types.  These bugs were discovered by running the tests/zone.py
+        Torture1 test.
 
-       * Fixed bugs in rdata to_wire() and from_wire() routines of a few
-       types.  These bugs were discovered by running the tests/zone.py
-       Torture1 test.
-       
-       * Added implementation of type APL.
+        * Added implementation of type APL.
 
 2003-06-20  Bob Halley  <halley@dnspython.org>
 
-       * DNS/rdtypes/IN/AAAA.py: Use our own versions of inet_ntop and
-       inet_pton if the socket module doesn't provide them for us.
+        * DNS/rdtypes/IN/AAAA.py: Use our own versions of inet_ntop and
+        inet_pton if the socket module doesn't provide them for us.
+
+        * The resolver now does a better job handling exceptions.  In
+        particular, it no longer eats all exceptions; rather it handles
+        those exceptions it understands, and leaves the rest uncaught.
 
-       * The resolver now does a better job handling exceptions.  In
-       particular, it no longer eats all exceptions; rather it handles
-       those exceptions it understands, and leaves the rest uncaught.
-       
-       * Exceptions have been pulled into their own module.  Almost all
-       exceptions raised by the code are now subclasses of
-       DNS.exception.DNSException.  All form errors are subclasses of
-       DNS.exception.FormError (which is itself a subclass of
-       DNS.exception.DNSException).
+        * Exceptions have been pulled into their own module.  Almost all
+        exceptions raised by the code are now subclasses of
+        DNS.exception.DNSException.  All form errors are subclasses of
+        DNS.exception.FormError (which is itself a subclass of
+        DNS.exception.DNSException).
 
 2003-06-19  Bob Halley  <halley@dnspython.org>
-       
-       * Added implementations of types DS, NXT, SIG, and WKS.
 
-       * __cmp__ for type A and AAAA could produce incorrect results.
+        * Added implementations of types DS, NXT, SIG, and WKS.
+
+        * __cmp__ for type A and AAAA could produce incorrect results.
 
 2003-06-18  Bob Halley  <halley@dnspython.org>
 
-       * Started test suites for zone.py and tokenizer.py.
-       
-       * Added implementation of type KEY.
-       
-       * DNS/rdata.py(_base64ify): \n could be emitted erroneously.
+        * Started test suites for zone.py and tokenizer.py.
+
+        * Added implementation of type KEY.
+
+        * DNS/rdata.py(_base64ify): \n could be emitted erroneously.
 
-       * DNS/rdtypes/ANY/SOA.py (SOA.from_text): The SOA RNAME field could
-       be set to the value of MNAME in common cases.
+        * DNS/rdtypes/ANY/SOA.py (SOA.from_text): The SOA RNAME field could
+        be set to the value of MNAME in common cases.
 
-       * DNS/rdtypes/ANY/X25.py: __init__ was broken.
+        * DNS/rdtypes/ANY/X25.py: __init__ was broken.
 
-       * DNS/zone.py (from_text): $TTL handling erroneously caused the
-       next line to be eaten.
+        * DNS/zone.py (from_text): $TTL handling erroneously caused the
+        next line to be eaten.
 
-       * DNS/tokenizer.py (Tokenizer.get): parsing was broken for empty
-       quoted strings.  Quoted strings didn't handle \ddd escapes.  Such
-       escapes are appear not to comply with RFC 1035, but BIND allows
-       them and they seem useful, so we allow them too.
+        * DNS/tokenizer.py (Tokenizer.get): parsing was broken for empty
+        quoted strings.  Quoted strings didn't handle \ddd escapes.  Such
+        escapes are appear not to comply with RFC 1035, but BIND allows
+        them and they seem useful, so we allow them too.
 
-       * DNS/rdtypes/ANY/ISDN.py (ISDN.from_text): parsing was
-       broken for ISDN RRs without subaddresses.
+        * DNS/rdtypes/ANY/ISDN.py (ISDN.from_text): parsing was
+        broken for ISDN RRs without subaddresses.
 
-       * DNS/zone.py (from_file): from_file() didn't work because
-       some required parameters were not passed to from_text().
+        * DNS/zone.py (from_file): from_file() didn't work because
+        some required parameters were not passed to from_text().
 
 2003-06-17  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.0.0b1 released)
+        * (Version 1.0.0b1 released)
 
 2003-06-17  Bob Halley  <halley@dnspython.org>
 
-       * Added implementation of type PX.
-       
+        * Added implementation of type PX.
+
 2003-06-16  Bob Halley  <halley@dnspython.org>
 
-       * Added implementation of types CERT, GPOS, LOC, NSAP, NSAP-PTR.
+        * Added implementation of types CERT, GPOS, LOC, NSAP, NSAP-PTR.
 
-       * DNS/rdatatype.py (_by_value): A cut-and-paste error had broken
-       NSAP and NSAP-PTR.
+        * DNS/rdatatype.py (_by_value): A cut-and-paste error had broken
+        NSAP and NSAP-PTR.
 
 2003-06-12  Bob Halley  <halley@dnspython.org>
 
-       * Created a tests directory and started adding tests.
-       
-       * Added "and its documentation" to the permission grant in the
-       license.
+        * Created a tests directory and started adding tests.
+
+        * Added "and its documentation" to the permission grant in the
+        license.
 
 2003-06-12  Bob Halley  <halley@dnspython.org>
 
-       * DNS/name.py (Name.is_wild): is_wild() erroneously raised IndexError
-       if the name was empty.
+        * DNS/name.py (Name.is_wild): is_wild() erroneously raised IndexError
+        if the name was empty.
 
 2003-06-10  Bob Halley  <halley@dnspython.org>
 
-       * Added implementations of types AFSDB, X25, and ISDN.
-       
-       * The documentation associated with the various rdata types has been
-       improved.  In particular, instance variables are now described.
+        * Added implementations of types AFSDB, X25, and ISDN.
+
+        * The documentation associated with the various rdata types has been
+        improved.  In particular, instance variables are now described.
 
 2003-06-09  Bob Halley  <halley@dnspython.org>
 
-       * Added implementations of types HINFO, RP, and RT.
-       
-       * DNS/message.py (make_query): Document that make_query() sets
-       flags to DNS.flags.RD, and chooses a random query id.
+        * Added implementations of types HINFO, RP, and RT.
+
+        * DNS/message.py (make_query): Document that make_query() sets
+        flags to DNS.flags.RD, and chooses a random query id.
 
 2003-06-05  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.0.0a2 released)
-       
+        * (Version 1.0.0a2 released)
+
 2003-06-05  Bob Halley  <halley@dnspython.org>
-       
-       * DNS/node.py: removed __getitem__ and __setitem__, since
-       they are not used by the codebase and were not useful in
-       general either.
 
-       * DNS/message.py (from_file): from_file() now allows a
-       filename to be specified instead of a file object.
+        * DNS/node.py: removed __getitem__ and __setitem__, since
+        they are not used by the codebase and were not useful in
+        general either.
+
+        * DNS/message.py (from_file): from_file() now allows a
+        filename to be specified instead of a file object.
 
-       * DNS/rdataset.py: The is_compatible() method of the
-       DNS.rdataset.Rdataset class was deleted.
+        * DNS/rdataset.py: The is_compatible() method of the
+        DNS.rdataset.Rdataset class was deleted.
 
 2003-06-04  Bob Halley  <halley@dnspython.org>
 
-       * DNS/name.py (class Name): Names are now immutable.
+        * DNS/name.py (class Name): Names are now immutable.
 
-       * DNS/name.py: the is_comparable() method has been removed, since
-       names are always comparable.
+        * DNS/name.py: the is_comparable() method has been removed, since
+        names are always comparable.
 
-       * DNS/resolver.py (Resolver.query): A query could run for up
-       to the lifetime + the timeout.  This has been corrected and the
-       query will now only run up to the lifetime.
+        * DNS/resolver.py (Resolver.query): A query could run for up
+        to the lifetime + the timeout.  This has been corrected and the
+        query will now only run up to the lifetime.
 
 2003-06-03  Bob Halley  <halley@dnspython.org>
 
-       * DNS/resolver.py: removed the 'new' function since it is not the
-       style of the library to have such a function.  Call
-       DNS.resolver.Resolver() to make a new resolver.
+        * DNS/resolver.py: removed the 'new' function since it is not the
+        style of the library to have such a function.  Call
+        DNS.resolver.Resolver() to make a new resolver.
 
 2003-06-03  Bob Halley  <halley@dnspython.org>
 
-       * DNS/resolver.py (Resolver._config_win32_fromkey): The DhcpServer
-       list is space separated, not comma separated.
+        * DNS/resolver.py (Resolver._config_win32_fromkey): The DhcpServer
+        list is space separated, not comma separated.
 
 2003-06-03  Bob Halley  <halley@dnspython.org>
 
-       * DNS/update.py: Added an update module to make generating updates
-       easier.
+        * DNS/update.py: Added an update module to make generating updates
+        easier.
 
 2003-06-03  Bob Halley  <halley@dnspython.org>
 
-       * Commas were missing in some of the __all__ entries in various
-       __init__.py files.
+        * Commas were missing in some of the __all__ entries in various
+        __init__.py files.
 
 2003-05-30  Bob Halley  <halley@dnspython.org>
 
-       * (Version 1.0.0a1 released)
+        * (Version 1.0.0a1 released)
index e51faa30c2088951403c60d6fef722241465c04e..f371fa7745c76844545d5bf7bcbe05b5443ec74a 100644 (file)
@@ -25,6 +25,8 @@ default is 'dns.rdtypes'.  Changing this value will break the library.
 chunk of hexstring that _hexify() produces before whitespace occurs.
 @type _hex_chunk: int"""
 
+import cStringIO
+
 import dns.exception
 import dns.rdataclass
 import dns.rdatatype
@@ -41,7 +43,7 @@ def _hexify(data, chunksize=None):
     @param chunksize: the chunk size.  Default is L{dns.rdata._hex_chunksize}
     @rtype: string
     """
-    
+
     if chunksize is None:
         chunksize = _hex_chunksize
     hex = data.encode('hex_codec')
@@ -95,7 +97,7 @@ def _escapify(qstring):
     @returns: the escaped string
     @rtype: string
     """
-    
+
     text = ''
     for c in qstring:
         if c in __escaped:
@@ -114,7 +116,7 @@ def _truncate_bitmap(what):
     @type what: string
     @rtype: string
     """
-    
+
     for i in xrange(len(what) - 1, -1, -1):
         if what[i] != '\x00':
             break
@@ -125,7 +127,7 @@ class Rdata(object):
     """
 
     __slots__ = ['rdclass', 'rdtype']
-    
+
     def __init__(self, rdclass, rdtype):
         """Initialize an rdata.
         @param rdclass: The rdata class
@@ -134,8 +136,8 @@ class Rdata(object):
         @type rdtype: int
         """
 
-       self.rdclass = rdclass
-       self.rdtype = rdtype
+        self.rdclass = rdclass
+        self.rdtype = rdtype
 
     def covers(self):
         """DNS SIG/RRSIG rdatas apply to a specific type; this type is
@@ -145,8 +147,8 @@ class Rdata(object):
         of a particular type, e.g. RRSIG(NS).
         @rtype: int
         """
-        
-       return dns.rdatatype.NONE
+
+        return dns.rdatatype.NONE
 
     def extended_rdatatype(self):
         """Return a 32-bit type value, the least significant 16 bits of
@@ -154,22 +156,29 @@ class Rdata(object):
         the "covered" type, if any.
         @rtype: int
         """
-        
+
         return self.covers() << 16 | self.rdtype
 
     def to_text(self, origin=None, relativize=True, **kw):
         """Convert an rdata to text format.
         @rtype: string
         """
-        raise NotImplementedError        
+        raise NotImplementedError
 
     def to_wire(self, file, compress = None, origin = None):
         """Convert an rdata to wire format.
         @rtype: string
         """
-        
+
         raise NotImplementedError
 
+    def to_digestable(self, origin = None):
+        """Convert rdata to a format suitable for digesting in hashes.  This
+        is also the DNSSEC canonical form."""
+        f = cStringIO.StringIO()
+        self.to_wire(f, None, origin)
+        return f.getvalue()
+
     def validate(self):
         """Check that the current contents of the rdata's fields are
         valid.  If you change an rdata by assigning to its fields,
@@ -177,28 +186,28 @@ class Rdata(object):
         changes.
         """
         dns.rdata.from_text(self.rdclass, self.rdtype, self.to_text())
-        
+
     def __repr__(self):
-       covers = self.covers()
+        covers = self.covers()
         if covers == dns.rdatatype.NONE:
             ctext = ''
         else:
             ctext = '(' + dns.rdatatype.to_text(covers) + ')'
         return '<DNS ' + dns.rdataclass.to_text(self.rdclass) + ' ' + \
                dns.rdatatype.to_text(self.rdtype) + ctext + ' rdata: ' + \
-              str(self) + '>'
+               str(self) + '>'
 
     def __str__(self):
-       return self.to_text()
+        return self.to_text()
 
     def _cmp(self, other):
         """Compare an rdata with another rdata of the same rdtype and
         rdclass.  Return < 0 if self < other in the DNSSEC ordering,
         0 if self == other, and > 0 if self > other.
         """
-        
+
         raise NotImplementedError
-    
+
     def __eq__(self, other):
         if not isinstance(other, Rdata):
             return False
@@ -265,7 +274,7 @@ class Rdata(object):
 
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         """Build an rdata object from wire format
-        
+
         @param rdclass: The rdata class
         @type rdclass: int
         @param rdtype: The rdata type
@@ -289,7 +298,7 @@ class Rdata(object):
         """Convert any domain names in the rdata to the specified
         relativization.
         """
-        
+
         pass
 
 
@@ -301,11 +310,11 @@ class GenericRdata(Rdata):
     """
 
     __slots__ = ['data']
-    
+
     def __init__(self, rdclass, rdtype, data):
         super(GenericRdata, self).__init__(rdclass, rdtype)
         self.data = data
-        
+
     def to_text(self, origin=None, relativize=True, **kw):
         return r'\# %d ' % len(self.data) + _hexify(self.data)
 
@@ -331,14 +340,14 @@ class GenericRdata(Rdata):
 
     def to_wire(self, file, compress = None, origin = None):
         file.write(self.data)
-        
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         return cls(rdclass, rdtype, wire[current : current + rdlen])
 
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-       return cmp(self.data, other.data)
+        return cmp(self.data, other.data)
 
 _rdata_modules = {}
 _module_prefix = 'dns.rdtypes'
@@ -351,7 +360,7 @@ def get_rdata_class(rdclass, rdtype):
         for comp in components[1:]:
             mod = getattr(mod, comp)
         return mod
-    
+
     mod = _rdata_modules.get((rdclass, rdtype))
     rdclass_text = dns.rdataclass.to_text(rdclass)
     rdtype_text = dns.rdatatype.to_text(rdtype)
@@ -398,7 +407,7 @@ def from_text(rdclass, rdtype, tok, origin = None, relativize = True):
     @param relativize: Should names be relativized?
     @type relativize: bool
     @rtype: dns.rdata.Rdata instance"""
-    
+
     if isinstance(tok, str):
         tok = dns.tokenizer.Tokenizer(tok)
     cls = get_rdata_class(rdclass, rdtype)
@@ -429,7 +438,7 @@ def from_wire(rdclass, rdtype, wire, current, rdlen, origin = None):
 
     Once a class is chosen, its from_wire() class method is called
     with the parameters to this function.
-    
+
     @param rdclass: The rdata class
     @type rdclass: int
     @param rdtype: The rdata type
index 1ce13f698699a04ff6f14733c07e1eca7ddb6963..cb325e0f4c35ef5b8add4e5c6b00c834e372ed5d 100644 (file)
@@ -15,7 +15,7 @@
 
 import dns.rdtypes.mxbase
 
-class AFSDB(dns.rdtypes.mxbase.UncompressedMX):
+class AFSDB(dns.rdtypes.mxbase.UncompressedDowncasingMX):
     """AFSDB record
 
     @ivar subtype: the subtype value
@@ -33,18 +33,18 @@ class AFSDB(dns.rdtypes.mxbase.UncompressedMX):
     # We probably lose some performance vs. a cut-and-paste
     # implementation, but this way we don't copy code, and that's
     # good.
-    
+
     def get_subtype(self):
         return self.preference
-    
+
     def set_subtype(self, subtype):
         self.preference = subtype
 
     subtype = property(get_subtype, set_subtype)
-    
+
     def get_hostname(self):
         return self.exchange
-    
+
     def set_hostname(self, hostname):
         self.exchange = hostname
 
index f12d091aaabcbdb55a79a4e2e24cbd473a43c0f6..b2fe6ea9740070b4311a6cb56c770f12cad61a98 100644 (file)
@@ -17,4 +17,5 @@ import dns.rdtypes.nsbase
 
 class DNAME(dns.rdtypes.nsbase.UncompressedNS):
     """DNAME record"""
-    pass
+    def to_digestable(self, origin = None):
+        return self.target.to_digestable(origin)
index f0f6a8903d76b6c2b02fb424cf4f7d82cf7e2cd8..4b2571c115d7843fc380ea7720cf11b57cb922f1 100644 (file)
@@ -28,7 +28,7 @@ class NXT(dns.rdata.Rdata):
     @see: RFC 2535"""
 
     __slots__ = ['next', 'bitmap']
-    
+
     def __init__(self, rdclass, rdtype, next, bitmap):
         super(NXT, self).__init__(rdclass, rdtype)
         self.next = next
@@ -44,7 +44,7 @@ class NXT(dns.rdata.Rdata):
                     bits.append(dns.rdatatype.to_text(i * 8 + j))
         text = ' '.join(bits)
         return '%s %s' % (next, text)
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         next = tok.get_name()
         next = next.choose_relativity(origin, relativize)
@@ -68,13 +68,16 @@ class NXT(dns.rdata.Rdata):
             bitmap[i] = chr(ord(bitmap[i]) | (0x80 >> (nrdtype % 8)))
         bitmap = dns.rdata._truncate_bitmap(bitmap)
         return cls(rdclass, rdtype, next, bitmap)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
         self.next.to_wire(file, None, origin)
         file.write(self.bitmap)
-        
+
+    def to_digestable(self, origin = None):
+        return self.next.to_digestable(origin) + self.bitmap
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         (next, cused) = dns.name.from_wire(wire[: current + rdlen], current)
         current += cused
@@ -88,7 +91,7 @@ class NXT(dns.rdata.Rdata):
 
     def choose_relativity(self, origin = None, relativize = True):
         self.next = self.next.choose_relativity(origin, relativize)
-        
+
     def _cmp(self, other):
         v = cmp(self.next, other.next)
         if v == 0:
index c48515d04f25476ff84cc7a4b150d417d491a1a6..2029bff45a731d2d3937431af8811f4aab826a38 100644 (file)
@@ -28,7 +28,7 @@ class RP(dns.rdata.Rdata):
     @see: RFC 1183"""
 
     __slots__ = ['mbox', 'txt']
-    
+
     def __init__(self, rdclass, rdtype, mbox, txt):
         super(RP, self).__init__(rdclass, rdtype)
         self.mbox = mbox
@@ -38,7 +38,7 @@ class RP(dns.rdata.Rdata):
         mbox = self.mbox.choose_relativity(origin, relativize)
         txt = self.txt.choose_relativity(origin, relativize)
         return "%s %s" % (str(mbox), str(txt))
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         mbox = tok.get_name()
         txt = tok.get_name()
@@ -46,13 +46,17 @@ class RP(dns.rdata.Rdata):
         txt = txt.choose_relativity(origin, relativize)
         tok.get_eol()
         return cls(rdclass, rdtype, mbox, txt)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
         self.mbox.to_wire(file, None, origin)
         self.txt.to_wire(file, None, origin)
-        
+
+    def to_digestable(self, origin = None):
+        return self.mbox.to_digestable(origin) + \
+            self.txt.to_digestable(origin)
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         (mbox, cused) = dns.name.from_wire(wire[: current + rdlen],
                                            current)
index e6b1bc4e89c01a05025ae2138e653d8cf87644b5..4969fcebfe123ac9c505a5dd40057274f048ad0d 100644 (file)
@@ -15,6 +15,6 @@
 
 import dns.rdtypes.mxbase
 
-class RT(dns.rdtypes.mxbase.UncompressedMX):
+class RT(dns.rdtypes.mxbase.UncompressedDowncasingMX):
     """RT record"""
     pass
index 96595288483a090253909a1fe79c77ad1813d1bf..584ee42e1b8579ca53fb1698362ae97fcb1fe125 100644 (file)
@@ -17,4 +17,10 @@ import dns.rdtypes.sigbase
 
 class SIG(dns.rdtypes.sigbase.SIGBase):
     """SIG record"""
-    pass
+    def to_digestable(self, origin = None):
+        return struct.pack('!HBBIIIH', self.type_covered,
+                           self.algorithm, self.labels,
+                           self.original_ttl, self.expiration,
+                           self.inception, self.key_tag) + \
+                           self.signer.to_digestable(origin) + \
+                           self.signature
index 6f95e1c36e1c59a3243adfad679d45dd39c1b50e..a36cacad034d9c338cf76de732f0f182e01e4f32 100644 (file)
@@ -82,7 +82,13 @@ class SOA(dns.rdata.Rdata):
         five_ints = struct.pack('!IIIII', self.serial, self.refresh,
                                 self.retry, self.expire, self.minimum)
         file.write(five_ints)
-        
+
+    def to_digestable(self, origin = None):
+        return self.mname.to_digestable(origin) + \
+            self.rname.to_digestable(origin) + \
+            struct.pack('!IIIII', self.serial, self.refresh,
+                        self.retry, self.expire, self.minimum)
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         (mname, cused) = dns.name.from_wire(wire[: current + rdlen], current)
         current += cused
index 1f4ad3227a0353bdd724c3156795774e6d206936..3372060438209bf4dcf1d30fa79966cfdadc37bf 100644 (file)
@@ -15,6 +15,7 @@
 
 """MX-like base classes."""
 
+import cStringIO
 import struct
 
 import dns.exception
@@ -30,7 +31,7 @@ class MXBase(dns.rdata.Rdata):
     @type exchange: dns.name.Name object"""
 
     __slots__ = ['preference', 'exchange']
-    
+
     def __init__(self, rdclass, rdtype, preference, exchange):
         super(MXBase, self).__init__(rdclass, rdtype)
         self.preference = preference
@@ -39,21 +40,25 @@ class MXBase(dns.rdata.Rdata):
     def to_text(self, origin=None, relativize=True, **kw):
         exchange = self.exchange.choose_relativity(origin, relativize)
         return '%d %s' % (self.preference, exchange)
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         preference = tok.get_uint16()
         exchange = tok.get_name()
         exchange = exchange.choose_relativity(origin, relativize)
         tok.get_eol()
         return cls(rdclass, rdtype, preference, exchange)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
         pref = struct.pack("!H", self.preference)
         file.write(pref)
         self.exchange.to_wire(file, compress, origin)
-        
+
+    def to_digestable(self, origin = None):
+        return struct.pack("!H", self.preference) + \
+            self.exchange.to_digestable(origin)
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         (preference, ) = struct.unpack('!H', wire[current : current + 2])
         current += 2
@@ -70,7 +75,7 @@ class MXBase(dns.rdata.Rdata):
 
     def choose_relativity(self, origin = None, relativize = True):
         self.exchange = self.exchange.choose_relativity(origin, relativize)
-        
+
     def _cmp(self, other):
         sp = struct.pack("!H", self.preference)
         op = struct.pack("!H", other.preference)
@@ -81,7 +86,20 @@ class MXBase(dns.rdata.Rdata):
 
 class UncompressedMX(MXBase):
     """Base class for rdata that is like an MX record, but whose name
-    is not compressed when convert to DNS wire format."""
+    is not compressed when converted to DNS wire format, and whose
+    digestable form is not downcased."""
 
     def to_wire(self, file, compress = None, origin = None):
         super(UncompressedMX, self).to_wire(file, None, origin)
+
+    def to_digestable(self, origin = None):
+        f = cStringIO.StringIO()
+        self.to_wire(f, None, origin)
+        return f.getvalue()
+
+class UncompressedDowncasingMX(MXBase):
+    """Base class for rdata that is like an MX record, but whose name
+    is not compressed when convert to DNS wire format."""
+
+    def to_wire(self, file, compress = None, origin = None):
+        super(UncompressedDowncasingMX, self).to_wire(file, None, origin)
index 43f2b2b95440d64cb64516a7a3e86392e743ab5e..1fcdb73cafd5603865cc2e4b238bae37e67185ae 100644 (file)
@@ -15,6 +15,8 @@
 
 """NS-like base classes."""
 
+import cStringIO
+
 import dns.exception
 import dns.rdata
 import dns.name
@@ -26,7 +28,7 @@ class NSBase(dns.rdata.Rdata):
     @type target: dns.name.Name object"""
 
     __slots__ = ['target']
-    
+
     def __init__(self, rdclass, rdtype, target):
         super(NSBase, self).__init__(rdclass, rdtype)
         self.target = target
@@ -34,18 +36,21 @@ class NSBase(dns.rdata.Rdata):
     def to_text(self, origin=None, relativize=True, **kw):
         target = self.target.choose_relativity(origin, relativize)
         return str(target)
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         target = tok.get_name()
         target = target.choose_relativity(origin, relativize)
         tok.get_eol()
         return cls(rdclass, rdtype, target)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
         self.target.to_wire(file, compress, origin)
-        
+
+    def to_digestable(self, origin = None):
+        return self.target.to_digestable(origin)
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         (target, cused) = dns.name.from_wire(wire[: current + rdlen],
                                              current)
@@ -59,13 +64,19 @@ class NSBase(dns.rdata.Rdata):
 
     def choose_relativity(self, origin = None, relativize = True):
         self.target = self.target.choose_relativity(origin, relativize)
-    
+
     def _cmp(self, other):
         return cmp(self.target, other.target)
 
 class UncompressedNS(NSBase):
     """Base class for rdata that is like an NS record, but whose name
-    is not compressed when convert to DNS wire format."""
+    is not compressed when convert to DNS wire format, and whose
+    digestable form is not downcased."""
 
     def to_wire(self, file, compress = None, origin = None):
         super(UncompressedNS, self).to_wire(file, None, origin)
+
+    def to_digestable(self, origin = None):
+        f = cStringIO.StringIO()
+        self.to_wire(f, None, origin)
+        return f.getvalue()