RE: async resolver

From: Murray S. Kucherawy <msk_at_cloudmark.com>
Date: Mon, 19 Oct 2009 11:11:33 -0700

> -----Original Message-----
> From: opendkim-dev-bounce_at_lists.opendkim.org [mailto:opendkim-dev-
> bounce_at_lists.opendkim.org] On Behalf Of Daniel Black
> Sent: Sunday, October 18, 2009 12:38 AM
> To: opendkim-dev_at_lists.opendkim.org
> Subject: async resolver
>
>
> I was looking at the DNS resolution used in libopendkim. It seems that
> the DNS
> resolution used rarely occurs in an async manner and in all cases uses
> a wait
> function to get the results.
>
> Further more it seems that there is no callback function in the libar.
>
> It seems this way that we are blocking milter calls while waiting for
> DNS
> responses.

libar does provide asynchronous resolution. It doesn't have a callback, but it has a wait timeout that allows libopendkim to implement the callback. Here's how it works:

When a thread creates a request with ar_addquery(), it receives a handle to the request and the request is placed in a resolution queue, and the dispatcher thread is notified that it has work to do. The requesting thread still has control while the dispatcher sends the request and waits for the reply.

Whenever it wants to do so, requesting thread can call ar_waitreply() with or without a timeout. Upon entry, if the dispatcher has already received a reply, then the call returns immediately indicating the result. Otherwise, it will block that thread waiting for a reply to arrive; when the dispatcher gets an answer, the data are delivered and the blocked thread is awakened. If a timeout is used, then ar_waitreply() will return a status code indicating "no reply yet" if that's the case when the timeout arrives, and the thread can then do other things while the dispatcher continues to wait for the answer.
 
libopendkim implements the callback mechanism. The function dkim_set_dns_callback() lets the caller specify a function to be called while DNS replies are pending, and a frequency. Once set, libopendkim will only call ar_waitreply() with that timeout set; when the timeout hits, the requested function is called and then it repeats the cycle until the query times out or an answer arrives. OpenDKIM uses this to arrange to call smfi_progress(), which tells the MTA "I'm still waiting for an answer, don't time out on me yet." In the case of sendmail at least (and probably postfix) this resets the milter read timeout.

If you use the stock resolver (usually bind, of course) there's no callback mechanism, but recent versions are at least asynchronous.

So we're already doing what c-ares offers, except for the "mature" part (depending on how you define that). :-)

In fact looking at http://c-ares.haxx.se/why.html, libar meets all of their requirements except for 1b and 5a (1b is "synchronous interface" which we don't want or need here, and they don't really do it anyway; 5a is "must not require multi-threading" but this is definitely a multi-threaded operation).
Received on Mon Oct 19 2009 - 18:11:51 PST

This archive was generated by hypermail 2.3.0 : Mon Oct 29 2012 - 23:32:29 PST