description
A non-blocking DNS resolver library in a single .c file. Supports both stub and recursive modes.
- Core DNS API built around actual DNS packet; as generic as DNS itself. This makes querying and manipulating records other than A, AAAA, and PTR much easier, yet with similar simplicity as API's which make annoying assumptions.
-
Thoughtful
/etc/resolv.confand/etc/hostsintegration. Easy to change system defaults, or to skip entirely. -
Restartable record iterators with user-specified
sorting. Iterate over MX or SRV records in
semantic order (i.e. preference and priority)
using a single
dns_rr_foreachloop. Interruptable loops supported withdns_rr_grep. -
"Smart" queries which automatically dereference NS,
MX, SRV, PTR, etc. to A records. Recursing, caching
nameservers don't usually do this explicitly, but
merely rely on the authoritative server to include
glue, which won't exist for out-of-bailiwick
references (very common these days). This means
software must do two separate logical DNS
operations; a headache when patching software which
only supported A lookups. Smart queries are
available with a flag to the core resolver--in both
stub and recursive modes--and more efficiently with
the built-in
struct addrinfoiterator. -
Randomized source ports and QIDs with a 16-bit
Feistel block cipher. User specifiable entropy
source; defaults to
arc4randomwhere available. -
No callbacks! Callbacks are usually inevitable when
writing non-blocking network software, but when too
many libraries introduce too many callback
interfaces code quickly becomes incomprehensible
beyond necessity.
dns.crequires no particular callback scheme, nor enforces callbacks at all. - Developed in OS X, OpenBSD, Linux, and MinGW environments; 32-bit and 64-bit architectures. Constantly tested with Valgrind.
Asynchronous SPF resolver, without caveats--no threading, no forking, no library dependencies.
-
A single source file,
spf.rl. Requires Ragel pre-compiler, but no run-time dependencies other thandns.c. - Tiny interruptable virtual machine with specialized DNS ops to execute the complex logic and queries without blocking, and without incomprehensible spaghetti code.
- Constantly tested with Valgrind.
- (WARNING: This is new code which is unlikely to pass the entire OpenSPF test suite, yet.)
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. Seefcrd.spffor 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