keepsimple1 / mdns-sd

Rust library for mDNS based Service Discovery
Apache License 2.0
88 stars 38 forks source link

Add support for resolving non-service hostnames #192

Closed oysteintveit-nordicsemi closed 2 months ago

oysteintveit-nordicsemi commented 2 months ago

Resolves #191.

This adds several pieces of public API, for resolving mDNS hostnames as standalone.

as well as

pub enum ResolutionEvent {
    /// Started searching for the ip address of a hostname.
    SearchStarted(String),
    /// One or more addresses for a hostname has been found.
    HostnameAddressesFound(String, HashSet<IpAddr>),
    /// One or more addresses for a hostname has been removed.
    HostnameAddressesRemoved(String, HashSet<IpAddr>),
    /// Stopped searching for the ip address of a hostname.
    SearchStopped(String),
}

The internal implementation uses the dns cache for addresses, which should make it possible for service discovery and hostname discovery to benefit from each other in the case that you are running both at the same time.

The rest of the implementation is largely either copy paste of- or merging with the code that handles the service discovery, with some exceptions where the events are reporting an aggregate of ip-addresses rather than reporting one at a time.

Other notes

I refactored DnsCache::evict_expired to resolve some borrow checker issues. The current implementation will evict all expired records before it starts sending out events. It should not have any effect on any users of ServiceDaemon::browse, since they don't have direct access to the cache.

The current implementation is a bit loud, because it's missing Known Answer Suppression (RFC6762, sec. 7.1) (which is stated as a MUST requirement). As far as I understand, the current implementation for service browsing does not have this either, so I think it should be considered as a new issue.

oysteintveit-nordicsemi commented 2 months ago

Okay, so I've added a timeout: Option<u64> to ServiceDaemon:resolve_hostname. This adds the potential timeout to a table of timeouts, Zeroconf::hostname_resolver_timeouts: HashMap<String, u64> // (hostname, timeout), marks it in timers, and the Command::ResolveHostname continues to add retransmissions until it has reached the timeout. A block in the runloop will then clean up the tables, and notify the listener of both the timeout and the search stop.

keepsimple1 commented 2 months ago

Btw, I added support for sending multiple questions in one query. You can try out the new send_query_vec .