5
votes

I ported an application to support IPv6, using popular tutorials. I decided to use only one socket listener for both protocols. Now I realized I have to set IPV6_V6ONLY properly (it's only working on my x86 linux out of the box, but not on my ARM).

Is this really the way to go? Some say IPV6_V6ONLY shouldn't be used (apparently it's outdated, because of IPv4 mapping over the wire), some say using one socket for both protocols is fine.

So, I'm confused. What is the current state about this problem? Did I misunderstand the problem?

2
Bit of clarification: V6ONLY affects how the software handles the packets. It does not affect the bits on the wire. On the software side everything looks like an IPv6 packet. If on the wire it is actually an IPv4 packet then the software side makes it look like an IPv6 packet and maps the IPv4 addresses to IPv6 addresses that are ::ffff: followed by the 32 bits of the IPv4 address. V6ONLY only changes this in the software. On the wire they are normal IPv4 and IPv6 packets. The ::ffff: addresses are never seen on the wire.Sander Steffann
Ah right, thx for the clarification. So it's only deprecated on the wire and using IPV6_V6ONLY is possible. How to handle it if it's supported or not is a different discussion :)duedl0r

2 Answers

4
votes

You should always bind both sockets explicitly, with the IPv6 socket bound with IPV6_V6ONLY.

Why? Cross-platform compatibility.

Windows by default requires that you explicitly bind on IPv4 and IPv6. Binding only to IPv6 will not implicitly bind to IPv4 as well.

Linux by default will implicitly bind to IPv4 as well when you bind on IPv6, only if the net.ipv6.bindv6only sysctl is set to 0. Distributions such as Debian change this default to 1, breaking your assumption.

I can't remember what Mac OS X does here (someone chirp in the comments please?), but the point is that explicitly binding to both protocols leaves no surprises.

2
votes

It is fine either way.

If you bind v4 and v6 explicitly, you need to set IPV6_V6ONLY, otherwise, you need to clear it. The default setting varies between platforms.

Some platforms do not support accepting v4 connections on v6 sockets, so for maximum compatibility I'd go with the "two sockets" approach.