Expand description
hick-reactor
§Introduction
hick-reactor is an async mDNS driver: it wires the Sans-I/O core
(mdns-proto) to multicast sockets (hick-udp) and runs the protocol on a
spawned driver task. The task is generic over an agnostic-net Net
implementation, so a single codebase serves both the tokio and smol
runtimes.
mDNS (Multicast DNS) discovers services on the local link with no central DNS server. Note that many cloud and shared-infrastructure networks block multicast, so mDNS is best suited to office, home, or private networks.
For a batteries-included entry point, use the hick facade (it defaults to
this driver). For the compio thread-per-core runtime, use hick-compio.
§Installation
[dependencies]
hick-reactor = "0.6" # tokio by defaultFor smol instead of tokio:
[dependencies]
hick-reactor = { version = "0.6", default-features = false, features = ["smol"] }§Example
use hick_reactor::{
Name, QuerySpec, ServerOptions, ServiceRecords, ServiceSpec, tokio, wire::ResourceType,
};
async fn run() -> Result<(), Box<dyn std::error::Error>> {
// `tokio::server` / `smol::server` pin the runtime; the returned `Endpoint`
// and its handles are otherwise the same.
let endpoint = tokio::server(ServerOptions::default()).await?;
// Advertise a service. Keep the handle alive to keep advertising; dropping it
// withdraws the service (TTL=0 goodbye) and unregisters it.
let mut records = ServiceRecords::new(
Name::try_from_str("_http._tcp.local.")?,
Name::try_from_str("My Device._http._tcp.local.")?,
Name::try_from_str("my-device.local.")?,
80,
120,
);
records.add_a([192, 168, 1, 10].into());
let _service = endpoint.register_service(ServiceSpec::new(records)).await?;
// Discover services of a type on the local link.
let mut query = endpoint
.start_query(QuerySpec::new(
Name::try_from_str("_ipp._tcp.local.")?,
ResourceType::Ptr,
))
.await?;
while let Some(event) = query.next().await {
match event {
hick_reactor::QueryEvent::Answer(answer) => println!("{answer:?}"),
hick_reactor::QueryEvent::Terminal(_) => break,
}
}
Ok(())
}§Feature flags
tokio(default) —tokioruntime viaagnostic-net.smol—smolruntime.tracing— forward structuredtracingspans/events from the driver and the proto core.stats— enableno_std-safe atomic counters; read a snapshot viaendpoint.stats().metrics— bridge counters to themetricsfacade (Prometheus/StatsD). Impliesstats.
§Observability
§tracing
Enable features = ["tracing"] and install a subscriber. The driver emits
tracing events during socket I/O, protocol state transitions, and errors.
§stats and metrics
Enable features = ["stats"] and call endpoint.stats() to obtain a
hick_trace::stats::StatsSnapshot:
let snap = endpoint.stats();
println!("packets_rx={} queries_active={}", snap.packets_rx, snap.queries_active);Enable features = ["metrics"] to additionally forward every counter/gauge
update to the metrics facade automatically.
§The hick family
hick (facade) · mdns-proto (Sans-I/O core) · hick-udp (UDP) ·
hick-reactor (this crate) · hick-compio (compio driver) ·
hick-smoltcp (smoltcp engine) · hick-embassy (embassy driver).
§Pedigree
A port and refactor of HashiCorp’s mdns; the wire format and protocol state machines are an independent, panic-free reimplementation.
§License
hick-reactor 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.
Modules§
- config
- Configuration types. Configuration types passed to Endpoint/Service/Query constructors.
- event
- Event types between Endpoint, Service, and Query.
Event types flowing between
Endpoint,Service, andQuery. - proto_
error - Cross-cutting error types. Cross-cutting error types and their shared detail-struct payloads.
- smol
smol - Per-runtime adapter for the
smolruntime. - tokio
tokio - Per-runtime adapter for the
tokioruntime. - wire
- mDNS wire format — panic-free parser and encoder. mDNS wire format — panic-free, no_alloc-capable parser and encoder.
Structs§
- Collected
Answer - One collected answer record for a Query.
- Endpoint
- Handle to a running mDNS endpoint.
- Endpoint
Config - Configuration for an
Endpoint. - Lookup
- A running DNS-SD lookup.
- Name
- Owned, canonical DNS name (lowercased on construction).
- Query
- Handle to an in-flight query.
- Query
Handle - Opaque identifier for an in-flight query.
- Query
Param - Parameters for a
Lookup/ browse. - Query
Spec - Spec for starting a query.
- Server
Options - Build-time configuration for an mDNS
Endpoint. - Service
- Handle to a registered service.
- Service
Entry - A resolved DNS-SD service instance.
- Service
Handle - Opaque identifier for a registered service.
- Service
Records - Records advertised by a single registered service.
- Service
Renamed - Detail payload for
ServiceUpdate::Renamed. - Service
Spec - Spec for registering a service.
Enums§
- Cancel
Error - Errors raised by
Query::cancelandService::unregister. - Query
Event - Per-answer event surfaced on the
Querystream. - Register
Error - Errors raised by
Endpoint::register_service. - Server
Error - Errors raised while constructing or running an
Endpoint. - Service
Update - App-level events emitted by
Service::poll(). - Start
Query Error - Errors raised by
Endpoint::start_query.