Hornet
Project Status
CI/CD Status
Code Quality
Technology
Security
Community
A fast, comprehensive Rust library for parsing, writing, and
validating BIND9 named.conf configuration
files and DNS zone files.
Features
| Capability | Details |
|---|---|
Parse named.conf |
options, zone, view, acl, logging, controls, key, primaries/masters, server |
| Parse zone files | A, AAAA, NS, MX, SOA, CNAME, PTR, TXT, SRV, CAA, SSHFP, TLSA, NAPTR, DS, DNSKEY, RRSIG, NSEC, HTTPS/SVCB, and unknown types |
| Write / format | Round-trip serialisation with configurable indentation and keyword normalisation |
| Validate | Semantic checks (undefined ACLs, duplicate zones, missing SOA/NS, CIDR correctness, …) |
| CLI tool | parse, zone, check, check-zone, fmt, convert subcommands |
| Error reporting | Rich diagnostics via miette |
| Modern keyword aliases | Automatically rewrite master → primary, slave → secondary |
Performance
Hornet is built on winnow parser combinators and processes DNS config files at memory-bandwidth speeds. Benchmarks measured with Criterion.rs on Apple M-series / macOS:
named.conf parsing
| Input | Median time | Throughput |
|---|---|---|
| Single options block (60 B) | 596 ns | 102 MiB/s |
| Simple server — options + 3 zones (~700 B) | 7.9 µs | 87 MiB/s |
| Production config — views + ACLs + 11 zones (~2.8 KB) | 34 µs | 81 MiB/s |
| Large deployment — 100 zones (~12 KB) | 218 µs | 54 MiB/s |
| Stress — 10 000 zones (~1.3 MB) | 1.19 s | 1.02 MiB/s |
| Stress — 50 000 zones (~6.5 MB) | 30.5 s | 207 KiB/s |
Zone file parsing
| Input | Median time | Throughput |
|---|---|---|
| Minimal zone — SOA + NS + 2 A records (~200 B) | 2.1 µs | 85 MiB/s |
| Typical domain — 20 records, all major types (~1 KB) | 8.4 µs | 134 MiB/s |
| Medium zone — 1 000 A records (~55 KB) | 228 µs | 99 MiB/s |
| Large zone — 10 000 A records (~550 KB) | 2.3 ms | 104 MiB/s |
Zone file throughput stays in the 85–134 MiB/s band across four orders of magnitude of input, demonstrating the linear-time behavior of the parser. See the Benchmarks reference for the full table including write and validation timings.
Installation
Library
[]
= "0.1"
CLI
Quick start
Parse a named.conf
use parse_named_conf;
let input = r#"
options {
directory "/var/cache/bind";
recursion yes;
allow-query { any; };
};
zone "example.com" {
type primary;
file "/etc/bind/zones/example.com.db";
};
"#;
let conf = parse_named_conf?;
println!;
Parse a zone file
use parse_zone_file;
let zone_text = r#"
$ORIGIN example.com.
$TTL 1h
@ IN SOA ns1 admin (2024010101 1d 2h 4w 5m)
@ IN NS ns1.example.com.
@ IN A 93.184.216.34
"#;
let zone = parse_zone_file?;
for record in zone.records
Validate
use ;
let conf = parse_named_conf?;
let diags = validate_named_conf;
for d in &diags
Write / format
use ;
use WriteOptions;
let conf = parse_named_conf?;
let opts = WriteOptions ;
let formatted = write_named_conf;
println!;
CLI
Usage: hornet <COMMAND>
Commands:
parse Parse a named.conf and print formatted output [alias: p]
zone Parse a zone file and print formatted output [alias: z]
check Validate a named.conf, print diagnostics [alias: c]
check-zone Validate a zone file
fmt Reformat a named.conf in-place
convert Convert legacy keywords (master→primary, etc.)
help Print help
Examples
# Parse and pretty-print
# Validate (exits 1 on errors/warnings)
# Format in-place
# Check only — don't write (useful in CI)
# Migrate legacy keywords
# Validate a zone file
Supported BIND9 constructs
named.conf statements
options { … };— full option block including listen-on, forwarders, allow-* ACLs, dnssec-validation, rate-limit, response-policy, …zone "name" [class] { … };— all zone types: primary/master, secondary/slave, stub, forward, hint, redirect, delegation, in-viewview "name" [class] { … };— with nested zonesacl "name" { … };logging { channel … ; category … ; };controls { inet … ; };key "name" { algorithm; secret; };primaries / masters "name" { … };server addr { … };include "path";- Unknown blocks preserved verbatim
Zone file record types
A, AAAA, NS, MX, SOA, CNAME, PTR, HINFO, TXT, SRV, CAA, SSHFP, TLSA, NAPTR, LOC, DS, DNSKEY, RRSIG, NSEC, NSEC3, NSEC3PARAM, HTTPS, SVCB, ANAME/ALIAS, TYPE<N> fallback
Zone file directives
$ORIGIN, $TTL, $INCLUDE, $GENERATE
Feature flags
| Flag | Default | Effect |
|---|---|---|
serde |
off | Adds Serialize/Deserialize to all AST types |
Project layout
hornet/
├── src/
│ ├── ast/ # AST definitions
│ │ ├── named_conf.rs
│ │ └── zone_file.rs
│ ├── parser/ # winnow parsers
│ │ ├── common.rs
│ │ ├── named_conf.rs
│ │ └── zone_file.rs
│ ├── writer/ # Serialisers
│ │ ├── named_conf.rs
│ │ └── zone_file.rs
│ ├── validator/ # Semantic checks
│ │ └── mod.rs
│ ├── error.rs
│ ├── lib.rs
│ └── main.rs # CLI binary (cli feature)
├── tests/
│ ├── named_conf.rs
│ └── zone_file.rs
├── .github/workflows/
├── Cargo.toml
└── README.md
Contributing
Contributions are welcome! Please open an issue or pull request on GitHub.
When adding support for a new statement or record type:
- Add the AST type(s) to
src/ast/ - Add a parser in
src/parser/ - Add a writer in
src/writer/ - Add validation rules in
src/validator/ - Add integration tests in
tests/
License
Licensed under the MIT License.