Subject: file_lookup errors and next_lookup behavior

file_lookup errors and next_lookup behavior

From: Erik Kline <ek_at_google.com>
Date: Tue, 27 Nov 2007 23:49:24 -0800

All,

Just ran in to an interesting case that highlighted some behavioral
difference between ares and c-ares (which isn't the point; I know
people don't need to hear about ares).

Randomly, it seems, /etc/hosts got chmod'd to 0600, which meant that
non-root applications couldn't read /etc/hosts. A call through
ares_gethostby{name,addr}() would go through file_lookup() and fail on
fopen() (of course), getting EPERM back (I suspect). C-ares
file_lookup() returns ARES_EFILE in this case, whereas ares
file_lookup() returns ARES_ENOTFOUND.

Why does this matter? Because the code in next_lookup is the same
between the two:

          status = file_lookup(hquery->name, &host);
          if (status != ARES_ENOTFOUND) {
            end_hquery(hquery, status, host);
            return;
          }

(apologies if that looks bad in your mail reader of choice)

In ares there seems to have been only two return values: ARES_SUCCESS
and ARES_ENOTFOUND. In c-ares there appear to be three: ARES_SUCCESS,
ARES_ENOTFOUND, and ARES_EFILE. Returning ARES_EFILE thus
short-circuits next_lookup() and, in the case of a
files-first/dns-second resolution, a dns lookup isn't performed. I
think it'd probably be nice to continue trying to resolve the
name/addr in the face of any file_lookup failures. Thoughts?

I can think of 2 ways to achieve this:

  [1] Add a "case EPERM" to the switch statement in file_lookup() so
that ARES_ENOTFOUND is returned. I don't know how portable (Windows?)
this is, nor do I think it's the right thing, necessarily.

  [2] Change that conditional in next_lookup() from "if (status !=
ARES_ENOTFOUND)" to the more explicit "if (status == ARES_SUCCESS)".
I think this may be more desirable.

Weird scenario, I know. Obviously option #3 is to leave well-enough alone. :-)

Thanks,
-Erik
Received on 2007-11-28