Expand description
mdns-proto
§Introduction
mdns-proto implements Multicast DNS (RFC 6762) and DNS-SD (RFC 6763) —
probing, conflict resolution, periodic announcement, known-answer suppression,
cache coherency, and response generation — as deterministic state machines that
perform no I/O of their own.
You feed inbound datagrams and timer ticks in via Endpoint::handle /
Endpoint::handle_timeout and drain outbound datagrams via
Endpoint::poll_transmit — the same Sans-I/O shape as quinn-proto. This
keeps the protocol logic portable and exhaustively testable: the same core runs
under any async runtime, on bare metal, or inside a fuzzer.
The async driver crates in the hick family (hick-reactor,
hick-compio, plus the bare-metal hick-smoltcp / hick-embassy) are
thin layers over this crate. Most applications want one of those, or the
hick facade, rather than this core directly.
§Feature tiers
std and alloc are independent features, so the crate scales from a full
std host down to bare metal with no allocator:
| Features | Environment |
|---|---|
std (default) | std hosts (e.g. tokio, smol) |
alloc | no_std with a global allocator (Embassy, RTIC, ESP-IDF, wasm32) |
no-atomic | no_std + allocator on cores without native atomic CAS (Cortex-M0+ / thumbv6m / RP2040): same Endpoint as alloc, but the refcounted Name / rdata use portable-atomic’s Arc (clone via a critical-section impl the binary provides) instead of smol_str + bytes. Mutually exclusive with alloc / std; no stats. |
heapless | no_std, fixed-capacity collections, no allocator |
| (none) | bare-metal no_std, no heap at all |
Other features:
| Feature | Description |
|---|---|
slab (default) | Slab-backed state pools for the protocol machines. |
tracing | Emit structured tracing events/spans internally (queries, cache, probing, conflicts). |
stats | Enable no_std-safe atomic counters; expose a snapshot via endpoint.stats(). Requires alloc. |
metrics | Bridge counters to the metrics facade (Prometheus/StatsD). Implies stats. Requires alloc. |
§Installation
[dependencies]
mdns-proto = "0.2" # std + slab
# no_std + alloc:
mdns-proto = { version = "0.2", default-features = false, features = ["alloc"] }
# no_std + alloc on a core WITHOUT native atomics (Cortex-M0+ / RP2040):
mdns-proto = { version = "0.2", default-features = false, features = ["no-atomic"] }
# bare no_std (no allocator):
mdns-proto = { version = "0.2", default-features = false }§Observability
§tracing
Enable mdns-proto = { …, features = ["tracing"] }. The state machine emits
structured tracing events (at DEBUG / INFO / WARN) during probing,
conflict resolution, cache inserts/evictions, query state transitions, and
service registration. Wire a subscriber in your application:
tracing_subscriber::fmt().init();§stats — atomic counters
Enable features = ["stats"] (requires alloc). Endpoint::stats() returns
a hick_trace::stats::StatsSnapshot:
let snap = endpoint.stats();
println!("packets_rx={} cache_size={}", snap.packets_rx, snap.cache_size);StatsSnapshot is a plain Copy struct of u64 fields. Counters include
packets_rx/tx, bytes_rx/tx, packets_dropped, parse_errors,
questions_rx, answers_rx/collected, cache_inserts/refreshes/evictions/ expirations, queries_started/done/timeout, services_registered/ established, conflicts, renames, responses_tx, probes_tx,
announcements_tx, goodbyes_tx, and gauges cache_size, queries_active,
services_active.
§metrics
Enable features = ["metrics"] (implies stats; requires alloc). Every
counter/gauge update is forwarded to the metrics facade so Prometheus,
StatsD, or any other exporter receives the data automatically.
§The hick family
hick (facade) · mdns-proto (this crate) · hick-udp (UDP) ·
hick-reactor (tokio / smol driver) · hick-compio (compio driver) ·
hick-smoltcp (smoltcp engine) · hick-embassy (embassy driver).
§License
mdns-proto is under the terms of both the MIT license and the Apache License
(Version 2.0).
See LICENSE-APACHE, LICENSE-MIT for details.
Copyright (c) 2025 Al Liu.
Re-exports§
pub use pool::Pool;pub use time::Instant;pub use handle::QueryHandle;pub use handle::ServiceHandle;pub use name::LabelTooLongDetail;pub use name::NameError;pub use name::NameTooLongDetail;pub use name::Name;allocorheaplessorno-atomicorstdpub use error::BufferTooShortDetail;pub use error::BufferTooSmallDetail;pub use error::EncodeError;pub use error::HandleError;pub use error::HandleTimeoutError;pub use error::ParseError;pub use error::PointerForwardDetail;pub use error::RdlengthOverrunDetail;pub use error::StartQueryError;pub use error::StorageFullError;pub use error::TransmitError;pub use error::CancelQueryError;allocorno-atomicorstdpub use error::HandleServiceRenamedError;allocorno-atomicorstdpub use error::RegisterServiceError;allocorno-atomicorstdpub use event::EndpointEvent;pub use event::HostConflict;pub use event::KnownAnswer;pub use event::ProbeConflict;pub use event::QueryEvent;pub use event::QueryUpdate;pub use event::RouteEvent;pub use event::ServiceEvent;pub use event::ServiceQuestion;pub use event::ToQuery;pub use event::ToService;pub use transmit::Transmit;pub use event::ServiceRenamed;allocorheaplessorno-atomicorstdpub use event::ServiceUpdate;allocorheaplessorno-atomicorstdpub use config::EndpointConfig;pub use records::ServiceRecords;allocorno-atomicorstdpub use config::ServiceSpec;allocorno-atomicorstdpub use config::QuerySpec;allocorheaplessorno-atomicorstdpub use cache::Cache;allocorno-atomicorstdpub use cache::CacheEntry;allocorno-atomicorstdpub use service::ServiceState;pub use service::Service;allocorno-atomicorstdpub use query::CollectedAnswer;allocorno-atomicorstdpub use query::Query;allocorno-atomicorstdpub use endpoint::Endpoint;allocorno-atomicorstdpub use endpoint::EndpointEventEntry;allocorno-atomicorstdpub use endpoint::RouteEvents;allocorno-atomicorstdpub use endpoint::ServiceRoute;allocorno-atomicorstdpub use endpoint::WithdrawalSend;allocorno-atomicorstdpub use endpoint::WithdrawalToken;allocorno-atomicorstdpub use slab;slab
Modules§
- cache
allocorno-atomicorstd - Passive record cache. Passive record cache observed from incoming traffic.
- config
- Configuration types. Configuration types passed to Endpoint/Service/Query constructors.
- constants
- Protocol-level constants (RFC 1035 + RFC 6762 limits). Constants defined by RFC 1035 (DNS), RFC 6762 (mDNS), and our internal limits.
- endpoint
allocorno-atomicorstd - Endpoint orchestrator.
Endpointorchestrator: demuxes incoming datagrams, holds routing metadata + cache, drives Service/Query registration. - error
- Cross-cutting error types. Cross-cutting error types and their shared detail-struct payloads.
- event
- Event types between Endpoint, Service, and Query.
Event types flowing between
Endpoint,Service, andQuery. - handle
- Opaque handles for services and queries. Opaque identifiers for registered services and in-flight queries.
- name
- Owned, canonical DNS name. Owned, canonical DNS name.
- pool
- Pluggable backing storage for protocol state machines. Pluggable backing storage for the protocol state machines.
- query
allocorno-atomicorstd - Query state machine. Query state machine — retry backoff + answer collection + KAS hints.
- records
allocorno-atomicorstd - Records published by a registered Service.
Records published by a registered
Service. - service
- Service state machine. Service state machine — probing, announcing, response generation.
- time
- Monotonic time abstraction. Monotonic time abstraction for protocol state machines.
- transmit
- Outgoing-datagram descriptor. Outgoing-datagram descriptor.
- wire
- mDNS wire format — panic-free parser and encoder. mDNS wire format — panic-free, no_alloc-capable parser and encoder.