pub struct Service<I, TQ, EV> { /* private fields */ }alloc or no-atomic or std only.Expand description
Service state machine. One per registered service.
Implementations§
Source§impl<I, TQ, EV> Service<I, TQ, EV>
impl<I, TQ, EV> Service<I, TQ, EV>
Sourcepub const fn handle(&self) -> ServiceHandle
pub const fn handle(&self) -> ServiceHandle
Returns the handle assigned at registration.
Sourcepub const fn state(&self) -> ServiceState
pub const fn state(&self) -> ServiceState
Returns the current state.
Sourcepub const fn records(&self) -> &ServiceRecords
pub const fn records(&self) -> &ServiceRecords
Returns the records this service advertises.
Sourcepub fn advertises_host(&self) -> bool
pub fn advertises_host(&self) -> bool
Whether this service has advertised (announced) its host A/AAAA records and they may still be cached by peers.
Unlike the instance-level announce state, this latch survives a conflict rename (the host name does not change). The driver consults it to decide whether a same-host sibling genuinely owns the shared host records: a merely-registered (still probing / never announced) sibling has put nothing into peer caches and so does NOT keep the withdrawing service from retracting the host addresses, whereas a renamed-but-previously-announced sibling DOES.
also requires the service to actually carry host A/AAAA — an address-less service advertises no host records and so owns none.
Sourcepub fn advertises_instance(&self) -> bool
pub fn advertises_instance(&self) -> bool
Whether this service has CONFIRMED-EMITTED at least one INSTANCE record
(PTR/SRV/TXT) on the wire — i.e. it has truly advertised its name, not merely
probed for it. Unlike Self::advertises_host this is set even for an
address-less service. Drivers gate the endpoint’s cancel-on-announce reclaim
on this so a probe alone cannot cancel a renamed-away old name’s goodbye
before the reclaiming service has actually announced.
Sourcepub fn advertised_a_addrs(&self) -> &[Ipv4Addr]
pub fn advertised_a_addrs(&self) -> &[Ipv4Addr]
The host IPv4 addresses this service has actually ADVERTISED (confirmed-
emitted), per address. This is the set a sibling truly owns in peer
caches — NOT ServiceRecords::a_addrs_slice, which is the configured set
(a §7.1 KAS-filtered send may have emitted only a subset). The driver
builds its shared-host retention set from this so a withdrawing service
retracts only addresses no remaining service actually advertised.
Sourcepub fn advertised_aaaa_addrs(&self) -> &[Ipv6Addr]
pub fn advertised_aaaa_addrs(&self) -> &[Ipv6Addr]
The host IPv6 addresses this service has actually ADVERTISED, per address
(the AAAA counterpart of Self::advertised_a_addrs).
Sourcepub fn note_transmit_result(&mut self, now: I, delivered: bool)
pub fn note_transmit_result(&mut self, now: I, delivered: bool)
Report the delivery result of the datagram most recently produced by
Self::poll_transmit (the confirm-on-send chokepoint).
This is the SOLE place service lifecycle state advances. poll_transmit
only encodes bytes and stamps a commit token (awaiting_confirm); the
driver then calls this with delivered = true when at least one socket
send succeeded (used > 0). Behaviour is keyed on the token:
- Probe, delivered — advance the §8.1 probe sequence (next probe, or
enter
Announcing(0)after the third). A name is therefore claimed only once a probe has actually reached the link. - Probe, NOT delivered — re-arm the same probe WITHOUT advancing, so a service whose probes never leave the host never announces (the RFC 6762 §8.1 guarantee; the fix).
- Announcement, delivered — latch the goodbye-ownership guards
(
announce_emitted/host_advertised) and advance the §8.3 announce phase, reachingEstablishedafter the second. - Announcement, NOT delivered — re-arm without advancing; the announcement is retried.
- Response / nothing pending — no lifecycle state to advance.
Sourcepub fn note_transmit_delivered(&mut self, now: I)
pub fn note_transmit_delivered(&mut self, now: I)
Convenience wrapper for a CONFIRMED delivery — equivalent to
note_transmit_result(now, true). Retained so call sites (and tests) that
always represent a successful send stay terse; all advancement logic lives
in Self::note_transmit_result.
Sourcepub fn withdrawal_snapshot(&mut self) -> WithdrawalSnapshot
pub fn withdrawal_snapshot(&mut self) -> WithdrawalSnapshot
Capture everything the endpoint needs to re-encode a TTL=0 goodbye for
this service without holding the Service alive.
Always captures the CURRENT confirmed-emitted state: the current
ServiceRecords, which instance record kinds (PTR/SRV/TXT/subtypes) were
actually put on the wire, and which host A/AAAA addresses were
confirmed-emitted. The endpoint further filters host addresses against
same-host siblings before encoding the actual goodbye datagram.
The OLD instance name of an in-flight §9 conflict rename is NOT carried
here. A rename now hands its old-name goodbye off via
Self::take_rename_goodbye_handoff the instant it happens, and the driver
enqueues it as an INDEPENDENT detached withdrawal item
(crate::Endpoint::enqueue_rename_withdrawal). A teardown during that
window is therefore simply two independent items — the detached old-name
item already enqueued, plus the route-attached current-name item this
snapshot produces — with no snapshot.rename inheritance.
Sourcepub fn take_rename_goodbye_handoff(&mut self) -> Option<RenameGoodbyeHandoff>
pub fn take_rename_goodbye_handoff(&mut self) -> Option<RenameGoodbyeHandoff>
Take the one-shot §9 rename goodbye handoff, if a conflict rename installed one (the OLD instance name advertised ≥1 instance record and so still needs a TTL=0 withdrawal so peers evict it).
Returns the OLD name’s ServiceRecords plus the per-record ownership
(EmittedRecords with the instance bits the old name actually put on the
wire; host A/AAAA empty — a rename never withdraws host addresses). The
driver MUST call this immediately after observing
ServiceUpdate::Renamed from Self::poll
and hand the result to crate::Endpoint::enqueue_rename_withdrawal, which
models the old-name goodbye as an independent detached withdrawal item. The
field is consumed (.take()) so the handoff happens exactly once. Returns
None when the renamed name had never advertised an instance record.
Sourcepub fn poll_timeout(&self) -> Option<I>
pub fn poll_timeout(&self) -> Option<I>
Returns the next deadline at which handle_timeout should be called.
This is the minimum of lifecycle_deadline and response_deadline
(either or both may be None). The caller should drive handle_timeout
when this instant is reached.
Sourcepub fn poll(&mut self) -> Option<ServiceUpdate>
pub fn poll(&mut self) -> Option<ServiceUpdate>
Drain a pending app-level update, if any.
Sourcepub fn handle_event(&mut self, event: ServiceEvent<'_>, now: I)
pub fn handle_event(&mut self, event: ServiceEvent<'_>, now: I)
Process an event routed to this service by the Endpoint.
now is the current time; it is cached so that handle_event can
compute KAS-hint expiration times and schedule the jittered response
deadline without needing handle_timeout to have fired first.
Sourcepub fn handle_timeout(&mut self, now: I) -> Result<(), HandleTimeoutError>
pub fn handle_timeout(&mut self, now: I) -> Result<(), HandleTimeoutError>
Drive timer-based transitions. Returns Ok unless arithmetic overflowed.
Sourcepub fn poll_transmit(
&mut self,
now: I,
buf: &mut [u8],
) -> Result<Option<Transmit>, TransmitError>
pub fn poll_transmit( &mut self, now: I, buf: &mut [u8], ) -> Result<Option<Transmit>, TransmitError>
Produce the next outgoing datagram, if any. Writes into buf.
Returns Ok(None) when the transmit queue is empty. The caller should
loop on this method until it returns Ok(None) to drain all pending
transmits (at most 2 can be queued when both a response deadline and a
lifecycle deadline fired at the same now).