1.. _dns_resolve_interface:
2
3DNS Resolve
4###########
5
6.. contents::
7    :local:
8    :depth: 2
9
10Overview
11********
12
13The DNS resolver implements a basic DNS resolver according
14to `IETF RFC1035 on Domain Implementation and Specification <https://tools.ietf.org/html/rfc1035>`_.
15Supported DNS answers are IPv4/IPv6 addresses and CNAME.
16
17If a CNAME is received, the DNS resolver will create another DNS query.
18The number of additional queries is controlled by the
19:kconfig:option:`CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES` Kconfig variable.
20
21The multicast DNS (mDNS) client resolver support can be enabled by setting
22:kconfig:option:`CONFIG_MDNS_RESOLVER` Kconfig option.
23See `IETF RFC6762 <https://tools.ietf.org/html/rfc6762>`_ for more details
24about mDNS.
25
26The link-local multicast name resolution (LLMNR) client resolver support can be
27enabled by setting the :kconfig:option:`CONFIG_LLMNR_RESOLVER` Kconfig variable.
28See `IETF RFC4795 <https://tools.ietf.org/html/rfc4795>`_ for more details
29about LLMNR.
30
31For more information about DNS configuration variables, see:
32:zephyr_file:`subsys/net/lib/dns/Kconfig`. The DNS resolver API can be found at
33:zephyr_file:`include/zephyr/net/dns_resolve.h`.
34
35DNS-based service discovery queries described in
36`IETF RFC6763 <https://datatracker.ietf.org/doc/html/rfc6763>`_
37can be done by :c:func:`dns_resolve_service` API.
38The returned service descriptions are passed to user supplied callback
39and the API sets the address family to :c:macro:`AF_LOCAL` to indicate that
40the value is not an IPv4 or IPv6 address but a service description.
41
42Example:
43
44.. code-block:: c
45
46   #include <zephyr/net/dns_resolve.h>
47
48   #define MAX_STR_LEN CONFIG_DNS_RESOLVER_MAX_NAME_LEN
49
50   static void dns_result_cb(enum dns_resolve_status status,
51                             struct dns_addrinfo *info,
52                             void *user_data)
53   {
54        if (status == DNS_EAI_CANCELED) {
55                /* dns: Timeout while resolving name */
56                return;
57	}
58
59        if (status == DNS_EAI_INPROGRESS && info) {
60                char str[MAX_STR_LEN + 1];
61
62                if (info->ai_family == AF_INET) {
63                        net_addr_ntop(AF_INET,
64                                      &net_sin(&info->ai_addr)->sin_addr,
65                                      str, NET_IPV4_ADDR_LEN);
66                } else if (info->ai_family == AF_INET6) {
67                        net_addr_ntop(AF_INET6,
68                                      &net_sin6(&info->ai_addr)->sin6_addr,
69                                      str, NET_IPV6_ADDR_LEN);
70                } else if (info->ai_family == AF_LOCAL) {
71                        /* service discovery */
72                        memset(str, 0, MAX_STR_LEN);
73                        memcpy(str, info->ai_canonname,
74                               MIN(info->ai_addrlen, MAX_STR_LEN));
75                } else {
76                        strncpy(str, "Invalid proto family", MAX_STR_LEN + 1);
77                }
78
79                str[MAX_STR_LEN] = '\0';
80
81                printk("dns: %s\n", str);
82                return;
83        }
84
85        if (status == DNS_EAI_ALLDONE) {
86                printk("dns: All results received\n");
87                return;
88        }
89
90        if (status == DNS_EAI_FAIL) {
91                printk("dns: No such name found.\n");
92                return;
93        }
94
95        printk("dns: Unhandled status %d received (errno %d)\n", status, errno);
96   }
97
98   #define DNS_TIMEOUT (MSEC_PER_SEC * 5) /* in ms */
99
100   static void discover_service(void)
101   {
102        int ret = dns_resolve_service(dns_resolve_get_default(),
103                                      "_http._tcp.dns-sd.org",
104                                      NULL, dns_result_cb,
105                                      NULL, DNS_TIMEOUT);
106        ...
107   }
108
109The above query would return output like this:
110
111.. code-block: console
112
113    Query for '_http._tcp.dns-sd.org' sent.
114    dns: . * cnn, world news._http._tcp.dns-sd.org
115    dns: .source de télévision, département de langues._http._tcp.dns-sd.org
116    dns: . * multicast dns._http._tcp.dns-sd.org
117    dns: . * amazon.com, on-line shopping._http._tcp.dns-sd.org
118    dns: . * google, searching the web._http._tcp.dns-sd.org
119    dns: . * ebay, online auctions._http._tcp.dns-sd.org
120    dns: . * apple, makers of the ipod._http._tcp.dns-sd.org
121    dns: . * yahoo, maps, weather, and stock quotes._http._tcp.dns-sd.org
122    dns: .about bonjour in web browsers._http._tcp.dns-sd.org
123    dns: .π._http._tcp.•bullets•.dns-sd.org
124    dns: . * dns service discovery._http._tcp.dns-sd.org
125    dns: . * wired, technology, culture, business, politics._http._tcp.dns-sd.org
126    dns: . * slashdot, news for nerds, stuff that matters._http._tcp.dns-sd.org
127    dns: . * bbc, world news._http._tcp.dns-sd.org
128    dns: .stuart’s printer._http._tcp.dns-sd.org
129    dns: . * zeroconf._http._tcp.dns-sd.org
130    dns: All results received
131
132As the service discovery query could return long strings and the packet size could
133be large, you might need to adjust following Kconfig options:
134
135- :kconfig:option:`CONFIG_DNS_RESOLVER_MAX_ANSWER_SIZE`. This tells the maximum size of the
136  answer, typical value for this option could be 1024. The default size for this option is
137  512 bytes.
138
139- :kconfig:option:`CONFIG_DNS_RESOLVER_MAX_NAME_LEN`. This tells the maximum length of the
140  returned name. The value depends on your expected data size, typical value might be 128 bytes.
141
142Sample usage
143************
144
145See :zephyr:code-sample:`dns-resolve` sample application for details.
146
147API Reference
148*************
149
150.. doxygengroup:: dns_resolve
151