dns v4.0.1 Release Notes
Release Date: 2019-11-20 // almost 5 years ago-
- 🛠 Bugfix: Retry without EDNS on empty FormatErr responses. Non-EDNS resolvers may return a FormErr response with an empty question section. Such a response must be accepted as a valid signal to switch to non-EDNS queries, even though the response does not contain a matching question.
- Feature: New RData constructors RD_CDS and RD_CDNSKEY
- Usability: More friendly network errors, instead of reporting the error location as an overly verbose "addrinfo" it is now just the essential "tcp@address" or "udp@address".
- BCP: The EDNS UDP buffer size has been changed to the RIPE recommended default of 1232 bytes. Note that this recomendation is for a default value, to be used when better information is not available. Users can still configure larger values if their networks support larger data frames and they are certain there is no risk of IP fragmentation.
- 🐧 CI: Linux tests now pass with GHC 8.0.2, 8.2.2, 8.4.4, 8.6.5 and 8.8.1. Windows tests now build and run, but pass only intermittently. The Windows doctests hang most of the time, perhaps a bug or portability issue in the doctest code, rather than the DNS library?
- 🏗 Build: Internal modules are no longer exposed outside the build, this uses Cabal 2.0 or later features to expose internal modules only to the test executables.
Previous changes from v4.0.0
-
- 💥 Breaking change: when
Domain
name ByteStrings are parsed as a sequence of DNS labels, backslashed escapes (single-character and 3-digit decimal) are decoded to the corresponding character or byte. Therefore,encode
is not a total function, it may raise aDecodeError
when aResourceRecord
contains a malformedDomain
. - 💥 Breaking change: when wire-form DNS names are converted
to
Domain
ByteStrings, special characters in DNS labels are now encoded as\c
(single-character backslash escapes) and non-printing characters as\DDD
(3-digit decimal escapes). - Output format change:
show
for TXT RDATA now includes enclosing double quotes, and escapes special characters. This is consistent with the format of TXT records in zone files and, e.g., dig(1) output. The DNS string quoting syntax is similar to a proper subset of the Haskell string quoting syntax, but its decimal escapes require exactly three digits, while Haskell accepts 1 or more, and uses'\&'
as a null. Therefore,read @String
does not reliably decode the DNS text string presentation form. - Breaking change: the DNSMessage component encoding functions are now internal. They're still exported from the new 'Nework.DNS.Encode.Internal' module, but this is only to make them available for the test-suite.
- ➕ Added the TYPE definition, but not yet RData, for CAA.
- ➕ Added decode, encode and show for NSEC3 RRs.
- ➕ Added base16-bytestring as a new dependency.
- ➕ Added decode, encode and show for NSEC RRs.
- 🆕 New RData constructor RD_NSEC.
- Correct presentation form of unknown RR types.
- Corrected encoding of long TXT records
- 🛰 RD_NULL now has an opaque data payload.
- Safety: Both 'decode' and 'decodeAt' must now consume exactly
the complete input buffer or a DecodeError is returned.
- The same applies to each complete message with 'decodeMany' and 'decodeManyAt'. Any final encoded message segment at the end of the input buffer is still returned as the second element of the result pair.
- 🛠 Bugfix: fixed incorrect decoding of TXT records, and corrected the associated test.
- Cleanup: More precise control over decoder error messages via 'failSGet', which avoids the unhelpful Attoparsec "Failure reading: " error prefix.
- Cleanup: Simplified loop detection in name decompression, making use of a monotone strictly decreasing limit on valid "pointer" targets.
- 💥 Breaking change: In the "Decode" module, expose only the
decode{,Many}{,At} functions. The rest of the "Decode" module's
functions are now internal, exposed only for testing. These
include:
- decodeDNSHeader
- decodeDNSFlags
- decodeResourceRecord
- decodeDomain
- decodeMailbox
- Cleanup: Reworked Decode module structure:
- Moved Decode.Internal to Decode.Parsers
- Created a new Decode.Internal which is now exposed, and moved some functions there from Decode which are only exposed for testing, since they could not reliably be used except as part of decoding a full message.
- 🔋 Feature: RRSIG support, we can now encode, decode and show RRSIG records. This uses the new 'decodeAt' and 'decodeManyAt' API.
- 🆕 New API: 'decodeAt' and 'decodeManyAt' make it possible for the decoder to get the current time, in order to decode some RR types (like RRSIG) whose full meaning is time-dependent.
- Re-export 'sendAll' and export 'encodeVC' for use with TCP.
- No longer using sendAll with UDP, UDP datagrams must not be sent piece-by-piece
- ✂ Removed socket I/O work-around for no longer supported GHC versions on Windows.
- TCP queries now also use EDNS, since the DO bit and other options may be relevant, even when the UDP buffer size is not. Therefore, TCP now also does a non-EDNS fallback.
- The resolvEDNS field is subsumed in resolvQueryControls and removed. The encodeQuestion function changes to no longer take an explicit "EDNSheader" argument, instead the EDNS record is built based on the supplied options. Also the encodeQuestions function has been removed, since we're deprecating it, but the legacy interface can no longer be maintained.
- 🆕 New API: lookupRawCtl
- 🆕 New API: ODataOp, doFlag, ednsEnable, ednsSetVersion, ednsSetSize and ednsSetOptions make it possible for 'QueryControls' to adjust EDNS settings.
- 🆕 New API: FlagOp, rdFlag, adFlag and cdFlag make it possible to override the default settings of the query-related DNS header flags.
- 💥 Breaking change: the decoded EDNS record no longer contains
an error field. Instead the header of decoded messages is
updated hold the extended error code when valid EDNS OPT records
(EDNS pseudo-headers) are found. The remaining EDNS record
fields have been renamed:
- udpSize -> ednsBufferSize
- dnssecOk -> ednsDnssecOk
- options -> ednsOptions The reverse process happens on output with the 12-bit header RCODE split across the wire-form DNS header and the OPT record. When EDNS is not enabled, and the RCODE > 15, it is mapped to FormatErr instead.
- 💥 Breaking change: The fromRCODEforHeader and toRCODEforHeader functions have been removed.
- 💥 Breaking change: DNSFormat and fromDNSFormat have been removed.
- The fromDNSMessage function now distinguishes between FormatErr responses without an OPT record (which signal no EDNS support), and FormatErr with an OPT record, which signal problems (malformed or unsupported version) with the OPT record received in the request. For the latter the 'BadOptRecord' error is returned.
- ➕ Added more RCODEs, including a BadRCODE that is generated locally, rather than parsed from the message. The value lies just above the EDNS 12-bit range, with the bottom 12-bits matching FormatErr.
- 💥 Breaking change: The DNSMessage structure now has an "ednsHeader" field, initialized to "EDNSheader defaultEDNS" in "defaultQuery" and to "NoEDNS" in "defaultResponse". The former enables EDNS(0) with default options, the latter leaves EDNS unconfigured.
- 👍 The BadOpt RCODE is renamed to BadVers to better resemble the term used in RFCs.
- ➕ Added EDNS OPTIONS: NSID, DAU, DHU, N3U
- Decoding of the ClientSubnet option is now a total function, provided the RDATA is structurally sound. Unexpected values just yield OD_ECSgeneric results.
- 💥 Breaking change: New OD_ECSgeneric EDNS constructor, represents ClientSubnet values whose address family is not IP or that violate the specification. The "family" field distinguishes the two cases.
- The ClientSubnet EDNS option is now encoded correctly even when the source bits match some trailing all-zero bytes.
- 💥 Breaking change: EDNS0 is renamed to EDNS.
- 💥 Breaking change: lookupRawAD, composeQuery, composeQueryAD are removed.
- 🔔 New OP codes: OP_NOTIFY and OP_UPDATE. #113
- 💥 Breaking change: when