This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]