Two copies of resolver routines in libc ?

Hajimu UMEMOTO ume at
Sat Nov 8 08:29:25 PST 2008


>>>>> On Sat, 8 Nov 2008 16:10:23 +0100
>>>>> Luigi Rizzo <rizzo at> said:

rizzo> thanks for the answer and the effort for merging back the two copies.
rizzo> I am looking at your proposed patch but i am not sure i understand it fully,
rizzo> so i would be grateful if you could explain me a few things (btw i
rizzo> am attaching a version of your patch constructed with 'diff -ubwp'
rizzo> and couple of formatting changes to remove whitespace differences;
rizzo> this should make the actual changes more evident):

Yes, I did 'diff -ubwp' to check during making this patch. :-)

rizzo> 1. i apologize for my ignorance, but i suppose there is a binding
rizzo>    between __res_nsearchN() and res_nsearchN(), and the same
rizzo>    for all function with and without the two leading __ . Where
rizzo>    is this binding established, as i don't see anything in the
rizzo>    diff that you sent.

The function with leading `__' is libc internal function.
Since, we need to call res_searchN() from getaddrinfo.c, I couldn't
make it static.  So, I renamed res_searchN() to __res_nsearchN().
The rest (res_queryN() and res_nquerydomainN()) are not called from
outside of res_query.c.  So, I made them static without leading `__'.

rizzo> 2. res_*() now become wrappers around the newly introduced res_*N()
rizzo>    functions. While this approach removes the duplication, it does
rizzo>    not address the "ease further merge from ISC BIND" case, which
rizzo>    definitely sounded as a valid concern.

Yes, it is annoying thing.  The differences in res_nsearch() and
res_nquerydomain() are trivial.  But, res_nquery() is bit complicate.
However, the diff is trivial with `diff -bw', as you did.
I think it confuses us that there are two copies of the resolver
functions, too.  However, I'm not sure which is better merging the two
or leaving it as it is.

rizzo>    So i wonder, what is it that prevents you from acting the other
rizzo>    way around, i.e. build the res_*N() around the existing res_*()
rizzo>    functions ? This way the original ISC code would really be
rizzo>    unmodified and perhaps the change would be even more confined.

Unfortunately, it is impossible.  We need to have `for loop' in
res_nquery() to solve the query order problem.  It is the reason to
have a copy in getaddrinfo.c.

rizzo>    Does this constraint apply to all three functions (res_query, res_search,
rizzo>    res_nquerydomain) or only for a subset of them ?

Yes, this constraint apply to all three functions.  Since, the
res_nquerydomain() and res_nsearch() call res_nquery(), we need to
have the modified version of them to change to call res_nqueryN().

rizzo>        From what i can tell, at least in res_nquery()
rizzo>    the only significant change seems to be the following

rizzo>         +    if (n > anslen)
rizzo>         +        hp->rcode = FORMERR;    /* XXX not very informative */

rizzo>    other than that it seems perfectly fine to implement res_nqueryN()
rizzo>    as a wrapper around the original res_nquery().

It is a check for buffer overflow vulnerability.  At a later time, we
enlarged the buffers for answer in netdb functions.  So, perhaps, this
check became useless.  But, I leaved it as it is for safety.

rizzo>    For the other two functions
rizzo>    and the other one (trspping TRYAGAIN) seems perfectly suitable to
rizzo>    be implemented in

rizzo> 2. i don't completely understand what is the additional functionality
rizzo>    in the resolver functions. You mention a 'query order problem'
rizzo>    but i don't exactly understand what it is and how the functional
rizzo>    change is implemented.

As basic use of the resolver to query AAAA RR and A RR, the query
order is:

  1) Call res_nquery(hostname, T_A) for A RR
  2) Call res_nquery(hostname, T_AAAA) for AAAA RR

With regard of domain name completion and sort_list.  Imagine querying
hosta with and in search list.  The query
order will be:

  1) Call res_nquery(hosta, T_A)
	Query T_A RR for hosta
  2) Call res_nquery(, T_A)
	Query T_A RR for
  3) Call res_nquery(, T_A)
	Query T_A RR for
  4) Call res_nquery(hosta, T_AAAA)
	Query AAAA RR for hosta
  5) Call res_nquery(, T_AAAA)
	Query T_AAAA RR for
  6) Call res_nquery(, T_AAAA)
	Query T_AAAA RR for

It may cause the problem where either or
cannot reply correctly.
With the change, the query order will be:

  1) Call res_nqueryN(hosta, T_A and T_AAAA)
	Query T_A RR for hosta
	Query AAAA RR for hosta
	Query T_A RR for
	Query T_AAAA RR for
	Query T_A RR for
	Query T_AAAA RR for


Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume at  ume@{,jp.}

More information about the freebsd-net mailing list