dns.c: Asynchronous DNS and SPF Resolver

description

A non-blocking DNS resolver library in a single .c file. Supports both stub and recursive modes.

Asynchronous SPF resolver, without caveats--no threading, no forking, no library dependencies.

todo

Write documentation.

Integrate OpenSPF test suite.

Finish EDNS0 support.

Polish address info smart queries (fallback to direct A query when MX query fails, for instance).

Refactor smart query recursion in core resolver to leverage interfaces added for smart queries in the address info API.

Make sure we do the Right Thing with error responses and other wierdness.

Track down elusive OpenBSD + GCC 3.3.5 + C99 compound literal + in while loop stack corruption. Currently fixed by not using compound literal from that particular loop when compiling on OpenBSD. Assembly experts welcome.

Add SSHFP resource record support.

Support DNSSEC.

news

2010-03-03

Replace internal _shuffle8 with _shuffle16 to mix full width of record index when using the shuffle rrset iterator.

2010-02-10

Release 20100210 (cb14dea94c0ed41c6c65adfa670ab597a6b08589).

Add dns_itype() complement to dns_strtype().

Add version interfaces: dns_vendor(), dns_v_rel(), dns_v_abi(), dns_v_api().

Add new (struct dns_options) parameter to object instantiators.

Add optional closefd callback to explictly notify app of discarded descriptors.

Support libevent bitmasks from _events() interfaces instead of poll(2) bitmasks.

Add _clear() routines to force closure of queued, discarded descriptors. Alternative to closefd callback, but also optional.

2009-11-28

Delay closure of descriptors so that kqueue(2) and epoll(2) callers have a chance to recognize a state change after installing a persistent event and where sequential descriptors with the same integer value returned from _pollfd() would be ambiguous.

Another interface needs to be added to flush the descriptors. Currently they're only flushed when the socket or resolver object is destroyed. Final solution will consist of one or all of (1) a new routine, perhaps exposing the _closefds() internal; (2) a new option to control automatic flushing; and/or (3) a callback to notify a caller exactly when a particular descriptor is being closed. The latter two will probably require a new options structure other than the resolv_conf structure.

This only changes the behavior of TCP descriptors. The UDP descriptor is retained throughout the lifetime of a socket or resolver object.

Support OpenBSD /etc/resolv.conf tcp option. As on OpenBSD it can be specified as plain "tcp" to force TCP only querying; or one of "tcp:enable", "tcp:only", or "tcp:disable". "tcp:enable" is the default, and "tcp:only" is equivalent to "tcp". "tcp:disable" disables TCP, currently causing a truncated packet to be returned when the resolver would otherwise switch to TCP.

Switch version name schema and roll 20091128 from commit 70a177ebd929e4afd454bc7369ac79e68335f902.

2009-11-04

Support OpenBSD /etc/resolv.conf nameserver port extension; e.g. nameserver [1.2.3.4]:5353. This will be useful when trying to bootstrap the OpenSPF.org test suite.

Add additional SPF VM ops and some premature performance optimizations.

Support C constants from SPF VM assembler; e.g. $AF_INET. See fcrd.spf for examples.

Roll 0.6.1 from commit 5668bd4c87471b7c482e095ffbc95c7da4a6298d.

2009-11-02

Reorganize SPF code so it's easier to read. Some bug fixes to the spf utility.

Add fcrd.spf, example bytecode for doing forward-confirmed reverse DNS the "hard way"; that is, without the built-in fcrd/fcrdx ops, and without the built-in addrinfo/nextent ops (which the fcrd macro op uses when it dynamically generates code to do the confirmation). This helps to show the way to refactoring the VM to support c-ares, without the benefit of the highly useful ancillary routines in dns.c :)

2009-11-01

Add dns_res_events() and dns_res_pollfd() to supplement/replace dns_res_pollin() and dns_res_pollout(). This makes it a tad easier to work with libevent (saves a few lines of code).

Debut asynchronous SPF resolver. WARNING: This is alpha code!

2009-05-28

Fix nasty regression in previous bugfix that broke CNAME chaining in stub mode.

2009-04-17

Fix bug where we didn't fallback from "bind" method to "file" method if the recurse flag was disabled. This solves the annoyance of, for instance, unqualified "localhost" not resolving. But, this calls for closer inspection of the search generator, me thinks.

Search generator may have changed the qname. So, in dns_ai_nextent() canonicalize the qname from the answer, not the qname originally submitted to the resolver.

2009-03-21

Numeric resolution in dns_ai_nextent() did not set the port properly. Fixed.

Add dns_res_stub() for convenience. Returns a resolver configured as a stub resolver, without requiring the user to manually instantiate the proper configuration objects.

Add include guards in dns.h.

2009-03-16

Set feature macros for POSIX/SUSv3 and BSD interfaces in dns.c. This should have the effect of fixing GNU/Linux regression compilation, and hopefully continue to build on BSD systems without issue.

When building against dns.h, one must ensure the definition of POSIX struct addrinfo. In practice, this means that on Linux (with glibc) one should define _POSIX_C_SOURCE or _XOPEN_SOURCE or _GNU_SOURCE, as appropriate. These are not defined in dns.h because of potential side-effects in application code. Alternatively, invoking GCC with -std=gnu99 rather than -std=c99 might work.

2009-03-09

Port to MinGW32 / Win32.

2009-03-08

Added address info API, semantically similar to POSIX getaddrinfo(), but non-blocking, re-entrant, and iterator-based. Does "smart" queries more optimally, since per-record recursion can be postponed (unlike "smart" recursion in the core resolver, which must collect all necessary records to return in the single answer packet).

struct addrino hints = { .ai_flags = AI_CANONNAME, };
struct dns_resolver *res = dns_res_open(...);
int error;

struct dns_addrinfo *ai = dns_ai_open("google.com", "25", DNS_T_MX, &hints, res, &error);
...
struct addrinfo *res;
int error;

switch ((error = dns_ai_nextent(&res, ai))) {
case 0:
/* do something */
case ENOENT:
/* no more */
case EAGAIN:
/* poll on dns_ai_pollin() / dns_ai_pollout() */
default:
/* OOPS! */
}

Fixed SRV record bug. Wrong value for record data length was written out when composing SRV object as packet data.

2009-02-28

Original public release.

usage

The last 1/6 of dns.c contains a full regression suite. The regression binary is the default target of the included Makefile.

Run make dns && ./dns -h for the regression commands and options. The regression tests show how to use the library.

Similarly, spf.rl compiles to a standalone utility which spf.t runs several regression tests against. The utility also includes a built-in assembler for executing ad-hoc bytecode in the SPF VM interpreter (see fcrd.spf).

Run make spf && ./spf -h for the commands and options.

license

Copyright (c) 2008-2010 William Ahern

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

download

Not currently intended to be versioned as an installable library. All updates are documented in Git.

For convenience, libdns-20100210.tgz. This is not always up-to-date.

source

Public Git repository is updated nightly (California time).

git clone http://25thandClement.com/~william/projects/libdns.git

other projects

airctl | bsdauth | cnippets | libmime | libarena | libevnet | authldap | streamlocal | libnostd | zoned | dns.c | delegate.c | AnonNet