Zero Configuration Networking: The Definitive Guide

3.3. Multicast DNS

Most conferences have a message board somewhere where you can post and retrieve messages. The key is that there is a well-known place for you to visit to send or read items of interest to an individual or to a group. The message board is not generally secure and you cannot be assured that messages have been reliably delivered unless the target of your message replies. Other people can see the same messages you can see. Often, a friend will stop you in the hall to let you know that there is a message waiting for you on the message board. The message board is a great mechanism to announce a so-called "birds of a feather" session where people who share a common interest convene.

A multicast address is the network world's equivalent of a shared public-notice board. Using a previously agreed-upon IP Multicast address and port, messages can be delivered that will be received by all subscribed devices. Devices on a local link can use Multicast DNS to resolve locally unique hostnames. Every device on the local link listens for queries that are sent to the multicast address, and when it sees any query for its own name, it answers. In this section, you will see how the multicast part of mDNS works.

3.3.1. The mDNS Multicast Address

Any DNS query for a name ending in .local is sent to the address 224.0.0.251, which is the IPv4 address that has been reserved for mDNS. For a list of assigned multicast addresses, see the IANA document "INTERNET MULTICAST ADDRES-SES" at http://www.iana.org/assignments/multicast-addresses (IPv4) and http://www.iana.org/assignments/ipv6-multicast-addresses (IPv6). The IPv6 mDNS link-local multicast address is FF02::FB. The concepts of Multicast DNS apply equally, whether the data is sent in IPv4 multicast packets or IPv6 multicast packets.

Because 224.0.0.251 and FF02::FB are in the link-local multicast ranges for IPv4 and IPv6, respectively, packets sent to these addresses are never forwarded outside the local link nor forwarded onto the local link from outside. A device can therefore be sure that any link-local multicast packets it sends remain on the local link, and any link-local multicast packets it receives must have originated on the local link.

In general, the mDNS-based algorithm for claiming names and handling conflicts replaces a central authority with cooperating participants. If there are participants on the local link intent on disrupting this process, then they can do so. In principle, this could be solved by using IPSEC and/or DNSSEC signatures to identify trusted participants, though, in practice, it has not yet been a problem, and no current products implement these kinds of protection.

Queries to determine the hostname for a particular link-local IP address ("reverse lookups") can also be sent to 224.0.0.251. For IPv4, this reverse address mapping is any DNS query for a name ending in 254.169.in-addr.arpa, and for IPv6, it is a name ending in 0.8.e.f.ip6.arpa.

3.3.2. Multicast DNS Queries

Multicast DNS Queries fall into three categories: one-shot with a single answer, one-shot with multiple answers, and ongoing .

The first category is a one-shot query. Modifying an existing DNS client to perform one-shot queries can be trivial. If the name ends in local, then set the destination address to 224.0.0.251, set the destination port to 5353, and send the UDP packet as usual. When the UDP response comes back, the DNS client receives it and handles it, as it would any other DNS response. If no response is received, then the query is retransmitted a few times, just as with a normal Unicast DNS query. The code doesn't have to be modified to do anything else special because it's using multicastfrom the code's point of view, it is just talking to a DNS server at a particular address and port number. If all you want to be able to do is to type http://somename.local/ into a web browser and have it work, then this level of Multicast DNS functionality is sufficient.

The second category is one-shot queries that accumulate multiple responses. The DNS client still sends a query to 224.0.0.251, but this time the DNS client is aware that there are queries for which more than one response is possible, so the DNS client both waits for more than one response and, when appropriate, retransmits its query. When the DNS client has got enough results or has waited long enough, it returns the results to the application that initiated the query. Because the DNS client may retransmit its query more than once, this could cause the same host (or group of hosts) to respond more than once, which would be a waste of network bandwidth. To prevent this, each successive query includes a Known Answer list. If a host sees its answer already in the Known Answer list, then it doesn't have to respond again. Successive queries are also not transmitted at a constant rate but at an exponentially decaying rate, with the interval between packets doubling each time.

The third category is continuous, ongoing queries. If you want to browse the network to find the list of available printers, then a query that waits for 10 seconds and then displays the results has two problems: (a) waiting for 10 seconds before you see the results is far too long, and (b) the moment you see it, the list is already beginning to get out of date. What you want is a list that appears instantly, updates immediately whenever a new printer appears, and, ideally, also shows you promptly whenever a printer goes away. Consider also an instant messenger client like iChat that shows a list of buddies on the local network. You don't want a snapshot of the list of buddies that were there when you launched iChat, and you don't want to have to keep clicking a refresh button to update the list. You simply want a list that's always up to date, from second to second, and you want a protocol that's smart enough to do this efficiently. By repeating queries, mDNS keeps the list up to date. By including a Known Answer list, mDNS reduces unnecessary traffic. By using exponential backoff instead of querying at a constant rate, the traffic rate is further reduced. The interval between queries can grow up to one hour. So that it doesn't take an hour for you to discover a new buddy on the network, new clients announce their presence by sending gratuitous responses when they arrive on the network. Every answer record that's received has a time to live (TTL) that tells the receiver how long to hold that record in the local cache. When the TTL is close to expiring, the querier queries for it again, and if no answer is received before the record expires, it is removed from the cache and disappears from the screen. The combination of these efficiency features and others results in a system that provides excellent responsiveness at a low packet rate.

For continuous, ongoing queries, responses are sent via multicast, not unicast. It may seem that multicast responses will lead to an unreasonable increase in traffic on the network. On the contrary, responses that are sent as multicast allow multiple machines to receive the same information without having to issue a query themselves. The machines on the network are all listening to queries and responses addressed to 224.0.0.251. When a machine receives a response to a query, other machines on the network receive the response too and can add it to their own caches for future use. If they later need this information, they don't have to issue a query because they already have it.

3.3.2.1. Reducing traffic

There are useful techniques employed to reduce the sending of redundant information. The first is the Known Answer Suppression, mentioned above. Think of a teacher trying to get additional answers from a class by saying, "What might you try before you implement the State Pattern? We've already seen that one solution is nested if statements and another solution is using the case statement." The idea is that when a Multicast DNS query is sent by a host that already knows some of the answers, the query must include the known answers in the Answer Section of the DNS message. The TTL of each known answer is set to indicate how many seconds remain before it expires from the querier's cache. A Multicast DNS responder does not respond if it sees its answer already in the Known Answer list with a TTL that's at least half the correct value. A TTL of less than half the original value indicates that the record may expire from the cache soon, so the responder responds to refresh all the neighboring caches. Because of this, the querier knows that records with remaining cache lifetime of less than half their original value needn't be included in the Known Answer list in the first place, thereby reducing the size of the initial query packet. If there are too many answers to fit in a single query packet, then the TC (truncated) bit is set in the DNS packet header, and the Known Answer list continues in the next packet. Information contained in the Known Answer list of the query is only used to signal information the querier believes to be correct and should not be taken as authoritative by other devices on the network.

Returning to our classroom example, once one student has been scolded for asking "Is this going to be on the test?" the other students get the message not to ask this same question. Similarly, if a host is preparing to transmit a query and it detects a query containing the same question, then it may not need to send the same question itself. The host that has not yet issued the query needs to check the Known Answer section to determine that there are not any answers there that this host would not have added as its own. In other words, if there is no additional information that can be learned by transmitting the query, then none should be sent.

Back in our classroom example, a student has just answered the teacher's question and all the other students who were going to give the same answer lower their hands. A similar optimization is used in mDNS. If a host is preparing a response and sees a response from another host with the same answer as its own, then it can suppress its own response.

If a host knows that certain of its resource record data has become invalid, it should send a goodbye packet. This is a gratuitous announcement mDNS response packet with an RR TTL value of 0. A host receiving this will update its local TTL for this entry to zero, which causes the cache entry to be deleted. When a service is shutting down cleanly, this goodbye packet causes it to be deleted immediately from peer caches, instead of lingering while its TTL slowly decrements all the way to 0. If the service does not shut down cleanly, or the goodbye packet is lost, the caches still converge to correctness eventuallyit just takes a little longer.

Категории