dnspython INTRODUCTION dnspython is a DNS toolkit for Python. It supports almost all record types. It can be used for queries, zone transfers, and dynamic updates. It supports TSIG authenticated messages and EDNS0. dnspython provides both high and low level access to DNS. The high level classes perform queries for data of a given name, type, and class, and return an answer set. The low level classes allow direct manipulation of DNS zones, messages, names, and records. To see a few of the ways dnspython can be used, look in the examples/ directory. dnspython originated at Nominum where it was developed to facilitate the testing of DNS software. Nominum has generously allowed it to be open sourced under a BSD-style license, and helps support its future development by continuing to employ the author :). ABOUT THIS RELEASE This is dnspython 1.9.1 New since 1.8.0: Nothing. Bugs fixed since 1.9.0 The dns.dnssec module didn't work with DSA due to namespace contamination from a "from"-style import. New since 1.8.0: dnspython now uses poll() instead of select() when available. Basic DNSSEC validation can be done using dns.dnsec.validate() and dns.dnssec.validate_rrsig() if you have PyCrypto 2.3 or later installed. Complete secure resolution is not yet available. Added key_id() to the DNSSEC module, which computes the DNSSEC key id of a DNSKEY rdata. Added make_ds() to the DNSSEC module, which returns the DS RR for a given DNSKEY rdata. dnspython now raises an exception if HMAC-SHA284 or HMAC-SHA512 are used with a Python older than 2.5.2. (Older Pythons do not compute the correct value.) Symbolic constants are now available for TSIG algorithm names. Bugs fixed since 1.8.0 dns.resolver.zone_for_name() didn't handle a query response with a CNAME or DNAME correctly in some cases. When specifying rdata types and classes as text, Unicode strings may now be used. Hashlib compatibility issues have been fixed. dns.message now imports dns.edns. The TSIG algorithm value was passed incorrectly to use_tsig() in some cases. New since 1.7.1: Support for hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384 and hmac-sha512 has been contributed by Kevin Chen. The tokenizer's tokens are now Token objects instead of (type, value) tuples. Bugs fixed since 1.7.1: Escapes in masterfiles now work correctly. Previously they were only working correctly when the text involved was part of a domain name. When constructing a DDNS update, if the present() method was used with a single rdata, a zero TTL was not added. The entropy pool needed locking to be thread safe. The entropy pool's reading of /dev/random could cause dnspython to block. The entropy pool did buffered reads, potentially consuming more randomness than we needed. The entropy pool did not seed with high quality randomness on Windows. SRV records were compared incorrectly. In the e164 query function, the resolver parameter was not used. New since 1.7.0: Nothing Bugs fixed since 1.7.0: The 1.7.0 kitting process inadventently omitted the code for the DLV RR. Negative DDNS prerequisites are now handled correctly. New since 1.6.0: Rdatas now have a to_digestable() method, which returns the DNSSEC canonical form of the rdata, suitable for use in signature computations. The NSEC3, NSEC3PARAM, DLV, and HIP RR types are now supported. An entropy module has been added and is used to randomize query ids. EDNS0 options are now supported. UDP IXFR is now supported. The wire format parser now has a 'one_rr_per_rrset' mode, which suppresses the usual coalescing of all RRs of a given type into a single RRset. Various helpful DNSSEC-related constants are now defined. The resolver's query() method now has an optional 'source' parameter, allowing the source IP address to be specified. Bugs fixed since 1.6.0: On Windows, the resolver set the domain incorrectly. DS RR parsing only allowed one Base64 chunk. TSIG validation didn't always use absolute names. NSEC.to_text() only printed the last window. We did not canonicalize IPv6 addresses before comparing them; we would thus treat equivalent but different textual forms, e.g. "1:00::1" and "1::1" as being non-equivalent. If the peer set a TSIG error, we didn't raise an exception. Some EDNS bugs in the message code have been fixed (see the ChangeLog for details). New since 1.5.0: Added dns.inet.is_multicast(). Bugs fixed since 1.5.0: If select() raises an exception due to EINTR, we should just select() again. 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. NAPTR comparisons didn't compare the preference field due to a typo. Testing of whether a Windows NIC is enabled now works on Vista thanks to code contributed by Paul Marks. New since 1.4.0: Answer objects now support more of the python sequence protocol, forwarding the requests to the answer 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]". Making requests using EDNS, including indicating DNSSEC awareness, is now easier. For example, you can now say: q = dns.message.make_query('www.dnspython.org', 'MX', want_dnssec=True) dns.query.xfr() can now be used for IXFR. Support has been added for the DHCID, IPSECKEY, and SPF RR types. UDP messages from unexpected sources can now be ignored by setting ignore_unexpected to True when calling dns.query.udp. Bugs fixed since 1.4.0: If /etc/resolv.conf didn't exist, we raised an exception instead of simply using the default resolver configuration. In dns.resolver.Resolver._config_win32_fromkey(), we were passing the wrong variable to self._config_win32_search(). New since 1.3.5: You can now convert E.164 numbers to/from their ENUM name forms: >>> import dns.e164 >>> n = dns.e164.from_e164("+1 555 1212") >>> n >>> dns.e164.to_e164(n) '+15551212' You can now convert IPv4 and IPv6 address to/from their corresponding DNS reverse map names: >>> import dns.reversename >>> n = dns.reversename.from_address("127.0.0.1") >>> n >>> dns.reversename.to_address(n) '127.0.0.1' You can now convert between Unicode strings and their IDN ACE form: >>> n = dns.name.from_text(u'les-\u00e9l\u00e8ves.example.') >>> n >>> n.to_unicode() u'les-\xe9l\xe8ves.example.' The origin parameter to dns.zone.from_text() and dns.zone.to_text() is now optional. If not specified, the origin will be taken from the first $ORIGIN statement in the master file. Sanity checking of a zone can be disabled; this is useful when working with files which are zone fragments. Bugs fixed since 1.3.5: The correct delimiter was not used when retrieving the list of nameservers from the registry in certain versions of windows. The floating-point version of latitude and longitude in LOC RRs (float_latitude and float_longitude) had incorrect signs for south latitudes and west longitudes. BIND 8 TTL syntax is now accepted in all TTL-like places (i.e. SOA fields refresh, retry, expire, and minimum; SIG/RRSIG field original_ttl). TTLs are now bounds checked when their text form is parsed, and their values must be in the closed interval [0, 2^31 - 1]. New since 1.3.4: In the resolver, if time goes backward a little bit, ignore it. zone_for_name() has been added to the resolver module. It returns the zone which is authoritative for the specified name, which is handy for dynamic update. E.g. import dns.resolver print dns.resolver.zone_for_name('www.dnspython.org') will output "dnspython.org." and print dns.resolver.zone_for_name('a.b.c.d.e.f.example.') will output ".". The default resolver can be fetched with the get_default_resolver() method. You can now get the parent (immediate superdomain) of a name by using the parent() method. Zone.iterate_rdatasets() and Zone.iterate_rdatas() now have a default rdtype of dns.rdatatype.ANY like the documentation says. A Dynamic DNS example, ddns.py, has been added. New since 1.3.3: The source address and port may now be specified when calling dns.query.{udp,tcp,xfr}. The resolver now does exponential backoff each time it runs through all of the nameservers. 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. New since 1.3.2: dns.message.Message.find_rrset() now uses an index, vastly improving the from_wire() performance of large messages such as zone transfers. Added dns.message.make_response(), which creates a skeletal response for the specified query. Added opcode() and set_opcode() convenience methods to the dns.message.Message class. Added the request_payload attribute to the Message class. The 'file' parameter of dns.name.Name.to_wire() is now optional; if omitted, the wire form will be returned as the value of the function. dns.zone.from_xfr() in relativization mode incorrectly set zone.origin to the empty name. The masterfile parser incorrectly rejected TXT records where a value was not quoted. New since 1.3.1: The NSEC format doesn't allow specifying types by number, so we shouldn't either. (Using the unknown type format is still OK though.) 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. 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. The conversion of LOC milliseconds values from text to binary was incorrect if the length of the milliseconds string was not 3. New since 1.3.0: Added support for the SSHFP type. New since 1.2.0: Added support for new DNSSEC types RRSIG, NSEC, and DNSKEY. This release fixes all known bugs. See the ChangeLog file for more detailed information on changes since the prior release. REQUIREMENTS Python 2.4 or later. INSTALLATION To build and install dnspython, type python setup.py install HOME PAGE For the latest in releases, documentation, and information, visit the dnspython home page at http://www.dnspython.org/ DOCUMENTATION Documentation is sparse at the moment. Use pydoc, or read the HTML documentation at the dnspython home page, or download the HTML documentation. BUG REPORTS Bug reports may be sent to bugs@dnspython.org MAILING LISTS A number of mailing lists are available. Visit the dnspython home page to subscribe or unsubscribe.