提交 eb4fda9f 编写于 作者: C coffeys

7123896: Unexpected behavior due to Solaris using separate IPv4 and IPv6 port spaces

Reviewed-by: alanb
上级 2f5770a7
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -68,6 +68,8 @@ JNI_OnLoad(JavaVM *vm, void *reserved) ...@@ -68,6 +68,8 @@ JNI_OnLoad(JavaVM *vm, void *reserved)
*/ */
IPv6_available = IPv6_supported() & (!preferIPv4Stack); IPv6_available = IPv6_supported() & (!preferIPv4Stack);
initLocalAddrTable (); initLocalAddrTable ();
parseExclusiveBindProperty(env);
return JNI_VERSION_1_2; return JNI_VERSION_1_2;
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -120,6 +120,7 @@ JNIEXPORT jobject JNICALL ...@@ -120,6 +120,7 @@ JNIEXPORT jobject JNICALL
NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port); NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port);
void initLocalAddrTable (); void initLocalAddrTable ();
void parseExclusiveBindProperty(JNIEnv *env);
void void
NET_SetTrafficClass(struct sockaddr *him, int trafficClass); NET_SetTrafficClass(struct sockaddr *him, int trafficClass);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -76,7 +76,7 @@ gai_strerror_f gai_strerror_ptr = NULL; ...@@ -76,7 +76,7 @@ gai_strerror_f gai_strerror_ptr = NULL;
getnameinfo_f getnameinfo_ptr = NULL; 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) #if defined(__solaris__) && !defined(TCP_EXCLBIND)
#define TCP_EXCLBIND 0x21 #define TCP_EXCLBIND 0x21
...@@ -113,6 +113,7 @@ void setDefaultScopeID(JNIEnv *env, struct sockaddr *him) ...@@ -113,6 +113,7 @@ void setDefaultScopeID(JNIEnv *env, struct sockaddr *him)
static int init_tcp_max_buf, init_udp_max_buf; static int init_tcp_max_buf, init_udp_max_buf;
static int tcp_max_buf; static int tcp_max_buf;
static int udp_max_buf; static int udp_max_buf;
static int useExclBind = 0;
/* /*
* Get the specified parameter from the specified driver. The value * Get the specified parameter from the specified driver. The value
...@@ -747,6 +748,26 @@ void initLocalAddrTable () {} ...@@ -747,6 +748,26 @@ void initLocalAddrTable () {}
#endif #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 /* In the case of an IPv4 Inetaddress this method will return an
* IPv4 mapped address where IPv6 is available and v4MappedAddress is TRUE. * IPv4 mapped address where IPv6 is available and v4MappedAddress is TRUE.
* Otherwise it will return a sockaddr_in structure for an IPv4 InetAddress. * Otherwise it will return a sockaddr_in structure for an IPv4 InetAddress.
...@@ -1450,8 +1471,8 @@ NET_SetSockOpt(int fd, int level, int opt, const void *arg, ...@@ -1450,8 +1471,8 @@ NET_SetSockOpt(int fd, int level, int opt, const void *arg,
* Linux allows a socket to bind to 127.0.0.255 which must be * Linux allows a socket to bind to 127.0.0.255 which must be
* caught. * 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 * bind to guarantee a unique port number across the IPv4 and
* IPv6 port spaces. * IPv6 port spaces.
* *
*/ */
...@@ -1481,10 +1502,10 @@ NET_Bind(int fd, struct sockaddr *him, int len) ...@@ -1481,10 +1502,10 @@ NET_Bind(int fd, struct sockaddr *him, int len)
#if defined(__solaris__) && defined(AF_INET6) #if defined(__solaris__) && defined(AF_INET6)
/* /*
* Solaris 8/9 have seperate IPv4 and IPv6 port spaces so we * Solaris has separate IPv4 and IPv6 port spaces so we
* use an exclusive bind when SO_REUSEADDR is not used to * use an exclusive bind when SO_REUSEADDR is not used to
* give the illusion of a unified port space. * 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 * to IPv4 mapped addresses whereby the socket conversion
* results in a late bind that fails because the * results in a late bind that fails because the
* corresponding IPv4 port is in use. * corresponding IPv4 port is in use.
...@@ -1493,11 +1514,12 @@ NET_Bind(int fd, struct sockaddr *him, int len) ...@@ -1493,11 +1514,12 @@ NET_Bind(int fd, struct sockaddr *him, int len)
int arg, len; int arg, len;
len = sizeof(arg); len = sizeof(arg);
if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&arg, if (useExclBind || getsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
&len) == 0) { (char *)&arg, &len) == 0) {
if (arg == 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 * UDP_EXCLBIND
*/ */
len = sizeof(arg); len = sizeof(arg);
......
...@@ -126,6 +126,7 @@ DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) ...@@ -126,6 +126,7 @@ DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
} }
void initLocalAddrTable () {} void initLocalAddrTable () {}
void parseExclusiveBindProperty (JNIEnv *env) {}
/* /*
* Since winsock doesn't have the equivalent of strerror(errno) * Since winsock doesn't have the equivalent of strerror(errno)
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
* @bug 4476378 * @bug 4476378
* @summary Check the specific behaviour of the setReuseAddress(boolean) * @summary Check the specific behaviour of the setReuseAddress(boolean)
* method. * method.
* @run main Basic
* @run main/othervm -Dsun.net.useExclusiveBind Basic
*/ */
import java.net.*; import java.net.*;
...@@ -170,7 +172,12 @@ public class Basic { ...@@ -170,7 +172,12 @@ public class Basic {
s2.bind( new InetSocketAddress(s1.getLocalPort()) ); s2.bind( new InetSocketAddress(s1.getLocalPort()) );
passed(); passed();
} catch (BindException e) { } catch (BindException e) {
failed(); if (System.getProperty("sun.net.useExclusiveBind") != null) {
// exclusive bind enabled - expected result
passed();
} else {
failed();
}
} }
s2.close(); s2.close();
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
* @bug 4476378 * @bug 4476378
* @summary Check that SO_REUSEADDR allows a server to restart * @summary Check that SO_REUSEADDR allows a server to restart
* after a crash. * after a crash.
* @run main Restart
* @run main/othervm -Dsun.net.useExclusiveBind Restart
*/ */
import java.net.*; import java.net.*;
...@@ -57,6 +59,12 @@ public class Restart { ...@@ -57,6 +59,12 @@ public class Restart {
// close the client socket // close the client socket
s1.close(); s1.close();
} catch (BindException be) {
if (System.getProperty("sun.net.useExclusiveBind") != null) {
// exclusive bind, expected exception
} else {
throw be;
}
} finally { } finally {
if (ss != null) ss.close(); if (ss != null) ss.close();
if (s1 != null) s1.close(); if (s1 != null) s1.close();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册