Chapter 165. DNS

Table of Contents
DNS API
DNS Client Testing

DNS API

The DNS client uses the normal BSD API for performing lookups: gethostbyname(), gethostbyaddr(), getaddrinfo(), getnameinfo().

There are a few restrictions:

  • If the DNS server returns multiple authoritive records for a host name to gethostbyname, the hostent will only contain a record for the first entry. If multiple records are desired, use getaddrinfo, which will return multiple results.

  • The code has been made thread safe. ie multiple threads may call gethostbyname() without causing problems to the hostent structure returned. What is not safe is one thread using both gethostbyname() and gethostbyaddr(). A call to one will destroy the results from the previous call to the other function. getaddrinfo() and getnameinfo() are thread safe and so these are the preferred interfaces. They are also address family independent so making it easier to port code to IPv6.

  • The DNS client will only return IPv4 addresses to RedBoot. At the moment this is not really a limitation, since RedBoot only supports IPv4 and not IPv6.

To initialise the DNS client the following function must be called:

#include <network.h>
int cyg_dns_res_start(char * dns_server)

Where dns_server is the address of the DNS server. The address must be in numeric form and can be either an IPv4 or an IPv6 address.

There also exists a deprecated function to start the DNS client:

int cyg_dns_res_init(struct in_addr *dns_server)

where dns_server is the address of the DNS server the client should query. The address should be in network order and can only be an IPv4 address.

On error both this function returns -1, otherwise 0 for success. If lookups are attemped before this function has been called, they will fail and return NULL, unless numeric host addresses are passed. In this cause, the address will be converted and returned without the need for a lookup.

A default, hard coded, server may be specified in the CDL option CYGDAT_NS_DNS_DEFAULT_SERVER. The use of this is controlled by CYGPKG_NS_DNS_DEFAULT. If this is enabled, init_all_network_interfaces() will initialize the resolver with the hard coded address. The DHCP client or user code my override this address by calling cyg_dns_res_init again.

The DNS client understands the concepts of the target being in a domain. By default no domain will be used. Host name lookups should be for fully qualified names. The domain name can be set and retrieved using the functions:

int getdomainname(char *name, size_t len);

int setdomainname(const char *name, size_t len);

Alternatively, a hard coded domain name can be set using CDL. The boolean CYGPKG_NS_DNS_DOMAINNAME enables this and the domain name is taken from CYGPKG_NS_DNS_DOMAINNAME_NAME.

Once set, the DNS client will use some simple heuristics when deciding how to use the domainname. If the name given to the client ends with a "." it is assumed to be a FQDN and the domain name will not be used. If the name contains a "." somewhere within it, first a lookup will be performed without the domainname. If that fails the domainname will be appended and looked up. If the name does not contain a ".", the domainname is appended and used for the first query. If that fails, the unadorned name is lookup.

The getaddrinfo will return both IPv4 and IPv6 addresses for a given host name, when IPv6 is enabled in the eCos configuration. The CDL option CYGOPT_NS_DNS_FIRST_FAMILY controls the order IPv6 and IPv4 addresses are returned in the linked list of addrinfo structures. If the value AF_INET is used, the IPv4 addresses will be first. If the value AF_INET6, which is the default, is used, IPv6 address will be first. This ordering will control how clients attempt to connect to servers, ie using IPv6 or IPv4 first.

2017-02-09
Documentation license for this page: Open Publication License