Changelog

View Source

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

main

v5.0.16

Fixed

  • decode_query/1 no longer rejects rfc1995 IXFR queries as formerr but as notimp.

v5.0.15

Fixed

  • decode_message/1 now decodes rfc2136 UPDATE messages, while decode_query/1 does not anymore as it shouldn't have, returning notimp.

v5.0.14

Updated

  • Optimized dns_domain:to_wire/3 (compressed name encoding): 1.4–2.8x faster on typical names, up to 17–22x on many-label names such as IPv6 reverse PTRs, with 1.1–3x less allocation.
  • Optimized dns_domain:from_wire/1,2 (wire-format name decoding): ~1.1–1.2x faster on typical compressed names, up to 1.4–1.5x on pointer chains, with up to 18% less allocation on pointer-heavy names.
  • Optimized message encoding: ~1.1–1.3x faster on typical bounded responses with 5–35% less allocation across message shapes.

Fixed

  • Correct name compression in the additional section of encode_message/2 for non-EDNS responses
  • NSEC/NSEC3/CSYNC/NXT type bitmap encoding shifted every type after the first by one bit position in any window whose first present type is a multiple of 256
  • MINFO records failed to decode inside full messages (formerr) due to swapped dns_domain:from_wire/2 arguments in the MINFO rdata decoder
  • encode_message/2 subtracted the question section twice when sizing the OPT RR and additional records, wrongly dropping them (including the EDNS OPT RR, contra RFC 6891) from responses within question-size bytes of max_size
  • LOC latitude and longitude used 2^31 - 1 instead of 2^31 as the equator/prime-meridian reference point (RFC 1876 §2)
  • LOC size/horiz/vert outside the representable 0–9e9 cm range now raise badarg, and in-range values round to nearest instead of truncating (RFC 1876 §2)
  • encode_message/2 with tc_mode => llq_event raised badmatch when the authority/additional tail or the question section exceeded max_size; it now truncates and sets TC
  • Zero-length <character-string>s were dropped when encoding TXT, SPF, RESINFO and WALLET records (RFC 1035 §3.3)
  • A NAPTR record whose REGEXP is not valid UTF-8 decoded into a record holding an error tuple instead of being rejected (RFC 3403 §4.1)
  • An EDNS OPT RR advertising a UDP payload size below 512 is clamped to 512 instead of raising badarg (RFC 6891 §6.2.3)
  • encode_message/2 with an unsupported tsig algorithm raised case_clause instead of badarg
  • An SVCB/HTTPS alpn id longer than 255 bytes silently truncated its length octet, producing undecodable wire data; it now raises {svcb_invalid_alpn_id, _}
  • SVCB/HTTPS mandatory, ipv4hint and ipv6hint values that are not a whole number of elements are rejected instead of silently dropping the remainder (RFC 9460 §7.4, §8)
  • An EDNS OPT RR with a non-root owner name, and a message carrying more than one OPT RR, now decode to formerr (RFC 6891 §6.1.1)
  • RDLENGTH = 0 for a type this library decodes now decodes to formerr instead of an opaque <<>> (RFC 1035 §3.2.1)
  • An OPT RR anywhere but first in the additional section was ignored when sizing the response and dropped from truncated ones (RFC 6891 §6.1.1)
  • URI targets were replaced by their normalized form when decoding, losing data and changing the canonical RDATA that RRSIGs cover (RFC 7553 §4.5)
  • A DNSKEY or CDNSKEY with a DSA algorithm but rdata too short to parse as one crashed on re-encode (RFC 2536 §2)
  • Re-encoding a DSA DNSKEY whose P began with a zero byte truncated G and Y, producing an undecodable record (RFC 2536 §2)
  • encode_rrdata/2 crashed with badmap on every KX record, and with it the DNSSEC canonical form (RFC 2230)
  • A repeated or out-of-order NSEC/NSEC3/CSYNC type-bitmap window decoded to a types list containing duplicates (RFC 4034 §4.1.2)
  • LOC precision octets with a base nibble above nine were accepted instead of being left opaque (RFC 1876 §2)
  • encode_message/1,2 would emit a message carrying two OPT RRs, which the decoder rejects (RFC 6891 §6.1.1)
  • A non-canonically encoded RSA DNSKEY/CDNSKEY public key changed shape when re-encoded, altering the canonical RDATA an RRSIG covers (RFC 3110 §2)

v5.0.13

Fixed

  • Correctly return formerr on invalid NOTIFY DNS messages (rfc1996 §3.7: a NOTIFY carries exactly one question (QDCOUNT=1) and at most one), (#130)

v5.0.12

Fixed

  • A malformed EDNS COOKIE option (RFC 7873) in a received message now decodes to a formerr result instead of raising bad_cookie.

v5.0.11

Fixed

  • WALLET (type 262) RDATA uses TXT-style character-strings on the wire and in zone files (data as a list of binaries), per IANA WALLET.
  • Zone file parsing and RDATA decoding: improved handling of BIND-style presentations and record types;
  • Empty TXT/RESINFO RDATA are rejected during semantic validation;
  • Empty A/AAAA RDATA is rejected (no longer skipped);

v5.0.10

Updated

v5.0.9

Updated

v5.0.8

Fixed

  • Handle truncated RR headers in additional and body sections (#121)

v5.0.7

Changed

  • Minor internal cleanups in the dnssec module (better function naming)

v5.0.6

Added

  • dnssec exports record types it works over as types.

Fixed

  • Fixed encoding and decoding of ECDSA signatures
  • Refactored dnssec to use the newer dns_domain API internally in a more efficient way
  • Incremented test coverage for DNSSEC

Removed

  • Internal ASN1 parser, as it is supported by OTP's public_key module.

v5.0.5

Fixed

  • SVCB/HTTPS params: treat numeric keys key0–key6 as reserved and equivalent to named params (mandatory, alpn, no-default-alpn, port, ipv4hint, ech, ipv6hint). Validate them the same at ingestion in zone parsing, JSON parsing, and wire decoding; key0–key6 are no longer accepted as generic unknown keys (#110, #111)
  • SVCB params JSON docs: document key0–key6 equivalence to named params, no-default-alpn as null, and keyNNNN format (value binary or null) in generated JSON documentation
  • SVCB params wire: decode unknown keys with zero-length value as none (not <<>>) so round-trip and to_json stay consistent (null vs empty binary)
  • SVCB params JSON: reject invalid param keys in to_json/1 (e.g. key > 65535) with {svcb_param_invalid_key, K} instead of emitting a map with undefined as key
  • Ensure strict parsing of IPv4 and IPv6 in zonefiles respectively (#108)

v5.0.4

Fixed

  • Fix parsing SVCB json records when svc_params are missing

v5.0.3

Fixed

  • Fix FQDNs an (C)DNSKEY payloads in zonefile encoding

v5.0.2

Changed

  • Use nulls instead of none in SVCB params JSON payloads #107

v5.0.1

Fixed

  • Fix an issue with the hex package not including all needed files

v5.0.0

Added

Changed

  • Require OTP 27 or later (minimum_otp_vsn set to "27")
  • dns:encode_message/2 changed how truncation is returned to a clearer type
  • Migrate domain name operations to new dns_domain module

All domain name processing functions have been moved to a new optimized dns_domain module. The old implementations in dns and related helper modules have been removed and replaced with calls to the new module.

Migration guide

All domain name functions have been moved to dns_domain. Update your code as follows:

% Old → New
dns:dname_to_lower(Name)             -> dns_domain:to_lower(Name)
dns:dname_to_upper(Name)             -> dns_domain:to_upper(Name)
dns:dname_to_labels(Name)            -> dns_domain:split(Name)
dns:labels_to_dname(Labels)          -> dns_domain:join(Labels)
dns:dname_to_lower_labels(Name)      -> dns_domain:split(dns_domain:to_lower(Name))
dns:compare_dname(NameA, NameB)      -> dns_domain:are_equal(NameA, NameB)
dns:compare_labels(LabelsA, LabelsB) -> dns_domain:are_equal_labels(LabelsA, LabelsB)
dns:escape_label(Label)              -> dns_domain:escape_label(Label)
dns_encode:encode_dname(Name)        -> dns_domain:to_wire(Name)
dns_encode:encode_dname(CM, Pos, N)  -> dns_domain:to_wire(CM, Pos, N)

Note: The wrapper functions in dns module (dname_to_labels/1, labels_to_dname/1, dname_to_lower_labels/1, dname_to_upper/1, dname_to_lower/1, compare_dname/2, compare_labels/2, escape_label/1) have been removed. Use dns_domain functions directly now.

Error Handling Changes:

  • decoding invalid wire packets previously used throw/1 for errors (decode_loop, bad_pointer), it uses error/1 now
  • Update error handling: try dns:decode_message(...) catch error:Reason -> ... end

Removed

  • Removed old dns_record and dns_record_info modules

4.9.1

Fixed

  • Fix a bug that would incorrectly calculate pointers, introduced in 4.9.0

4.9.0

Added

  • Add extended support for SVCB and HTTPS Resource Records — RFC9460
  • Add support for OPENPGPKEY (Type 61) — RFC 7929
  • Add support for SMIMEA (Type 53) — RFC 8162
  • Add support for URI (Type 256) — RFC 7553
  • Add support for WALLET (Type 262) — IANA Registration
  • Add support for EUI48 (Type 108) and EUI64 (Type 109) — RFC 7043
  • Add support for CSYNC (Type 62) — RFC 7477
  • Add support for DSYNC (Type 66) — RFC 9859
  • Add dns:decode_query/1 function for strict query validation to prevent DoS attacks

Changed

  • Performance improvements in message encoding (~5-15% faster for encode/1, ~0-20% faster for encode/2)

4.8.1

Fixed

  • Fix bad size for reserved OptRR record during encoding

4.8.0

Added

  • Add support for RFC8976: Message Digest for DNS Zones

Fixed

  • Fix Base64 lexing of zone files

4.7.0

Added

  • Extend support for RFC8914: Extended DNS Errors.

4.6.0

Added

  • Add support for DNS zone file parsing

4.5.0

Added

  • Add support for RFC8080: Ed22519/Ed448 for DNSSEC.
  • Add support for RFC8914: Extended DNS Errors.

4.4.0

Added

  • Add support for RFC6605: ECDSA for DNSSEC.
  • Add support for RFC9077: NSEC/NSEC3 TTLs.

4.3.0

Added

  • Add support for TLSA records.

4.2.0

Added

  • Add shortcuts for normalizing and converting domains into labels.
  • Add a helper for comparing label lists.
  • Add helpers to convert from and to codes into their string representation.

4.1.0

Added

  • Add support for RFC7873 EDNS cookies encoding and decoding

4.0.1

Fixed

  • Fix additional count when truncating a message

4.0.0

Changed

  • Use erlang:system_time/1 for timestamps.
  • Use maps instead of proplists for options to be passed to encoding, decoding, TSIG, and DNSSEC functions.
  • Encoding logic builds responses that contain the full question section, and optionally drop the answers if the response is to be truncated.
  • Use consistent record names.
  • Split names functions into a standalone dns_names module.
  • Extends and reorganise documentation.

3.1.3

Fixed

  • Fix: now using the reserved space for the OPT RR records during the encoding of the message (#74)

3.1.2

Added

  • Add NXNAME type to terms types.

3.1.1

Fixed

  • Fix EDNS0 compliance for truncated records and unsupported versions

3.1.0

Fixed

  • Fix EDNS0 compliance for truncated records and unsupported versions

3.0.5

Fixed

  • Fix max_size in encode_message opts

3.0.4

Changed

  • Upgrade dependencies
  • Apply linter specs

3.0.3

Changed

  • Performance improvements in string manipulations

3.0.2

Fixed

  • Fix type definitions

3.0.1

Fixed

  • Ensure ASN1 compilation before building package

3.0.0

Added

  • Add xref, dialyzer, and ex_doc
  • Add strict typing and RFC references to all records
  • Add support for TXT splitting of strings over the maximum permitted size

2.0.0

Changed

  • Bump to OTP/27
  • Replace "jsx" with "json"

Added

  • Erlfmt
  • CONTRIBUTING.md
  • CHANGELOG.md
  • Release process to hex.pm

1.1.0

N/A