dnsbox
High-performance DNS message parsing and building for Rust — queries and
responses, zero-copy, no_std, with broad RFC extension coverage (EDNS(0),
DNSSEC, SVCB/HTTPS, TSIG, and more).
Status: pre-1.0. Wire formats, EDNS(0), DNSSEC, SVCB/HTTPS, TSIG and the long tail of record types are implemented; the API may still change. See the roadmap for what is left before 1.0 (rustdoc examples everywhere, the final threat model, the stability policy).
Goals
- Safe on hostile input — no panics, no out-of-bounds reads,
#![forbid(unsafe_code)]. - Zero-copy parsing — messages are views over your buffer; names and record data decode lazily.
- Fast building — write straight into a caller-supplied buffer with name compression and truncation handled for you.
no_std—allocandstdare optional features.
Example
use ;
use ;
EDNS(0): a query and the response echo
use ;
use ;
use Aaaa;
SVCB / HTTPS
use Https;
Zone files
use ZoneReader;
What is covered
- Core (RFC 1035, 3596, 3597, 2181, 4343): zero-copy
Messageviews, hardened name decompression, whole-message validation, a compressing builder with atomic pushes, RRset-level truncation (TC) and size limits, query/response constructors, TCP framing and stream reassembly. - EDNS(0) (RFC 6891): OPT view and builder, extended RCODE, DO/CO flags, the full option-code registry and typed options — Client Subnet, Cookies (with RFC 9018 server cookies), Padding with RFC 8467 policies, TCP keepalive, Extended DNS Errors, NSID, Chain, Key tag, Expire, Zone version, Report-Channel, DAU/DHU/N3U.
- Record types: about 80 typed RDATA formats — the RFC 1035 set, SRV,
NAPTR, CAA, SSHFP, TLSA, SMIMEA, OPENPGPKEY, DNAME, URI, CERT, DHCID, LOC,
RP, AFSDB, ILNP, EUI48/64, CSYNC, ZONEMD, APL, IPSECKEY, HIP, KX, SVCB and
HTTPS (all RFC 9460 SvcParams), the DNSSEC types and the legacy types —
each with presentation-format
Display; unknown types round-trip. - DNSSEC (RFC 4033–4035, 5155, 6840): canonical form and RRset order,
key tags, DS digests, NSEC3 hashing, RRSIG validation logic, the chain of
trust (DS → DNSKEY → RRset, wildcard expansions), NSEC/NSEC3
denial-of-existence proofs (NXDOMAIN, NODATA, wildcards, unsigned
delegations, Opt-Out, RFC 9276 iteration limits), ZONEMD zone digests
(RFC 8976), and with the
dnssecfeature RSA, ECDSA P-256/P-384, Ed25519 and Ed448 verification and signing. - Zone files (RFC 1035 §5): a streaming, allocation-free master-file
reader (
$ORIGIN,$TTL,$INCLUDE, BIND's$GENERATE, TTL units, RFC 3597 generic RDATA, errors with line and column) and presentation-format parsing of RDATA (ParseRdataText). - Transactions and zone transfer: TSIG (RFC 8945), SIG(0) (RFC 2931), dynamic UPDATE (RFC 2136), NOTIFY (RFC 1996), AXFR/IXFR (RFC 5936, RFC 1995) stream processing, DNS Stateful Operations (RFC 8490).
- Text and owned data:
dig-styleDisplayof whole messages (no allocation, matches BIND'sdigline for line), ownedOwnedMessage/OwnedRecord/OwnedRDatatypes (alloc) andserdesupport.
Features
| Feature | Default | What it adds |
|---|---|---|
std |
yes | std::io TCP helpers, $INCLUDE from the file system (implies alloc) |
alloc |
Vec-backed builders, owned message types (OwnedMessage, ...) |
|
dnssec-digest |
DS digests and NSEC3 hashing (no alloc); ZONEMD digests (with alloc) |
|
dnssec |
DNSSEC and SIG(0) signature verification and signing (implies alloc, dnssec-digest) |
|
tsig |
TSIG HMAC backend (HMAC-MD5/SHA-1/SHA-2) | |
cookie-siphash |
RFC 9018 server cookie generation and verification | |
serde |
Serialize/Deserialize (no_std): protocol numbers as mnemonics, names as text, owned types with alloc |
dnsbox never implements cryptography itself: the crypto features pull in
the optional, no_std-capable purecrypto
crate. Every crypto-using API sits behind a trait, so other backends can be
plugged in, and all wire-format work (signed data, MAC input, canonical
forms) is available without these features.
See ARCHITECTURE.md for the design and extension guide.
Assurance and performance
dnsbox is continuously fuzzed (fuzz/), property-tested, and
checked against real responses from BIND, NSD, Knot, PowerDNS, Unbound and
public resolvers (tests/corpus/). Benchmarks against
hickory-proto and domain are in BENCH.md.
Minimum supported Rust version
Rust 1.89, edition 2024.
License
MIT — see LICENSE.