DNS Resolve
Overview
The DNS resolver implements a basic DNS resolver according to IETF RFC1035 on Domain Implementation and Specification. Supported DNS answers are IPv4/IPv6 addresses and CNAME.
If a CNAME is received, the DNS resolver will create another DNS query.
The number of additional queries is controlled by the
CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES
Kconfig variable.
The multicast DNS (mDNS) client resolver support can be enabled by setting
CONFIG_MDNS_RESOLVER
Kconfig option.
See IETF RFC6762 for more details
about mDNS.
The link-local multicast name resolution (LLMNR) client resolver support can be
enabled by setting the CONFIG_LLMNR_RESOLVER
Kconfig variable.
See IETF RFC4795 for more details
about LLMNR.
For more information about DNS configuration variables, see: subsys/net/lib/dns/Kconfig. The DNS resolver API can be found at include/zephyr/net/dns_resolve.h.
DNS-based service discovery queries described in
IETF RFC6763
can be done by dns_resolve_service()
API.
The returned service descriptions are passed to user supplied callback
and the API sets the address family to AF_LOCAL
to indicate that
the value is not an IPv4 or IPv6 address but a service description.
Example:
#include <zephyr/net/dns_resolve.h>
#define MAX_STR_LEN CONFIG_DNS_RESOLVER_MAX_NAME_LEN
static void dns_result_cb(enum dns_resolve_status status,
struct dns_addrinfo *info,
void *user_data)
{
if (status == DNS_EAI_CANCELED) {
/* dns: Timeout while resolving name */
return;
}
if (status == DNS_EAI_INPROGRESS && info) {
char str[MAX_STR_LEN + 1];
if (info->ai_family == AF_INET) {
net_addr_ntop(AF_INET,
&net_sin(&info->ai_addr)->sin_addr,
str, NET_IPV4_ADDR_LEN);
} else if (info->ai_family == AF_INET6) {
net_addr_ntop(AF_INET6,
&net_sin6(&info->ai_addr)->sin6_addr,
str, NET_IPV6_ADDR_LEN);
} else if (info->ai_family == AF_LOCAL) {
/* service discovery */
memset(str, 0, MAX_STR_LEN);
memcpy(str, info->ai_canonname,
MIN(info->ai_addrlen, MAX_STR_LEN));
} else {
strncpy(str, "Invalid proto family", MAX_STR_LEN + 1);
}
str[MAX_STR_LEN] = '\0';
printk("dns: %s\n", str);
return;
}
if (status == DNS_EAI_ALLDONE) {
printk("dns: All results received\n");
return;
}
if (status == DNS_EAI_FAIL) {
printk("dns: No such name found.\n");
return;
}
printk("dns: Unhandled status %d received (errno %d)\n", status, errno);
}
#define DNS_TIMEOUT (MSEC_PER_SEC * 5) /* in ms */
static void discover_service(void)
{
int ret = dns_resolve_service(dns_resolve_get_default(),
"_http._tcp.dns-sd.org",
NULL, dns_result_cb,
NULL, DNS_TIMEOUT);
...
}
The above query would return output like this:
As the service discovery query could return long strings and the packet size could be large, you might need to adjust following Kconfig options:
CONFIG_DNS_RESOLVER_MAX_ANSWER_SIZE
. This tells the maximum size of the answer, typical value for this option could be 1024. The default size for this option is 512 bytes.CONFIG_DNS_RESOLVER_MAX_NAME_LEN
. This tells the maximum length of the returned name. The value depends on your expected data size, typical value might be 128 bytes.
Sample usage
See DNS resolve sample application for details.