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:
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.