DDNS
ddns provides DNS discovery and resolver support for DHTTP applications. It is a
single Rust package: the historical ddns-core, gmdns, ddns, and
ddns-server crate boundaries now live as modules and feature-gated targets in
one published Cargo package named dyns, with a library target kept as ddns
for source compatibility.
Crate layout
| Module / target | Role |
|---|---|
ddns::core |
DNS packet parser, resource-record types, endpoint E record encoding, and HTTP multi-record response wire format. |
ddns::mdns |
RFC 6762 multicast DNS transport, LAN publisher, and LAN resolver support. |
ddns::resolvers |
Resolver chain plus optional System, mDNS, DNS-over-H3, and DNS-over-HTTP resolvers. |
ddns::publisher |
Feature-gated endpoint record signing and publishing loop helpers for DHTTP endpoints. |
ddns-server |
DNS-over-H3 publish/lookup server binary, enabled by the server feature. |
ddns is endpoint-facing support code for the DHTTP ecosystem. Applications
normally reach it through the dhttp endpoint facade; lower-level consumers can
depend on package dyns directly (typically renamed locally to ddns) when
they need DNS wire types, resolver composition, mDNS, or the DNS-over-H3 server.
= { = "dyns", = "0.3.0" }
Features
All optional integrations are feature-gated; the default feature set is empty.
| Feature | Enables |
|---|---|
h3x-resolver |
DNS-over-H3 resolver and publisher using h3x/dquic. |
mdns-resolver |
mDNS resolver integration backed by an existing h3x::dquic::Network. |
http-resolver |
DNS-over-HTTP resolver/publisher using reqwest and native roots. |
server |
ddns-server, Redis storage support, TOML config parsing, and tracing setup. |
Bootstrap constants
build.rs generates the resolver defaults exposed from ddns::resolvers:
| Environment variable | Public constant | Fallback when unset |
|---|---|---|
DHTTP_H3_DNS_SERVER |
DHTTP_H3_DNS_SERVER |
https://dhttp.example.net |
DHTTP_HTTP_DNS_SERVER |
DHTTP_HTTP_DNS_SERVER |
https://dhttp.example.net |
DHTTP_MDNS_SERVICE |
DHTTP_MDNS_SERVICE |
dhttp.example.net |
The fallbacks are docs/build placeholders, not operational defaults. Real endpoint, server, and E2E runs should set the DHTTP bootstrap environment before building.
Quick start
Resolver chain
Resolvers queries all configured resolvers and streams endpoint addresses from
successful backends. System DNS is always available; mDNS, H3, and HTTP builders
appear behind their features.
use Resolvers;
use StreamExt;
async
mDNS discovery
use ;
use StreamExt;
async
Runnable examples live in examples/:
DNS-over-H3 examples
See examples/README.md for the example CLI parameters
and response decoding notes.
DNS-over-H3 server
Start the server with the server feature:
The server exposes two HTTP/3 routes:
| Route | Meaning |
|---|---|
POST /publish?host=<name> |
Publish a DNS packet for host. Client mTLS is required. |
GET /lookup?host=<name>[&limit=N] |
Look up active records for host; limit caps newest-first dynamic records. |
Lookup responses use header x-record-format: multi and the binary body from
ddns::core::wire::MultiResponse:
u32 count
repeated count times:
u32 dns_len | dns packet bytes | u32 cert_len | DER publisher certificate bytes
Server configuration lives in server.toml:
- storage is in-memory by default, or Redis when
redis = "redis://..."is set; ttl_secscontrols dynamic record expiry;require_signaturecontrols signed endpoint-record enforcement for Standard domains;domain_policiesare matched in order, with unlisted domains using the Standard policy;seed_recordsadd static bootstrap endpoints to lookup results.
Domain policies:
| Policy | Behavior |
|---|---|
standard |
Client certificate DNS SAN must match the published host; signed E records are required when require_signature = true; each certificate fingerprint owns one active record for the host. |
open_multi |
Any authenticated client certificate may publish; signature checks are skipped; multiple certificate fingerprints can coexist and lookup returns newest-first records. |
Public DHTTP identity hostnames should use the canonical DhttpName::SUFFIX
(.dhttp.net). Infrastructure names such as nat.genmeta.net can remain under
Genmeta infrastructure domains.
Endpoint E records
Custom DNS record type E (QTYPE = 266) carries DHTTP endpoint addresses. The
current wire format is:
flags(u8)
[sequence(varint) if CLUSTERED]
primary address: port(u16) + IPv4/IPv6 bytes
[agent address if NAT]
[load(f32) if LOAD]
[signature: scheme(u16) + len(varint) + bytes if SIGNED]
Flag bits:
| Bit mask | Name | Meaning |
|---|---|---|
0x80 |
FAMILY |
0 = IPv4, 1 = IPv6. |
0x40 |
MAIN |
Primary endpoint for the name. |
0x20 |
CLUSTERED |
Sequence number is present; multiple publishers share the name. |
0x10 |
NAT |
Agent address is present for NAT traversal. |
0x08 |
LOAD |
One-minute load value is present. |
0x01 |
SIGNED |
Signature with explicit TLS signature scheme is present. |
For DHTTP endpoint publishing, MAIN and sequence are derived from the
publisher certificate's DHTTP subject key identifier. Operators do not choose
these fields manually: primary certificates publish MAIN = true,
secondary certificates publish MAIN = false, and the certificate-chain
sequence becomes the normalized endpoint-record sequence. An omitted sequence
field means sequence 0.
Signed records encode the signature scheme in the record; the no-scheme signed format is not accepted. Legacy unsigned fixed-length endpoint address records are still parsed by length for address-only compatibility.
Project structure
src/core.rs DNS core module root
src/core/parser/ DNS packet, name, question, record, varint, and signature parsers
src/core/parser/record/ A/AAAA/SRV/TXT/PTR/CNAME/E record parsing and encoding
src/core/wire.rs HTTP multi-record response wire format
src/mdns.rs mDNS module root
src/mdns/protocol.rs UDP multicast socket and packet routing
src/mdns/service.rs High-level mDNS service API
src/mdns/resolvers/ mDNS resolver integration
src/resolvers.rs Resolver chain and resolver defaults
src/resolvers/h3.rs DNS-over-H3 resolver/publisher
src/resolvers/http.rs DNS-over-HTTP resolver/publisher
src/resolvers/deferred.rs Deferred resolver initialization helper
src/publisher.rs Endpoint record signer and publication loop
src/publisher/ Address selection, publish dispatch, packet signing
src/bin/ddns-server/ DNS-over-H3 server implementation
examples/ mDNS and DNS-over-H3 example programs
server.toml Example server configuration