After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 692291 - Can't resolve localhost when offline.
Can't resolve localhost when offline.
Status: RESOLVED OBSOLETE
Product: libsoup
Classification: Core
Component: HTTP Transport
2.40.x
Other Linux
: Normal normal
: ---
Assigned To: libsoup-maint@gnome.bugs
libsoup-maint@gnome.bugs
Depends on:
Blocks:
 
 
Reported: 2013-01-22 13:32 UTC by Manuel Quiñones
Modified: 2018-09-21 16:12 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Soup testcase (732 bytes, text/x-python)
2013-01-22 13:32 UTC, Manuel Quiñones
Details
another test (424 bytes, text/plain)
2013-01-22 14:36 UTC, Dan Winship
Details
WebKit test (364 bytes, text/plain)
2013-01-22 18:14 UTC, Manuel Quiñones
Details

Description Manuel Quiñones 2013-01-22 13:32:15 UTC
Created attachment 234105 [details]
Soup testcase

I attach a testcase using libsoup with python through introspection.

TestCase:

- have a HTTP server serving in http://localhot:8000, for example doing 'python -m SimpleHTTPServer'
- run the testsoup.py testcase while online
- run the testsoup.py testcase while offline

Expected: both tests should give 'OK'.

What I get for online is:

[olpc@xo-93-20-69 prog]$ python testsoup.py 
<enum SOUP_STATUS_OK of type SoupKnownStatusCode>
OK

What I get for offline is:

[olpc@xo-93-20-69 prog]$ python testsoup.py 
<enum SOUP_STATUS_CANT_RESOLVE of type SoupKnownStatusCode>
Cannot resolve hostname (localhost)

Using F18 and rpm package libsoup-2.40.2-1.fc18.armv7hl

The bug in olpc trac: http://dev.laptop.org/ticket/12479
Comment 1 Dan Winship 2013-01-22 13:57:15 UTC
Can anything else resolve localhost when you're offline? libsoup just uses GResolver, which just calls getaddrinfo(), so it should be getting the same behavior as every other app on your system.

Is there an entry for "localhost" in /etc/hosts, and does /etc/nssswitch.conf list "files" before "dns" for "hosts"?
Comment 2 Manuel Quiñones 2013-01-22 14:11:31 UTC
(In reply to comment #1)
> Can anything else resolve localhost when you're offline? libsoup just uses
> GResolver, which just calls getaddrinfo(), so it should be getting the same
> behavior as every other app on your system.

Yes Firefox can resolve localhost, unlike Epiphany or our olpc browser Browse, which uses WebKitGTK too.  Although I hope Firefox is not falling back to 127.0.0.1 or 0.0.0.0, which works in WebKit too.

I have also tested this snippet, robbed from https://fedoraproject.org/wiki/Networking/NameResolution and 'localhost' is resolved too.

>>> from socket import *
>>> for item in getaddrinfo("localhost", "http", AF_UNSPEC, SOCK_STREAM, SOL_TCP, AI_PASSIVE):
...     print item
... 
(2, 1, 6, '', ('127.0.0.1', 80))

> Is there an entry for "localhost" in /etc/hosts, and does /etc/nssswitch.conf
> list "files" before "dns" for "hosts"?

Yes, the content of /etc/hosts is:

127.0.0.1 xo-93-20-69.localdomain xo-93-20-69 localhost
::1		localhost6.localdomain6 localhost6

And yes, the entry for "hosts" in /etc/nsswitch.conf is:

hosts:      files dns myhostname
Comment 3 Dan Winship 2013-01-22 14:36:47 UTC
Created attachment 234106 [details]
another test

so what does this test program output for you?
Comment 4 Manuel Quiñones 2013-01-22 14:42:10 UTC
(In reply to comment #3)
> Created an attachment (id=234106) [details]
> another test
> 
> so what does this test program output for you?

Running online:

[olpc@xo-93-20-69 ~]$ python testsoup2.py 
soup_address_resolve_sync returns status 200, addr 127.0.0.1
g_resolver_lookup_by_name returns:
  127.0.0.1

Running offline:

[olpc@xo-93-20-69 ~]$ python testsoup2.py 
soup_address_resolve_sync returns status 2, addr None
Traceback (most recent call last):
  • File "testsoup2.py", line 9 in <module>
    addrs = resolver.lookup_by_name('localhost', None)
  • File "/usr/lib/python2.7/site-packages/gi/types.py", line 47 in function
    return info.invoke(*args, **kwargs)
gi._glib.GError: Error resolving 'localhost': No address associated with hostname

Comment 5 Dan Winship 2013-01-22 15:23:44 UTC
what's the output of "ifconfig -a" when you're offline?

(specifically, does going offline bring down the loopback interface for some reason?)

(In reply to comment #2)
> >>> from socket import *
> >>> for item in getaddrinfo("localhost", "http", AF_UNSPEC, SOCK_STREAM, SOL_TCP, AI_PASSIVE):
> ...     print item
> ... 
> (2, 1, 6, '', ('127.0.0.1', 80))

the equivalent of what GResolver does would be to replace AI_PASSIVE with AI_ADDRCONFIG (which is why it could possibly be screwing up if the loopback interface is down).

If running that with AI_ADDRCONFIG works, but GResolver doesn't, then I have no clue what's going on, unless you have multiple copies of glibc installed or something.
Comment 6 Manuel Quiñones 2013-01-22 16:10:08 UTC
(In reply to comment #5)
> what's the output of "ifconfig -a" when you're offline?
> 
> (specifically, does going offline bring down the loopback interface for some
> reason?)

"ifconfig -a" when offline shows a loopback interface:

eth0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet6 fe80::227c:8fff:fe93:2069  prefixlen 64  scopeid 0x20<link>
        ether 20:7c:8f:93:20:69  txqueuelen 1000  (Ethernet)
        RX packets 22398  bytes 32484415 (30.9 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 12918  bytes 981191 (958.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 16436
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 0  (Local Loopback)
        RX packets 1066  bytes 913130 (891.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1066  bytes 913130 (891.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

> 
> (In reply to comment #2)
> > >>> from socket import *
> > >>> for item in getaddrinfo("localhost", "http", AF_UNSPEC, SOCK_STREAM, SOL_TCP, AI_PASSIVE):
> > ...     print item
> > ... 
> > (2, 1, 6, '', ('127.0.0.1', 80))
> 
> the equivalent of what GResolver does would be to replace AI_PASSIVE with
> AI_ADDRCONFIG (which is why it could possibly be screwing up if the loopback
> interface is down).

Aha! You found something:

>>> for item in getaddrinfo('localhost', 'http', AF_UNSPEC, SOCK_STREAM, SOL_TCP, AI_PASSIVE):
...     print item
... 
(2, 1, 6, '', ('127.0.0.1', 80))
>>> for item in getaddrinfo('localhost', 'http', AF_UNSPEC, SOCK_STREAM, SOL_TCP, AI_ADDRCONFIG):
...     print item
... 
Traceback (most recent call last):
  • File "<stdin>", line 1 in <module>
    socket.gaierror: [Errno -5] No address associated with hostname

Comment 7 Pavel Simerda 2013-01-22 16:43:29 UTC
Please also post the contents of your /etc/hosts, especially to know whether 'localhost' is IPv4-only or dual-protocol.

AFAIK this problem can only be seen when you have no IPv4 except 127.0.0.1 and some non-localhost IPv6 address (e.g. a link-local address on eth0).

The easiest way around should be to have localhost point to both protocols (but it may create other problems with AI_PASSIVE, unfortunately). Another is to temporarily avoid AI_ADDRCONFIG and wait for getaddrinfo to be fixed.
Comment 8 Manuel Quiñones 2013-01-22 17:26:29 UTC
(In reply to comment #7)
> Please also post the contents of your /etc/hosts, especially to know whether
> 'localhost' is IPv4-only or dual-protocol.

From comment 2 above, the content of /etc/hosts is:

127.0.0.1 xo-93-20-69.localdomain xo-93-20-69 localhost
::1        localhost6.localdomain6 localhost6

Thanks for your insights.
Comment 9 Pavel Simerda 2013-01-22 17:39:58 UTC
Mine is:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
...

(Fedora 17/18)

Upstream bug report (a bit messy, sorry for that):

http://sourceware.org/bugzilla/show_bug.cgi?id=14966
Comment 10 Manuel Quiñones 2013-01-22 18:14:18 UTC
Created attachment 234126 [details]
WebKit test
Comment 11 Manuel Quiñones 2013-01-22 18:21:28 UTC
(In reply to comment #9)
> Mine is:
> 
> 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
> ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
> ...

Aha! Changed /etc/hosts to yours, and both testcases succeed now, being offline.

By the way WebKit still gets "Cannot connect to destination (localhost)" when I'm offline.  Attached another testcase.

- have a HTTP server serving in http://localhot:8000, for example doing 'python
-m SimpleHTTPServer'
- run the testwebkit.py testcase while online
- run the testwebkit.py testcase while offline

Expected: both tests should display a list of the current directory as a webpage.

What I get for online is correct.  But for offline, I get a message "Cannot connect to destination (localhost)".

> Upstream bug report (a bit messy, sorry for that):
> 
> http://sourceware.org/bugzilla/show_bug.cgi?id=14966

Oh I see, looks like the same bug.
Comment 12 Manuel Quiñones 2013-01-25 19:45:53 UTC
(In reply to comment #11)
> (In reply to comment #9)
> > Mine is:
> > 
> > 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
> > ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
> > ...
> 
> Aha! Changed /etc/hosts to yours, and both testcases succeed now, being
> offline.

False.  My fault, I was testing a modified version of the first attached testcase.  It gives "Cannot connect to destination (localhost)", which matches the WebKit testcase.
Comment 13 Daniel Drake 2013-01-25 20:00:50 UTC
Tested here. After modifying /etc/hosts to make localhost resolve to ::1 in addition to 127.0.0.1, testsoup.py still doesn't quite work: it fails to connect to python's SimpleHTTPServer (Cannot connect to destination).

However, the python code shows that the server is only listening on AF_INET (no AF_INET6), and netstat confirms. I guess localhost is now resolving as an IPv6 address in the context of GResolver - and hence it doesn't find any listening server. So I guess this behaviour is somewhat reasonable.

So, I guess the question is: is having "localhost" resolve to both IPv4 and IPv6 a good/recommended/required setup to have? If it is, then we can say that OLPC has misconfigured systems, and that python is being a bit outdated in not listening on IPv6 by default in its SocketServer class. Fixing both of those would solve the problem.

Also, it does look like AI_ADDRCONFIG might be behaving as documented, so I'm not sure if http://sourceware.org/bugzilla/show_bug.cgi?id=14966 is actually a bug.

       If  hints.ai_flags includes the AI_ADDRCONFIG flag, then IPv4 addresses
       are returned in the list pointed to by res only if the local system has
       at  least  one  IPv4  address  configured,  and IPv6 addresses are only
       returned if the local system has at least one IPv6 address  configured.
       The loopback address is not considered for this case as valid as a con-
       figured address.

In the offline case where /etc/hosts only has an IPv4 address for localhost, there is no IPv4 address configured on the system (except for the loopback address), so it refuses to return any IPv4 addresses.

However, in the offline case when /etc/hosts has an IPv6 address, the system does also have a link-local IPv6 address, meaning that it can return IPv6 addresses, and it then returns the loopback address ::1 for localhost.

Although documented, this does seem like odd behaviour, and that point seems to be well argued at
https://fedoraproject.org/wiki/Networking/NameResolution/ADDRCONFIG
Comment 14 Pavel Simerda 2013-01-25 20:18:29 UTC
(In reply to comment #12)
> False.  My fault, I was testing a modified version of the first attached
> testcase.  It gives "Cannot connect to destination (localhost)", which matches
> the WebKit testcase.

That's... surprising, at the least.

My getaddrinfo tests with glibc 2.16.0 show:

a) with no addresses (or loopback addresses only):

getaddrinfo host="localhost" hints.ai_flags=AI_ADDRCONFIG:
  ::1
  127.0.0.1

b) with link-local IPv6 address

getaddrinfo host="localhost" hints.ai_flags=AI_ADDRCONFIG:
  ::1

That means that in the second case, ::1 is still returned and would be used for connection. If this is your case, then it means the error comes probably from connect(). One possibility is, that the service itself is not listening on IPv6.

[write this part of the comment before seeing the new one]

(In reply to comment #13)
> Tested here. After modifying /etc/hosts to make localhost resolve to ::1 in
> addition to 127.0.0.1, testsoup.py still doesn't quite work: it fails to
> connect to python's SimpleHTTPServer (Cannot connect to destination).
> 
> However, the python code shows that the server is only listening on AF_INET (no
> AF_INET6), and netstat confirms. I guess localhost is now resolving as an IPv6
> address in the context of GResolver - and hence it doesn't find any listening
> server. So I guess this behaviour is somewhat reasonable.

Exactly.

> So, I guess the question is: is having "localhost" resolve to both IPv4 and
> IPv6 a good/recommended/required setup to have?

It definitely is. It works for IPv4-only, IPv6-only and dual-protocol use cases.

> If it is, then we can say that
> OLPC has misconfigured systems, and that python is being a bit outdated in not
> listening on IPv6 by default in its SocketServer class. Fixing both of those
> would solve the problem.

Looks correct.

> Also, it does look like AI_ADDRCONFIG might be behaving as documented, so I'm
> not sure if http://sourceware.org/bugzilla/show_bug.cgi?id=14966 is actually a
> bug.

It doesn't behave as documented in the manpage when offline. And it never behaves as documented in POSIX1-2008. And what more, the documented behavior is even more destructive than the actual behavior.

It is definitely a bug to break localhost whether it is documented or not. Feel free to comment on the upstream bug, though.

> Although documented, this does seem like odd behaviour, and that point seems to
> be well argued at
> https://fedoraproject.org/wiki/Networking/NameResolution/ADDRCONFIG

And we plan to fix it:

https://fedoraproject.org/wiki/Features/FixNetworkNameResolution
Comment 15 Dan Winship 2015-02-10 11:58:01 UTC
[mass-moving all "UNCONFIRMED" libsoup bugs to "NEW" after disabling the "UNCONFIRMED" status for this product now that bugzilla.gnome.org allows that. bugspam-libsoup-20150210]
Comment 16 GNOME Infrastructure Team 2018-09-21 16:12:19 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/libsoup/issues/47.