提交 4ad2063f 编写于 作者: A alanb

8060170: Support SIO_LOOPBACK_FAST_PATH option on Windows

Reviewed-by: alanb
Contributed-by: kirk.shoop@microsoft.com, v-valkop@microsoft.com
上级 384923db
...@@ -110,6 +110,8 @@ SUNWprivate_1.1 { ...@@ -110,6 +110,8 @@ SUNWprivate_1.1 {
NET_Bind; NET_Bind;
NET_MapSocketOption; NET_MapSocketOption;
NET_Wait; NET_Wait;
NET_EnableFastTcpLoopback;
NET_ThrowNew;
ipv6_available; ipv6_available;
local: local:
......
...@@ -50,30 +50,8 @@ public class Net { ...@@ -50,30 +50,8 @@ public class Net {
// set to true if exclusive binding is on for Windows // set to true if exclusive binding is on for Windows
private static final boolean exclusiveBind; private static final boolean exclusiveBind;
static { // set to true if the fast tcp loopback should be enabled on Windows
int availLevel = isExclusiveBindAvailable(); private static final boolean fastLoopback;
if (availLevel >= 0) {
String exclBindProp =
java.security.AccessController.doPrivileged(
new PrivilegedAction<String>() {
@Override
public String run() {
return System.getProperty(
"sun.net.useExclusiveBind");
}
});
if (exclBindProp != null) {
exclusiveBind = exclBindProp.length() == 0 ?
true : Boolean.parseBoolean(exclBindProp);
} else if (availLevel == 1) {
exclusiveBind = true;
} else {
exclusiveBind = false;
}
} else {
exclusiveBind = false;
}
}
// -- Miscellaneous utilities -- // -- Miscellaneous utilities --
...@@ -391,6 +369,23 @@ public class Net { ...@@ -391,6 +369,23 @@ public class Net {
} }
} }
public static boolean isFastTcpLoopbackRequested() {
String loopbackProp = java.security.AccessController.doPrivileged(
new PrivilegedAction<String>() {
@Override
public String run() {
return System.getProperty("jdk.net.useFastTcpLoopback");
}
});
boolean enable;
if ("".equals(loopbackProp)) {
enable = true;
} else {
enable = Boolean.parseBoolean(loopbackProp);
}
return enable;
}
// -- Socket operations -- // -- Socket operations --
private static native boolean isIPv6Available0(); private static native boolean isIPv6Available0();
...@@ -413,15 +408,16 @@ public class Net { ...@@ -413,15 +408,16 @@ public class Net {
throws IOException { throws IOException {
boolean preferIPv6 = isIPv6Available() && boolean preferIPv6 = isIPv6Available() &&
(family != StandardProtocolFamily.INET); (family != StandardProtocolFamily.INET);
return IOUtil.newFD(socket0(preferIPv6, stream, false)); return IOUtil.newFD(socket0(preferIPv6, stream, false, fastLoopback));
} }
static FileDescriptor serverSocket(boolean stream) { static FileDescriptor serverSocket(boolean stream) {
return IOUtil.newFD(socket0(isIPv6Available(), stream, true)); return IOUtil.newFD(socket0(isIPv6Available(), stream, true, fastLoopback));
} }
// Due to oddities SO_REUSEADDR on windows reuse is ignored // Due to oddities SO_REUSEADDR on windows reuse is ignored
private static native int socket0(boolean preferIPv6, boolean stream, boolean reuse); private static native int socket0(boolean preferIPv6, boolean stream, boolean reuse,
boolean fastLoopback);
public static void bind(FileDescriptor fd, InetAddress addr, int port) public static void bind(FileDescriptor fd, InetAddress addr, int port)
throws IOException throws IOException
...@@ -634,4 +630,30 @@ public class Net { ...@@ -634,4 +630,30 @@ public class Net {
POLLCONN = pollconnValue(); POLLCONN = pollconnValue();
} }
static {
int availLevel = isExclusiveBindAvailable();
if (availLevel >= 0) {
String exclBindProp =
java.security.AccessController.doPrivileged(
new PrivilegedAction<String>() {
@Override
public String run() {
return System.getProperty(
"sun.net.useExclusiveBind");
}
});
if (exclBindProp != null) {
exclusiveBind = exclBindProp.length() == 0 ?
true : Boolean.parseBoolean(exclBindProp);
} else if (availLevel == 1) {
exclusiveBind = true;
} else {
exclusiveBind = false;
}
} else {
exclusiveBind = false;
}
fastLoopback = isFastTcpLoopbackRequested();
}
} }
...@@ -182,9 +182,13 @@ NET_MapSocketOption(jint cmd, int *level, int *optname); ...@@ -182,9 +182,13 @@ NET_MapSocketOption(jint cmd, int *level, int *optname);
JNIEXPORT int JNICALL JNIEXPORT int JNICALL
NET_MapSocketOptionV6(jint cmd, int *level, int *optname); NET_MapSocketOptionV6(jint cmd, int *level, int *optname);
JNIEXPORT jint JNICALL
NET_EnableFastTcpLoopback(int fd);
int getScopeID (struct sockaddr *); int getScopeID (struct sockaddr *);
int cmpScopeID (unsigned int, struct sockaddr *); int cmpScopeID (unsigned int, struct sockaddr *);
unsigned short in_cksum(unsigned short *addr, int len); unsigned short in_cksum(unsigned short *addr, int len);
#endif /* NET_UTILS_H */ #endif /* NET_UTILS_H */
...@@ -777,6 +777,11 @@ void parseExclusiveBindProperty(JNIEnv *env) { ...@@ -777,6 +777,11 @@ void parseExclusiveBindProperty(JNIEnv *env) {
#endif #endif
} }
JNIEXPORT jint JNICALL
NET_EnableFastTcpLoopback(int fd) {
return 0;
}
/* 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.
......
...@@ -231,7 +231,7 @@ Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl) ...@@ -231,7 +231,7 @@ Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
JNIEXPORT int JNICALL JNIEXPORT int JNICALL
Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6, Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
jboolean stream, jboolean reuse) jboolean stream, jboolean reuse, jboolean ignored)
{ {
int fd; int fd;
int type = (stream ? SOCK_STREAM : SOCK_DGRAM); int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
......
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
#include "net_util.h" #include "net_util.h"
#include "jni.h" #include "jni.h"
// Taken from mstcpip.h in Windows SDK 8.0 or newer.
#define SIO_LOOPBACK_FAST_PATH _WSAIOW(IOC_VENDOR,16)
#ifndef IPTOS_TOS_MASK #ifndef IPTOS_TOS_MASK
#define IPTOS_TOS_MASK 0x1e #define IPTOS_TOS_MASK 0x1e
#endif #endif
...@@ -844,6 +847,25 @@ jint getDefaultIPv6Interface(JNIEnv *env, struct SOCKADDR_IN6 *target_addr) ...@@ -844,6 +847,25 @@ jint getDefaultIPv6Interface(JNIEnv *env, struct SOCKADDR_IN6 *target_addr)
} }
} }
/**
* Enables SIO_LOOPBACK_FAST_PATH
*/
JNIEXPORT jint JNICALL
NET_EnableFastTcpLoopback(int fd) {
int enabled = 1;
DWORD result_byte_count = -1;
int result = WSAIoctl(fd,
SIO_LOOPBACK_FAST_PATH,
&enabled,
sizeof(enabled),
NULL,
0,
&result_byte_count,
NULL,
NULL);
return result == SOCKET_ERROR ? WSAGetLastError() : 0;
}
/* If address types is IPv6, then IPv6 must be available. Otherwise /* If address types is IPv6, then IPv6 must be available. Otherwise
* no address can be generated. In the case of an IPv4 Inetaddress this * no address can be generated. In the case of an IPv4 Inetaddress this
* method will return an IPv4 mapped address where IPv6 is available and * method will return an IPv4 mapped address where IPv6 is available and
......
...@@ -127,7 +127,7 @@ Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl) ...@@ -127,7 +127,7 @@ Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6, Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
jboolean stream, jboolean reuse) jboolean stream, jboolean reuse, jboolean fastLoopback)
{ {
SOCKET s; SOCKET s;
int domain = (preferIPv6) ? AF_INET6 : AF_INET; int domain = (preferIPv6) ? AF_INET6 : AF_INET;
...@@ -152,6 +152,20 @@ Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6, ...@@ -152,6 +152,20 @@ Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
NET_ThrowNew(env, WSAGetLastError(), "socket"); NET_ThrowNew(env, WSAGetLastError(), "socket");
} }
if (stream && fastLoopback) {
static int loopback_available = 1;
if (loopback_available) {
int rv = NET_EnableFastTcpLoopback((jint)s);
if (rv) {
if (rv == WSAEOPNOTSUPP) {
loopback_available = 0;
} else {
NET_ThrowNew(env, rv, "fastLoopback");
}
}
}
}
return (jint)s; return (jint)s;
} }
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
/* @test /* @test
* @bug 6834246 6842687 * @bug 6834246 6842687
* @summary Stress test connections through the loopback interface * @summary Stress test connections through the loopback interface
* @run main StressLoopback
* @run main/othervm -Djdk.net.useFastTcpLoopback StressLoopback
*/ */
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册