Subject: Asynchronous SPF resolver

Asynchronous SPF resolver

From: William Ahern <william_at_25thandclement.com>
Date: Sat, 31 Oct 2009 22:37:08 -0700

Just got a non-blocking SPF resolver in something approximating working
order. SPF is a ridiculously complex spec (especially so asynchronously,
because of the recursion and macro language), and I ended up attacking it by
compiling the policies into a custom bytecode and executing the "check" in a
tiny, interruptible virtual machine.

        http://www.25thandclement.com/~william/projects/dns.c.html

I started writing this intending it to be easily useable with C-Ares, but I
just didn't have the time to make it _that_ abstract. As-is it requires my
dns.c resolver.

Perhaps if somebody else has the wherewithal, it might not be too difficult;
certainly less difficult than starting from scratch. Basically some of the
bytecode generators would need to generate different code for acquiring the
DNS records, and an interface added so the client can determine the next
required query and queueing the result.

The high-level API is simple. Here's an example showing all the relevant
routines. spf_poll() is a helper routine--for my regression tests--which
uses spf_events() and spf_pollfd() to get the read-write events and poll
descriptor, respectively. NOTE: There's no built-in callback interface; you
just restart spf_check() until it doesn't return EAGAIN (0 would be
success, something other than EAGAIN an unrecoverable error).

struct spf_env env;
struct spf_resolver *spf;
int error;

spf_env_init(...); /* set the required SPF macro variables */

spf = spf_open(&env, &error);
assert(spf);

while ((error = spf_check(spf))) {
        assert(error == EAGAIN);
        spf_poll(spf, 3);
}

printf("result: %s\n", spf_strresult(spf_result(spf)));
printf("exp: %s\n", (spf_exp(spf))? spf_exp(spf) : "[no exp]");
Received on 2009-11-01