Zero Configuration Networking: The Definitive Guide
3.4. Claiming Your Local Name
This section looks at the dance that results in a device obtaining a locally unique name. The details of the Multicast DNS Querier and Responder, and other mechanics of where the messages are being sent and which devices are listening, were covered in the previous section. For now, consider a device that has an IP address that is now trying to claim a unique name in the .local domain. The steps and precautions parallel much of what was described in Chapter 2. The sequence is very similar: first, a name has to be chosen, then the device probes to check for uniqueness , and then it announces its chosen name. 3.4.1. Probing to Check for Uniqueness
Once a hostname is chosen for a particular device and an IP address has been selected or assigned, the next step is to create a local Multicast DNS address record that maps the name to the IP address. DNS Record types are documented in the IETF's RFC 1035 "Domain Names - Implementation and Specification" (http://www.ietf.org/rfc/rfc1035.txt). DNS Record type A is the IPv4 address record type. Having created our tentative address record (also known as an A record), we need to check to see if someone is already using an address record with that same name. (The name of the A record and our desired hostname are one and the same.) We could send an mDNS query for our desired hostname, DNS type A, and see if we get any responses. However we may also want to create other record types for our hostname, such as host info (HINFO), so we instead send a query for DNS query type T_ANY, in order to find if there are records of any type with that name.
If no conflicting Multicast DNS response is received, then a second query is sent 250 ms after the first and, in the absence of conflicts, a third query is sent 250 ms after that. After waiting an additional 250 ms, or a total of 750 ms for the three queries and corresponding waiting time, if no conflicting Multicast DNS response has been received, then the host has successfully verified uniqueness and proceeds to the announcement step. If, at any point in the probing step, a conflicting Multicast DNS response is received, then the host must select a new name for each of the conflicting records that need unique names. A device may have a mechanism for selecting another name or it may, if appropriate, be set up to display an error message to prompt a human user to manually select another name. What if two devices probe to verify the same name at exactly the same time? Neither will be able to answer the other's probe because neither owns the name yet. Certainly, this normally shouldn't happen very often, but the reliability goals of Zeroconf dictate that even the situations that don't happen very often still need to be handled correctly. Multicast DNS solves this race condition by adding the desired new record to the authority section of the query packet. This usage is analogous to the way DNS UPDATE packets use the authority section to convey the new data to be added to the server. When two hosts probing the same name see each other's probes, they consult the authority section and use the data there as a tiebreaker. This type of conflict is resolved in favor of the record with the lexicographically later rdata . The determination of lexicographically later is made by first comparing the record class, then the record type, then a raw comparison of the binary content of the rdata without regard for meaning or structure. If the record classes differ, then the numerically greater class is considered lexicographically later. Otherwise, if the record types differ, then the numerically greater type is considered lexicographically later. If the type and class both match, then the rdata is compared. The bytes of the raw rdata are compared in turn, interpreting the bytes as eight-bit unsigned values, until a byte is found whose value is greater than that of its counterpart (in which case, the rdata whose byte has the greater value is deemed lexicographically later) or one of the resource records runs out of rdata (in which case, the resource record that still has remaining data is deemed lexicographically later). The following is an example of a conflict: sctibook.local. A 169.254.99.200 sctibook.local. A 169.254.200.50
In this case, 169.254.200.50 is lexicographically later (the third byte, with value 200, is greater than its counterpart with value 99), so it is deemed the winner. The loser is expected to pick a new name and the winner proceeds as if nothing had happened. If the loser refuses to cooperate, then the conflict is still detected and resolved eventually; it just takes longer. The reason the protocol chooses the lexicographically later data as the winner (rather than the lexicographically earlier) is because of the way some networks (particularly wireless networks) can delay and repeat old packets. After a name conflict, a host typically responds by appending "-2" to the end of its name, or incrementing "2" to "3," both of which yield a new name that's lexicographically later. Situations have been observed when a host, probing for uniqueness of its DNS "SRV" service records (described in Chapter 4), would see an old packet of its own, from half a second ago, come back from the network. If the lexicographically earlier data were to win, then, in this situation, the host could sometimes conclude that it had lost a tiebreaker with itself (as of half a second ago)! Declaring the lexicographically later data as the winner means that in these strange and uncommon situations, a host's current state will tend to win in comparison to its old self. It's a minor consideration, but given that there's really no other reason to prefer lexicographically earlier or lexicographically later, this one point tipped the balance in favor of declaring the lexicographically later data to be the winner. 3.4.2. Announcing
After issuing three queries and waiting 250 ms after each query, if a host has not received a conflicting Multicast DNS response, it begins the announcing step. In this step, the Multicast DNS Responder sends a gratuitous Multicast DNS response that contains all of its resource records in the Answer Section. The purpose of these announcements is (just like ARP announcements) to update neighboring caches on the network that might still be holding old, stale data. This announcement is normally sent more than once to guard against packet loss. For records that have been verified unique, the mDNS cache flush bit of the rrclass is set to 1. This is the most significant bit of the rrclass, and as the mDNS spec explains: When a resource record appears in the answer section of the DNS Response with the "cache flush" bit set, it means, "This is an assertion that this information is the truth and the whole truth, and anything you may have heard before regarding records of this name/type/class is no longer valid". Upon receiving this data, neighboring caches will delete all old records they have with this name and replace them with the new data. A host needs to be able to detect conflicts anytime it is operating and advertising mDNS records, not just during the initial probing phase. Anytime a host sees another host send answer records that disagree with its own (for example, an address record with the same hostname but a different IP address), that's a conflict, which needs to be resolved. This is one of the places that the usefulness of sending replies via multicast instead of unicast is evident. When all the replies are public, you can quickly see when another host is advertising records that you don't agree with. When two hosts see each other send conflicting answers, both hosts reset their records back to probing state. When they then proceed to send their three probe packets, each will see the other's probes, and the tiebreaking rules will be invoked to determine who has to rename and who does not. |
Категории