Mercurial > hg > release > icedtea7-forest-2.3 > jdk
changeset 5382:538f6eff4041
7123896: Unexpected behavior due to Solaris using separate IPv4 and IPv6 port spaces
Reviewed-by: alanb
author | coffeys |
---|---|
date | Fri, 04 May 2012 11:40:35 +0100 |
parents | ea7a324102bf |
children | ba975a730f4b |
files | src/share/native/java/net/net_util.c src/share/native/java/net/net_util.h src/solaris/native/java/net/net_util_md.c src/windows/native/java/net/net_util_md.c test/java/net/Socket/setReuseAddress/Basic.java test/java/net/Socket/setReuseAddress/Restart.java |
diffstat | 6 files changed, 53 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/native/java/net/net_util.c Mon Apr 23 13:23:28 2012 -0700 +++ b/src/share/native/java/net/net_util.c Fri May 04 11:40:35 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,6 +68,8 @@ */ IPv6_available = IPv6_supported() & (!preferIPv4Stack); initLocalAddrTable (); + parseExclusiveBindProperty(env); + return JNI_VERSION_1_2; }
--- a/src/share/native/java/net/net_util.h Mon Apr 23 13:23:28 2012 -0700 +++ b/src/share/native/java/net/net_util.h Fri May 04 11:40:35 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,7 +108,7 @@ jfieldID NET_GetFileDescriptorID(JNIEnv *env); -JNIEXPORT jint JNICALL ipv6_available() ; +JNIEXPORT jint JNICALL ipv6_available(); void NET_AllocSockaddr(struct sockaddr **him, int *len); @@ -120,6 +120,7 @@ NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port); void initLocalAddrTable (); +void parseExclusiveBindProperty(JNIEnv *env); void NET_SetTrafficClass(struct sockaddr *him, int trafficClass);
--- a/src/solaris/native/java/net/net_util_md.c Mon Apr 23 13:23:28 2012 -0700 +++ b/src/solaris/native/java/net/net_util_md.c Fri May 04 11:40:35 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ getnameinfo_f getnameinfo_ptr = NULL; /* - * EXCLBIND socket options only on Solaris 8 & 9. + * EXCLBIND socket options only on Solaris */ #if defined(__solaris__) && !defined(TCP_EXCLBIND) #define TCP_EXCLBIND 0x21 @@ -131,6 +131,7 @@ static int init_tcp_max_buf, init_udp_max_buf; static int tcp_max_buf; static int udp_max_buf; +static int useExclBind = 0; /* * Get the specified parameter from the specified driver. The value @@ -790,6 +791,25 @@ #endif +void parseExclusiveBindProperty(JNIEnv *env) { +#ifdef __solaris__ + jstring s, flagSet; + jclass iCls; + jmethodID mid; + + s = (*env)->NewStringUTF(env, "sun.net.useExclusiveBind"); + CHECK_NULL(s); + iCls = (*env)->FindClass(env, "java/lang/System"); + CHECK_NULL(iCls); + mid = (*env)->GetStaticMethodID(env, iCls, "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;"); + CHECK_NULL(mid); + flagSet = (*env)->CallStaticObjectMethod(env, iCls, mid, s); + if (flagSet != NULL) { + useExclBind = 1; + } +#endif +} /* In the case of an IPv4 Inetaddress this method will return an * IPv4 mapped address where IPv6 is available and v4MappedAddress is TRUE. * Otherwise it will return a sockaddr_in structure for an IPv4 InetAddress. @@ -1497,7 +1517,7 @@ * Linux allows a socket to bind to 127.0.0.255 which must be * caught. * - * On Solaris 8/9 with IPv6 enabled we must use an exclusive + * On Solaris with IPv6 enabled we must use an exclusive * bind to guaranteed a unique port number across the IPv4 and * IPv6 port spaces. * @@ -1528,10 +1548,10 @@ #if defined(__solaris__) && defined(AF_INET6) /* - * Solaris 8/9 have seperate IPv4 and IPv6 port spaces so we + * Solaris has seperate IPv4 and IPv6 port spaces so we * use an exclusive bind when SO_REUSEADDR is not used to * give the illusion of a unified port space. - * This also avoid problems with IPv6 sockets connecting + * This also avoids problems with IPv6 sockets connecting * to IPv4 mapped addresses whereby the socket conversion * results in a late bind that fails because the * corresponding IPv4 port is in use. @@ -1540,11 +1560,12 @@ int arg, len; len = sizeof(arg); - if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&arg, - &len) == 0) { - if (arg == 0) { + if (useExclBind || getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, + (char *)&arg, &len) == 0) { + if (useExclBind || arg == 0) { /* - * SO_REUSEADDR is disabled so enable TCP_EXCLBIND or + * SO_REUSEADDR is disabled or sun.net.useExclusiveBind + * property is true so enable TCP_EXCLBIND or * UDP_EXCLBIND */ len = sizeof(arg);
--- a/src/windows/native/java/net/net_util_md.c Mon Apr 23 13:23:28 2012 -0700 +++ b/src/windows/native/java/net/net_util_md.c Fri May 04 11:40:35 2012 +0100 @@ -126,6 +126,7 @@ } void initLocalAddrTable () {} +void parseExclusiveBindProperty (JNIEnv *env) {} /* * Since winsock doesn't have the equivalent of strerror(errno)
--- a/test/java/net/Socket/setReuseAddress/Basic.java Mon Apr 23 13:23:28 2012 -0700 +++ b/test/java/net/Socket/setReuseAddress/Basic.java Fri May 04 11:40:35 2012 +0100 @@ -26,6 +26,8 @@ * @bug 4476378 * @summary Check the specific behaviour of the setReuseAddress(boolean) * method. + * @run main Basic + * @run main/othervm -Dsun.net.useExclusiveBind Basic */ import java.net.*; @@ -170,7 +172,12 @@ s2.bind( new InetSocketAddress(s1.getLocalPort()) ); passed(); } catch (BindException e) { - failed(); + if (System.getProperty("sun.net.useExclusiveBind") != null) { + // exclusive bind enabled - expected result + passed(); + } else { + failed(); + } } s2.close();
--- a/test/java/net/Socket/setReuseAddress/Restart.java Mon Apr 23 13:23:28 2012 -0700 +++ b/test/java/net/Socket/setReuseAddress/Restart.java Fri May 04 11:40:35 2012 +0100 @@ -26,6 +26,8 @@ * @bug 4476378 * @summary Check that SO_REUSEADDR allows a server to restart * after a crash. + * @run main Restart + * @run main/othervm -Dsun.net.useExclusiveBind Restart */ import java.net.*; @@ -57,6 +59,12 @@ // close the client socket s1.close(); + } catch (BindException be) { + if (System.getProperty("sun.net.useExclusiveBind") != null) { + // exclusive bind, expected exception + } else { + throw be; + } } finally { if (ss != null) ss.close(); if (s1 != null) s1.close();