nonymous 0.5.1

DNS protocol and algorithm library
Documentation
**Note:** after version [0.3.3 (2021-07-05)](#markdown-header-033-2021-07-05), the [nonymous](https://crates.io/crates/nonymous) and [bore](https://crates.io/crates/bore) crates are versioned separately.


# bore ?.?.? (????-??-??)


- increased **minimum Rust version** from 1.46 to **1.72**
- new option `--trace` to use iterative resolution rather than recursive resolution
- new option `--tcp` to send queries over TCP rather than UDP
- OpenBSD: fixed pledge(2) panic when `--host` and `--show-resolvers` are used together
- unknown OPCODE and RCODE values now show as `OPCODE?x` and `RCODE?x` rather than `<x>`


# nonymous 0.5.1 (2025-10-20)


- fixed build errors with `--features alloc` but without `--features std`
- CI commit checks now include running nonymous crate tests under `--features alloc`
- CI commit checks now include running all tests under `--features bench`


# nonymous 0.5.0 (2025-10-13)


- increased **minimum Rust version** from 1.72 to **1.81**
- new type `NameBuf` representing an owned name, for use in data structures keyed on names
- `core`
    - `Type` now implements `Copy` + `Eq` + `Hash` + `Ord` + `PartialOrd`
- `emit::MessageBuilder`
    - new method `question_with_name` adds a question with the given `Name`, `Type`, and `Class`
- `view`
    - **breaking change:** `Labels::new` is no longer public
        - use `Name::labels_with_null` or `Name::labels_not_null` instead
    - **breaking change:** `Questions::new` is no longer public
        - use `Message::qd` instead
    - **breaking change:** `Records::new` is no longer public
        - use `Message::an` or `Message::ns` or `Message::ar` instead
- `view::Name`
    - **breaking change:** the `root` method has been renamed to `is_root`
    - **breaking change:** the `labels` method has been renamed to `labels_with_null`
    - new method `labels_not_null` iterates through the name’s labels, excluding the null label
    - new method `is_subdomain_of` checks if the name is a subdomain of (or equal) to another name
    - now implements `PartialEq` with `Name`, `[u8]`, `&[u8]`, `[u8; N]`, `&[u8; N]`, `str`, `&str`, `String`, `&String`
    - now implements `Ord` + `PartialOrd` + `Eq` with `Name`
    - now implements `Hash`
- `view::Label`
    - **breaking change:** all `PartialEq` impls now resolve pointers
    - **breaking change:** the `null` method has been renamed to `is_null`
    - **breaking change:** the `literal` method has been removed in favour of `value`
    - new method `value` gets the label’s contents after resolving pointers
    - now implements `PartialEq` with `Label`, `&[u8]`, `&[u8; N]`, `str`, `&str`, `String`, `&String`
    - now implements `Ord` + `PartialOrd` + `Eq` with `Label`
    - now implements `Hash`
- `view::rdata::InAddress`
    - new method `to_ipv4_addr` converts the RDATA to an Ipv4Addr
    - new method `to_ip_addr` converts the RDATA to an IpAddr
    - now implements `Into<Ipv4Addr>` and `Into<IpAddr>`
- `view::rdata::InAaaa`
    - new method `to_ipv6_addr` converts the RDATA to an Ipv6Addr
    - new method `to_ip_addr` converts the RDATA to an IpAddr
    - now implements `Into<Ipv6Addr>` and `Into<IpAddr>`


# nonymous 0.4.0 (2025-10-11)


- increased **minimum Rust version** from 1.46 to **1.72**
- **`view` and `fmt` (formerly `zone`) are now fuzzed and guaranteed to be panic-free**
- new `{opcode,rcode,type,class}` macros to get values by name at compile time
- new `server::response` helper function to start building a response to the given query
- new `MAX_SUPPORTED_EDNS_VERSION` constant representing supported EDNS version (0)
    - `view::Extension` returns `UnimplementedVersion` error when VERSION exceeds this value
- new example `dynrdns` that dynamically generates responses to reverse DNS queries
- `core`
    - new `core::{Opcode,Rcode}` types representing OPCODE and (extended) RCODE
    - new `core::Serial` type representing SOA SERIAL with serial number arithmetic (RFC 1982)
    - numeric types in `core` are now returned directly by view methods (see breaking changes)
- `emit`
    - **improved runtime performance by over 10x** when using `ArrayVec`
    - new `emit::MessageBuilder::{opcode,rcode}` methods to set OPCODE and (extended) RCODE
    - new `emit::MessageBuilder::copy_question` methods to copy the given `view::Question`
    - new `emit::ExtensionBuilder::{udp,version,do}` methods to set UDP payload size, VERSION, and DO flag
    - new `emit::Sink::new` method to create a sink without an explicit limit
    - new `emit::Sink::capacity_limit` function to calculate the limit imposed by the given buffer
    - new `emit::Sink::response_limit` function to calculate the limit for a buffer, protocol, and query
    - `emit::MessageBuilder::extension` now implies `MessageBuilder::into_ar` if needed
    - builder docs now clearly categorise state machine methods as down/step/up transitions
    - added ArrayVec-based versions of builder benches
    - squelched new warning about unused attribute on macro invocation
    - squelched new warning about renamed private_intra_doc_links lint
- `view`
    - new `view::Message::udp_limit` method returning the requestor’s UDP payload size
    - `View::view` now accepts values of any `RangeBounds<usize>` type, such as `..`
    - `view::Label` now implements `PartialEq` with `[u8]` and `[u8; N]`
    - `view::Label::literal` now returns lifetime of source (`'s`) rather than lifetime of `&self`
    - `Plain` and `Pretty` formatters now implement `Debug`, not just `Display`
- `OPCODE`
    - added “DSO”, number 6
    - fixed incorrect numbering of “Notify” and “Update” as 3 and 4 (now 4 and 5)
- `RCODE`
    - added “DSOTYPENI”, number 11
    - added “BADCOOKIE”, number 23
    - fixed incorrect naming of 6 as “BADTYPE” (now “BADTIME”)


## Breaking changes


- **note: there are a great deal of breaking changes, but we have tried to list as many as possible below**
- `emit::Buffer` has been migrated from [arrayvec]https://crates.io/crates/arrayvec 0.5 to 0.7
    - to migrate, replace the following
        - `ArrayVec::<[u8; N]>``ArrayVec::<u8, N>`
        - `<A: Array<Item = u8>> ArrayVec::<A>``<const N: usize> ArrayVec::<u8, N>`
- `const` has been merged into `core` and reworked to...
    - rename `Names::{name,number}` to `NamedConstants::to_{name,number}` for clarity
    - give `RCODE` explicit support for the context-sensitive value 16 (BADVERS or BADSIG)
        - use `RCODE::to_name_opt` or `RCODE::to_name_tsig` instead of `to_name`
- `emit` has been reworked to...
    - borrow rather than own its output buffers
        - `Builder` and its concrete types are now marked `#[must_use]`
        - to migrate, declare the buffer separately, then pass it with `&mut` to `Sink` and the builder chain
    - ensure that questions and records contain exactly one QNAME and NAME respectively
        - `NameError` has two new variants, `Question` and `Record`
        - to migrate `NameBuilder` usage in question QNAME, replace `.finish()?.finish(...)?` with `.finish_question(...)?`
        - to migrate `NameBuilder` usage in record NAME, replace `.finish()?.try_into_data()?` with `.try_into_rdata()?`
        - to migrate `NameBuilder` usage in record RDATA, replace `.finish()?` with `.return_to_rdata()?`
    - ensure that extended RCODE values are correctly split between message header and EDNS OPT RR
        - `MessageBuilder::finish` returns `ExtensionRequired` error with non-zero extended part but no EDNS OPT RR
        - to migrate, replace `.finish()` with `.finish()?`
    - use the consistent term “step” for state machine states
        - `message::QuestionSection` was renamed to `QuestionStep`
        - `message::RecordSection` was renamed to `RecordStep`
- `view` has been reworked to...
    - include the EDNS version (if any) in errors for malformed messages
        - `MessageError` is now a struct wrapping the old enum, which is now `MessageErrorKind`
    - use the new `core::{Opcode,Rcode,Serial}` types for OPCODE, (extended) RCODE, and SOA SERIAL
        - `Header::opcode` now returns `core::Opcode`
        - `Message::rcode` now returns `core::Rcode`
        - `Soa::serial` now returns `core::Serial`
    - use the `core::Ttl` type more consistently
        - `Record::ttl` now returns `core::Ttl`
        - `Soa::{refresh,retry,expire,minimum}` now return `core::Ttl`
    - remove the `Type` and `Class` views in favour of `core::{Type,Class}`
        - `Question::qtype` and `Record::r#type` now return `core::Type`
        - `Question::qclass` and `Record::class` now return `core::Class`
    - make it easier to distinguish the null label from other labels
        - `Label::literal` now returns `None` for the null label
- `zone` has been renamed to `fmt`


# [bore 0.4.1]https://codeberg.org/shuppy/nonymous/src/tag/bore-0.4.1/bore (2021-11-28)


- fixed bug where positional argument `@<host>` was ignored


# [bore 0.4.0]https://codeberg.org/shuppy/nonymous/src/tag/bore-0.4.0/bore (2021-11-28)


- new positional argument `@<host>` as a shorthand for `--host <host>`
- positional arguments can now be given in any order, including `<type>` before `<name>`
- added hint to improve error message when `-x` (`--reverse`) given without name


## Breaking changes


- positional argument `<name>`
    - now requires at least one dot or colon, e.g. use `mx.` to query the top-level domain “mx”
    - now requires leading `@` to be escaped, e.g. use `\@.example` to query the name `@.example`


## Project changes


- CI migrated from Bitbucket Pipelines to Bamboo ([bamboo.daz.cat]https://bamboo.daz.cat)
- [commit checks]https://bamboo.daz.cat/browse/NO-COMM now include OpenBSD (x64) and Windows (x64 + x86) in addition to Linux x64 (MSRV + nightly)
- [test coverage]https://bamboo.daz.cat/browse/NO-TCOV is now being calculated again, with cargo-tarpaulin 0.18.0 instead of 0.9.3


# [0.3.3]https://codeberg.org/shuppy/nonymous/src/tag/0.3.3 (2021-07-05)


## bore


- Windows: use ENABLE_VIRTUAL_TERMINAL_PROCESSING to ensure that `--color` works natively
- Unix: fixed a bug where SIGPIPE might cause a visible panic (especially on macOS)
- OpenBSD: fixed pledge(2) promises for `--show-resolvers` (was broken in 0.3.0)
- added scripts to check for regressions on non-CI platforms (Windows + macOS + OpenBSD)


# [0.3.2]https://codeberg.org/shuppy/nonymous/src/tag/0.3.2 (2021-07-05)


## bore


- OpenBSD: fixed pledge(2) promises for `--decode` (regression in 0.3.1)


# [0.3.1]https://codeberg.org/shuppy/nonymous/src/tag/0.3.1 (2021-07-05)


## bore


- fixed bug where failure to gather default resolvers would break `--decode`
    - this is necessary for a useful installCheckPhase in the Nix derivation
    - note that failure otherwise remains fatal unless `--host` is given


# [0.3.0]https://codeberg.org/shuppy/nonymous/src/tag/0.3.0 (2021-07-04)


- nonymous-scoop was removed (0.0.2 was the last version)
    - please install [bore]https://crates.io/crates/bore instead
- nonymous + bore: increased minimum Rust version from 1.39 to 1.46
- nonymous + bore: the “strict” package feature has been removed in favour of `#[cfg(ci_)]`
    - use `RUSTFLAGS='--cfg ci'` instead of `--feature strict` to build these crates with `#[deny(warnings)]`
- nonymous + bore: `Label` now displays symbols other than `-_;` and space in the more compact `\;` format


## Conformance


- nonymous + bore: IPv6 addresses are now displayed in canonical format ([RFC 5952]https://datatracker.ietf.org/doc/html/rfc5952)
- nonymous + bore: `NameBuilder::labels` and &lt;host> argument now parse names in zone format (supporting escapes)


## nonymous


- removed all hard dependencies on `alloc` and `std` outside of tests
    - `Record::{rdata, try_rdata}` now return non-exhaustive enum instead of `Box<dyn>`
    - `Type` and `Class` name/value maps are now backed by compile-time sorted arrays
    - all tests except one now run in `#![no_std]` without `alloc` (but not benches)
    - all `alloc`/`std`-dependent features in dependencies are now disabled or feature-gated
    - CI runs a new test (nonono) that will fail to compile given any future regressions
- fixed broken links in rustdoc for `view` iterator types and some `MessageBuilder` methods


## bore


- new option `--show-resolvers` lists resolver hosts and ports that would be used
- new option `--reverse` (`-x`) makes a reverse DNS query (in-addr.arpa. or ip6.arpa.)
- new option `--color` highlights output to draw your attention to important parts
- new option `--man` views detailed docs compiled into the binary
- crate now uses [pledge(2)]https://man.openbsd.org/OpenBSD-6.3/pledge.2 + [unveil(2)]https://man.openbsd.org/OpenBSD-6.4/unveil.2 for security on OpenBSD
- crate now gathers system resolvers with GetAdaptersAddresses on Windows
- crate now gathers system resolvers with dns_configuration_copy on macOS
- crate now uses [eyre]https://crates.io/crates/eyre for error reporting (was [failure]https://crates.io/crates/failure)
- crate now correctly reports nested errors with full source chains (causes)
- crate now has meaningful error messages on every fallible code path
- crate can no longer be consumed as a library (was a hack for nonymous-scoop)


## Breaking changes


- **note: there are a great deal of breaking changes, but we have tried to list as many as possible below**
- error handling has been reworked
    - all error types now implement std::error::Error where available (was [failure]https://crates.io/crates/failure::Error)
        - note: without the “std” feature, `view::rdata::RdataError` discards original error for now
    - all error messages have been rewritten and improved with the help of [displaydoc]https://crates.io/crates/displaydoc
    - `emit::BoundsError` is now an enum with three tuple variants (was unit struct)
    - `emit::NameError` new variants: DecimalEscapeRange, DecimalEscapeSyntax, UnfinishedEscape, UnfinishedLabel
- `emit` has been reworked and simplified to a new panic-free API with fallible packet writing
    - `Sink` now replaces `RootBuilder` and `RootBuildee` as the top of the builder hierarchy
    - eliminated the distinction between `Buildee` (no `Sink`) and `Builder` (buildee plus sink)
    - `Sink::new` has been split into `TryFrom::from` (no limit) and `Sink::with_limit` (limit: u16)
    - `Sink` growth is now fallible with a new `GrowError` type (previously panicking)
    - `Sink` creation is now fallible with a new `SinkError` type (previously panicking)
    - `NewBuilder::new` is now fallible in the same way as `Sink` creation
- `view`: zone-like view formatting has been moved to `crate::zone`
    - to migrate, wrap view objects in a `Plain`, then `Display` as usual
- `NameBuilder::labels` now requires trailing dot and rejects lone dot (bore is unaffected)
- `NameBuilder::labels` now takes a `&[u8]` rather than a `&str`
    - for the old behaviour, pass `str` arguments through `str::as_bytes`


# [0.0.2]https://codeberg.org/shuppy/nonymous/src/tag/0.0.2 (2021-01-03)


## Breaking changes


- scoop(1) ([nonymous-scoop]https://crates.io/crates/nonymous-scoop) was renamed to bore(1) ([bore]https://crates.io/crates/bore)
    - you can still install nonymous-scoop if you want scoop(1), but this version will be the last
- nonymous: increased minimum Rust version from 1.37 to 1.39
- nonymous: `crate::emit` was rewritten from scratch (pull request #2)
    - for an example of how to migrate, see bore/src/main.rs
    - API is now zero-copy, `#![no_std]` compatible, and harder to misuse
    - you can pass a packet size limit to `Sink`, for UDP and similar use cases
- nonymous: `crate::NeverError` was removed (but it was only used by the old `crate::emit`)
- nonymous: `crate::emit::{Type, TypeError}` were moved to `crate::core::{Type, TypeFromStrError}`
- nonymous: `crate::emit::{Class, ClassError}` were moved to `crate::core::{Class, ClassFromStrError}`
- nonymous: `crate::emit::{Ttl, TtlError}` were moved to `crate::core::{Ttl, TtlFromStrError}`
- nonymous: `NameBuilder::label` (moved from `Name::parent`) now takes a `&[u8]` rather than a `&str`
    - for the old behaviour, pass `str` arguments through `str::as_bytes`


## Issues


- fixed bug where RecordError::Bounds display message is incomplete (issue #1)
- added code coverage checks, currently disabled by default due to [a CI problem] issue #2
- fixed bug where `nonymous::emit::Name` doesn’t accept arbitrary binary labels (issue #3)


[a CI problem]: https://twitter.com/dazabani/status/1201527372740096000


## bore


- new options: `--encode` + `--decode` + `--dump` + `--load`
- crate is now built against Rust 1.39.0 on CI (was nightly-2019-09-13)
- crate now uses the stable Tokio 0.2 API (was 0.2.0-alpha.4)


# [0.0.1]https://codeberg.org/shuppy/nonymous/src/tag/0.0.1 (2019-09-29)


## Breaking changes


- `nonymous::emit::Record::new` is now fallible, failing when the given `rdata` is too long
- `nonymous::view::ExtensionError` removes the unused `Bounds` variant
- `nonymous::view::Len` was removed
    - for the old behaviour, replace `Len::len` calls with `View::len` calls
- `nonymous::view::Record::rdata` is now infallible, returning `Malformed` as a last resort
    - for the old behaviour, rename `Record::rdata` calls to `Record::try_rdata`
- `nonymous::view::Record::rdata_offset` was removed
    - for the old behaviour, replace calls with `Record::rdata_range(x).start`
- `nonymous::view::View` adds a required `fn len`


## nonymous


- crate is now `#![forbid(unsafe_code)]`
- `crate::view` error types now have meaningful error messages
- crate moves [assert_matches] from `[dependencies]` to `[dev-dependencies]`
- crate cleans up unwrap calls outside of tests and benches
- crate cleans up FIXME sites for `as {integer}` casts


## nonymous-scoop


- crate is now `#![forbid(unsafe_code)]`
- scoop(1) now uses `Display` to report fatal errors and their causes
- crate moves [assert_matches] from `[dependencies]` to `[dev-dependencies]`
- crate bumps tokio to 0.2.0-alpha.4 explicitly
- crate cleans up unwrap calls outside of tests and benches


[assert_matches]: https://crates.io/crates/assert_matches


# [0.0.0]https://codeberg.org/shuppy/nonymous/src/tag/0.0.0 (2019-09-16)


## nonymous


- initial release with view and emit modules


## nonymous-scoop


- initial release with resolv.conf(5) support