Multicast DNS and DNS-SD

Multicast DNS and DNS-SD are a key part of the stack Zero-configuration networking (zeroconf) and are responsible for the name service and automatic search for devices within the local network.

Technology zeroconfwhich allows you to assemble a working local network with zero effort in administration and configuration, has been known for a long time. Back in the 1980s, AppleTalk, a local network for Apple computers and devices, allowed you to simply connect devices with wires and start working right away.

AppleTalk couldn't compete with TCP/IP in the Internet era, but the idea of ​​a network that runs itself didn't die. In the TCP/IP world, Apple markets it under the name Bonjour (formerly Rendezvous).

mDNS/DNS-SD are one of the key technologies in the design of a modern print and scan stack. In addition, they can be used in the “cloud”, allowing individual components of a cloud service to find each other, provided that they are connected to the same local network, real or virtual.

In this article, I will tell you how this whole structure is arranged under the hood. This information can be useful for system and network programmers who have to work with the corresponding APIs, network administrators, and simply for a better understanding of how modern networks are arranged.

A bit of philosophy

A person gives names to the objects around him in order to be able to interact with them.

If the objects are devices connected to a local network, then the user's wishes will typically be:

  1. Get a list of devices by name in a specific category (e.g. printers, scanners, network storage)

  2. Select the required device from the list and start working with it.

Names should be clear so that the user can easily associate the name with a physical device.

If we want names to be assigned automatically, and not by the administrator, a completely working approach would be when the device name matches the name of its model (i.e., it is written on it), but can be changed if it is more convenient for a person (for example, if there are many similar devices). Computer names are usually assigned manually when installing the operating system.

Multicasting

The classic network management scheme involves the use of some dedicated controller, whose task is to centrally store the configuration of the entire network and distribute this information among connected devices.

In zeroconf networks, a centralized controller is not used. Configuration information is stored, in a distributed form, on the devices themselves and often coincides with the factory settings.

When there is a need to access this information, the request is sent to all participants in the network, and each one answers for itself. The device that requested the information collects all the responses and provides this information to the user (or the program that requested it).

UDP multicasting is used as a transport – a method of sending UDP packets in which the recipient is not a specific host, but a group of machines.

Unlike broadcasting, with multicasting, the recipients of packets are not all devices in the network, but only those that have explicitly expressed a desire to receive packets from a given group. Filtering usually occurs at the level of the network card controller. This reduces the load on the CPU and reduces battery consumption. in the case of mobile devices.

What does DNS have to do with it?

DNS, the Domain Name System, is a system that was originally created to link domain names to network and email addresses. Well, at least in RFC1034 This is roughly what is written.

However, the result was a decentralized, distributed key-value database of a completely general purpose.

The database consists of records, which in DNS terminology are called Resource Records (RRs). A record has a name, a class type, and a value. The search key is always a combination of name and type.

Class in our case is always IN (from the word Internet), so we will not focus on it in particular.

There are many types of records, and different types are used for different purposes. The type also determines how the contents of the record should be interpreted. For example, records of the type A contain IPv4 addresses, records of the type AAAAA – IPv6, etc.

So, to find out the IP address of a website www.example.com you need to request a record named “www.example.com” and type AThe response received will be the website address.

So, we have reduced the problem of getting an address from a name to a more general problem of searching a universal database.

And having such a universal database as DNS at hand, it can be easily adapted to solve other problems, which we will discuss further.

DNS itself is a very broad topic, and if anyone is interested, I have a separate article about it

Classic (Unicast) DNS is based on a hierarchy of servers. If someone needs to get information about a domain www.example.comthen first he or she must contact the so-called root servers to find out who is handling the domain. com. Then you will need to contact the domain server. comto find out who is handling the domain **example.com“”. And so on, until the final answer is received.

In the case of Multicast DNS, there is no such hierarchy of servers. The questioner asks the question of all the network, and everyone answers for themselves.

Names

General structure of the name

Since we still have a domain system, the names that are used as search keys are not simple names, but domain names.

A domain name consists of a sequence tags (labels in English) , which are written with a dot and read from right to left. In the name www.example.com three tags: “www”, “example” And “com”.

Domain names form a nested hierarchy in the sense that example.com – this is a subdomain of a domain comA www.example.com – domain example.comAs you add labels to the left, the namespace narrows, which is why domain names are read backwards.

Things that are not domains in nature are still written in pseudo-domain name syntax. For example, an IP address 192.168.0.1 will turn into 1.0.168.192.in-addr.arpa. A special top-level pseudo-domain, in-addr.arpa is reserved specifically for IPv4 addresses, and the address is written backwards because domain names are read from right to left.

A top-level domain is reserved for names managed via mDNS. .local. So a typical hostname in mDNS would look like this: hostname.local.

By the way, the dot as a separator is a way of externally representing a name. Internally, the DNS protocol is binary, and there is simply a sequence of lines.

Size restrictions

Names have limitations: no label can exceed 63 bytes, and the entire name cannot be longer than 255 bytes. And we are talking about bytes, not characters.

Character set

Classic DNS imposes very strict restrictions on what characters can be used in labels. A rather fancy encoding system called Punycode is used to represent foreign words.

However, the protocol itself does not use these restrictions to its advantage, they are just agreements. Which, however, specific DNS implementations can use within themselves.

Therefore, mDNS, without being burdened with the burden of compatibility with older implementations, allows the use of any valid UTF-8 sequences inside labels.

And at this point it is worth remembering that the size limits are expressed in bytes, not characters, and not every UTF-8 character fits into a byte.

Multicast DNS, like the classic one, is not case-sensitive to the characters in the names. However, in order not to carry around UNICODE tables, the authors of the standard explicitly stipulate that this insensitivity applies only to ASCII characters.

Service names

Types of services

DNS-SD operates with the concept of a service, not a device. A service is something that does some specific useful work. For example, it prints, scans documents, stores files, or works as a local web server.

One physical device can contain many services. For example, printing and scanning.

DNS-SD associates a service type with the network protocol the service uses to operate. For example, a printer running on the IPP protocol would use _ipp._tcp as the service name. A printer with a built-in LPR server will announce the service _printer._tcp. The standard service for an SMB server is _smb._tcpA device that supports multiple protocols will advertise a separate service for each protocol.

Service instances

To select a specific device from the list, you need to know its name. In DNS-SD terminology, this is called the service instance name.

DNS-SD is unusual in that the service instance names are both convenient for humans in that they look human-readable, and for computers in that they are not just a name but a unique identifier for a device within a local network.

For example, a printer instance name might look like this: :”Kyocera ECOSYS M2040dn._ipp._tcp.local.”and this is a real example (the suffix “_ipp._tcp.local.” is not shown to the user).

Instance names should not be confused with hostnames. The hostname for the same printer is KM7B6A91.localnot memorable and rather nondescript. The point here is that the user will only deal with human-readable names of instances, while host names for devices have a purely technical purpose and are usually not visible to the user.

Uniqueness of names

Instance and host names are unique within a local network. Together, devices take care of this themselves. Before a device or computer announces its presence on the network (called “publishing” in mDNS/DNS-SD terminology), it must ensure that the name is not already taken.

To do this, before starting to use the desired name, the device first polls the network for another device that is already using this name, and only then takes it.

There are many subtleties and nuances in this procedure. It is described in detail in RFC 6267, 8. Probing and Announcing on Startup.

It should be noted that not all names are unique in meaning. For example, if a name means “all printers on the network”, then all printers publish it, i.e. they give out their part of the overall response, but it is the device that publishes the name of a specific device.

In principle, the protocol allows several devices to act as one whole. That is, to publish one name to all and somehow be responsible for it together. At the same time, the protocol does not stipulate how exactly they should coordinate their joint efforts with each other.

Record Types

Now it's probably time to get a little technical, and first we'll talk a little about the basic types of DNS records.

DNS defines many different types of records, but for our purposes, the five that are of primary interest are:

  • A – network address, IPv4

  • AAAAA – network address, IPv6

  • PTR – pointer to another domain name

  • SRV – service descriptor

  • TXT – a text entry used to transmit a set of additional parameters in the format “key=value…”

A and AAAA records

These records are pretty simple. They link a host's domain name to its IP address.

PTR type records

Type entries PTR contain a domain name in their value. That is, we have a name at the input (search key) and some other name at the output (record value). Such records provide coherence in the DNS database and are used for quite a variety of purposes.

A simple example: to obtain a domain name by IP address, a PTR record is used, which “translates” the IP address, presented in the form of a domain, into a domain name. For example:

102.1.168.192.in-addr.arpa. -> KM7B6A91.local.

A more complex example is getting a list of specific devices providing this service by service type. For example, getting a list of all printers. But more on that later.

SRV type records

The SRV record type contains

For example, for the printer already used in the previous examples, it looks like this:

0 0 631 KM7B6A91.local.
~ ~ ~~~  ~~~~~~~~~~~~~
| |  |         | 
| |  |         `--------- hostname, он нужен, чтобы получить IP-адрес
| |  `------------------- TCP (или UDP) порт
| `---------------------- "вес"
`------------------------ приоритет

The mysterious parameters “weight” and “priority” came, along with the SRV record itself, from classical DNS and are described, along with other details, in RFC2782. There they are intended to set the priority when choosing between many similar services (for example, an e-mail sending service). In the case of mDNS/DNS-SD, the choice usually occurs from one option, and these parameters are not used.

The purpose of the remaining two parameters is quite obvious.

TXT type records

These records allow to provide any additional information about the service in the form of a set of values ​​(key=value,…). The specific set of parameters and their syntax depends on the service.

Here is a highly abbreviated example of a TXT record for the printer mentioned above:


pdl=image/pwg-raster,application/octet-stream,...   поддерживаемые форматы
ty=Kyocera ECOSYS M2040dn                           производитель+модель
Duplex=T                                            это дуплексный принтер
Color=F                                             не цветной
UUID=4509a320-00a0-008f-00b6-002507510eca           UUID устройства
. . .

Now it's all together

How to get a list of all printers on the network by name, and then the parameters of a specific printer? Let's look at it step by step. And at the same time, let's experiment a little.

Tools

For experiments we will need a utility capable of sending arbitrary mDNS requests and printing responses. I did not find such a utility in a ready-made form and wrote my own: mcdig.

The program is written in Go, and to run it, you need to compile it. Luckily, with Go, it's really easy. Even if you don't know the Go language, installation (once you have the compiler) is very simple and comes down to one command:

$ go install github.com/alexpevzner/mcdig@master

Go will download everything it needs, compile it, and post the result under the name ~go/bin/mcdig.

By the way, in principle this should also work under Windows, but I haven’t checked.

Searching for printers manually

For simplicity, we will limit ourselves to printers that operate on the IPP protocol. The service type name for IPP printers is _ipp._tcp.

Step 1: Find all instances of the service

Utility mcdig sends random mDNS queries, collects the results for a while, and then prints them in the “DNS zone file” format – text files describing the contents of the DNS database.

So:

$ mcdig _ipp._tcp.local. ptr
;; QUESTION PSEUDOSECTION:
;_ipp._tcp.local.	IN	 PTR

;; ANSWER SECTION:
_ipp._tcp.local.	4500	IN	PTR	Kyocera\ ECOSYS\ M2040dn._ipp._tcp.local.

;; AUTHORITY SECTION:
_ipp._tcp.local.	4500	IN	PTR	Kyocera\ ECOSYS\ M2040dn._ipp._tcp.local.

;; ADDITIONAL SECTION:
Kyocera\ ECOSYS\ M2040dn._ipp._tcp.local.       4500    IN      SRV     0 0 631 KM7B6A91.local.

Issuance mcdig resembles the output of the utility that system administrators are accustomed to digwith the only difference being that dig works with regular, classic DNS, and has a few more options.

Section QUESTION contains, in formal form, the question we asked. In this case, we asked for all PTR records for the name _ipp._tcp.localand all printers that support the IPP protocol must answer this question.

Section ANSWER contains the answer or answers (there may be many).

Section AUTHORITY contains information about who sent the response.

And finally, the section ADDITIONAL contains information that we have not requested, but which we are likely to request soon. Including it in ADDITIONAL section can speed up the process, saving several request/response turns. The information that gets there is not actually chosen randomly, on the principle of “let me send him this too”, but is very carefully regulated in RFC 6763, 12. DNS Additional Record Generation. But now we will not use it, but will manually go all the way to the end.

So, we requested a PTR record for the name .local and got a list of names of service instances that implement this:

_ipp._tcp.local
~~~~~~~~~~~~~~~
 |
 `-> PTR -> "Kyocera ECOSYS M2040dn._ipp._tcp.local" (имя экземпляра сервиса)

Let's also note that we received the answer in the domain _ipp._tcp.localand not just local – this way DNS-SD binds instance names to a specific service type.

Step 2. Get SRV and TXT records

So, we have already found the name of the service instance. In my case, it is a choice of one item, but if you experiment in a large office network, in which mDNS traffic is not prohibited by security rules, the output may well be a couple of screens of text.

Now we can get the SRV and TXT records:

$ mcdig Kyocera\ ECOSYS\ M2040dn._ipp._tcp.local. srv
;; ANSWER SECTION:
Kyocera\ ECOSYS\ M2040dn._ipp._tcp.local.   120    IN    SRV    0 0 631 KM7B6A91.local.
$ mcdig Kyocera\ ECOSYS\ M2040dn._ipp._tcp.local. txt
;; ANSWER SECTION:
Kyocera\ ECOSYS\ M2040dn._ipp._tcp.local.   4500   IN    TXT    "txtvers=1" "pdl=image/pwg-raster,..."

I've shortened the output a bit mcdigso as not to overload the article.

So, based on the service instance name, we get an SRV record containing the information needed to work with the service, and a TXT record containing additional technical details:

Kyocera ECOSYS M2040dn._ipp._tcp.local.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
 | `---> SRV (hostname, TCP port)
 `-----> TXT (дополнительная информация о сервисе)

Step 3. Obtain IP addresses

$ mcdig KM7B6A91.local. a
;; ANSWER SECTION:
KM7B6A91.local. 120     IN      A       192.168.1.102
$ mcdig KM7B6A91.local. aaaa
;; ANSWER SECTION:
KM7B6A91.local. 120     IN      AAAA    fe80::217:c8ff:fe7b:6a91

So, using the hostname obtained in the previous step, we get the IP addresses of the device:

KM7B6A91.local
~~~~~~~~~~~~~~
 | |
 | `---> A    (адрес IPv4)
 `-----> AAAA (адрес IPv6)

Nuances

Now let's talk about some of the nuances of this technology.

Multiple network interfaces

A computer can be connected to several networks at the same time. For example, WiFi and Ethernet. Or a local network and an office VPN.

It may happen that these networks are not connected to each other. In that case, their namespaces, from the mDNS point of view, are also not connected to each other. And it may happen, although with a small probability, that two different devices will choose the same name on different networks.

Unfortunately, the IP address also does not always uniquely identify the network. Ideally, an application using mDNS/DNS-SD should take into account in which of the local networks accessible from a given computer it has found a particular device, and make efforts to ensure that the connection to it occurs in this network (for example, by explicitly indicating the local IP address of the outgoing connection, binding it to the corresponding network interface).

Unfortunately, this is all quite complicated and does not look like what is written in network programming textbooks, so most programs do not do this.

IPv4 and IPv6

It would seem that there are no particular difficulties here. Everything is the same, except for the record type, which is used at the very end to obtain the IP address: A for IPv4, AAAA for IPv6.

In reality, IPv4 and IPv6 running on the same physical LAN behave like two different, unrelated, logical networks. Ideally, any device should register the same name on both networks and seek to resolve conflicts on both networks simultaneously. They usually do, but there may be nuances.

If we are not talking about computers, but about devices (for example, printers), firmware is very often buggy. For example, a request sent via IPv4 may or may not contain records related to IPv6, and vice versa. This should be taken into account.

Also, keep in mind that responses for different protocols do not arrive simultaneously. If you receive an IPv4 address, this does not mean that you have received an IPv6 address. It may arrive later. Or it may not arrive at all.

Reliability

Multicasts can be lost. This is especially noticeable in wireless networks, such as WiFi. Caching responses and constant network monitoring help. It is good when the system has an mDNS/DNS-SD daemon (such as Avahi in Linux), which constantly does this. It is worse if the protocol is implemented directly in the process that uses it (for example, with the help of an appropriate library). The system service has a lot of time after the system is started to “warm up” its cache. The application program must “think” quickly, and it is necessary to choose a compromise between the speed of initialization and reliability.

However, based on the experience of many years of support sane-airscanof which I am the author, I can say that, in general, mDNS/DNS-SD works reliably enough for everyday use.

Safety

Unfortunately, when using mDNS/DNS-SD there is no guarantee that the response received will be reliable. This is not a problem in a home network, and is not a problem in a network where the owner has full control and monitors the absence of foreign devices (for example, if mDNS is used in a private local network in the “cloud” to search for cloud service components), but it can become a problem in a network where all participants cannot be trusted. One possible attack vector is to slip in a fake service and arrange MITMintercepting traffic. Getting at least a selective copy of your organization's document flow can be very interesting and informative 🙂

Large corporate networks

In a large corporate network, there may be, for example, 50 identical devices in the field of view. Of these, the user may be interested in only two or three, but the rest will make the response very noisy.

DNS-SD includes some means to narrow the search range somewhat, but these means are very rudimentary. For example, in the printer settings you can usually specify a “location” (it is assumed that something like “Printers in the accounting department” will be entered there), but the protocol does not provide any more fine-grained settings.

Conclusion

In this article I tried to give some insight into how mDNS/DNS-SD works. I feel that the article is probably too technical. On the other hand, there is a lot left behind the scenes.

Unfortunately, modern networks are quite complex to study and describe. Technologies that aim to provide the user with a simple metaphor for working with a computer often turn out to be quite complex “under the hood”. This happens because their creators take the liberty and responsibility to hide all this complexity, offering on the surface an interface that is understandable and convenient for humans.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *