|
| 1 | +# Multicast DNS (mDNS) |
| 2 | + |
| 3 | +Author: Richard Schneider ( [email protected]) |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The goal is to allow peers to discover each other when on the same local network with zero configuration. mDNS uses a multicast system of DNS records; this allows all peers on the local network to see all query responses. |
| 8 | + |
| 9 | +Conceptually, it is very simple. When a peer starts (or detects a network change), it sends a query for all peers. As responses come in, the peer adds the other peers' information into its local database of peers. |
| 10 | + |
| 11 | +## Definitions |
| 12 | + |
| 13 | +- `service-name` is the DNS Service Discovery (DNS-SD) service name for all peers. It is defined as `_p2p._udp.local`. |
| 14 | +- `host-name` is the fully qualified name of the peer. It is derived from the peer's name and `p2p.local`. |
| 15 | +- `peer-name` is the case-insensitive unique identifier of the peer, and is less than 64 characters. It is normally the base-32 encoding of the peer's ID. |
| 16 | + |
| 17 | + If the encoding of the peer's ID exceeds 63 characters, then the [Split at 63rd character](https://github.com/ipfs/in-web-browsers/issues/89#issue-341357014) workaround can be used. |
| 18 | + |
| 19 | +If a [private network](https://github.com/libp2p/specs/blob/master/pnet/Private-Networks-PSK-V1.md) is in use, then the `service-name` contains the base-16 encoding of the network's fingerprint as in `_p2p-X._udp.local`. |
| 20 | +The prevents public and private networks from discovering each other's peers. |
| 21 | + |
| 22 | +## Peer Discovery |
| 23 | + |
| 24 | +### Request |
| 25 | + |
| 26 | +To find all peers, a DNS message is sent with the question `_p2p._udp.local PTR`. Peers will then start responding with their details. |
| 27 | + |
| 28 | +Note that a peer must respond to its own query. This allows other peers to passively discover it. |
| 29 | + |
| 30 | +### Response |
| 31 | + |
| 32 | +On receipt of a `find all peers` query, a peer sends a DNS response message (QR = 1) that contains the **answer** |
| 33 | + |
| 34 | +``` |
| 35 | +<service-name> PTR <peer-name>.<service-name> |
| 36 | +``` |
| 37 | + |
| 38 | +The **additional records** of the response contain the peer's discovery details: |
| 39 | + |
| 40 | +``` |
| 41 | +<peer-name>.<service-name> TXT "dnsaddr=..." |
| 42 | +``` |
| 43 | + |
| 44 | +The TXT record contains the multiaddresses that the peer is listening on. Each multiaddress is a TXT attribute with the form `dnsaddr=/.../p2p/QmId`. Multiple `dnsaddr` attributes and/or TXT records are allowed. |
| 45 | + |
| 46 | +## DNS Service Discovery |
| 47 | + |
| 48 | +DNS-SD support is not needed for peers to discover each other. However, it is extremely useful for network administrators to discover what is running on the network. |
| 49 | + |
| 50 | +### Meta Query |
| 51 | + |
| 52 | +This allows discovery of all services. The question is `_services._dns-sd._udp.local PTR`. |
| 53 | + |
| 54 | +A peer responds with the answer |
| 55 | + |
| 56 | +``` |
| 57 | + _services._dns-sd._udp.local PTR <service-name> |
| 58 | +``` |
| 59 | + |
| 60 | +### Find All Response |
| 61 | + |
| 62 | +On receipt of a `find all peers` query, the following **additional records** should be included |
| 63 | + |
| 64 | +``` |
| 65 | + <peer-name>.<service-name> SRV ... <host-name> |
| 66 | + <host-name> A <ipv4 address> |
| 67 | + <host-name> AAAA <ipv6 address> |
| 68 | +``` |
| 69 | + |
| 70 | +### Gotchas |
| 71 | + |
| 72 | +Many existing tools ignore the Additional Records, and always send individual queries for the peer's discovery details. To accomodate this, a peer should respond to the following queries: |
| 73 | + |
| 74 | +- `<peer-name>.<service-name> SRV` |
| 75 | +- `<peer-name>.<service-name> TXT` |
| 76 | +- `<host-name> A` |
| 77 | +- `<host-name> AAAA` |
| 78 | + |
| 79 | +## Issues |
| 80 | + |
| 81 | +[ ] mDNS requires link-local addresses. Loopback and "NAT busting" addresses should not sent and must be ignored on receipt? |
| 82 | + |
| 83 | +## References |
| 84 | + |
| 85 | +- [RFC 1035 - Domain Names (DNS)](https://tools.ietf.org/html/rfc1035) |
| 86 | +- [RFC 6762 - Multicast DNS](https://tools.ietf.org/html/rfc6762) |
| 87 | +- [RFC 6763 - DNS-Based Service Discovery](https://tools.ietf.org/html/rfc6763) |
| 88 | +- [Multiaddr](https://github.com/multiformats/multiaddr) |
| 89 | + |
| 90 | +## Worked Examples |
| 91 | + |
| 92 | +Asumming that `peer-id` is `QmQusTXc1Z9C1mzxsqC9ZTFXCgSkpBRGgW4Jk2QYHxKE22`, then the `peer-name` is `ciqcmoputolsfsigvm7nx5fwkko2eq26h46qhbj6o4co7uyn2f2srdy` (base32 encoding of the peer ID). |
| 93 | + |
| 94 | +To make the examples more readable `id` and `name` are used. |
| 95 | + |
| 96 | +### Meta Query |
| 97 | + |
| 98 | +Goal: find all services on the local network. |
| 99 | + |
| 100 | +#### Question |
| 101 | + |
| 102 | +``` |
| 103 | +_services._dns-sd._udp.local PTR |
| 104 | +``` |
| 105 | + |
| 106 | +#### Answer |
| 107 | + |
| 108 | +``` |
| 109 | +_services._dns-sd._udp.local IN PTR _p2p._udp.local |
| 110 | +``` |
| 111 | + |
| 112 | +### Find All Peers |
| 113 | + |
| 114 | +Goal: find all peers on the local network. |
| 115 | + |
| 116 | +#### Question |
| 117 | + |
| 118 | +``` |
| 119 | +_p2p._udp.local PTR |
| 120 | +``` |
| 121 | + |
| 122 | +#### Answer |
| 123 | + |
| 124 | +``` |
| 125 | +_p2p._udp.local IN PTR `name`._p2p._udp.local |
| 126 | +``` |
| 127 | + |
| 128 | +#### Additional Records |
| 129 | + |
| 130 | +- `name`._p2p._udp.local IN TXT dnsaddr=/ip6/fe80::7573:b0a8:46b0:bfea/tcp/4001/ipfs/`id` |
| 131 | +- `name`._p2p._udp.local IN TXT dnsaddr=/ip4/192.168.178.21/tcp/4001/ipfs/'id' |
0 commit comments