The DNS Resolver allows a user to translate a hostname to an IP address, an IP address to a hostname, and to retrieve information about a host's mail exchangers (which is necessary to send SMTP e-mail). If you have purchased the Treck DNS resolver, the following API will automatically be made available.
Note: the Dynamic DNS Update feature is a separate product that is documented separately.
- Initialize the DNS service. This must be called before any other DNS API call is made.
- Specify the IPv4 or IPv6 address of the primary and/or secondary DNS servers to retrieve hostname information from. This function replaces the IPv4-only function tfDnsSetServer().
- Sets various options regarding the operation of DNS: timeout lengths, number of retries, etc. This function replaces tfDnsSetOption().
- Invalidates the DNS cache. Because there may be outstanding DNS queries the user is not allowed to clear the cache, but the user is allowed to invalidate the cache, making all current cache entries unusable. Outstanding DNS queries will be immediately timed out and will return TM_EANSWER.
- Get a list of IP addresses for a given hostname (e.g. "www.treck.com" might resolve to 10.2.3.4). Function tfDnsGetHostByName() is limited in that it returns a single IPv4 address only.
- Get the hostname for a given IP address (also called a reverse DNS lookup). Function tfDnsGetHostByAddr() is limited in that supports IPv4 only.
- Returns the first MX record in the list (tfNgDnsGetMailHost()) and then retrieves any records that follow (tfNgDnsGetNextMailHost()). Please see below for more information on using MX records. Functions tfDnsGetMailHost() and tfDnsGetNextMailHost() support IPv4 only.
- Get a list of servers for the requested service. IP addresses and ports are returned in order of server priority, highest first, via consecutive calls to tfDnsGetSrvHost(). By default, this API is removed to reduce code size. To enable this API, uncomment compile time macro TM_DNS_USE_SRV in trsystem.h.
Any of the user interface calls may return an error from the Treck stack or from the DNS server. The errors from the Treck stack are the normal socket errors (e.g., TM_ENOMEM, TM_EHOSTUNREACH). Errors returned from the DNS server are outlined below (derived from RFC 1035):
TM_DNS_EFORMAT Format error - The name server was unable to interpret the query. TM_DNS_ESERVER Server Failure - The name server was unable to process this query due to a problem with the name server. TM_DNS_ENAME_ERROR Name Error - Meaningful only for responses from an authoritative name server, this code signifies that the domain name referenced in the query does not exist. TM_DNS_ENOT_IMPLEM Not Implemented - The name server does not support the requested kind of query. TM_DNS_EREFUSED Refused - The name server refuses to perform the specified operation for policy reasons. For example, a name server may not wish to provide the information to the particular requester, or a name server may not wish to perform a particular operation (e.g., zone transfer) for particular data. TM_DNS_EANSWER No answer received from name server (i.e., response packet received, but it did not contain the answer to our query). TM_DNS_ECACHE_FULL The DNS query could not be honored because the request/reply cache is full. By default, Treck limits the DNS cache to 10 entries or less. See tfDnsSetUserOption() and tfDnsCacheInvalidate() for more information.
The call to perform a DNS function will simply block until the operation is complete (or an error is received). However, with non-blocking mode it is necessary to poll the DNS Resolver to determine if the operation has completed. If an operation is still in progress, the call will return TM_EWOULDBLOCK. If an error code other than TM_EWOULDBLOCK is received, the operation has completed.
Mail Exchanger (MX) Records
Each hostname contains a list of machines that are willing to accept mail destined for that hostname. This is necessary should one of the machines be unable to receive mail. Each one of the hosts in this list contains a preference value that indicates the order that these hosts should be used. An e-mail program should first attempt delivery to the hostname with the lowest preference value, and if unable to connect, to attempt delivery to the hostname with the next highest preference. For instance, "treck.com" may have the following MX entries:
mail1.example.com 10 220.127.116.11 mail2.example.com 20 18.104.22.168 mail3.example.com 30 22.214.171.124
Mail should first be sent to mail1.treck.com. If that fails it should be sent to mail2.treck.com and so on. This behavior can be emulated with the Treck resolver by first calling tfDnsGetMailHost() and then repeatedly calling tfDnsGetNextMailHost(), which will return TM_EANSWER when no more records are available. With each call to tfDnsGetNextMailHost(), the IP address and preference value of the previous lookup must be included. For instance, the following code retrieves all three entries in the example above:
unsigned short mxPref1, mxPref2, mxPref3; ttUserIpAddress ipAddress1, ipAddress2, ipAddress3; /* Get the first MX record (mail1.example.com) */ errorCode = tfDnsGetMailHost("example.com", &ipAddress1, &mxPref1); /* Get the second MX record (mail2.example.com) */ errorCode = tfDnsGetNextMailHost("example.com", ipAddress1, mxPref1, &ipAddress2, &mxPref2); /* * Get the third MX record (mail3.example.com) * If tfDnsGetNextMailHost were called with ipAddress3 * and mxPref3, it would return TM_EANSWER. */ errorCode = tfDnsGetNextMailHost("example.com", ipAddress2, mxPref3, &ipAddress3, &mxPref3);
The Treck DNS resolver can optionally apply a list of domain suffixes when trying to resolve a hostname that may not be a fully qualified domain name. Domain search names can be provided manually or automatically as part of a DHCP response. The Domain Search feature is disabled by default and can be enabled by uncommenting the following compile time macro in your trsystem.h.
The following API is provided for manually configuring domain search names. The list of user-supplied names is maintained globally for all interfaces and is independent of any domain search information supplied by DHCP.
The Treck DHCP client may be enabled to provide additional domain information, if you have purchased the product. DHCP options 119 (Domain Search), 15 (Domain) and 81 (Client FQDN) are candidates for supplying domain information. You will need to enable the appropriate code by uncommenting the following compile time macros in your trsystem.h.
#define TM_USE_DHCP /* DHCP client + Option 15 */ #define TM_USE_DHCP_DOMAIN_SEARCH /* Option 119 */ #define TM_USE_DHCP_FQDN /* Option 81 */
The Treck DHCPv6 client may be enabled to provide additional domain information, if you have purchased the product. DHCPv6 options 24 (Domain Search) and 39 (Client FQDN) are candidates for supplying domain information. You will need to enable the appropriate code by uncommenting the following compile time macros in your trsystem.h.
#define TM_6_USE_DHCP /* DHCPv6 client + Option 24 */ #define TM_6_DHCP_USE_FQDN /* Option 39 */
Manually supplied domains are searched prior to domains supplied by DHCP.
Hosts Table Support
The Treck Hosts Table is similar to the UNIX hosts file. It allows a user-defined name to be assigned to an IP address. A subsequent look-up on the name will go first to the Hosts Table and, failing resolution, will attempt to query an available name server. The Hosts Table can be managed with the following APIs:
Default Address Selection for IPv6 Table Management APIs
RFC 3484 introduces a DNS policy table that provides the user with a mechanism to tune the behavior of the ordering tests performed by the getaddrinfo() API. This allows the user to partially determine which address(es) the Treck stack considers the "best".
For more information on the DNS policy table, including some illustrative configuration examples, please refer to RFC 3484.
Here is the default policy table from the RFC:
If the user wishes to modify this table, they may do so with the following APIs:
Strong End System Model Support
You can enable the Strong End System Model by defining compile time macro TM_USE_STRONG_ESL. When the feature has been enabled, you can restrict DNS traffic to one specific interface (possibly for security reasons).
To restrict DNS traffic to one interface, call tfDnsSetUserOption() and specify option TM_DNS_OPTION_BINDTODEVICE. Outbound DNS queries will be sent from the specified interface and inbound DNS responses coming in on any other interface will be ignored.