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 646082 - Addresses from GSocket should be normalized before returning
Addresses from GSocket should be normalized before returning
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: network
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2011-03-29 11:49 UTC by Jonny Lamb
Modified: 2011-08-30 03:45 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gsocket: normalize ipv6 addresses before returning them (2.18 KB, patch)
2011-03-29 11:49 UTC, Jonny Lamb
reviewed Details | Review
gsocketaddress: normalize ipv6 addresses before parsing sockaddrs (3.45 KB, patch)
2011-03-30 12:28 UTC, Jonny Lamb
needs-work Details | Review
GSocketAddress: create IPv4 addresses for IPv6 mapped-IPv4 addresses (6.63 KB, patch)
2011-08-27 23:48 UTC, Dan Winship
committed Details | Review

Description Jonny Lamb 2011-03-29 11:49:57 UTC
Created attachment 184570 [details] [review]
gsocket: normalize ipv6 addresses before returning them

I was using GSocketListener and wanted to listen on both IPv6 and IPv4. As my IPv6 socket didn't have IPV6_V6ONLY set, it was sufficient for listening on both socket families. Cool.

However, that means that IPv4 connections have v6-in-v4 remote addresses which is annoying. These should be filtered out in the GSocket level so when calling _get_remote_address or _get_local_address you get an actual IPv4 address, not some kind of ::ffff:192.168.0.101.

Here's a patch.
Comment 1 Dan Winship 2011-03-29 16:47:12 UTC
Comment on attachment 184570 [details] [review]
gsocket: normalize ipv6 addresses before returning them

>+      u_int32_t addr_big_endian;

just "addr" is fine; we don't need to do any endian-swapping.

>+  g_socket_normalize_address (&buffer);
>+
>   return g_socket_address_new_from_native (&buffer, len);

>+      g_socket_normalize_address (&buffer);
>+
>       socket->priv->remote_address = g_socket_address_new_from_native (&buffer, len);

seems like it would be simpler to just make g_socket_address_new_from_native() do this.
Comment 2 Jonny Lamb 2011-03-30 12:28:06 UTC
Created attachment 184689 [details] [review]
gsocketaddress: normalize ipv6 addresses before parsing sockaddrs

(In reply to comment #1)
> seems like it would be simpler to just make g_socket_address_new_from_native()
> do this.

Okay, makes sense.

Here's an updated patch. I could have changed more of g_socket_address_new_from_native() to use the union more instead of things like:

    struct sockaddr_in *addr = (struct sockaddr_in *) &(normalized.sa_in)

but wanted to keep this patch small and that belongs in another patch anyway. Let me know if you want me to do that.
Comment 3 Dan Winship 2011-04-26 20:57:10 UTC
Comment on attachment 184689 [details] [review]
gsocketaddress: normalize ipv6 addresses before parsing sockaddrs

>+  /* We have to use a union here so we don't break strict aliasing
>+   * rules. */

That's really ugly, and I don't get any warnings when I change it to be just a struct sockaddr_storage...
Comment 4 Jonny Lamb 2011-04-27 16:09:29 UTC
(In reply to comment #3)
> That's really ugly, and I don't get any warnings when I change it to be just a
> struct sockaddr_storage...

Odd, I do.

gsocketaddress.c: In function 'g_socket_address_new_from_native':
gsocketaddress.c:212: warning: dereferencing pointer 's4' does break strict-aliasing rules
gsocketaddress.c:210: warning: dereferencing pointer 's4' does break strict-aliasing rules
gsocketaddress.c:205: note: initialized from here
gsocketaddress.c:244: warning: dereferencing pointer 'normalized.34' does break strict-aliasing rules
gsocketaddress.c:244: note: initialized from here
gsocketaddress.c:259: warning: dereferencing pointer 'addr' does break strict-aliasing rules
gsocketaddress.c:251: note: initialized from here
gsocketaddress.c:274: warning: dereferencing pointer 'addr' does break strict-aliasing rules
gsocketaddress.c:266: note: initialized from here
gsocketaddress.c:290: warning: dereferencing pointer 'addr' does break strict-aliasing rules
gsocketaddress.c:282: note: initialized from here

That's with simply getting rid of the union and using "struct sockaddr_storage normalized" directly.
Comment 5 Dan Winship 2011-07-24 19:00:32 UTC
(In reply to comment #4)
> (In reply to comment #3)
> > That's really ugly, and I don't get any warnings when I change it to be just a
> > struct sockaddr_storage...
> 
> Odd, I do.

very belatedly... it turned out that this was lossage caused by ccache; I wasn't really using the compiler options I thought I was.
Comment 6 Dan Winship 2011-07-24 19:03:38 UTC
Comment on attachment 184689 [details] [review]
gsocketaddress: normalize ipv6 addresses before parsing sockaddrs

so, the normalization thing really only applies to IPv6 addresses, so it would be simpler to just have it exist entirely within the G_SOCKET_FAMILY_IPV6 branch of g_socket_address_new_from_native(), rather than "normalizing" IPv4 and UNIX sockaddrs to themselves.

Also, I just now pushed some additions to gio/tests/socket.c to make it do more testing that GSocket works, and it would be good to add another test there for this case too. Eg, that if you create an IPv6 server, and g_socket_speaks_ipv4() returns TRUE on it, and you connect to it via an IPv4 address, that the right thing happens.
Comment 7 Dan Winship 2011-08-27 23:48:00 UTC
Created attachment 194945 [details] [review]
GSocketAddress: create IPv4 addresses for IPv6 mapped-IPv4 addresses

based on a patch from Jonny Lamb

====

So, I tried this, but the test case doesn't work. I can't seem to
create a socket that listens on both ipv6 and ipv4... what am I doing
wrong?
Comment 8 Dan Winship 2011-08-30 03:45:31 UTC
figured it out; the dual v4/v6 thing only happens if you create the
server socket with g_inet_address_new_any(), not
g_inet_address_new_loopback(),

Attachment 194945 [details] pushed as fb74f6e - GSocketAddress: create IPv4 addresses for IPv6 mapped-IPv4 addresses