DNS-SD (DNS-Based Service Discovery)
Приложению нужно не «адрес хоста», а «все веб-серверы и принтеры в этой сети». DNS-SD отвечает на такой вопрос обычными записями DNS: PTR перечисляет экземпляры службы, SRV говорит, где каждый живёт, TXT добавляет параметры.
Обновлено Редакция GAW
DNS-SD (DNS-Based Service Discovery, обнаружение служб на основе DNS) — соглашение RFC 6763 о том, как описывать сетевые службы обычными записями DNS, чтобы клиент мог найти все экземпляры нужного типа и подключиться к любому из них. Новых типов записей и кодов операций стандарт не вводит (разд. 1): служба описывается тремя существующими записями, а запросы идут либо через mDNS в домене .local без всякой настройки, либо через обычный одноадресный DNS в домене организации.
Три записи на одну службу
| Запись | Имя | Содержимое | Роль |
|---|---|---|---|
| PTR | <Service>.<Domain> | имя экземпляра | перечисление: «какие есть принтеры» |
| SRV | <Instance>.<Service>.<Domain> | целевой хост и порт | разрешение: «где живёт этот принтер» |
| TXT | <Instance>.<Service>.<Domain> | строки key=value | параметры экземпляра |
Имя экземпляра службы строится как <Instance>.<Service>.<Domain> (разд. 4.1). <Service> — две метки: подчёркивание плюс имя службы из реестра IANA (до 15 символов — буквы, цифры, дефисы) и _tcp для служб поверх TCP либо _udp для всех прочих транспортов, включая UDP (разд. 4.1.2, 7). <Domain> — local. для mDNS или обычный домен (разд. 4.1.3). <Instance> — человекочитаемое имя в UTF-8, например «Jhon's ESP32 Web Server», одной меткой DNS до 63 байт (разд. 4.1.1).
Запрос PTR на _http._tcp.local работает как листинг каталога: в ответ приходит набор имён экземпляров. Для выбранного экземпляра клиент запрашивает SRV и TXT (разд. 5). Запись SRV снимает нужду в заранее закреплённых портах: каждое устройство объявляет тот порт, который само выбрало. При одном экземпляре поля priority и weight в SRV равны нулю. Чтобы не плодить обмены, ответчик кладёт SRV, TXT и адресные записи A/AAAA в дополнительную секцию уже в ответ на PTR (разд. 12.1).
Запись TXT
TXT — последовательность строк, каждая из байта длины и 0–255 байт данных, в формате key=value; ключ — всё до первого знака = (разд. 6.1, 6.3). Пример из разд. 6.6: 0x09 key=value, 0x08 paper=A4, 0x07 passreq — последняя строка без значения. Ключ не короче одного символа и желательно не длиннее девяти (разд. 6.4). Пустой TXT запрещён: вместо него одна пустая строка, то есть один нулевой байт. Размеры по разд. 6.2: типично до 200 байт, до 400 байт укладывается в сообщение DNS 512 байт, до 1300 — в кадр Ethernet 1500 байт; больше 1300 байт не рекомендуется.
На микроконтроллере
На ESP32 компонент mDNS из ESP-Protocols объявляет службу одним вызовом: mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0); параметры TXT задаются массивом mdns_txt_item_t, например {"board", "{esp32}"}, а имя экземпляра — mdns_service_instance_name_set. Поиск с платы — mdns_query_ptr("_http", "_tcp", 3000, 20, &results): в результате PTR (имя экземпляра), SRV (hostname.local:port), TXT и адреса. В Zephyr запрос DNS-SD делает dns_resolve_service(), описание службы приходит в обратный вызов с семейством AF_LOCAL; ответы бывают длинными, поэтому CONFIG_DNS_RESOLVER_MAX_ANSWER_SIZE поднимают с 512 до 1024 байт.
Для устройства это удобный способ сообщить, что на нём есть веб-интерфейс, брокер MQTT или сервер CoAP, не заставляя пользователя искать адрес. Служба объявляется один раз, а запросы обрабатывает стек mDNS; что из этого стоит реализовать самому, а что оставить библиотеке, — в статье о реализации протоколов.
Частые вопросы
Чем DNS-SD отличается от mDNS?
Это два разных протокола, которые обычно работают вместе. mDNS (RFC 6762) — транспорт: как доставить DNS-запрос всем узлам сегмента без сервера и получить ответ. DNS-SD (RFC 6763) — соглашение об именах и записях: как описать службу записями PTR, SRV и TXT, чтобы клиент мог её найти. DNS-SD работает и поверх обычного одноадресного DNS, тогда вместо .local используется домен организации, а записи публикуют через DNS Update.
Как клиент находит, например, все веб-серверы в сети?
Запрашивает записи PTR для имени _http._tcp.local и получает список имён экземпляров вида «Jhon's ESP32 Web Server._http._tcp.local». Затем для выбранного экземпляра запрашивает SRV (там имя хоста и порт, скажем my-esp32.local:80) и TXT с параметрами. По правилам разд. 12.1 ответчик кладёт SRV, TXT и адреса A/AAAA в дополнительную секцию уже в ответ на PTR, так что обычно хватает одного обмена.
Что писать в запись TXT и какого размера она может быть?
Набор строк key=value, каждая не длиннее 255 байт, ключ желательно до 9 символов; пустой TXT запрещён — вместо него одна пустая строка. RFC 6763 (разд. 6.2) рассчитывает на TXT до 200 байт; до 400 байт ещё помещается в классическое сообщение DNS в 512 байт, до 1300 — в кадр Ethernet, а больше 1300 байт не рекомендуется. Значения — параметры службы: путь, версия, модель платы.
Источники
- S. Cheshire, M. Krochmal. DNS-Based Service Discovery. RFC 6763, February 2013 — разд. 1: экземпляр службы описывают записи SRV и TXT с именем <Instance>.<Service>.<Domain>, SRV даёт целевой хост и порт, TXT — пары ключ/значение, список экземпляров — запрос PTR на имя <Service>.<Domain>; новых типов записей и кодов нет; с mDNS работает без настройки, с обычным DNS нужны домен и ключи DNS Update; разд. 4.1: запрос PTR как листинг каталога, Service Instance Name = <Instance>.<Service>.<Domain>; разд. 4.1.2 и 7: <Service> — две метки, подчёркивание плюс имя службы по RFC 6335 и _tcp для TCP либо _udp для всех остальных транспортов, имя службы до 15 символов из букв, цифр и дефисов; разд. 4.1.1: имя экземпляра — произвольный текст Net-Unicode (UTF-8) без управляющих символов, хранится одной меткой DNS до 63 байт; разд. 4.1.3: <Domain> — local. для mDNS или обычный домен; разд. 5: клиент запрашивает SRV и TXT экземпляра, SRV снимает нужду в заранее закреплённых портах, при одном экземпляре priority и weight равны 0; разд. 6.1: TXT до 65 535 байт, в пакете mDNS не более 9000 байт — около 8900 на TXT, запись — набор строк «байт длины + 0–255 байт», пустой TXT запрещён — одна пустая строка (нулевой байт); разд. 6.2: типичный TXT до 200 байт, до 400 байт входит в сообщение DNS 512 байт, до 1300 — в кадр Ethernet 1500 байт, больше 1300 не рекомендуется; разд. 6.3: каждая строка — key=value, ключ — всё до первого «=»; разд. 6.4: ключ не короче 1 символа и желательно не длиннее 9; разд. 6.6: пример 0x09 key=value, 0x08 paper=A4, 0x07 passreq; разд. 12.1–12.2: в ответ на PTR добавлять SRV, TXT и адресные записи A/AAAA, в ответ на SRV — A/AAAA
- Espressif. ESP-Protocols documentation, latest: mDNS Service (ESP32) — службу объявляют mdns_service_add(instance, "_http", "_tcp", 80, txt, n): тип службы и протокол с подчёркиванием, порт, массив mdns_txt_item_t вида {"board", "{esp32}"}; mdns_service_instance_name_set задаёт имя экземпляра; mdns_query_ptr("_http", "_tcp", 3000, 20, &results) ищет службы, результат содержит PTR (instance_name), SRV (hostname.local:port), TXT и адреса A/AAAA; примеры типов _http, _arduino, _smb, _ipp, _printer, _ftp
- Zephyr Project. Zephyr Project Documentation, latest: Networking APIs — DNS Resolve — запросы обнаружения служб по RFC 6763 делает dns_resolve_service(), в примере — имя _http._tcp.dns-sd.org с таймаутом 5 с; описание службы приходит в обратный вызов с семейством AF_LOCAL; ответ может быть большим — CONFIG_DNS_RESOLVER_MAX_ANSWER_SIZE по умолчанию 512 байт, типично 1024, CONFIG_DNS_RESOLVER_MAX_NAME_LEN около 128
Нашли ошибку? ·
Смотрите также
- mDNSРазрешение имён .local групповыми DNS-запросами на 224.0.0.251 / FF02::FB, порт 5353, без сервера
- UDPДатаграммы без соединения: заголовок 8 байт, порты, нет гарантий доставки
- TCPНадёжный поток байтов поверх IP: рукопожатие, порты, подтверждения, keep-alive
- CoAPПротокол запрос-ответ поверх UDP для ограниченных устройств: типы сообщений, методы, таймауты, порт 5683
- MQTTПротокол издатель — подписчик через брокер: топики, QoS, retain, Last Will
- ESP32ESP32, S2, S3, C2, C3, C5, C6, H2, P4: ядра, радио, USB, GPIO — сравнение и выбор
- Реализация протокола обменаКадры по паузе, длине и разделителю, COBS, CRC-16, таймауты, разбор потока