Subject: Re: How to cancel a single gethostbyname request without canceling any others?

Re: How to cancel a single gethostbyname request without canceling any others?

From: William Ahern <william_at_25thandclement.com>
Date: Tue, 13 Jul 2010 14:53:51 -0700

On Tue, Jul 13, 2010 at 10:52:38PM +0200, Daniel Stenberg wrote:
<snip>
> I'm just the maintainer and some kind of leader here, I certainly do not
> write c-ares myself and I never actually did most of the implementation
> work. Feel free to step up and bring on your ambition and energy. We need
> all the help we can get!

IMHO the whole channel thing causes more headaches than its worth. It
obscures how each request is actually processed, and adding layer on top of
layer of interfaces to return some control back to the caller just makes for
more obsfuscation. It was all premature optimization, IMO. ADNS made the
same mistake. I'm not even sure it made sense back-in-the-day when c-ares
and ADNS were originally written, though socket creation has gotten orders
of magnitude more peformant in the intervening 10 or 15 years.

That's why in my DNS library there's a single socket object per resolver
object, and a single outstanding query per resolver. The caller owns that
resolver exclusively. The caller can of course cache and reuse the resolver,
but that's entirely up to the application. Usually it's far easier to
create, destroy, forget. (Or if caching the resolver, resetting its state.)
Configuration objects have their own lifetime and are immutable after
creation, so they can be cached and shared between resolvers. If you need
to do a million queries a second, all the underlying routines for socket I/O
and packet parsing are maintained as part of the API.

Also, the trend for DNS best-practice has been to randomize the source port
on a per-request basis. In that context, you lose nothing and gain a
significant amount of simplicity by keeping queries one-to-one with resolver
objects.

As for cancelling a c-ares query, the answer is simple: use one channel per
request. A typical libc getaddrinfo() implementation will call res_init()
every query anyhow, which will stat(2) /etc/resolv.conf. An unmodified
ares_init() might do superfluous work, but it's still a win over
getaddrinfo() and friends because it's async.
Received on 2010-07-13