[ On Tuesday, January 6, 2004 at 15:49:51 (-0800), Jason Thorpe wrote: ]
> Subject: Re: re-reading /etc/resolv.conf on change
>
> Your argument is bogus, of course, because of the implicit res_init()
> call made by all of the other res_*() functions.
I'm sorry you see it that way, especially since it's not quite true, or
at least it's not that simple. There are layers within the resolver(3)
itself, with those that do call res_init() being add-on helper functions
which are explicitly designed to combine the other res_*() routines,
including res_init() in the most commonly used ways.
There's also the the thread-safe versions of these functions (which are
of course from BIND-8's resolver library, i.e. which are not (yet) in
NetBSD), the res_n*() functions, which not only expect the caller to
call res_ninit() first, but also to manage the storage space for the
res_state structure initialized by res_ninit() and to pass a pointer to
that structure to all res_n*() calls. Although the BIND-8 resolver(3)
manual page does include the sentence: "Initialization normally occurs
on the first call to one of the other resolver routines." it's very
important to note that statement only applies to some of the deprecated
old res_*() routines, and not any of the new thread-safe res_n*()
routines. In BIND-8's resolver the IRS library is what manages the
res_state structure and the call(s) to res_ninit(), and of course IRS
sits as a shim between all the get*() functions and the res_n*()
functions in order to provide for non-DNS lookups of hostname and
address information.
So clearly the direction is to move away from automatic initialization
of the lowest layer.
There are even new res_getservers() and res_setservers() calls in
BIND-8's API.
I.e. there are good reasons the ISC folks threw it all out and now
provide a new liblwres and accompanying light-weight stub resolver
daemon with BIND-9, and only very begrudgingly still provide an
encapsulated libbind containing the BIND-8 API. :-)
> However, res_init() is currently used
> *purely* as an internal function call,
Well, no, even in NetBSD res_init() isn't currently used only as an
internal-only API, at least not if you consider that (most of) the
get*by*() routines call it and if you don't consider them to be internal
to resolver(3), and it certainly was not intended to be an internal-only
call as it's a well documented public interface that's intended to both
initialize _and_ re-initialize the lower resolver(3) layer. Even the
_res variable I complained about others using is strictly a public part
of the BIND-4 API, though of course it's deprecated in BIND-8's API.
> But, I'm willing to compromise (consider it a late Christmas present).
> Here's a new proposal:
>
> Add a new function:
>
> int
> res_reinit(void)
> {
>
> if ((_res.options & RES_INIT) == 0 && res_init() == -1)
> return (-1);
>
> return (0);
> }
>
> ...and replace all of the implicit calls to res_init() that include
> checks for RES_INIT with a call to res_reinit().
>
> Then we can centralize the handling of resolv.conf into this new
> res_reinit() function. Your precious res_init() function remains
> unchanged.
I appreciate that. It's a good compromise, though it is essentially
what I've been proposing all along (sans what I thought was a more or
less obvious implementation detail of putting it all in a separate
function). :-)
I sure wouldn't make it a public function though, and certainly not
before ISC do so, if they ever do, which is extremely unlikely.
I still don't think the res_*() routines themselves should call the new
res_reinit() though -- they should continue to use only res_init() as it
can be expected that direct users of the resolver(3) code (including the
get*() layer in libc) will know to do their own thing with res_init(),
and as you say there are relatively few actual applications which make
direct use of the resolver(3) API.
--
Greg A. Woods
+1 416 218-0098 VE3TCP RoboHack <woods@robohack.ca>
Planix, Inc. <woods@planix.com> Secrets of the Weird <woods@weird.com>