Skip to main content

Engine

Struct Engine 

Source
pub struct Engine<I: Instant, R> { /* private fields */ }
Expand description

The runtime-agnostic mDNS engine.

Generic over the monotonic clock I (an mdns_proto::Instant) and the RNG R; the storage pools are fixed to the alloc-tier slab backing.

Implementations§

Source§

impl<I, R> Engine<I, R>
where I: Instant, R: Rng,

Source

pub fn new(config: EndpointConfig, rng: R) -> Self

Create an engine from a proto-layer config and an RNG (used for probe tiebreak seeds and query transaction ids).

Source

pub fn set_local_subnets(&mut self, subnets: Vec<IpCidr>)

Set the device’s local subnets — the RFC 6762 §11 on-link heuristic used when the transport cannot surface the received hop-limit (neither supplied transport can; smoltcp’s UdpMetadata carries no RX TTL).

OPTIONAL. With no subnets configured the §11 gate accepts every inbound mDNS datagram (the groups are link-scoped multicast routers do not forward, so it is on-link by IP design) rather than dropping all of it and going deaf. Configure the device’s own subnets to additionally REJECT sources outside them — a best-effort defence against a same-link host spoofing on-link traffic.

Source

pub fn register_service( &mut self, spec: ServiceSpec, now: I, ) -> Result<ServiceHandle, RegisterServiceError>

Register a service. The proto state machine is owned by the engine and driven by Self::pump; updates are read via Self::poll_service_update.

Source

pub fn unregister_service(&mut self, handle: ServiceHandle, now: I)

Unregister a service, beginning its RFC 6762 §10.1 endpoint-owned withdrawal. The endpoint KEEPS the route (holding the name against a same-name re-registration) and drives the TTL=0 goodbye resend schedule; Self::pump pumps each due goodbye datagram and, on completion, frees the route and GCs the driver slot.

The withdrawal covers whatever the service must retract: the records it confirmed-emitted under its current name (host A/AAAA filtered against same-host siblings by the endpoint), AND — if a conflict rename left an old-name withdrawal still pending — that old instance name too, in the SAME goodbye (Service::withdrawal_snapshot captures both). A never-announced service has an empty snapshot and completes on the next pump with no datagram on the wire.

The driver slot is NOT removed here: it is kept (marked errored) so any already-queued ServiceUpdate::Conflict still reaches the host, and is GC’d when the endpoint reports the withdrawal complete.

Source

pub fn start_query( &mut self, spec: QuerySpec, now: I, ) -> Result<QueryHandle, StartQueryError>

Start a query. Updates are read via Self::poll_query_update.

Source

pub fn cancel_query(&mut self, handle: QueryHandle)

Cancel a query and free its pool slot.

Source

pub fn collected_answers( &self, handle: QueryHandle, ) -> impl Iterator<Item = &CollectedAnswer> + '_

Iterate the answers a query has collected so far — the browse / discovery results. Empty if handle is not an active query. Read this after any Self::pump (or a Self::poll_query_update); the proto keeps a bounded snapshot, so compare its length against Self::query_accepted_count to detect answers the max_answers cap evicted before you read them.

Source

pub fn query_accepted_count(&self, handle: QueryHandle) -> Option<u64>

Total answers ever accepted by a query (including ones the max_answers cap has since evicted from Self::collected_answers). None if handle is not an active query.

Source

pub fn pump<T: UdpIo>( &mut self, now: I, io: &mut T, scratch: &mut [u8], ) -> Option<I>

Step the engine once: fire due timers, drain all ready RX through the §11 gate into the proto, surface service updates, drain all pending TX via io, pump any due endpoint-owned withdrawal goodbyes, and return the next deadline to sleep until.

Graceful shutdown. There is no separate flush path: unregister_service begins each service’s endpoint-owned §10.1 withdrawal, and pump drives the goodbye sends + frees the route on completion. To flush all pending withdrawals before exiting, drive pump until Self::poll_deadline returns None (no service, query, cache, or withdrawal deadline remains) — at which point every withdrawal has completed (sent its budget or hit its 2 s anti-pin ceiling) and its route is freed.

Source

pub fn poll_deadline(&self) -> Option<I>

The earliest deadline across the endpoint, services, and queries.

Endpoint-owned withdrawal deadlines (the next due goodbye round and the anti-pin ceiling) are already folded into Endpoint::poll_timeout, so the driver no longer tracks them here.

Source

pub fn poll_service_update( &mut self, handle: ServiceHandle, ) -> Option<ServiceUpdate>

Pop one app-facing update for a registered service.

If this drains the LAST update of a slot whose endpoint-owned withdrawal has already completed (route_freed), the slot is GC’d here — the deferred GC that lets a retirement Conflict survive a withdrawal which completed in the same pump that began it (see the ServiceSlot::route_freed field).

Source

pub fn poll_query_update(&mut self, handle: QueryHandle) -> Option<QueryUpdate>

Pop one app-facing update for a query. A query the driver RETIRED (its question is un-encodable, or permanently unsendable on every reachable family) was forced to the proto’s TIMEOUT terminal when the driver retired it, so it surfaces one QueryUpdate::Timeout here — the caller learns it died (and can read Self::collected_answers, frozen, then cancel) instead of waiting forever for a result it can never request.

Source

pub fn poll_endpoint_event(&mut self) -> Option<EndpointEvent>

Pop one endpoint-level event.

Auto Trait Implementations§

§

impl<I, R> Freeze for Engine<I, R>
where R: Freeze, I: Freeze,

§

impl<I, R> RefUnwindSafe for Engine<I, R>

§

impl<I, R> Send for Engine<I, R>
where R: Send, I: Send,

§

impl<I, R> Sync for Engine<I, R>
where R: Sync, I: Sync,

§

impl<I, R> Unpin for Engine<I, R>
where R: Unpin, I: Unpin,

§

impl<I, R> UnsafeUnpin for Engine<I, R>
where R: UnsafeUnpin, I: UnsafeUnpin,

§

impl<I, R> UnwindSafe for Engine<I, R>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.