8222562: Don't set IPV6_V6ONLY when IPv4 is not available
authoraeubanks
Tue, 16 Apr 2019 13:16:49 -0700
changeset 54627 22323f20401b
parent 54626 3fb6efa2c9f1
child 54628 dcb78d2f07e5
8222562: Don't set IPV6_V6ONLY when IPv4 is not available Reviewed-by: dfuchs, chegar Contributed-by: aeubanks@google.com
src/java.base/share/native/libnet/net_util.c
src/java.base/share/native/libnet/net_util.h
src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c
src/java.base/unix/native/libnet/PlainSocketImpl.c
src/java.base/unix/native/libnet/net_util_md.c
src/java.base/unix/native/libnio/ch/Net.c
src/java.base/windows/native/libnet/net_util_md.c
--- a/src/java.base/share/native/libnet/net_util.c	Thu Apr 25 18:41:52 2019 -0400
+++ b/src/java.base/share/native/libnet/net_util.c	Tue Apr 16 13:16:49 2019 -0700
@@ -27,12 +27,19 @@
 
 #include "java_net_InetAddress.h"
 
+int IPv4_supported();
 int IPv6_supported();
 int reuseport_supported();
 
+static int IPv4_available;
 static int IPv6_available;
 static int REUSEPORT_available;
 
+JNIEXPORT jint JNICALL ipv4_available()
+{
+    return IPv4_available;
+}
+
 JNIEXPORT jint JNICALL ipv6_available()
 {
     return IPv6_available;
@@ -68,6 +75,7 @@
      * check now whether we have IPv6 on this platform and if the
      * supporting socket APIs are available
      */
+    IPv4_available = IPv4_supported();
     IPv6_available = IPv6_supported() & (!preferIPv4Stack);
 
     /* check if SO_REUSEPORT is supported on this platform */
--- a/src/java.base/share/native/libnet/net_util.h	Thu Apr 25 18:41:52 2019 -0400
+++ b/src/java.base/share/native/libnet/net_util.h	Tue Apr 16 13:16:49 2019 -0700
@@ -126,6 +126,7 @@
 
 jfieldID NET_GetFileDescriptorID(JNIEnv *env);
 
+JNIEXPORT jint JNICALL ipv4_available();
 JNIEXPORT jint JNICALL ipv6_available();
 
 JNIEXPORT jint JNICALL reuseport_available();
--- a/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c	Thu Apr 25 18:41:52 2019 -0400
+++ b/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c	Tue Apr 16 13:16:49 2019 -0700
@@ -915,8 +915,10 @@
         return;
     }
 
-    /* Disable IPV6_V6ONLY to ensure dual-socket support */
-    if (domain == AF_INET6) {
+    /*
+     * If IPv4 is available, disable IPV6_V6ONLY to ensure dual-socket support.
+     */
+    if (domain == AF_INET6 && ipv4_available()) {
         arg = 0;
         if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
                        sizeof(int)) < 0) {
--- a/src/java.base/unix/native/libnet/PlainSocketImpl.c	Thu Apr 25 18:41:52 2019 -0400
+++ b/src/java.base/unix/native/libnet/PlainSocketImpl.c	Tue Apr 16 13:16:49 2019 -0700
@@ -187,8 +187,10 @@
         return;
     }
 
-    /* Disable IPV6_V6ONLY to ensure dual-socket support */
-    if (domain == AF_INET6) {
+    /*
+     * If IPv4 is available, disable IPV6_V6ONLY to ensure dual-socket support.
+     */
+    if (domain == AF_INET6 && ipv4_available()) {
         int arg = 0;
         if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
                        sizeof(int)) < 0) {
--- a/src/java.base/unix/native/libnet/net_util_md.c	Thu Apr 25 18:41:52 2019 -0400
+++ b/src/java.base/unix/native/libnet/net_util_md.c	Tue Apr 16 13:16:49 2019 -0700
@@ -278,6 +278,16 @@
     return (*env)->GetFieldID(env, cls, "fd", "I");
 }
 
+jint  IPv4_supported()
+{
+    int fd = socket(AF_INET, SOCK_STREAM, 0) ;
+    if (fd < 0) {
+        return JNI_FALSE;
+    }
+    close(fd);
+    return JNI_TRUE;
+}
+
 #if defined(DONT_ENABLE_IPV6)
 jint  IPv6_supported()
 {
--- a/src/java.base/unix/native/libnio/ch/Net.c	Thu Apr 25 18:41:52 2019 -0400
+++ b/src/java.base/unix/native/libnio/ch/Net.c	Tue Apr 16 13:16:49 2019 -0700
@@ -216,8 +216,10 @@
         return handleSocketError(env, errno);
     }
 
-    /* Disable IPV6_V6ONLY to ensure dual-socket support */
-    if (domain == AF_INET6) {
+    /*
+     * If IPv4 is available, disable IPV6_V6ONLY to ensure dual-socket support.
+     */
+    if (domain == AF_INET6 && ipv4_available()) {
         int arg = 0;
         if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
                        sizeof(int)) < 0) {
--- a/src/java.base/windows/native/libnet/net_util_md.c	Thu Apr 25 18:41:52 2019 -0400
+++ b/src/java.base/windows/native/libnet/net_util_md.c	Tue Apr 16 13:16:49 2019 -0700
@@ -214,6 +214,12 @@
     return (*env)->GetFieldID(env, cls, "fd", "I");
 }
 
+jint  IPv4_supported()
+{
+    /* TODO: properly check for IPv4 support on Windows */
+    return JNI_TRUE;
+}
+
 jint  IPv6_supported()
 {
     SOCKET s = socket(AF_INET6, SOCK_STREAM, 0) ;