Skip to main content

ServiceDaemon

Struct ServiceDaemon 

Source
pub struct ServiceDaemon { /* private fields */ }
Expand description

A daemon thread for mDNS

This struct provides a handle and an API to the daemon. It is cloneable.

Implementations§

Source§

impl ServiceDaemon

Source

pub fn new() -> Result<Self>

Creates a new daemon and spawns a thread to run the daemon.

Creates a new mDNS service daemon using the default port (5353).

For development/testing with custom ports, use ServiceDaemon::new_with_port.

§Errors

Returns Error::Msg if the daemon cannot be initialized. This wraps an underlying OS-level failure.

Note that this constructor does not open the mDNS multicast sockets — those are opened lazily by the daemon thread once it starts, so platform issues such as “multicast not permitted” are surfaced later via DaemonEvent from monitor rather than here.

Source

pub fn new_with_port(port: u16) -> Result<Self>

Creates a new mDNS service daemon using a custom port.

§Arguments
  • port - The UDP port to bind for mDNS communication.
    • In production, this should be MDNS_PORT (5353) per RFC 6762.
    • For development/testing, you can use a non-standard port (e.g., 5454) to avoid conflicts with system mDNS services.
    • Both publisher and browser must use the same port to communicate.
§Example
use mdns_sd::ServiceDaemon;

// Use standard mDNS port (production)
let daemon = ServiceDaemon::new_with_port(5353)?;

// Use custom port for development (avoids macOS Bonjour conflict)
let daemon_dev = ServiceDaemon::new_with_port(5454)?;
§Errors

See new for the set of OS-level failures that may surface here. Note that port is not validated against the kernel until the daemon thread tries to bind the mDNS sockets, so an unusable port (e.g., already in use, requires elevated privileges) will not be reported by this constructor — listen for such failures via monitor.

Source

pub fn browse(&self, service_type: &str) -> Result<Receiver<ServiceEvent>>

Starts browsing for a specific service type.

service_type must end with a valid mDNS domain: ‘._tcp.local.’ or ‘._udp.local.’

Returns a channel Receiver to receive events about the service. The caller can call .recv_async().await on this receiver to handle events in an async environment or call .recv() in a sync environment.

When a new instance is found, the daemon automatically tries to resolve, i.e. finding more details, i.e. SRV records and TXT records.

§Errors

Returns Error::Msg if service_type does not end with ._tcp.local. or ._udp.local..

Returns Error::Again if the daemon’s command queue is full.

Returns Error::DaemonShutdown if the daemon thread has already exited.

Source

pub fn browse_cache(&self, service_type: &str) -> Result<Receiver<ServiceEvent>>

Preforms a “cache-only” browse.

service_type must end with a valid mDNS domain: ‘._tcp.local.’ or ‘._udp.local.’

The functionality is identical to ‘browse’, but the service events are based solely on the contents of the daemon’s cache. No actual mDNS query is sent to the network.

See accept_unsolicited if you want to do cache-only browsing.

§Errors

Same error conditions as browse.

Source

pub fn stop_browse(&self, ty_domain: &str) -> Result<()>

Stops searching for a specific service type.

§Errors

Returns Error::Again if the daemon’s command queue is full.

Returns Error::DaemonShutdown if the daemon thread has already exited.

Source

pub fn resolve_hostname( &self, hostname: &str, timeout: Option<u64>, ) -> Result<Receiver<HostnameResolutionEvent>>

Starts querying for the ip addresses of a hostname.

Returns a channel Receiver to receive events about the hostname. The caller can call .recv_async().await on this receiver to handle events in an async environment or call .recv() in a sync environment.

The timeout is specified in milliseconds.

§Errors

Returns Error::Msg if:

  • hostname does not end with .local.;
  • hostname is exactly .local. (the label before .local. is empty);
  • hostname is longer than 255 bytes.

Returns Error::Again if the daemon’s command queue is full.

Returns Error::DaemonShutdown if the daemon thread has already exited.

Source

pub fn stop_resolve_hostname(&self, hostname: &str) -> Result<()>

Stops querying for the ip addresses of a hostname.

§Errors

Same error conditions as stop_browse.

Source

pub fn register(&self, service_info: ServiceInfo) -> Result<()>

Registers a service provided by this host.

If service_info has no addresses yet and its addr_auto is enabled, this method will automatically fill in addresses from the host.

To re-announce a service with an updated service_info, just call this register function again. No need to call unregister first.

§Errors

Returns Error::Msg if the ServiceInfo is malformed, for example:

  • the fullname does not end with ._tcp.local. or ._udp.local.;
  • the hostname does not end with .local., is exactly .local., or is longer than 255 bytes.

Returns Error::Again if the daemon’s command queue is full.

Returns Error::DaemonShutdown if the daemon thread has already exited.

Source

pub fn unregister(&self, fullname: &str) -> Result<Receiver<UnregisterStatus>>

Unregisters a service. This is a graceful shutdown of a service.

Returns a channel receiver that is used to receive the status code of the unregister.

§Errors

Returns Error::Again if the daemon’s command queue is full.

Returns Error::DaemonShutdown if the daemon thread has already exited.

Source

pub fn monitor(&self) -> Result<Receiver<DaemonEvent>>

Starts to monitor events from the daemon.

Returns a channel Receiver of DaemonEvent.

§Errors

Returns Error::Again if the daemon’s command queue is full.

Returns Error::DaemonShutdown if the daemon thread has already exited.

Source

pub fn shutdown(&self) -> Result<Receiver<DaemonStatus>>

Shuts down the daemon thread and returns a channel to receive the status.

§Errors

Returns Error::Again if the daemon’s command queue is full.

Returns Error::DaemonShutdown if the daemon thread has already exited.

Source

pub fn status(&self) -> Result<Receiver<DaemonStatus>>

Returns the status of the daemon.

§Errors

Returns Error::Again if the daemon’s command queue is full.

Returns Error::DaemonShutdown if the daemon thread has already exited.

Source

pub fn get_metrics(&self) -> Result<Receiver<Metrics>>

Returns a channel receiver for the metrics, e.g. input/output counters.

The metrics returned is a snapshot. Hence the caller should call this method repeatedly if they want to monitor the metrics continuously.

§Errors

Returns Error::Again if the daemon’s command queue is full.

Returns Error::DaemonShutdown if the daemon thread has already exited.

Source

pub fn set_service_name_len_max(&self, len_max: u8) -> Result<()>

Change the max length allowed for a service name.

As RFC 6763 defines a length max for a service name, a user should not call this method unless they have to. See SERVICE_NAME_LEN_MAX_DEFAULT.

len_max is capped at an internal limit, which is currently 30.

§Errors

Returns Error::Msg if len_max exceeds the internal cap (30).

Returns Error::Again if the daemon’s command queue is full.

Returns Error::DaemonShutdown if the daemon thread has already exited.

Source

pub fn set_ip_check_interval(&self, interval_in_secs: u32) -> Result<()>

Change the interval for checking IP changes automatically.

Setting the interval to 0 disables the IP check.

See IP_CHECK_INTERVAL_IN_SECS_DEFAULT for the default interval.

Source

pub fn get_ip_check_interval(&self) -> Result<u32>

Get the current interval in seconds for checking IP changes automatically.

Source

pub fn enable_interface(&self, if_kind: impl IntoIfKindVec) -> Result<()>

Include interfaces that match if_kind for this service daemon.

For example:

    daemon.enable_interface("en0")?;
Source

pub fn disable_interface(&self, if_kind: impl IntoIfKindVec) -> Result<()>

Ignore/exclude interfaces that match if_kind for this daemon.

For example:

    daemon.disable_interface(IfKind::IPv6)?;
Source

pub fn accept_unsolicited(&self, accept: bool) -> Result<()>

If accept is true, accept and cache all responses, even if there is no active querier for a given service type. This is useful / necessary when doing cache-only browsing. See browse_cache.

If accept is false (default), accept only responses matching queries that we have initiated.

For example:

    daemon.accept_unsolicited(true)?;
Source

pub fn include_apple_p2p(&self, include: bool) -> Result<()>

Include or exclude Apple P2P interfaces, e.g. “awdl0”, “llw0”. By default, they are excluded.

Source

pub fn set_multicast_loop_v4(&self, on: bool) -> Result<()>

Enable or disable the loopback for locally sent multicast packets in IPv4.

By default, multicast loop is enabled for IPv4. When disabled, a querier will not receive announcements from a responder on the same host.

Reference: https://learn.microsoft.com/en-us/windows/win32/winsock/ip-multicast-2

“The Winsock version of the IP_MULTICAST_LOOP option is semantically different than the UNIX version of the IP_MULTICAST_LOOP option:

In Winsock, the IP_MULTICAST_LOOP option applies only to the receive path. In the UNIX version, the IP_MULTICAST_LOOP option applies to the send path.“

Which means, in order NOT to receive localhost announcements, you want to call this API on the querier side on Windows, but on the responder side on Unix.

Source

pub fn set_multicast_loop_v6(&self, on: bool) -> Result<()>

Enable or disable the loopback for locally sent multicast packets in IPv6.

By default, multicast loop is enabled for IPv6. When disabled, a querier will not receive announcements from a responder on the same host.

Reference: https://learn.microsoft.com/en-us/windows/win32/winsock/ip-multicast-2

“The Winsock version of the IP_MULTICAST_LOOP option is semantically different than the UNIX version of the IP_MULTICAST_LOOP option:

In Winsock, the IP_MULTICAST_LOOP option applies only to the receive path. In the UNIX version, the IP_MULTICAST_LOOP option applies to the send path.“

Which means, in order NOT to receive localhost announcements, you want to call this API on the querier side on Windows, but on the responder side on Unix.

Source

pub fn verify(&self, instance_fullname: String, timeout: Duration) -> Result<()>

Proactively confirms whether a service instance still valid.

This call will issue queries for a service instance’s SRV record and Address records.

For timeout, most users should use VERIFY_TIMEOUT_DEFAULT unless there is a reason not to follow RFC.

If no response is received within timeout, the current resource records will be flushed, and if needed, ServiceRemoved event will be sent to active queriers.

Reference: RFC 6762

§Errors

Returns Error::Again if the daemon’s command queue is full.

Returns Error::DaemonShutdown if the daemon thread has already exited.

Trait Implementations§

Source§

impl Clone for ServiceDaemon

Source§

fn clone(&self) -> ServiceDaemon

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.