[Bug 1154599] Re: getaddrinfo() returns -11 (EAI_SYSTEM) instead of -2

Thomas Hood 1154599 at bugs.launchpad.net
Sun Jul 7 12:41:36 UTC 2013


(Copied here from a post by me to debian-devel.)

Executive summary: The getaddrinfo() returns different values
depending on the OS and on nsswitch.conf settings, making it
very difficult to use getaddrinfo() return values to deciding how
to handle an error.

Here are the results of further experiments with getaddrinfo().
I am using the attached x.c program.  It tries to look up the
valid domain name 'www.google.com' and an invalid name
four times:
* once with empty /etc/resolv.conf (in which case the resolver tries 127.0.0.1:53)
* once with /etc/resolv.conf pointing to a working nameserver on my LAN
* once with empty /etc/resolv.conf (again)
* once with /etc/resolv.conf pointing to an IP address where there is no working nameserver

OS is Debian 7.0.

================================
# ./a.out
Making resolv.conf empty
Results of looking up www.google.com: status = -2, errno = 2
Results of looking up a bogus name: status = -2, errno = 2
Writing nameserver option to resolv.conf
Results of looking up www.google.com: status = 0, errno = 101
Results of looking up a bogus name: status = -2, errno = 2
Making resolv.conf empty
Results of looking up www.google.com: status = -2, errno = 2
Results of looking up a bogus name: status = -2, errno = 2
Writing incorrect nameserver option to resolv.conf
Results of looking up www.google.com: status = -2, errno = 2
Results of looking up a bogus name: status = -2, errno = 2
================================

As I saw before, status is always -2 (EAI_NONAME).  The manpage
doesn't say that errno is significant in that case. (It is significant
when status is -11.)

Helmut got different results. Is the difference between my machine
and Helmut's machine attributable to some diff in nsswitch.conf,
perhaps?  I have:

    hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4

I tested next with

    hosts: dns

and got different results.

================================
Making resolv.conf empty
Results of looking up www.google.com: status = -2, errno = 111
Results of looking up a bogus name: status = -2, errno = 111
Writing nameserver option to resolv.conf
Results of looking up www.google.com: status = 0, errno = 101
Results of looking up a bogus name: status = -2, errno = 101
Making resolv.conf empty
Results of looking up www.google.com: status = -2, errno = 111
Results of looking up a bogus name: status = -2, errno = 111
Writing incorrect nameserver option to resolv.conf
Results of looking up www.google.com: status = -2, errno = 111
Results of looking up a bogus name: status = -2, errno = 111
================================

Now errno for empty or incorrect resolv.conf is 111 (ECONNREFUSED ).
And with correct resolv.conf and bogus domain name errno is 101
(ENETUNREACH).  That doesn't make too much sense but as I
said I don't think we are supposed to pay attention to errno if
status is -2.

Next I ran the program on Ubuntu 13.04 with "hosts: dns".

================================
Making resolv.conf empty
Results of looking up www.google.com: status = -11, errno = 111
Results of looking up a bogus name: status = -11, errno = 111
Writing nameserver option to resolv.conf
Results of looking up www.google.com: status = 0, errno = 101
Results of looking up a bogus name: status = -2, errno = 101
Making resolv.conf empty
Results of looking up www.google.com: status = -11, errno = 111
Results of looking up a bogus name: status = -11, errno = 111
Writing incorrect nameserver option to resolv.conf
Results of looking up www.google.com: status = -11, errno = 110
Results of looking up a bogus name: status = -11, errno = 110
================================

This is different in two ways. First the status is -11 (EAI_SYSTEM)
instead of -2 (EAI_NONAME) when no nameserver can be reached.
Second, there is now a difference between the empty-resolv.conf
case and the resolv.conf-with-bogus-address case. In the latter
case errno is 110 (ETIMEDOUT) instead of 111 (ECONNREFUSED).
This is better.

Debian 7.0 has libc6 version 2.13-37.
Ubuntu 13.04 has libc6 version 2.17-0ubuntu5.

What's behind all this?  [google, google...]  I see that in
November 2012 a change was made upstream

http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=cfde9b463d63092ff0908d4c2748ace648e2ead8

in response to a complaint that the wrong status was returned
in the case of an internal error (out-of-fds).

  http://sourceware.org/bugzilla/show_bug.cgi?id=14719

This is possibly the reason that I get status -11 instead of
-2 on Ubuntu.

But the result of the change was that getaddrinfo() returned
EAI_SYSTEM in too many cases.

  http://sourceware.org/bugzilla/show_bug.cgi?id=15339

This has recently (May 2013) been fixed

  http://sourceware.org/bugzilla/show_bug.cgi?id=15635
  http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=3d04f5db20c8f0d1ba3881b5f5373586a18cf188

such that (IIUC) now getaddrinfo() should return different
status/errno combinations for internal errors, network errors
and name resolution failures. I haven't tested the upstream
code yet.

I don't get the impression that the handling of return values
by the various eglibc layers has been well thought out and
documented; the developers seem to be making changes ad-hoc.

In any case, because of all these differences and changes we
won't have a good, stable getaddrinfo() interface to program
against for a while.  In the meantime a program that needs to
distinguish between different causes for a name resolution
failure will have to do more than just check the status and
errno from getaddinfo().


** Bug watch added: Sourceware.org Bugzilla #14719
   http://sourceware.org/bugzilla/show_bug.cgi?id=14719

** Bug watch added: Sourceware.org Bugzilla #15635
   http://sourceware.org/bugzilla/show_bug.cgi?id=15635

-- 
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to eglibc in Ubuntu.
https://bugs.launchpad.net/bugs/1154599

Title:
  getaddrinfo() returns -11 (EAI_SYSTEM) instead of -2

Status in “eglibc” package in Ubuntu:
  Confirmed
Status in “python2.7” package in Ubuntu:
  Confirmed

Bug description:
  $ cat lookup.py
  #!/usr/bin/python
  import sys, socket
  names = ["slashdot.org", "foooooooooowhizzzzzzzz.com"]
  if len(sys.argv) > 1:
     names = sys.argv[1:]
  for iname in names:
      try:
          result = socket.getaddrinfo(iname, None, 0, 0, socket.SOCK_STREAM,
                                      socket.AI_CANONNAME)
          for (fam, stype, proto, cname, sockaddr) in result:
              sys.stdout.write("cname=%s, sockaddr=%s\n" % (cname, sockaddr))
      except socket.gaierror as error:
          sys.stderr.write("%s failed lookup" % iname)

  $ python2.7 lookup.py
  cname=slashdot.org, sockaddr=('216.34.181.45', 0)
  Traceback (most recent call last):
    File "/tmp/x.py", line 10, in <module>
      socket.AI_CANONNAME)
  socket.error: [Errno 2] No such file or directory

  shell returned 1

  $ dpkg -S /usr/bin/python2.7
  python2.7-minimal: /usr/bin/python2.7
  $ dpkg-query --show python2.7-minimal
  python2.7-minimal	2.7.3-16ubuntu1

  This is a behavioral change from quantal (2.7.3-5ubuntu4).

  ProblemType: Bug
  DistroRelease: Ubuntu 13.04
  Package: python 2.7.3-10ubuntu5
  ProcVersionSignature: Ubuntu 3.5.0-21.32-generic 3.5.7.1
  Uname: Linux 3.5.0-21-generic x86_64
  ApportVersion: 2.9.1-0ubuntu1
  Architecture: amd64
  Date: Wed Mar 13 09:52:55 2013
  EcryptfsInUse: Yes
  InstallationDate: Installed on 2011-10-19 (511 days ago)
  InstallationMedia: Ubuntu 11.10 "Oneiric Ocelot" - Release amd64 (20111012)
  MarkForUpload: True
  ProcEnviron:
   TERM=xterm
   PATH=(custom, no user)
   XDG_RUNTIME_DIR=<set>
   LANG=en_US.UTF-8
   SHELL=/bin/bash
  SourcePackage: python-defaults
  UpgradeStatus: Upgraded to raring on 2013-01-07 (64 days ago)

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/1154599/+subscriptions




More information about the foundations-bugs mailing list