D. J. Bernstein
Internet publication

The dns library

The djbdns package features a new client library designed to replace the old BIND res_*/dn_* library.

High-level lookups

The dns library provides several easy-to-use DNS lookup routines: dns_ip4, dns_ip4_qualify, dns_name4, dns_mx, and dns_txt.

dns_ip4_qualify supports the traditional configuration mechanisms for hostname rewriting: $LOCALDOMAIN, /etc/resolv.conf, and gethostname. It also supports a powerful new user-controlled rewriting mechanism.

The functions that read /etc/resolv.conf automatically reread it every ten minutes, so system administrators don't have to kill long-running programs.

Low-level lookups

The dns_domain_* and dns_packet_* functions make it easy to safely parse DNS packets. The dns_transmit_* functions send DNS queries of arbitrary types to arbitrary servers. These are the functions used in the dnscache program.


The dns library, unlike the BIND client library, has no problems looking up addresses for non-ASCII domain names.

Asynchronous lookups

UNIX offers three levels of support for parallel DNS lookups:
  1. Multiple processes. Any client library can be used here.
  2. Multiple threads. The client library must be threadable. (This means that, in functions that wait for responses, global variables are protected with mutexes, and are not used while the function is waiting. Other functions can be mutexed by the caller.) Thread creation is generally faster than process creation.
  3. Event handling with poll or select. The client library must be asynchronous. (This means that none of the functions wait for responses. Event information is passed to the caller.) Event handling is generally the fastest solution, but puts the most stringent requirements on the client library. Asynchronous libraries are automatically threadable.

The dns_transmit_* functions are asynchronous. The high-level features of dns_ip4, dns_name4, etc. are available as asynchronous functions: dns_ip4_packet, dns_name4_packet, etc. There is a sample dnsfilter program that shows how to do many PTR lookups in parallel.

Memory use

The old res_query function places its packets in a user-supplied buffer. The buffer is inevitably much too large for typical results, wasting memory, and too small for large results, making lookups fail on occasion.

In contrast, the dns functions dynamically allocate the right amount of space for incoming DNS packets and for final results.