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 732317 - Support GSocketConnectable for loopback addresses
Support GSocketConnectable for loopback addresses
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: network
2.41.x
Other All
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2014-06-27 08:24 UTC by Philip Withnall
Modified: 2014-11-29 19:23 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gnetworkaddress: Add g_network_address_new_loopback() constructor (13.78 KB, patch)
2014-10-27 11:03 UTC, Philip Withnall
none Details | Review
gnetworkaddress: Add g_network_address_new_loopback() constructor (8.19 KB, patch)
2014-11-23 17:59 UTC, Dan Winship
committed Details | Review

Description Philip Withnall 2014-06-27 08:24:41 UTC
Currently, to connect to a local service using IPv4 or IPv6 (where you don’t know whether the service is running on one or the other) on a loopback connection, you need to manually create several GInetSocketAddresses:

    GInetAddress *ipv4_address = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
    GInetSocketAddress *ipv4_s_address = g_inet_socket_address_new (ipv4_address, 1234);

    /* same for IPv6, then somehow try and connect to both and choose the one which works */

It would be more useful if we could have a GSocketConnectable which would automatically enumerate all possible loopback addresses (i.e. both IPv4 and IPv6) on the given port, so that we can use g_socket_client_connect() to magically enumerate and try the different addresses.

Using a GNetworkAddress doesn’t work (and I’m not sure it _can_ work):

    g_network_address_new ("localhost", 1234);

gives a GSocketConnectable which only enumerates 127.0.0.1, and not ::1 as well. This is because /etc/hosts lists localhost and localhost6 separately. (Why is that?)

So either we could somehow change GNetworkAddress to have some way of resolving to 127.0.0.1 *and* ::1; or we could add a new GSocketConnectable implementation which enumerates loopback addresses for a specified port. e.g.:

    GLoopbackAddress extends GObject, implements GSocketConnectable
    GSocketConnectable *g_loopback_address_new (guint16 port);

Which option would make more sense?
Comment 1 Dan Winship 2014-10-26 15:51:47 UTC
(In reply to comment #0)
> Using a GNetworkAddress doesn’t work (and I’m not sure it _can_ work):
> 
>     g_network_address_new ("localhost", 1234);
> 
> gives a GSocketConnectable which only enumerates 127.0.0.1, and not ::1 as
> well. This is because /etc/hosts lists localhost and localhost6 separately.
> (Why is that?)

That's distro-specific to some extent, but I think it's because in the past, some code looked up 'localhost' and couldn't deal with getting back an IPv6 address.

> So either we could somehow change GNetworkAddress to have some way of resolving
> to 127.0.0.1 *and* ::1; or we could add a new GSocketConnectable implementation
> which enumerates loopback addresses for a specified port. e.g.:
> 
>     GLoopbackAddress extends GObject, implements GSocketConnectable
>     GSocketConnectable *g_loopback_address_new (guint16 port);
> 
> Which option would make more sense?

I don't think we should special-case 'g_network_address_new("localhost", port)', but we could add g_network_address_new_localhost() (or _new_loopback()) that returned a GNetworkAddress with hostname='localhost', but always had both addresses. (So basically like your second idea, except without the effort of creating a new subclass.)
Comment 2 Philip Withnall 2014-10-27 11:03:03 UTC
Created attachment 289404 [details] [review]
gnetworkaddress: Add g_network_address_new_loopback() constructor

This is a convenience method for creating a GNetworkAddress which is
guaranteed to return IPv4 and IPv6 loopback addresses. The host cannot
guarantee to resolve ‘localhost’ to both types of address, so programs
which wish to connect to a local service over IPv4 or IPv6 must
currently manually create an IPv4 and another IPv6 socket, and detect
which of the two are working. This new API allows the existing
GSocketConnectable machinery to be used to automate that.

Unit tests are included.
Comment 3 Dan Winship 2014-11-23 17:59:31 UTC
Created attachment 291318 [details] [review]
gnetworkaddress: Add g_network_address_new_loopback() constructor

I was imagining something a little simpler than that. Does this work
for you?
Comment 4 Philip Withnall 2014-11-26 10:07:51 UTC
(In reply to comment #3)
> Created an attachment (id=291318) [details] [review]
> gnetworkaddress: Add g_network_address_new_loopback() constructor
> 
> I was imagining something a little simpler than that. Does this work
> for you?

That looks a lot simpler, yes. Looks good to me. :-)
Comment 5 Dan Winship 2014-11-29 19:22:58 UTC
Attachment 291318 [details] pushed as 64f9bf9 - gnetworkaddress: Add g_network_address_new_loopback() constructor