This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: On glibc's resolver
On Tue, Dec 25, 2012 at 11:17:22PM -0500, Carlos O'Donell wrote:
> On Tue, Dec 25, 2012 at 10:14 PM, Dimitrios Apostolou <jimis@gmx.net> wrote:
> > I have been tracing weird behaviour of my mail client (alpine) and ended up
> > in getaddrinfo() calls, which are handled by glibc's resolver. In
> > particular, when I connect my laptop to different networks and the previous
> > DNS server is unreachable, resolver never re-reads its cache and all queries
> > timeout after several retries.
>
> What we need is a test case with expected and observed behaviour.
> Given a test case we can justify or refute the expected or observed
> behaviour against relevant standards or prior art.
I don't think there are any standards that define this behaviour,
which is why any behaviour is 'correct'. The reproducer is quite
simple:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int
main ()
{
const char *host = "priv.network.foo.com";
int err;
struct addrinfo *result = NULL;
while (1)
{
if ((err = getaddrinfo(host, NULL, NULL, &result)) < 0)
fprintf(stderr, "Lookup: unable to create socket for %s: %s\n",
host, gai_strerror (err));
sleep (2);
}
return 0;
}
where priv.network.foo.com is resolvable only by a specific DNS
server A and not by DNS server B. Set up resolv.conf with
nameserver B
and start the above program, watching it fail the DNS query every 2
seconds. Now modify resolv.conf to:
nameserver A
and watch it continue to fail. This is because resolv.conf is not
read in again when it is changed.
A lot of desktop applications depend on NetworkManager to do this for
them. NetworkManager has an API that notifies applications when an
interface has changed. This allows applications to do a res_init.
Firefox or pidgin code are good references for this.
> > 3) Patch glibc to stat() /etc/resolv.conf, checking for changes. Debian,
> > Ubuntu are patched.
>
> This sounds like the worst possible solution, imposing a penalty on
> all applications for a change that is well defined in a higher level.
* Linux-specific: Use the kernel notify interface (or something
similar) to asynchronously reinitialize the resolver when a change
is detected.
* Memory map resolv.conf and iterate through the nameservers
everytime, like we do for hosts. Really bad for performance and
hence I'd think this would get a 'no'.
Siddhesh