1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! Multicast protocol related components for DNS

mod mdns_client_stream;
mod mdns_stream;

pub use self::mdns_client_stream::{MdnsClientConnect, MdnsClientStream};
pub use self::mdns_stream::{MdnsStream, MDNS_IPV4, MDNS_IPV6};

/// See [rfc6762](https://tools.ietf.org/html/rfc6762#section-5) details on these different types.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum MdnsQueryType {
    /// The querier using this socket will only perform standard DNS queries over multicast. (clients only)
    ///
    /// Effectively treats mDNS as essentially no different than any other DNS query; one request followed by one response.
    ///   Only one UDP socket will be created.
    OneShot,
    /// The querier is fully compliant with [rfc6762](https://tools.ietf.org/html/rfc6762#section-5). (servers, clients)
    ///
    /// mDNS capable clients will sent messages with many queries, and they will expect many responses. Two UDP sockets will be
    ///   created, one for receiving multicast traffic, the other used for sending queries and direct responses. This requires
    ///   port 5353 to be available on the system (many modern OSes already have mDNSResponders running taking this port).
    Continuous,
    /// The querier operates under the OneShot semantics, but also joins the multicast group. (non-compliant servers, clients)
    ///
    /// This is not defined in the mDNS RFC, but allows for a multicast client to join the group, receiving all multicast network
    ///   traffic. This is useful where listening for all mDNS traffic is of interest, but because another mDNS process may have
    ///   already taken the known port, 5353. Query responses will come from and to the standard UDP socket with a random port,
    ///   multicast traffic will come from the multicast socket. This will create two sockets.
    OneShotJoin,
    /// The querier operates under the OneShot semantics, but also joins the multicast group. (servers)
    ///
    /// Not defined in the RFC, allows for a passive listener to receive all mDNS traffic.
    Passive,
}

impl MdnsQueryType {
    /// This will be sending packets, i.e. a standard UDP socket will be created
    pub fn sender(self) -> bool {
        match self {
            MdnsQueryType::Passive => false,
            MdnsQueryType::OneShot | MdnsQueryType::OneShotJoin => true,
            MdnsQueryType::Continuous => true,
        }
    }

    /// Returns true if this process can bind to *:5353
    pub fn bind_on_5353(self) -> bool {
        match self {
            MdnsQueryType::OneShot | MdnsQueryType::OneShotJoin | MdnsQueryType::Passive => false,
            MdnsQueryType::Continuous => true,
        }
    }

    /// Returns true if this mDNS client should join, listen, on the multicast address
    pub fn join_multicast(self) -> bool {
        match self {
            MdnsQueryType::OneShot => false,
            MdnsQueryType::Continuous | MdnsQueryType::OneShotJoin | MdnsQueryType::Passive => true,
        }
    }
}