Skip to main content

mdns_sd_discovery/
lib.rs

1#![warn(missing_docs)]
2#![warn(unused_extern_crates, unused_qualifications)]
3
4//! Access the operating system's built-in
5//! [DNS-SD](https://en.wikipedia.org/wiki/Zero-configuration_networking#DNS-based_service_discovery) /
6//! [mDNS](https://en.wikipedia.org/wiki/Multicast_DNS) stack for service
7//! discovery.
8//!
9//! This crate provides a cross-platform async API (using [Tokio](https://tokio.rs)) for
10//! browsing DNS-SD services via the native OS facilities:
11//!
12//! - **macOS**: native [DNS-SD framework](https://developer.apple.com/documentation/dnssd) (available since macOS 10.12)
13//! - **Windows**: native [Win32 DNS-SD API](https://learn.microsoft.com/en-us/uwp/api/windows.networking.servicediscovery.dnssd?view=winrt-28000) (available since Windows 10)
14//! - **Linux/FreeBSD**: [Avahi](https://avahi.org) via D-Bus (no binary dependency on libavahi)
15//!
16//! Service registration lives in a separate crate.
17//!
18//! # Discovery
19//!
20//! By default a [`ServiceBrowser`] discovers every service type on the network.
21//! Filter on [`DiscoveredService::service_type`], or narrow to a single type
22//! with [`ServiceBrowserBuilder::service_type`].
23//!
24//! ```no_run
25//! use mdns_sd_discovery::{BrowseEvent, ServiceBrowserBuilder};
26//!
27//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
28//! let mut browser = ServiceBrowserBuilder::new().browse().await?;
29//!
30//! while let Some(event) = browser.recv().await {
31//!     match event? {
32//!         BrowseEvent::Found(svc) => {
33//!             println!("+ [{}] {} at {}:{}", svc.service_type, svc.name, svc.host_name, svc.port);
34//!         }
35//!         BrowseEvent::Removed(svc) => println!("- [{}] {}", svc.service_type, svc.name),
36//!     }
37//! }
38//! // Dropping `browser` stops the browse.
39//! # Ok(())
40//! # }
41//! ```
42
43pub use self::browse::*;
44
45mod browse;
46
47/// Wire-format parsing internals re-exported for the fuzz targets in `fuzz/`.
48///
49/// `cargo fuzz` builds the whole graph with `--cfg fuzzing`; on regular builds
50/// this module does not exist. It is **not** part of the public API.
51#[cfg(fuzzing)]
52#[doc(hidden)]
53pub mod fuzzing {
54    use crate::TxtRecord;
55
56    /// Parses a single `key[=value]` TXT entry. See `browse::parse_txt_entry`.
57    pub fn parse_txt_entry(entry: &[u8]) -> TxtRecord {
58        crate::browse::parse_txt_entry(entry)
59    }
60
61    /// Parses a packed, length-prefixed DNS-SD TXT record buffer.
62    /// See `browse::parse_txt_buffer`.
63    pub fn parse_txt_buffer(buf: &[u8]) -> Vec<TxtRecord> {
64        crate::browse::parse_txt_buffer(buf)
65    }
66
67    /// Strips trailing `.` characters from a DNS name. See `browse::trim_dot`.
68    pub fn trim_dot(s: &str) -> String {
69        crate::browse::trim_dot(s)
70    }
71}
72
73#[cfg(all(unix, not(target_os = "macos")))]
74mod linux;
75#[cfg(target_os = "macos")]
76mod macos;
77#[cfg(target_os = "windows")]
78mod windows;