libevnet: Network Daemon Services for libevent

description

libevnet provides a suite of interfaces, all built around libevent, useful to network daemons.

bufio.h: Non-blocking line and block buffered I/O routines, implementing tail calls so callers cannot overflow their stack with multiple back-to-back I/O issues (i.e. attempting unbounded recursive I/O operations before falling into the event loop). This feature preserves the natural way to code in an asychronous manner by safeguarding against certain types of pathological behavior and malicious attacks. Using the same underlying mechanism, wasteful event_add() and event_del() calls are mitigated so that applications can utilize the simple "oneshot" I/O request programming pattern without the performance cost.

socket.h: Asychronous accept(2) and connect(2), supporting IPv4, IPv6 and Unix Domain sockets transparently. Also supports encapsulated host address lookups for "one-shot" connection handling with automatic fallback (for MX and SRV hosts).

tls.h: OpenSSL interface which plugs into the buffered I/O API in bufio.h and socket.h API.

thread.h: Threading implementation for running "blocking" routines asychronously. Run a function in a separate thread, and have the return value collected and passed back asynchronously to the original caller.

lookup.h: Comprehensive DNS resolver with a dead simple interface. Supports PTR, A, AAAA, CNAME, NS, MX, TXT, SOA and SRV records, as well as "compound queries".

A lookup of A+AAAA+SRV first queries the SRV records, sorts them, then resolves each SRV host to an A and/or AAAA host (with a configurable CNAME chaining limit). The response is a linked list of lookup structures, beginning with an SRV record, associated A/AAAA sockaddr structures, the next SRV record, and so on. A+MX has similar behavior. This feature actually reduces network traffic, since most of the time the initial DNS query response contains all the necessary information in the additional section.

DNS SRV records are compliantly sorted according to RFC 2782.

libevnet requires libarena, GNU Make, c-ares, and OpenSSL.

todo

Finish c-ares replacement.

(DONE) Integrate liblookup, c-ares wrapper.

(DONE) Integrate lookup API into socket_accept() and socket_connect() to support host domain name binding.

(DONE) Default set of read/write/mode functions for easy OpenSSL integration. teach the socket interface about TLS/SSL.

Add SSHFP resource record support.

Support DNSSEC.

news

2009-12-08

Fix arc4random_buf compilation on FreeBSD, and match c-ares callback signature based on version. Thanks to Tom Pusateri.

Roll 0.3.12.

2009-11-28

Roll 0.3.11. Forgot to make public releases while fixing stuff for RemoTV.

Fix string comparison bugs in lookup.c.

Support close-on-exec flags.

Fix descriptor leak in socket compat library.

Fix memory bug in lookup.c; forgot to remove timer when closing a c-ares channel.

Match new c-ares callback signature.

Add Debian package support.

2008-01-07

More work on new DNS library. Supports parsing as well as building arbitrary queries. Record types are pluggable. Full DN compression with label suffixing. Can round-trip "MX IN yahoo.com", matching the 511-byte compression.

Iteration has changed slightly, with some sweet new CPP macros:
DNS_M_RR_FOREACH(rr, m, &m->an, DNS_DN_ANY, DNS_RR_C(IN), DNS_RR_T(A, AAAA)) {
    ...
}

2007-11-30

Begun work on a c-ares replacement. DNS response parsing almost entirely complete. Can even do nifty things, like:
m = dns_m_open(&dns_defaults);

dns_m_parse(&m, pkt, len);

DNS_M_RR_FOREACH(rr, m, DNS_M_SECTION_ANY, DNS_RR_CLASS(DNS_RR_C_IN), DNS_RR_TYPES(DNS_RR_T_A, DNS_RR_T_AAAA)) {
    char name[256];
    dns_m_dn_expand(m, name, sizeof name, rr->name.base);
    puts(name);
}

2007-05-03

(0.3.8) Fix SRV sorting bug which could cause an infinite loop.

Integrate libnostd compat layer.

2007-02-21

Until the release of version 0.3.2 of libarena, libevnet-0.3.7 needs to be built against the latest snapshot of libarena. I just haven't had time to tag and roll a release.

2007-02-13

Released 0.3.7 to fix a deadlock resulting from recursive mutex locking. If a thread_run() callback itself calls thread_run(), then a deadlock will result when the library attempts to acquire the thread pool mutex.

The fix was to move the callback execution outside of the critical section, by first moving the finished job(s) to a temporary queue, releasing the lock, then issuing the callback(s).

2006-12-15

Released 0.3.6, which includes the aforementioned OpenSSL error management fix.

The build is still in poor shape. FYI, here's how I currently build libevnet:

make CPPFLAGS="-I/usr/local/include -DUSE_OPENSSL -DUSE_CARES -DUSE_PTHREADS -DUSE_IPV6" all|check|install

2006-12-07

Latest SNAP contains fix to OpenSSL interface component. OpenSSL persistent error queues were not being cleared, which in some situtions could lead to OpenSSL errors from one connection propogating over to other connections, with baffling results.

2006-12-01

Released 0.3.5, containing fixes to all known bugs (save anything on the TODO list).

2006-11-30

Cancellations were not handled by the buffered I/O component properly. Latest SNAP should resolve this issue.

2006-11-16

UPDATE: Some very, very common general-purpose code has been abstracted into libnostd. To build a snapshot download libnostd; untar it; and then cp, mv or ln the directory to libevnet-source/libcom, adjacent to libevnet-source/src.

Also, the header files have been cleaned up to remove some accidental compilation issues (e.g. requirement for queue.h).

2006-06-18

Tag and release libevnet 0.3.4 which fixes yet another parser bug (related to the first, really), which caused parsing to stop on the first blank line. Added some NULL pointer checks in some close functions to maintain consistency (ultimately to carry forward the convenience which free(2) provides). And fix a missing return statement in a bufio.h static function.

2006-06-08

libevnet 0.3.3 includes a refactored socket connection component. At this point most major refactoring should be accomplished. Next step is to attack the error reporting API.

More importantly, however, are significant fixes to the lookup.h library. I've discovered that the c-ares functions ares_destroy() and ares_cancel() are fatally flawed for any but the most simplistic uses (and in those cases you still must be very careful how you use them).

From the very first version of ares and c-ares it would seem that objects were accessed willy-nilly after issuing a callback to the library user. This flies against the cardinal rule in asynchronous programming, namely that you must never assume the state of any objects after a callback. It's the most difficult issue w/ asynchronous programming. libevnet eases that rule somewhat since it maintains an internal stack of calls, and using automatic storage can communicate down the stack the state of objects. The cancel and close functions in each component utilize this, and of course various other areas must be smart enough to cooperate using this second stack. (Yes, this certainly precludes the use of longjmp(3) and friends in tandem with libevnet!)

With the current version of c-ares cancellations will never work safely in libevnet given the loose restrictions libevnet promises. socket_cancel() and socket_close() are affected by this and so are unsafe to use until they've issued their callbacks, or if only IP address socket names are used. lookup_cancel() was never implemented.

In 0.3.2 and earlier lookup_close() could encounter this deficiency in c-ares. 0.3.3 fixes this issue by delaying destruction of ares channels till just before falling back into the libevent event loop, though lookup_close() should never be called until all queries have returned.

2006-05-31

Version 0.3.2 sports a re-engineered I/O interface for bufio.h. The new design utilizes source and sink objects, which means block buffering is possible. In fact, line buffering for bufio_gets() is implemented this way.

The new implementation still supports tail calls. However, the code is much cleaner this time round since the polling logic is farmed out to the sink and source objects.

libevent is also still optimized so that immediately calling back into the I/O library from a previous callback will preserve any existing libevent poll. This makes libevent even faster--for epoll and kqueue--while preserving a simple interface.

2006-05-13

Version 0.3.1 with TLS/SSL integrated into the socket.h interface. See socket_tls_enable(). Renamed `struct socket_service' to just `struct socket'. Still not sure about about the naming. The returned socket object really is more of a service, since, for instance, you can call socket_accept() multiple times and get multiple listening sockets. But, I still sort of want to make it look like one socket "object", since idealy this capability will be hidden (e.g. when listening on INET4 *and* INET6 ports simultanously some platforms require muliple listening sockets, but this really should be transparent). socket_connect() has similar behavior; you can fire off multiple connections; in fact, you can call socket_connect() and socket_accept() off of the same socket object.

Cancellations--i.e. socket_close() when a connection is pending--are still not fully supported with socket_connect(); not until ares_cancel() is integrated.

Next release bufio.h might see some changes, at least in the semantics. Currently the input block buffering will return immediately after every read, even if the full amount wasn't satisfied; to continue you return BUFIO_RESTART from the callback. This doesn't follow the "make simple things easy" paradigm, though. Will probably remove the return code altogther. Restarting is can occur explicitly by the caller with another call into bufio_read(), and it's even already optimized so that event_del() isn't removed prematurely.

2006-05-12

Committed and released as version 0.3.0 the bulk of OpenSSL integration. Also deprecated the nio.h interfaces in favor of bufio.h. Currently almost exactly the same, but bufio.h might change slightly in the future. Similarly, the socket API might change. These changes should hopefully occur throughout the 0.3.x series.

2006-05-02

Found two interestings resources on DNSSEC: http://ds9a.nl/dnssec and http://www.ripe.net/disi/dnssec_howto. Also, nlnetlabs.nl has functional DNSSEC records in-place. Can't wait to begin the work.

2006-04-23

Integrated liblookup, c-ares wrapper, as well teach socket_connect() how to use the lookup interface.

2006-04-10

Project page put up.

usage

Regression tests can offer example code, though not the best.

license

Copyright (c) 2006-2007 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

Download the latest snapshot tarball.

Download the latest 0.3.12 tarball.

Download the previous 0.3.11 tarball.

Download the previous 0.3.8 tarball.

Download the previous 0.3.7 tarball.

Download the previous 0.3.6 tarball.

Download the previous 0.3.5 tarball.

Download the previous 0.3.4 tarball.

Download the previous 0.3.3 tarball.

Download the previous 0.3.2 tarball.

Download the previous 0.3.1 tarball.

Download the previous 0.3.0 tarball.

Download the previous 0.2 tarball.

other projects

airctl | bsdauth | cnippets | libmime | libarena | libevnet | authldap | streamlocal | libnostd | zoned | dns.c | delegate.c | llrb.h | lpegk | json.c | cqueues | siphash.h | hexdump.c | timeout.c | luapath | luaossl | lunix | phf | AnonNet