8313804: JDWP support for -Djava.net.preferIPv6Addresses=system
Reviewed-by: cjplummer, amenkov
This commit is contained in:
parent
afa48333ab
commit
9291b46bcf
@ -727,11 +727,13 @@ socketTransport_startListening(jdwpTransportEnv* env, const char* address,
|
||||
return err;
|
||||
}
|
||||
|
||||
// Try to find bind address of preferred address family first.
|
||||
for (ai = addrInfo; ai != NULL; ai = ai->ai_next) {
|
||||
if (ai->ai_family == preferredAddressFamily) {
|
||||
listenAddr = ai;
|
||||
break;
|
||||
// Try to find bind address of preferred address family first (if java.net.preferIPv6Addresses != "system").
|
||||
if (preferredAddressFamily != AF_UNSPEC) {
|
||||
for (ai = addrInfo; ai != NULL; ai = ai->ai_next) {
|
||||
if (ai->ai_family == preferredAddressFamily) {
|
||||
listenAddr = ai;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -743,9 +745,9 @@ socketTransport_startListening(jdwpTransportEnv* env, const char* address,
|
||||
// Binding to IN6ADDR_ANY allows to serve both IPv4 and IPv6 connections,
|
||||
// but binding to mapped INADDR_ANY (::ffff:0.0.0.0) allows to serve IPv4
|
||||
// connections only. Make sure that IN6ADDR_ANY is preferred over
|
||||
// mapped INADDR_ANY if preferredAddressFamily is AF_INET6 or not set.
|
||||
// mapped INADDR_ANY if preferIPv4Stack is false.
|
||||
|
||||
if (preferredAddressFamily != AF_INET) {
|
||||
if (!allowOnlyIPv4) {
|
||||
inet_pton(AF_INET6, "::ffff:0.0.0.0", &mappedAny);
|
||||
|
||||
if (isEqualIPv6Addr(listenAddr, mappedAny)) {
|
||||
@ -967,8 +969,10 @@ socketTransport_attach(jdwpTransportEnv* env, const char* addressString, jlong a
|
||||
return err;
|
||||
}
|
||||
|
||||
/* 1st pass - preferredAddressFamily (by default IPv4), 2nd pass - the rest */
|
||||
for (pass = 0; pass < 2 && socketFD < 0; pass++) {
|
||||
// 1st pass - preferredAddressFamily (by default IPv4), 2nd pass - the rest;
|
||||
// if java.net.preferIPv6Addresses == "system", only 2nd pass is needed
|
||||
pass = preferredAddressFamily != AF_UNSPEC ? 0 : 1;
|
||||
for (; pass < 2 && socketFD < 0; pass++) {
|
||||
for (ai = addrInfo; ai != NULL; ai = ai->ai_next) {
|
||||
if ((pass == 0 && ai->ai_family == preferredAddressFamily) ||
|
||||
(pass == 1 && ai->ai_family != preferredAddressFamily))
|
||||
@ -1305,6 +1309,43 @@ static int readBooleanSysProp(int *result, int trueValue, int falseValue,
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads java.net.preferIPv6Addresses system value, sets preferredAddressFamily to
|
||||
* - AF_INET6 if the property is "true";
|
||||
* - AF_INET if the property is "false".
|
||||
* - AF_UNSPEC if the property is "system".
|
||||
* Doesn't change preferredAddressFamily if the property is not set or failed to read.
|
||||
*/
|
||||
static int readPreferIPv6Addresses(JNIEnv* jniEnv,
|
||||
jclass sysClass, jmethodID getPropMethod, const char *propName)
|
||||
{
|
||||
jstring value;
|
||||
jstring name = (*jniEnv)->NewStringUTF(jniEnv, propName);
|
||||
|
||||
if (name == NULL) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
value = (jstring)(*jniEnv)->CallStaticObjectMethod(jniEnv, sysClass, getPropMethod, name);
|
||||
if ((*jniEnv)->ExceptionCheck(jniEnv)) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
if (value != NULL) {
|
||||
const char *theValue = (*jniEnv)->GetStringUTFChars(jniEnv, value, NULL);
|
||||
if (theValue == NULL) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
if (strcmp(theValue, "true") == 0) {
|
||||
preferredAddressFamily = AF_INET6;
|
||||
} else if (strcmp(theValue, "false") == 0) {
|
||||
preferredAddressFamily = AF_INET;
|
||||
} else if (strcmp(theValue, "system") == 0) {
|
||||
preferredAddressFamily = AF_UNSPEC;
|
||||
}
|
||||
(*jniEnv)->ReleaseStringUTFChars(jniEnv, value, theValue);
|
||||
}
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
jdwpTransport_OnLoad(JavaVM *vm, jdwpTransportCallback* cbTablePtr,
|
||||
jint version, jdwpTransportEnv** env)
|
||||
@ -1362,7 +1403,7 @@ jdwpTransport_OnLoad(JavaVM *vm, jdwpTransportCallback* cbTablePtr,
|
||||
}
|
||||
readBooleanSysProp(&allowOnlyIPv4, 1, 0,
|
||||
jniEnv, sysClass, getPropMethod, "java.net.preferIPv4Stack");
|
||||
readBooleanSysProp(&preferredAddressFamily, AF_INET6, AF_INET,
|
||||
readPreferIPv6Addresses(
|
||||
jniEnv, sysClass, getPropMethod, "java.net.preferIPv6Addresses");
|
||||
} while (0);
|
||||
|
||||
|
@ -36,15 +36,16 @@ import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8184770
|
||||
* @bug 8184770 8313804
|
||||
* @summary Tests that JDWP agent honors jdk net properties
|
||||
* @library /test/lib
|
||||
*
|
||||
* @build HelloWorld JdwpNetProps
|
||||
* @run main/othervm JdwpNetProps
|
||||
* @run main/othervm -Djava.net.preferIPv6Addresses=system JdwpNetProps
|
||||
*/
|
||||
public class JdwpNetProps {
|
||||
|
||||
@ -60,33 +61,88 @@ public class JdwpNetProps {
|
||||
}
|
||||
}
|
||||
|
||||
String preferIPv6Address = System.getProperty("java.net.preferIPv6Addresses");
|
||||
if (!Objects.equals(preferIPv6Address, "system")) {
|
||||
throw new AssertionError(
|
||||
"Expected -Djava.net.preferIPv6Address=system, was " + preferIPv6Address);
|
||||
}
|
||||
boolean systemPrefersIPv6 = addrs[0] instanceof Inet6Address;
|
||||
|
||||
if (ipv4Address != null) {
|
||||
new ListenTest("localhost", ipv4Address)
|
||||
.preferIPv4Stack(true)
|
||||
.run(TestResult.Success);
|
||||
new ListenTest("localhost", ipv4Address)
|
||||
.preferIPv4Stack(true)
|
||||
.preferIPv6Addresses("true")
|
||||
.run(TestResult.Success);
|
||||
new ListenTest("localhost", ipv4Address)
|
||||
.preferIPv4Stack(true)
|
||||
.preferIPv6Addresses("system")
|
||||
.run(TestResult.Success);
|
||||
new ListenTest("localhost", ipv4Address)
|
||||
.preferIPv4Stack(false)
|
||||
.run(TestResult.Success);
|
||||
if (ipv6Address != null) {
|
||||
// - only IPv4, so connection prom IPv6 should fail
|
||||
// - only IPv4, so connection from IPv6 should fail
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.preferIPv4Stack(true)
|
||||
.preferIPv6Addresses(true)
|
||||
.preferIPv6Addresses("true")
|
||||
.run(TestResult.AttachFailed);
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.preferIPv4Stack(true)
|
||||
.preferIPv6Addresses("system")
|
||||
.run(TestResult.AttachFailed);
|
||||
// - listen on IPv4
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.preferIPv6Addresses(false)
|
||||
.preferIPv6Addresses("false")
|
||||
.run(TestResult.AttachFailed);
|
||||
// - listen on IPv4 (preferIPv6Addresses defaults to false)
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.run(TestResult.AttachFailed);
|
||||
// - listen on IPv6
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.preferIPv6Addresses(true)
|
||||
.preferIPv6Addresses("true")
|
||||
.run(TestResult.Success);
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.preferIPv6Addresses("system")
|
||||
.run(systemPrefersIPv6 ? TestResult.Success : TestResult.AttachFailed);
|
||||
// - listen on IPv6, connect from IPv4
|
||||
new ListenTest("localhost", ipv4Address)
|
||||
.preferIPv4Stack(false)
|
||||
.preferIPv6Addresses("true")
|
||||
.run(TestResult.AttachFailed);
|
||||
// - listen on system preference, connect from IPv4
|
||||
new ListenTest("localhost", ipv4Address)
|
||||
.preferIPv4Stack(false)
|
||||
.preferIPv6Addresses("system")
|
||||
.run(systemPrefersIPv6 ? TestResult.AttachFailed : TestResult.Success);
|
||||
}
|
||||
} else {
|
||||
if (!systemPrefersIPv6) {
|
||||
throw new AssertionError("The system is IPv6-only, but systemPrefersIPv6 was unexpectedly false");
|
||||
}
|
||||
|
||||
// IPv6-only system - expected to fail on IPv4 address
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.preferIPv4Stack(true)
|
||||
.run(TestResult.ListenFailed);
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.preferIPv4Stack(true)
|
||||
.preferIPv6Addresses("system")
|
||||
.run(TestResult.ListenFailed);
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.preferIPv4Stack(true)
|
||||
.preferIPv6Addresses("true")
|
||||
.run(TestResult.ListenFailed);
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.run(TestResult.Success);
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.preferIPv6Addresses("system")
|
||||
.run(TestResult.Success);
|
||||
new ListenTest("localhost", ipv6Address)
|
||||
.preferIPv6Addresses("true")
|
||||
.run(TestResult.Success);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +156,7 @@ public class JdwpNetProps {
|
||||
private final String listenAddress;
|
||||
private final InetAddress connectAddress;
|
||||
private Boolean preferIPv4Stack;
|
||||
private Boolean preferIPv6Addresses;
|
||||
private String preferIPv6Addresses;
|
||||
public ListenTest(String listenAddress, InetAddress connectAddress) {
|
||||
this.listenAddress = listenAddress;
|
||||
this.connectAddress = connectAddress;
|
||||
@ -109,7 +165,7 @@ public class JdwpNetProps {
|
||||
preferIPv4Stack = value;
|
||||
return this;
|
||||
}
|
||||
public ListenTest preferIPv6Addresses(Boolean value) {
|
||||
public ListenTest preferIPv6Addresses(String value) {
|
||||
preferIPv6Addresses = value;
|
||||
return this;
|
||||
}
|
||||
@ -120,7 +176,7 @@ public class JdwpNetProps {
|
||||
options.add("-Djava.net.preferIPv4Stack=" + preferIPv4Stack.toString());
|
||||
}
|
||||
if (preferIPv6Addresses != null) {
|
||||
options.add("-Djava.net.preferIPv6Addresses=" + preferIPv6Addresses.toString());
|
||||
options.add("-Djava.net.preferIPv6Addresses=" + preferIPv6Addresses);
|
||||
}
|
||||
log("Starting listening debuggee at " + listenAddress
|
||||
+ (expectedResult == TestResult.ListenFailed ? ": expected to fail" : ""));
|
||||
@ -201,4 +257,5 @@ public class JdwpNetProps {
|
||||
System.out.println(String.valueOf(o));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user