6882910: Unexplained lack of IP4 network ability when transparent IP6 to IP4 is disabled.
Reviewed-by: alanb
--- a/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Tue Aug 10 10:07:33 2010 -0400
+++ b/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Tue Aug 10 17:30:43 2010 +0100
@@ -1052,30 +1052,38 @@
Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
jobject this) {
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- int fd;
-
- int t = 1;
+ int fd, t = 1;
+#ifdef AF_INET6
+ int domain = ipv6_available() ? AF_INET6 : AF_INET;
+#else
+ int domain = AF_INET;
+#endif
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return;
- } else {
-#ifdef AF_INET6
- if (ipv6_available()) {
- fd = JVM_Socket(AF_INET6, SOCK_DGRAM, 0);
- } else
-#endif /* AF_INET6 */
- {
- fd = JVM_Socket(AF_INET, SOCK_DGRAM, 0);
- }
}
- if (fd == JVM_IO_ERR) {
+
+ if ((fd = JVM_Socket(domain, SOCK_DGRAM, 0)) == JVM_IO_ERR) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"Error creating socket");
return;
}
+#ifdef AF_INET6
+ /* Disable IPV6_V6ONLY to ensure dual-socket support */
+ if (domain == AF_INET6) {
+ int arg = 0;
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
+ sizeof(int)) < 0) {
+ NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
+ close(fd);
+ return;
+ }
+ }
+#endif /* AF_INET6 */
+
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int));
#ifdef __linux__
@@ -1088,7 +1096,7 @@
* On Linux for IPv6 sockets we must set the hop limit
* to 1 to be compatible with default ttl of 1 for IPv4 sockets.
*/
- if (ipv6_available()) {
+ if (domain == AF_INET6) {
int ttl = 1;
setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl,
sizeof(ttl));
--- a/jdk/src/solaris/native/java/net/PlainSocketImpl.c Tue Aug 10 10:07:33 2010 -0400
+++ b/jdk/src/solaris/native/java/net/PlainSocketImpl.c Tue Aug 10 17:30:43 2010 +0100
@@ -181,6 +181,12 @@
jboolean stream) {
jobject fdObj, ssObj;
int fd;
+ int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
+#ifdef AF_INET6
+ int domain = ipv6_available() ? AF_INET6 : AF_INET;
+#else
+ int domain = AF_INET;
+#endif
if (socketExceptionCls == NULL) {
jclass c = (*env)->FindClass(env, "java/net/SocketException");
@@ -194,25 +200,29 @@
(*env)->ThrowNew(env, socketExceptionCls, "null fd object");
return;
}
-#ifdef AF_INET6
- if (ipv6_available()) {
- fd = JVM_Socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
- } else
-#endif /* AF_INET6 */
- {
- fd = JVM_Socket(AF_INET, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
- }
- if (fd == JVM_IO_ERR) {
+
+ if ((fd = JVM_Socket(domain, type, 0)) == JVM_IO_ERR) {
/* note: if you run out of fds, you may not be able to load
* the exception class, and get a NoClassDefFoundError
* instead.
*/
NET_ThrowNew(env, errno, "can't create socket");
return;
- } else {
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
}
+#ifdef AF_INET6
+ /* Disable IPV6_V6ONLY to ensure dual-socket support */
+ if (domain == AF_INET6) {
+ int arg = 0;
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
+ sizeof(int)) < 0) {
+ NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
+ close(fd);
+ return;
+ }
+ }
+#endif /* AF_INET6 */
+
/*
* If this is a server socket then enable SO_REUSEADDR
* automatically and set to non blocking.
@@ -221,9 +231,15 @@
if (ssObj != NULL) {
int arg = 1;
SET_NONBLOCKING(fd);
- JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
- sizeof(arg));
+ if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
+ sizeof(arg)) < 0) {
+ NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR");
+ close(fd);
+ return;
+ }
}
+
+ (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
}
/*
--- a/jdk/src/solaris/native/sun/nio/ch/Net.c Tue Aug 10 10:07:33 2010 -0400
+++ b/jdk/src/solaris/native/sun/nio/ch/Net.c Tue Aug 10 17:30:43 2010 +0100
@@ -170,6 +170,22 @@
if (fd < 0) {
return handleSocketError(env, errno);
}
+
+#ifdef AF_INET6
+ /* Disable IPV6_V6ONLY to ensure dual-socket support */
+ if (domain == AF_INET6) {
+ int arg = 0;
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
+ sizeof(int)) < 0) {
+ JNU_ThrowByNameWithLastError(env,
+ JNU_JAVANETPKG "SocketException",
+ "sun.nio.ch.Net.setIntOption");
+ close(fd);
+ return -1;
+ }
+ }
+#endif
+
if (reuse) {
int arg = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,