Skip to main content

rtc_ice/mdns/
mod.rs

1//#[cfg(test)]
2//mod mdns_test;
3
4use mdns::Mdns;
5use mdns::MdnsConfig;
6use std::net::{IpAddr, Ipv4Addr};
7use std::time::{Duration, Instant};
8use uuid::Uuid;
9
10use shared::error::Result;
11
12/// Represents the different Multicast modes that ICE can run.
13#[derive(Default, PartialEq, Eq, Debug, Copy, Clone)]
14#[non_exhaustive]
15pub enum MulticastDnsMode {
16    /// Means remote mDNS candidates will be discarded, and local host candidates will use IPs.
17    Disabled,
18
19    /// Means remote mDNS candidates will be accepted, and local host candidates will use IPs.
20    #[default]
21    QueryOnly,
22
23    /// Means remote mDNS candidates will be accepted, and local host candidates will use mDNS.
24    QueryAndGather,
25}
26
27pub(crate) fn generate_multicast_dns_name() -> String {
28    // https://tools.ietf.org/id/draft-ietf-rtcweb-mdns-ice-candidates-02.html#gathering
29    // The unique name MUST consist of a version 4 UUID as defined in [RFC4122], followed by “.local”.
30    // This is a short-lived privacy alias, not a credential. `Uuid::new_v4` obtains randomness
31    // from the UUID crate's secure random source without forcing provider ownership into mDNS.
32    let u = Uuid::new_v4();
33    format!("{u}.local")
34}
35
36pub(crate) fn create_multicast_dns(
37    now: Instant,
38    mdns_mode: MulticastDnsMode,
39    mdns_local_name: &str,
40    mdns_local_ip: &Option<IpAddr>,
41    mdns_query_timeout: &Option<Duration>,
42) -> Result<Option<Mdns>> {
43    if mdns_mode == MulticastDnsMode::Disabled {
44        return Ok(None);
45    }
46
47    let mut config = if mdns_mode == MulticastDnsMode::QueryAndGather {
48        let local_ip = if let Some(local_ip) = mdns_local_ip {
49            *local_ip
50        } else {
51            IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))
52        };
53        log::info!("mDNS is using {local_ip} as local ip");
54
55        MdnsConfig::new()
56            .with_local_names(vec![mdns_local_name.to_owned()])
57            .with_local_ip(local_ip)
58    } else {
59        MdnsConfig::new()
60    };
61
62    if let Some(query_timeout) = mdns_query_timeout {
63        config = config.with_query_timeout(*query_timeout);
64    }
65
66    let mdns_server = Mdns::new(now, config);
67
68    Ok(Some(mdns_server))
69}