CLI tool
c-ares/c-ares avatar
c-ares/c-ares

c-ares: A C89 DNS Resolver That Prioritizes Async and Security

A C library for asynchronous DNS requests

2,192 stars687 forksCMIT

At a glance

What is it?
c-ares is a C library for asynchronous DNS resolution, built for applications that cannot block on system resolvers. It offers broad platform support, modern RFC coverage, and a strong security posture, but its C API and manual event loop integration demand careful handling.
Who is it for?
Adopt c-ares if you write a network application in C that needs non-blocking DNS resolution or parallel queries, and you value a library with over two decades of maintenance, modern RFC support, and security fuzzing. Avoid it if you prefer a synchronous, high-level resolver or if your team lacks experience with C event loops and manual memory management.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 15 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 14, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The Problem: Blocking and Serial DNS Queries

Most operating system resolvers are synchronous. A call to resolve a hostname blocks the calling thread until the query completes, which can stall a network application for seconds. c-ares solves this by providing an asynchronous interface: you start a query, get a callback or poll a socket, and continue doing other work. The README states it was originally intended for applications that need DNS queries without blocking or need to perform multiple queries in parallel. This is the core problem it addresses. It is for C developers building servers, clients, or tools where a stalled event loop is unacceptable, or where you need to resolve many names at once, such as a mail server processing incoming connections.

How c-ares Works: Event Loops and Callbacks

The library abstracts the DNS protocol, but it does not hide the asynchronous nature. You do not call a blocking function and get a result. Instead, you create a channel, submit queries, and then integrate with your own event loop. The library exposes file descriptors that you must watch for readability and writability. When an event occurs, you call the library's processing function, which may invoke your callback with the resolved address or an error. The README mentions that c-ares provides interfaces for asynchronous queries while trying to abstract the intricacies of the DNS protocol. In practice, this means you manage state: you track outstanding queries, handle timeouts, and ensure you call the library's tick function regularly. This design gives you control over scheduling, but it adds complexity compared to a blocking resolver.

Getting Started: Build and First Query

The README points to INSTALL.md for build information, but the repository layout and release archives indicate a standard C library build. You typically run ./configure, then make, then make install. The library is C89-compatible, so it compiles with older compilers and on many platforms, including Linux, Windows, Android, and iOS. After installation, you link against libcares and include the header. A minimal query involves ares_init to create a channel, ares_gethostbyname to submit a query, and a callback that receives the result. The callback must be non-blocking. The README gives an example of verifying release signatures with gpg, but not a code sample. For a working example, you would consult the documentation in the repository or the man pages that come with the library. The build process is straightforward, but the integration with your event loop is where the real work happens.

Security as a Feature, Not an Afterthought

The README emphasizes a strong focus on security. c-ares implements safe parsers and data builders to avoid common pitfalls of other C libraries. It is constantly validated with static and dynamic analyzers, and it is fuzzed by OSS Fuzz. This is not marketing fluff; the project has a security procedure and a dedicated email address for reporting vulnerabilities. The release process includes GPG signatures and SLSA provenance, which lets you verify that the tarball you download was built from the intended repository. For a C library that parses untrusted network data, this level of hardening matters. However, the README does not list specific CVEs or past vulnerabilities, so you should check the security page for historical issues. The security posture is a reason to choose c-ares over a homegrown resolver, but it does not absolve you from writing safe code around the API.

Modern DNS Support: Beyond A and AAAA

c-ares does not stop at basic hostname resolution. The README lists support for RFCs covering SRV records, NAPTR, DANE TLSA, SVCB and HTTPS records, CAA, and URI records. This is important for applications that need service discovery or security extensions. For example, an email client can use SRV records to find the mail server for a domain, or a TLS client can use DANE to verify a certificate. The library also supports EDNS0. This breadth means you do not need a second library for these record types. But it also means the API has more functions and options than a simple resolver. You need to understand which record types your application actually needs and not pull in the entire feature set if you only need A/AAAA lookups. The documentation states these RFCs are supported, but the exact API for each is not in the README, so you will need to consult the header files or man pages.

Limitations and When It Is the Wrong Tool

c-ares is not a drop-in replacement for getaddrinfo. It is asynchronous, so you cannot call it from a simple script or a single-threaded program without an event loop. If your application is a small utility that resolves one name and exits, the overhead of setting up a channel and managing events is not worth it. Also, the library is written in C and requires manual memory management. You must free the results and the channel, and handle errors properly. The README recommends using c-ares in all network applications, but that is a strong claim. For a simple synchronous use case, the system resolver is simpler and faster to implement. Another limitation: c-ares is a stub resolver, meaning it sends queries to a recursive resolver; it does not implement a full DNS server. If you need to host zones or provide authoritative answers, this is the wrong tool. The documentation does not mention any built-in caching, so repeated queries may go to the network each time.

Alternatives and How They Differ

The main alternative is the system resolver, getaddrinfo, which is synchronous and blocking. It is part of the C standard library on POSIX systems, so it requires no extra dependency. The difference in approach is fundamental: getaddrinfo blocks the calling thread, while c-ares uses an event-driven model. Another alternative is a threaded resolver, where you call getaddrinfo in a separate thread and communicate with the main thread via a queue. That approach is simpler to code but uses more resources and can still block if the thread pool is exhausted. c-ares avoids threads by using non-blocking I/O. For applications with an existing event loop, c-ares integrates more cleanly than spawning threads. For a simple single-threaded program, getaddrinfo is the pragmatic choice.

Maintenance and Upgrade Costs

c-ares has been maintained for over 20 years, and the release history shows frequent updates: v1.34.8 was pushed on 2026-07-07, just a day after v1.34.7. This indicates active development and quick fixes. The project uses GitHub Actions for CI and has a security procedure. The license is MIT, which is permissive for commercial use. The README mentions that releases are signed, and SLSA provenance is generated, which adds a verification step to your upgrade process. You should plan to verify signatures and provenance before deploying a new version, as the README shows the commands. The API may change between major versions, so you need to read the release notes. The library is stable enough for production, but the rapid release cadence means you should track updates for security fixes. Upgrading is not free: you must recompile and test your integration, especially if you use newer record types like SVCB.

Editorial conclusion

Adopt c-ares if you write a network application in C that needs non-blocking DNS resolution or parallel queries, and you value a library with over two decades of maintenance, modern RFC support, and security fuzzing. Avoid it if you prefer a synchronous, high-level resolver or if your team lacks experience with C event loops and manual memory management. Before adopting, verify the API version and the event loop integration points in your code, and confirm that the latest release (v1.34.8) includes the security fixes you expect from the release notes and SLSA provenance.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Community notes

Community notes