Numa becomes a true DNS resolver — resolves from root nameservers with complete DNSSEC chain-of-trust verification. Recursive resolution: - Iterative RFC 1034 from configurable root hints (13 default) - CNAME chasing (depth 8), referral following (depth 10) - A+AAAA glue extraction, IPv6 nameserver support - TLD priming: NS + DS + DNSKEY for 34 gTLDs + EU ccTLDs - Config: mode = "recursive" in [upstream], root_hints, prime_tlds DNSSEC (all 4 phases): - EDNS0 OPT pseudo-record (DO bit, 1232 payload per DNS Flag Day 2020) - DNSKEY, DS, RRSIG, NSEC, NSEC3 record types with wire read/write - Signature verification via ring: RSA/SHA-256, ECDSA P-256, Ed25519 - Chain-of-trust: zone DNSKEY → parent DS → root KSK (key tag 20326) - DNSKEY RRset self-signature verification (RRSIG(DNSKEY) by KSK) - RRSIG expiration/inception time validation - NSEC: NXDOMAIN gap proofs, NODATA type absence, wildcard denial - NSEC3: SHA-1 iterated hashing, closest encloser proof, hash range - Authority RRSIG verification for denial proofs - Config: [dnssec] enabled/strict (default false, opt-in) - AD bit on Secure, SERVFAIL on Bogus+strict - DnssecStatus cached per entry, ValidationStats logging Performance: - TLD chain pre-warmed on startup (root DNSKEY + TLD DS/DNSKEY) - Referral DS piggybacking from authority sections - DNSKEY prefetch before validation loop - Cold-cache validation: ~1 DNSKEY fetch (down from 5) - Benchmarks: RSA 10.9µs, ECDSA 174ns, DS verify 257ns Also: - write_qname fix for root domain "." (was producing malformed queries) - write_record_header() dedup, write_bytes() bulk writes - DnsRecord::domain() + query_type() accessors - UpstreamMode enum, DEFAULT_EDNS_PAYLOAD const - Real glue TTL (was hardcoded 3600) - DNSSEC restricted to recursive mode only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
47 lines
1.3 KiB
TOML
47 lines
1.3 KiB
TOML
[package]
|
|
name = "numa"
|
|
version = "0.5.0"
|
|
authors = ["razvandimescu <razvan@dimescu.com>"]
|
|
edition = "2021"
|
|
description = "Portable DNS resolver in Rust — .numa local domains, ad blocking, developer overrides, DNS-over-HTTPS"
|
|
license = "MIT"
|
|
repository = "https://github.com/razvandimescu/numa"
|
|
keywords = ["dns", "dns-server", "ad-blocking", "reverse-proxy", "developer-tools"]
|
|
categories = ["network-programming", "development-tools"]
|
|
|
|
[dependencies]
|
|
tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "time"] }
|
|
axum = "0.8"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
toml = "0.8"
|
|
log = "0.4"
|
|
env_logger = "0.11"
|
|
reqwest = { version = "0.12", features = ["rustls-tls", "gzip", "http2"], default-features = false }
|
|
hyper = { version = "1", features = ["client", "http1", "server"] }
|
|
hyper-util = { version = "0.1", features = ["client-legacy", "http1", "tokio"] }
|
|
http-body-util = "0.1"
|
|
futures = "0.3"
|
|
socket2 = { version = "0.5", features = ["all"] }
|
|
rcgen = { version = "0.13", features = ["pem", "x509-parser"] }
|
|
time = "0.3"
|
|
rustls = "0.23"
|
|
tokio-rustls = "0.26"
|
|
arc-swap = "1"
|
|
ring = "0.17"
|
|
|
|
[dev-dependencies]
|
|
criterion = { version = "0.5", features = ["html_reports"] }
|
|
|
|
[[bench]]
|
|
name = "hot_path"
|
|
harness = false
|
|
|
|
[[bench]]
|
|
name = "throughput"
|
|
harness = false
|
|
|
|
[[bench]]
|
|
name = "dnssec"
|
|
harness = false
|