JDK-8148424 : Support IPv6-only Unix environments
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 8,9
  • Priority: P3
  • Status: In Progress
  • Resolution: Unresolved
  • OS: linux
  • CPU: generic
  • Submitted: 2016-01-28
  • Updated: 2017-04-20
Related Reports
Relates :  
Relates :  
Description
At Google, we maintain environments that have only IPv6 (IPv4 not supported).  Naturally, some things in the JDK fail then.  We should fix that.

There is evidence of attempts to support missing IPv4 in the sources already, but it is not complete.

Experimental patch at:
http://cr.openjdk.java.net/~martin/webrevs/openjdk9/ipv6-only/
(this is a port of local changes to openjdk9)

When setting the IPV6_V6ONLY=0 socket option, ignore errors instead of throwing an exception.

When checking for "protocol not supported", check for both EAFNOSUPPORT and EPROTONOSUPPORT.


Comments
Christoph or Chris, feel free to take ownership of this set of changes. Obviously cross-platform testing is necessary.
25-05-2016

We have changes that are in use at Google with jdk8 on linux-x64. Here are ports to jdk9, together with some motivation: http://cr.openjdk.java.net/~martin/webrevs/openjdk9/ipv6-only/ Use NetworkInterface.getByInetAddress() instead of DatagramSocket to determine whether an IP address is available. http://cr.openjdk.java.net/~martin/webrevs/openjdk9/ipv6-only-ip-address-available/ When STDIN is a socket, only disable IPv6 if that socket is IPv4. This makes the implementation consistent with the comment. Previously, even an AF_UNIX socket would cause IPv6 to be disabled. http://cr.openjdk.java.net/~martin/webrevs/openjdk9/ipv6-only-stdin-socket/ I am not the author - Paul Marks pmarks@google.com is. If you send mail about these, please cc him.
25-05-2016

I had to apply a few additional fixes in order to support IPV6Only networks on MacOSX and iOS. We might want to consider just removing the #ifdef __linux__. --- a/src/solaris/native/java/net/Inet4AddressImpl.c +++ b/src/solaris/native/java/net/Inet4AddressImpl.c @@ -824,17 +824,18 @@ switch (errno) { case ENETUNREACH: /* Network Unreachable */ case EAFNOSUPPORT: /* Address Family not supported */ + case EPROTONOSUPPORT: /* Protocol not supported */ case EADDRNOTAVAIL: /* address is not available on the remote machine */ -#ifdef __linux__ +#if defined( __linux__) || defined(MACOSX) case EINVAL: case EHOSTUNREACH: /* - * On some Linux versions, when a socket is bound to the loopback - * interface, connect will fail and errno will be set to EINVAL - * or EHOSTUNREACH. When that happens, don't throw an exception, - * just return false. + * On some Linux, Mac or iOS versions, when a socket is bound + * to the loopback interface, connect will fail and errno will + * be set to EINVAL or EHOSTUNREACH. When that happens, don't + * throw an exception, just return false. */ -#endif /* __linux__ */ +#endif /* __linux__ || MACOSX */ close(fd); return JNI_FALSE; --- a/src/solaris/native/java/net/Inet6AddressImpl.c +++ b/src/solaris/native/java/net/Inet6AddressImpl.c @@ -813,17 +813,18 @@ switch (errno) { case ENETUNREACH: /* Network Unreachable */ case EAFNOSUPPORT: /* Address Family not supported */ + case EPROTONOSUPPORT: /* Protocol not supported */ case EADDRNOTAVAIL: /* address is not available on the remote machine */ -#ifdef __linux__ +#if defined( __linux__) || defined(MACOSX) case EINVAL: case EHOSTUNREACH: /* - * On some Linux versions, when a socket is bound to the - * loopback interface, connect will fail and errno will - * be set to EINVAL or EHOSTUNREACH. When that happens, - * don't throw an exception, just return false. + * On some Linux, Mac or iOS versions, when a socket is bound + * to the loopback interface, connect will fail and errno will + * be set to EINVAL or EHOSTUNREACH. When that happens, don't + * throw an exception, just return false. */ -#endif /* __linux__ */ +#endif /* __linux__ || MACOSX */ close(fd); return JNI_FALSE; }
19-05-2016