An event-driven DNS server framework
C Protocol Buffer
Switch branches/tags
Nothing to show
Clone or download
Pull request Compare This branch is 18 commits ahead, 8 commits behind raybellis:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
m4
.gitignore
AUTHORS
COPYING
ChangeLog
INSTALL
Makefile.am
NEWS
README
as112d.c
chaos.c
configure.ac
dnstap.proto
dtwhoami.c
evldns.c
evldns.h
fixed.c
function.c
mod_arec.c
mod_mangler.c
mod_myip.c
mod_txtrec.c
network.c
oas112d.c
plugin.c
testtcp.c

README

ABOUT
-----

evldns is a library and framework designed to ease the creation of
small and fast DNS servers, especially where the responses from those
servers are dynamically synthesised.

It is a mashup of libevent and ldns.  Specifically it's derived from
the server-side half of libevent's "evdns" module re-written to use
the ldns package handling APIs.

APIs
----

evldns works using callback functions.  A list of packet matching patterns
may be registered, along with a pointer to the function that will be
invoked when each pattern is matched.

The packet match works on the usual DNS triple of (QNAME, QCLASS, QTYPE)
where QNAME may be an exact match or a wildcard, and QCLASS or QTYPE may
be "ANY".

The callback function is passed two parameters:

  void callback(struct evldns_server_request *req, void *data)

The "req" parameter contains the complete received DNS request as an
"ldns_pkt".  The callback should create a response packet and populate
"req" with that response, which may either be in raw wire format
(req->wire_response and req->wire_len) or in ldns format (req->response).

If the callback function fails to populate either of the response fields
then the evldns system will pass the received packet onto the next
matching callback.

Should no callback match then evldns will automatically generate and
return a packet with RCODE = 5 (Refused).

The "data" parameter is used to pass an additional parameter supplied when
the callback function was registered.  See "mod_txtrec.c" for an example
of how "data" may be used to pass expected response data into a callback.

A complete evldns application requires just a few extra lines of code:

  event_init();				/* initialise libevent */
  evldns_init();			/* initialise evldns */

  /* create an evldns server context */
  struct evldns_server *server = evldns_add_server();

  /* register the socket with evldns */
  evldns_add_server_port(server, bind_to_udp4_port(53));

  /* register callbacks here */
  evldns_add_callback(server, qname, qclass, qtype, callback, data);
  ...

  /* and set libevent running */
  event_dispatch();

and that's it!

DEMOS
-----

- as112d

This application shows how evldns may be used to construct an extremely
fast and lightweight server for negative responses for RFC 1918 IP addresses,
as implemented by the AS112 anycast cloud.

On a single core of an HP DL385 2.0 GHz Opteron server this application has
been benchmarked at over 60,000 queries per second.

- chaos

Demonstrates use of plugin modules and callback data to handle queries
for BIND-style "version.bind CH TXT" and "author.bind CH TXT".

It also includes support for "client.bind CH TXT" and "client.bind IN A/TXT"
which returns the IP(v4) address of the host from which it received the query.

PLUGINS
-------

evldns supports dynamic (shared) modules, and run-time binding to named
callback functions.

However the implementation of these is quite likely to change.

LICENSING
---------

This code is open source with a BSD license.

Please see "COPYING" for the full license details.

TODO
----

- Support for multiple response packets

  1.  Needed for AXFR

  2.  Also for OARC style varying response length responsders,
      where multiple packets of differing lengths are sent back
      in response to a single inbound request

- Support for deferred responses

  So that queries can be intentionally delayed, or if for whatever
  reason the framework is used in a system where response packets
  cannot be immediately synthesised.