GNOME Bugzilla – Bug 669724
souphttpsrc: doesn't support ipv6 link-local addresses
Last modified: 2013-08-19 17:43:01 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()
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
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
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
I guess this should be moved to glib/gio then. Brian, could you confirm your GLib version?
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
This no longer gives any warning with 1.x. Brian, can you confirm ?
It's a GLib bug anyway, and it was fixed apparently, so let's close this.
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
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.
fixed with the latest git glib and libsoup, and presumably the .90 releases