A couple of decades ago Daniel Stenberg started looking for an asynchronous DNS resolver library to use in libcurl. Through this process, someone pointed out the ares library (archived here) and eureka! This was almost exactly what he was looking for, for use in libcurl. We started expanding it and soon discovered that the ares author wasn’t prepared to accept the changes we deemed necessary, and so c-ares was born.

Over the course of the last couple of decades, the code may no longer resemble the original ares code, but the public API is still heavily influenced by it as we strive to maintain API and ABI compatibility across versions.

Resolver Library Requirements

1. Interface

  • Asynchronous interface should be based on non-blocking sockets.
  • Must not use signals as a mean of communication.

2. Queries

  • Must support both IPv4 and IPv6 addresses.
  • Must support hostname and address lookup (A and PTR types)
  • Must support other types of lookup (e.g. CNAME and MX types)

3. Integration

  • Should integrate easily with applications.

4. Portability

  • Must be portable to most commonly used platforms (Linux, Solaris, Win32, etc).
  • Should be portable to as many platforms as possible.
  • Should not rely on hardware or compiler specifics, e.g. endianess and size/alignment of primitive types.
  • Should be no worse, and optimally better than the system’s native resolver.

5. Multi-threading

  • Must not require multi-threading.
  • Must work correctly in multi-threaded environments.

6. Licensing

  • Must allow use in Open Source and proprietary projects.

What Other Libraries Are There?

Some of these libraries existed at the time we started looking for one to use, but several have appeared or changed a lot since.

  • glibc-2.2.4: (and maybe a few earlier releases) provides a new function getaddrinfo_a() – similar to getaddrinfo(), but asynchronous. results can be collected by polling or notified using a signal. This is probably the right thing to do on linux, although the use of a signal handler within the library could be problematic (if a linking application also wants to use the same signal).
  • ADNS: ADNS is a GPL library which provides async DNS lookup.
  • Mozilla netlib: Provides an async DNS lookup abstraction, and per-platform backend implementations. it’s written on top of the NSPR (portable runtime), and so it’s use would require a whole chunk of Mozilla code.
  • arlib: BIND v4.9.5’s contrib section had a thing called arlib, from Darren Reed. looks pretty simple. its licence prohibits redistribution without explicit permission. It doesn’t seem to be in BIND9 though, so it might not work anymore.
  • FireDNS: GPL. We asked the author about reconsidering the license. No luck.
  • djbdns: Written by Dan Bernstein and dedicated to the public domain.
  • Poslib: GPL. A DNS client/server library written in C++. Available for many platforms, including Linux, FreeBSD, other Unices and Windows.
  • UDNS: LGPL license. A newcomer that seems to address claimed shortcomings in ADNS and c-ares.
  • dns.c: MIT-style license. A recursive, reentrant, non-blocking DNS resolver library in a single .c file.