Architectural changes ===================== Resource record template ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ Resource record interface is implemented using the following functions to facilitate conversions to and from string and wire format: ‐ decode_rdata ## decode rdata from wire‐format byte string ‐ encode_rdata ## encode rdata as wire‐format byte string ‐ format_rdata ## format rdata portion of RR string ‐ parse_rdata ## parse RR attributes in argument list Some of these functions may be omitted, the interface model then being completed by default implementations inherited from the RR base type. These functions loosely replace the previously required new, rr_rdata, new_from_string and rdatastr functions. If all interface functions are omitted, the RR is an unknown RRTYPE with implementation defined by RFC3597. The new functions provide (much clearer) separation of concerns. Note that in the old architecture, all RRs should be constructed via Net::DNS::RR::new() and new_from_string() functions of the type‐specific subclass, which were not intended to be called directly. Additionally the functions _normalize_dnames and _canonicalRdata are no longer needed as they are now handled by the classes implementing the owner name and domain name rdata fields. Default values for rdata fields may be set with the optional defaults() function. This was provided for completeness, and intended to offer convenience when creating a new RR from a hash specification. ** Consequences RR.pm currently contains a compatibility layer which implements the "old" interface as methods which are inherited by the "new" architecture RR subtype modules. The compatibility layer is controlled by a configuration constant COMPATIBLE, which switches between the two RR subtype interfaces. This provides a useful method of testing if the transition plan actually works. There is no well defined relationship between releases of Net::DNS and Net::DNS::SEC, so one possible migration scenario would be to operate Net::DNS in compatible mode for some number of revisions. This will allow Net‐DNS‐SEC‐0.16 and earlier to continue operating. Net‐DNS‐ SEC‐0.17 and later versions could then be implemented using the "new" interface, and operated using compatibility mode until such time as it is deemed appropriate to turn it off (when 0.16 becomes too old to use). Note that RRSIGs for wildcards, a feature that is in Net‐DNS‐SEC from the subversion trunk only and not in the releases, does not currently work with the new architecture. [I have only tested against 0.16, being the latest release ‐ RWF] Resource record owner names ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ RR owner names are represented internally by Net::DNS::DomainName1035 (compressible domain name) objects. This makes it possible, when Net::LibIDN is available, to construct RRs with Unicode owner names which will be represented in IDN A‐label format. ** Consequences: This has no impact on backwards compatibility as the user only has access to Perl native strings. Conversions between character encodings occur (conceptually at least) somewhere close to the wire. You need to be aware that domain labels are stored in wire‐format, which minimises the total number of conversions for the core functionality of resolving domain names. Other uses, zone file parsing and pretty printing for example, incur less favourable treatment, with two conversions where none might be expected. Resource record rdata domain name fields ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ RDATA domain names are represented internally by Net::DNS::DomainName objects. This makes it possible, when Net::LibIDN is available, to construct RDATA containing Unicode domain names which will be represented in IDN A‐label format. RR subtype modules which are subject to compression and/or downcasing requirements are implemented using Net::DNS::DomainName1035 and Net::DNS::DomainName2535 objects which specialise the base type by the substitution of a new encode() method. The list of modules affected appears in RFC3597 as amended. Canonicalisation of RR wire‐format data is implemented by calling the RR subtype encode() method with an undefined value instead of the reference to the name compression hash. (Dick, for creating and verifying RRSIGs?) Yes, at least to the extent tested by Net::DNS::SEC test suite. ** Consequences: This has no impact on backwards compatibility as the user only has access to Perl native strings. Resource records with rdata fields containing text ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ Rdata fields containing text are represented internally by Net::DNS::Text objects. This allows text rdata fields to be constructed using the full Unicode character set. Affected rdata fields are: HINFO‐>cpu, HINFO‐>os, NAPTR‐>flags, NAPTR‐>service, NAPTR‐>regexp and TXT‐>txtdata. Of these, TXT is the only RR where Unicode text is likely to be used. ** Consequences: The relevent RFCs define text to be encoded on the wire using ASCII, which is a proper subset of the UTF8 encoding used by the Text module. The interpretation of non‐ASCII character codes has never been defined, and presumably never (ab)used. There is therefore no impact on backwards compatibility. Text rdata fields will return a standard Perl string using the internal encoding appropriate for the platform. Characters which cannot otherwise be represented will be expressed as RFC1035 numeric escape sequences. Resource records with rdata fields containing mailboxes ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ Mailboxes rdata fields are represented internally by Net::DNS::Mailbox objects and can now be constructed with the mailbox name in RFC822 format; i.e. user@domain or name. Affected rdata fields are: MINFO‐>rmailbx, MINFO‐>emailbx, RP‐>mbox and SOA‐>rname. RFC1035 defines the encoding method to be used for mail addresses and therefore responsibility for such encoding/decoding should lie with Net::DNS and not be devolved to the user. ** Consequences: Those rdata fields will now return the email box in RFC822 format. This is a difference that we are willing to accept because of the enrichment it provides for the type. The "old" encoded form is also accepted when modifying these fields. The packet header incorporates EDNS0 ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ Header extensions provided by the EDNS0 OPT resource record are now accessible transparently through the $packet‐>header interface. This includes the DO flag, extended response codes and UDP packet size. Directly accessing opt‐>class or opt‐>ttl functions now triggers a warning (once) advising the use of the appropriate function instead. ** Consequences: Net::DNS::Header now needs to be associated with a Net::DNS::Packet and must not be constructed independently any more. The quantity attributes qdcount, ancount, nscount and arcount (or their dynamic update counterparts) now return the number of RRs in the addressed section. As a consequence they can not be set directly. For a decoded packet, the counter value is derived from the packet header and may differ from the actual number of RRs in the corresponding section if a decoding error occurred. However, for a newly constructed packet, the header count reflects the current length of the section. DNS parameters in separate module ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ The DNS parameters are now also provided in a separate module Net::DNS::Parameters. This file will (in the future) automatically be generated from the authoritative resource at IANA: http://www.iana.org/assignments/dns‐parameters/dns‐parameters.xml Net::DNS internally uses Net::DNS::Parameters for all dns parameters, but they are also still present in DNS.pm for backwards compatibility. This change also removes the circularities present in the module dependency "tree" which results in unnecessary multiple compilation of some modules. It now really _is_ a tree. ** Consequences: The name of opcode 4 is altered from NS_NOTIFY_OP to NOTIFY. This pulls the code into line with the opcode registry but will break backwards compatibility. Dick, Should we change this back and put it on the wish list for a more major version update? No, I think not; we should regard the IANA registry as the definitive source of mnemonics. As this occurs in both forward and reverse tables, there is no backward compatibility workaround that will please everyone. Users are likely to respond positively if we are seen to be tying ourselves to published standards which will offer them long‐term stability albeit incurring a small one‐off inconvenience. We are very lucky that this appears to be the only inconsistent mnemonic. Packet decoding errors ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ Packet decoding errors are now collected in the $@ ($EVAL_ERROR) variable. Before the error message was returned in the second item of the array returned when construction a Net::DNS::Packet in array context. Now that second argument contains the number of octets successfully decoded. This makes packet decoding more robust and gives more refined control over the decoding process (by returning a pointer to potentially uninterpreted data). ** Consequences: We believe it is safe because requesting an error message before also required a test for the returned packet to be defined (i.e. not undef). This behaviour is backwards compatible. The only thing different is the error message which is now in $@. In the worst case a number will be printed as an error message. Exception-based error handling schemes can now be supported simply by adding 'die if $@' to propagate the exception. The entire packet is now decoded immediately; the previous deferred decoding scheme has been abandoned. As a consequence, no exceptions will be raised for decoding errors during calls to the packet->answer and similar methods. This was a design response to the problem of determining the length of a decoded packet encountered by Mark Andrews. Upgradable aplists in APL RRs ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ APL RRs now allow for gradually appending (negate,family)address/prefix items. ** Consequences: Net::DNS::RR::APL::ApItem is replaced with Net::DNS::RR::APL::Item that cannot be constructed independently. It is unlikely (and not the intention) that people ever used Net::DNS::RR::APL::ApItem directly. Therefore we believe it is safe.