evldns - A Framework for Light-weight DNS Servers
I’ve recently written and released source code for “evldns”.
evldns is a software mashup - it takes libevent’s fast event processing code and combines it with ldns’s DNS packet handling. It’s derived from the server-side half of libevent’s “evdns” component.
The resulting framework is particularly intended for writing servers which generate custom responses. Examples included are:
- an AS112 server which has been benchmarked at over 60,000 queries per second on an HP DL385 server.
- a server which responds with the IP address of the client which sent the query - this can be useful for network discovery
The framework could also be used to write a “fuzzing” DNS server - one that deliberately returns malformed responses so as to trigger and test for bugs in DNS clients.
Here’s an extract from the package’s README:
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_responseandreq->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 lines of code:
event_init(); /* initialise libevent */
evldns_init(); /* initialise evldns */
/* create an evldns server context */
struct evldns_server *server = evldns_add_server();
/* register a UDP 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();
Please see the project home page for more information. There is also a Google hosted discussion group.
Ray Bellis, Advanced Projects Team
