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 669724 - souphttpsrc: doesn't support ipv6 link-local addresses
souphttpsrc: doesn't support ipv6 link-local addresses
Status: RESOLVED FIXED
Product: libsoup
Classification: Core
Component: Misc
2.43.x
Other Linux
: Normal normal
: ---
Assigned To: libsoup-maint@gnome.bugs
libsoup-maint@gnome.bugs
Depends on:
Blocks:
 
 
Reported: 2012-02-09 01:57 UTC by Brian
Modified: 2013-08-19 17:43 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Brian 2012-02-09 01:57:50 UTC
If I setup a simple ipv6 http server (python code below) in a directory containing an mp3 file, I can play the file using:

>gst-launch-0.10 playbin uri="http://[::1]:8080/file.mp3"

But this only works on the host; to access it from another machine on the LAN, I would need to use the link-local address.  I tried (from the same host) using the link-local address with and without the scopeID, but neither of them work.

without the scopeid, i get:

>playbin uri="http://[fe80::52e5:49ff:fe5c:22a]:8080/file.mp3"

ERROR: from element /GstPlayBin:playbin0/GstSoupHTTPSrc:source: Cannot connect to destination

with the scopeid, i get:

>playbin uri="http://[fe80::52e5:49ff:fe5c:22a%2]:8080/file.mp3"

ERROR: from element /GstPlayBin:playbin0/GstSoupHTTPSrc:source: Cannot resolve hostname


The error for the link-local address without the scopeid makes sence, as I guess it's required for the link-local address to have meaning.  Adding the scope-id, or even the iface name should resolve successfully though (it works with getaddrinfo() and utilities like ping6).


the following is the python server:
--------------------------------------------------------
import socket
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

class HTTPServerV6(HTTPServer):
  address_family = socket.AF_INET6

def main():
  server = HTTPServerV6(('', 8080),SimpleHTTPRequestHandler)
  server.serve_forever()

if __name__ == '__main__':
  main()
Comment 1 Sebastian Dröge (slomo) 2012-02-09 08:17:08 UTC
GStreamer is directly passing the URL to libsoup. Do you get the same behaviour with any other libsoup based application?

You could use this for example:
http://git.gnome.org/browse/libsoup/tree/tests/get.c
Comment 2 Davy 2012-02-10 05:47:55 UTC
glib problem.

As you can see the log message,
It’s a DNS lookup fail caused by link-local address including zone_id delimiter (%)

It means that glib try to resolve link-local address, already resolved address, due to glib think it as a domain name.

Let’s see the g_resolve_lookup_by_name_async at gio / gresolver.c

At the first time, it checks whether the hostname is IP address or not. 
In case of Linux, it calls inet_pton() after then see the return value, success or fail.

Easily speaking, 
if the inet_pton() is succeeded, it’s a domain name so we need to resolve it via getaddrinfo()
if the inet_pton() is failed, it’s a IP address so we don’t need to call getaddrinfo()

The problem is inet_pton() can’t recognize zone_id delimiter, %.
You can find more detail in glibc library (system library, not a GTK’s glib), inet_pton.c or man inet_pton.

As a consequence, if some IPv6 address contains zone_id (%), you never get HTTP connection due to DNS lookup fail.

Davy
Comment 3 Davy 2012-02-10 05:50:38 UTC
fixed typo
"
Easily speaking, 
if the inet_pton() is failed, it’s a domain name so we need to resolve it
via getaddrinfo()
if the inet_pton() is succeeded, it’s a IP address so we don’t need to call
getaddrinfo()
"

(In reply to comment #2)
> glib problem.
> As you can see the log message,
> It’s a DNS lookup fail caused by link-local address including zone_id delimiter
> (%)
> It means that glib try to resolve link-local address, already resolved address,
> due to glib think it as a domain name.
> Let’s see the g_resolve_lookup_by_name_async at gio / gresolver.c
> At the first time, it checks whether the hostname is IP address or not. 
> In case of Linux, it calls inet_pton() after then see the return value, success
> or fail.
> Easily speaking, 
> if the inet_pton() is succeeded, it’s a domain name so we need to resolve it
> via getaddrinfo()
> if the inet_pton() is failed, it’s a IP address so we don’t need to call
> getaddrinfo()
> The problem is inet_pton() can’t recognize zone_id delimiter, %.
> You can find more detail in glibc library (system library, not a GTK’s glib),
> inet_pton.c or man inet_pton.
> As a consequence, if some IPv6 address contains zone_id (%), you never get HTTP
> connection due to DNS lookup fail.
> Davy
Comment 4 Tim-Philipp Müller 2012-10-16 10:35:50 UTC
I guess this should be moved to glib/gio then.

Brian, could you confirm your GLib version?
Comment 5 Brian 2012-10-20 20:09:18 UTC
I don't have the same install I did when I originally posted this bug report.

I just tried this on a fresh Ubuntu 12.10 upgrade and the first command which use to work:

>gst-launch-0.10 playbin uri="http://[::1]:8080/file.mp3"

now gives the error: 
"(gst-launch-0.10:12685): GLib-GIO-WARNING **: Invalid URI 'http://::1:8084'"

So it seems to be stripping the square brackets.



gstl-launch-0.10 --version:
gst-launch-0.10 version 0.10.36
GStreamer 0.10.36
https://launchpad.net/distros/ubuntu/+source/gstreamer0.10


i think the libglib version is 2.34.0
Comment 6 Edward Hervey 2013-08-14 08:05:29 UTC
This no longer gives any warning with 1.x.

Brian, can you confirm ?
Comment 7 Tim-Philipp Müller 2013-08-14 10:56:55 UTC
It's a GLib bug anyway, and it was fixed apparently, so let's close this.
Comment 8 Brian 2013-08-17 17:42:12 UTC
what version was it fixed in?  I still get this behavior with gstreamer 0.1 and 1.0.  I believe i'm using glib 2.36.3
Comment 9 Tim-Philipp Müller 2013-08-17 19:24:36 UTC
Sorry, it seems I misunderstood the issue at hand.

It looks like this is still a problem with glib/gio and libsoup from git master:

tpm@zingle:~/gst/glib-git/libsoup/examples$ ./get 'http://[fe80::21e:c2ff:fec0:edf0%lo]:8080/file.mp3'
IPv6: forbidden character: %
(lt-get:11007): GLib-GIO-WARNING **: Invalid URI 'http://[fe80::21e:c2ff:fec0:edf0%lo]:8080/'

There's some API to get/set a numerical scope_id in

   https://developer.gnome.org/gio/stable/GInetSocketAddress.html

but I don't see a way for GInetAddress to pick up on this and make it available.

There's some code to test this exact thing, but it uses g_network_address_new().

So maybe libsoup or some code somewhere is using the wrong API, or GInetAddr should preserve the identifier (never mind parse the URI correctly)?

Moving to libsoup for the time being.
Comment 10 Dan Winship 2013-08-19 17:43:01 UTC
fixed with the latest git glib and libsoup, and presumably the .90 releases