8016521: InetAddress should not always re-order addresses returned from name service
Reviewed-by: chegar
This commit is contained in:
parent
27a77176a6
commit
af7a591d39
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2016, 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
|
||||
@ -23,7 +23,10 @@
|
||||
* questions.
|
||||
*/
|
||||
package java.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import static java.net.InetAddress.PREFER_IPV6_VALUE;
|
||||
import static java.net.InetAddress.PREFER_SYSTEM_VALUE;
|
||||
|
||||
/*
|
||||
* Package private implementation of InetAddressImpl for dual
|
||||
@ -35,15 +38,23 @@ import java.io.IOException;
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
class Inet6AddressImpl implements InetAddressImpl {
|
||||
public native String getLocalHostName() throws UnknownHostException;
|
||||
public native InetAddress[]
|
||||
lookupAllHostAddr(String hostname) throws UnknownHostException;
|
||||
public native String getHostByAddr(byte[] addr) throws UnknownHostException;
|
||||
private native boolean isReachable0(byte[] addr, int scope, int timeout, byte[] inf, int ttl, int if_scope) throws IOException;
|
||||
|
||||
public boolean isReachable(InetAddress addr, int timeout, NetworkInterface netif, int ttl) throws IOException {
|
||||
public native String getLocalHostName() throws UnknownHostException;
|
||||
|
||||
public native InetAddress[] lookupAllHostAddr(String hostname)
|
||||
throws UnknownHostException;
|
||||
|
||||
public native String getHostByAddr(byte[] addr) throws UnknownHostException;
|
||||
|
||||
private native boolean isReachable0(byte[] addr, int scope, int timeout,
|
||||
byte[] inf, int ttl, int if_scope)
|
||||
throws IOException;
|
||||
|
||||
public boolean isReachable(InetAddress addr, int timeout,
|
||||
NetworkInterface netif, int ttl)
|
||||
throws IOException
|
||||
{
|
||||
byte[] ifaddr = null;
|
||||
int scope = -1;
|
||||
int netif_scope = -1;
|
||||
@ -79,7 +90,8 @@ class Inet6AddressImpl implements InetAddressImpl {
|
||||
|
||||
public synchronized InetAddress anyLocalAddress() {
|
||||
if (anyLocalAddress == null) {
|
||||
if (InetAddress.preferIPv6Address) {
|
||||
if (InetAddress.preferIPv6Address == PREFER_IPV6_VALUE ||
|
||||
InetAddress.preferIPv6Address == PREFER_SYSTEM_VALUE) {
|
||||
anyLocalAddress = new Inet6Address();
|
||||
anyLocalAddress.holder().hostName = "::";
|
||||
} else {
|
||||
@ -91,7 +103,8 @@ class Inet6AddressImpl implements InetAddressImpl {
|
||||
|
||||
public synchronized InetAddress loopbackAddress() {
|
||||
if (loopbackAddress == null) {
|
||||
if (InetAddress.preferIPv6Address) {
|
||||
if (InetAddress.preferIPv6Address == PREFER_IPV6_VALUE ||
|
||||
InetAddress.preferIPv6Address == PREFER_SYSTEM_VALUE) {
|
||||
byte[] loopback =
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
|
||||
@ -103,6 +116,6 @@ class Inet6AddressImpl implements InetAddressImpl {
|
||||
return loopbackAddress;
|
||||
}
|
||||
|
||||
private InetAddress anyLocalAddress;
|
||||
private InetAddress loopbackAddress;
|
||||
private InetAddress anyLocalAddress;
|
||||
private InetAddress loopbackAddress;
|
||||
}
|
||||
|
@ -26,8 +26,6 @@
|
||||
package java.net;
|
||||
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.Scanner;
|
||||
@ -41,6 +39,7 @@ import java.io.ObjectInputStream;
|
||||
import java.io.ObjectInputStream.GetField;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectOutputStream.PutField;
|
||||
import java.lang.annotation.Native;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
@ -193,6 +192,11 @@ import sun.net.util.IPAddressUtil;
|
||||
*/
|
||||
public
|
||||
class InetAddress implements java.io.Serializable {
|
||||
|
||||
@Native static final int PREFER_IPV4_VALUE = 0;
|
||||
@Native static final int PREFER_IPV6_VALUE = 1;
|
||||
@Native static final int PREFER_SYSTEM_VALUE = 2;
|
||||
|
||||
/**
|
||||
* Specify the address family: Internet Protocol, Version 4
|
||||
* @since 1.4
|
||||
@ -206,8 +210,7 @@ class InetAddress implements java.io.Serializable {
|
||||
static final int IPv6 = 2;
|
||||
|
||||
/* Specify address family preference */
|
||||
static transient boolean preferIPv6Address = false;
|
||||
|
||||
static transient final int preferIPv6Address;
|
||||
|
||||
static class InetAddressHolder {
|
||||
/**
|
||||
@ -293,8 +296,19 @@ class InetAddress implements java.io.Serializable {
|
||||
* Load net library into runtime, and perform initializations.
|
||||
*/
|
||||
static {
|
||||
preferIPv6Address = java.security.AccessController.doPrivileged(
|
||||
new GetBooleanAction("java.net.preferIPv6Addresses")).booleanValue();
|
||||
String str = java.security.AccessController.doPrivileged(
|
||||
new GetPropertyAction("java.net.preferIPv6Addresses"));
|
||||
if (str == null) {
|
||||
preferIPv6Address = PREFER_IPV4_VALUE;
|
||||
} else if (str.equalsIgnoreCase("true")) {
|
||||
preferIPv6Address = PREFER_IPV6_VALUE;
|
||||
} else if (str.equalsIgnoreCase("false")) {
|
||||
preferIPv6Address = PREFER_IPV4_VALUE;
|
||||
} else if (str.equalsIgnoreCase("system")) {
|
||||
preferIPv6Address = PREFER_SYSTEM_VALUE;
|
||||
} else {
|
||||
preferIPv6Address = PREFER_IPV4_VALUE;
|
||||
}
|
||||
AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<>() {
|
||||
public Void run() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 1998, 2016, 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
|
||||
@ -35,7 +35,7 @@ alter the mechanisms and behavior of the various classes of the
|
||||
java.net package. Some are checked only once at startup of the VM,
|
||||
and therefore are best set using the -D option of the java command,
|
||||
while others have a more dynamic nature and can also be changed using
|
||||
the <a href="../../lang/System.html#setProperty(java.lang.String,%20java.lang.String)">System.setProperty()</a> API.
|
||||
the <a href="../../lang/System.html#setProperty(java.lang.String,%20java.lang.String)">System.setProperty()</a> API.
|
||||
The purpose of this document is to list
|
||||
and detail all of these properties.</P>
|
||||
<P>If there is no special note, a property value is checked every time it is used.</P>
|
||||
@ -58,7 +58,8 @@ and detail all of these properties.</P>
|
||||
applications that depend on the representation of an IPv4 address
|
||||
(e.g. 192.168.1.1). This property can be set to <B>true</B> to
|
||||
change that preference and use IPv6 addresses over IPv4 ones where
|
||||
possible.</P>
|
||||
possible, or <B>system</B> to preserve the order of the addresses as
|
||||
returned by the operating system.</P>
|
||||
</UL>
|
||||
<P>Both of these properties are checked only once, at startup.</P>
|
||||
<a name="Proxies"></a>
|
||||
@ -73,7 +74,7 @@ of proxies.</P>
|
||||
<P>The following proxy settings are used by the HTTP protocol handler.</P>
|
||||
<UL>
|
||||
<LI><P><B>http.proxyHost</B> (default: <none>)<BR>
|
||||
The hostname, or address, of the proxy server
|
||||
The hostname, or address, of the proxy server
|
||||
</P>
|
||||
<LI><P><B>http.proxyPort</B> (default: 80)<BR>
|
||||
The port number of the proxy server.</P>
|
||||
@ -94,7 +95,7 @@ of proxies.</P>
|
||||
<P>The following proxy settings are used by the HTTPS protocol handler.</P>
|
||||
<UL>
|
||||
<LI><P><B>https.proxyHost</B>(default: <none>)<BR>
|
||||
The hostname, or address, of the proxy server
|
||||
The hostname, or address, of the proxy server
|
||||
</P>
|
||||
<LI><P><B>https.proxyPort</B> (default: 443)<BR>
|
||||
The port number of the proxy server.</P>
|
||||
@ -105,7 +106,7 @@ of proxies.</P>
|
||||
<P>The following proxy settings are used by the FTP protocol handler.</P>
|
||||
<UL>
|
||||
<LI><P><B>ftp.proxyHost</B>(default: <none>)<BR>
|
||||
The hostname, or address, of the proxy server
|
||||
The hostname, or address, of the proxy server
|
||||
</P>
|
||||
<LI><P><B>ftp.proxyPort</B> (default: 80)<BR>
|
||||
The port number of the proxy server.</P>
|
||||
@ -160,7 +161,7 @@ of proxies.</P>
|
||||
<LI><P><B>http.agent</B> (default: “Java/<version>”)<BR>
|
||||
Defines the string sent in the User-Agent request header in http
|
||||
requests. Note that the string “Java/<version>” will
|
||||
be appended to the one provided in the property (e.g. if
|
||||
be appended to the one provided in the property (e.g. if
|
||||
-Dhttp.agent=”foobar” is used, the User-Agent header will
|
||||
contain “foobar Java/1.5.0” if the version of the VM is
|
||||
1.5.0). This property is checked only once at startup.</P>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
||||
@ -61,7 +61,7 @@ Java_java_net_InetAddress_init(JNIEnv *env, jclass cls) {
|
||||
CHECK_NULL(iac_class);
|
||||
ia_holderID = (*env)->GetFieldID(env, ia_class, "holder", "Ljava/net/InetAddress$InetAddressHolder;");
|
||||
CHECK_NULL(ia_holderID);
|
||||
ia_preferIPv6AddressID = (*env)->GetStaticFieldID(env, ia_class, "preferIPv6Address", "Z");
|
||||
ia_preferIPv6AddressID = (*env)->GetStaticFieldID(env, ia_class, "preferIPv6Address", "I");
|
||||
CHECK_NULL(ia_preferIPv6AddressID);
|
||||
|
||||
iac_addressID = (*env)->GetFieldID(env, iac_class, "address", "I");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, 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
|
||||
@ -48,6 +48,7 @@
|
||||
|
||||
#include "java_net_Inet4AddressImpl.h"
|
||||
#include "java_net_Inet6AddressImpl.h"
|
||||
#include "java_net_InetAddress.h"
|
||||
|
||||
/* the initial size of our hostent buffers */
|
||||
#ifndef NI_MAXHOST
|
||||
@ -312,8 +313,8 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return NULL;
|
||||
} else {
|
||||
int i = 0;
|
||||
int inetCount = 0, inet6Count = 0, inetIndex, inet6Index;
|
||||
int i = 0, addressPreference = -1;
|
||||
int inetCount = 0, inet6Count = 0, inetIndex = 0, inet6Index = 0, originalIndex = 0;
|
||||
struct addrinfo *itr, *last = NULL, *iterator = res;
|
||||
while (iterator != NULL) {
|
||||
int skip = 0;
|
||||
@ -394,14 +395,18 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
|
||||
if ((*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID)) {
|
||||
addressPreference = (*env)->GetStaticIntField(env, ia_class, ia_preferIPv6AddressID);
|
||||
|
||||
if (addressPreference == java_net_InetAddress_PREFER_IPV6_VALUE) {
|
||||
/* AF_INET addresses will be offset by inet6Count */
|
||||
inetIndex = inet6Count;
|
||||
inet6Index = 0;
|
||||
} else {
|
||||
} else if (addressPreference == java_net_InetAddress_PREFER_IPV4_VALUE) {
|
||||
/* AF_INET6 addresses will be offset by inetCount */
|
||||
inetIndex = 0;
|
||||
inet6Index = inetCount;
|
||||
} else if (addressPreference == java_net_InetAddress_PREFER_SYSTEM_VALUE) {
|
||||
inetIndex = inet6Index = originalIndex = 0;
|
||||
}
|
||||
|
||||
while (iterator != NULL) {
|
||||
@ -414,7 +419,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
}
|
||||
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
|
||||
setInetAddress_hostName(env, iaObj, host);
|
||||
(*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj);
|
||||
(*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj);
|
||||
inetIndex++;
|
||||
} else if (iterator->ai_family == AF_INET6) {
|
||||
jint scope = 0;
|
||||
@ -435,9 +440,13 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
setInet6Address_scopeid(env, iaObj, scope);
|
||||
}
|
||||
setInetAddress_hostName(env, iaObj, host);
|
||||
(*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj);
|
||||
(*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj);
|
||||
inet6Index++;
|
||||
}
|
||||
if (addressPreference == java_net_InetAddress_PREFER_SYSTEM_VALUE) {
|
||||
originalIndex++;
|
||||
inetIndex = inet6Index = 0;
|
||||
}
|
||||
iterator = iterator->ai_next;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, 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
|
||||
@ -97,7 +97,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
|
||||
/* get the address preference */
|
||||
preferIPv6Address
|
||||
= (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
|
||||
= (*env)->GetStaticIntField(env, ia_class, ia_preferIPv6AddressID);
|
||||
|
||||
/* Try once, with our static buffer. */
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
@ -122,7 +122,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
}
|
||||
} else {
|
||||
int i = 0;
|
||||
int inetCount = 0, inet6Count = 0, inetIndex, inet6Index;
|
||||
int inetCount = 0, inet6Count = 0, inetIndex = 0, inet6Index = 0, originalIndex = 0;
|
||||
struct addrinfo *itr, *last, *iterator = res;
|
||||
while (iterator != NULL) {
|
||||
int skip = 0;
|
||||
@ -203,12 +203,14 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
|
||||
if (preferIPv6Address) {
|
||||
if (preferIPv6Address == java_net_InetAddress_PREFER_IPV6_VALUE) {
|
||||
inetIndex = inet6Count;
|
||||
inet6Index = 0;
|
||||
} else {
|
||||
} else if (preferIPv6Address == java_net_InetAddress_PREFER_IPV4_VALUE) {
|
||||
inetIndex = 0;
|
||||
inet6Index = inetCount;
|
||||
} else if (preferIPv6Address == java_net_InetAddress_PREFER_SYSTEM_VALUE) {
|
||||
inetIndex = inet6Index = originalIndex = 0;
|
||||
}
|
||||
|
||||
while (iterator != NULL) {
|
||||
@ -220,7 +222,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
}
|
||||
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
|
||||
setInetAddress_hostName(env, iaObj, host);
|
||||
(*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj);
|
||||
(*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj);
|
||||
inetIndex ++;
|
||||
} else if (iterator->ai_family == AF_INET6) {
|
||||
jint scope = 0;
|
||||
@ -240,9 +242,13 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
setInet6Address_scopeid(env, iaObj, scope);
|
||||
}
|
||||
setInetAddress_hostName(env, iaObj, host);
|
||||
(*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj);
|
||||
(*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj);
|
||||
inet6Index ++;
|
||||
}
|
||||
if (preferIPv6Address == java_net_InetAddress_PREFER_SYSTEM_VALUE) {
|
||||
originalIndex++;
|
||||
inetIndex = inet6Index = 0;
|
||||
}
|
||||
iterator = iterator->ai_next;
|
||||
}
|
||||
}
|
||||
|
132
jdk/test/java/net/Inet6Address/PreferIPv6AddressesTest.java
Normal file
132
jdk/test/java/net/Inet6Address/PreferIPv6AddressesTest.java
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8016521
|
||||
* @summary InetAddress should not always re-order addresses returned from name
|
||||
* service
|
||||
* @run main/othervm -Djava.net.preferIPv6Addresses=false PreferIPv6AddressesTest
|
||||
* @run main/othervm -Djava.net.preferIPv6Addresses=true PreferIPv6AddressesTest
|
||||
* @run main/othervm -Djava.net.preferIPv6Addresses=system PreferIPv6AddressesTest
|
||||
* @run main/othervm PreferIPv6AddressesTest
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.IntStream;
|
||||
import static java.lang.System.out;
|
||||
|
||||
public class PreferIPv6AddressesTest {
|
||||
|
||||
// A name, that if resolves, returns both IPv4 and IPv6 addresses.
|
||||
static final String HOST_NAME = "www.google.com";
|
||||
|
||||
static final InetAddress LOOPBACK = InetAddress.getLoopbackAddress();
|
||||
|
||||
static final String preferIPV6Address =
|
||||
System.getProperty("java.net.preferIPv6Addresses", "false");
|
||||
|
||||
public static void main(String args[]) throws IOException {
|
||||
|
||||
InetAddress addrs[];
|
||||
try {
|
||||
addrs = InetAddress.getAllByName(HOST_NAME);
|
||||
} catch (UnknownHostException e) {
|
||||
out.println("Unknown host " + HOST_NAME + ", cannot run test.");
|
||||
return;
|
||||
}
|
||||
|
||||
int firstIPv4Address = IntStream.range(0, addrs.length)
|
||||
.filter(x -> addrs[x] instanceof Inet4Address)
|
||||
.findFirst().orElse(-1);
|
||||
int firstIPv6Address = IntStream.range(0, addrs.length)
|
||||
.filter(x -> addrs[x] instanceof Inet6Address)
|
||||
.findFirst().orElse(-1);
|
||||
|
||||
out.println("IPv6 supported: " + IPv6Supported());
|
||||
out.println("Addresses: " + Arrays.asList(addrs));
|
||||
|
||||
if (preferIPV6Address.equalsIgnoreCase("true") && firstIPv6Address != -1) {
|
||||
int off = firstIPv4Address != -1 ? firstIPv4Address : addrs.length;
|
||||
assertAllv6Addresses(addrs, 0, off);
|
||||
assertAllv4Addresses(addrs, off, addrs.length);
|
||||
assertLoopbackAddress(Inet6Address.class);
|
||||
assertAnyLocalAddress(Inet6Address.class);
|
||||
} else if (preferIPV6Address.equalsIgnoreCase("false") && firstIPv4Address != -1) {
|
||||
int off = firstIPv6Address != -1 ? firstIPv6Address : addrs.length;
|
||||
assertAllv4Addresses(addrs, 0, off);
|
||||
assertAllv6Addresses(addrs, off, addrs.length);
|
||||
assertLoopbackAddress(Inet4Address.class);
|
||||
assertAnyLocalAddress(Inet4Address.class);
|
||||
} else if (preferIPV6Address.equalsIgnoreCase("system") && IPv6Supported()) {
|
||||
assertLoopbackAddress(Inet6Address.class);
|
||||
assertAnyLocalAddress(Inet6Address.class);
|
||||
} else if (preferIPV6Address.equalsIgnoreCase("system") && !IPv6Supported()) {
|
||||
assertLoopbackAddress(Inet4Address.class);
|
||||
assertAnyLocalAddress(Inet4Address.class);
|
||||
}
|
||||
}
|
||||
|
||||
static void assertAllv4Addresses(InetAddress[] addrs, int off, int len) {
|
||||
IntStream.range(off, len)
|
||||
.mapToObj(x -> addrs[x])
|
||||
.forEach(x -> {
|
||||
if (!(x instanceof Inet4Address))
|
||||
throw new RuntimeException("Expected IPv4, got " + x);
|
||||
});
|
||||
}
|
||||
|
||||
static void assertAllv6Addresses(InetAddress[] addrs, int off, int len) {
|
||||
IntStream.range(off, len)
|
||||
.mapToObj(x -> addrs[x])
|
||||
.forEach(x -> {
|
||||
if (!(x instanceof Inet6Address))
|
||||
throw new RuntimeException("Expected IPv6, got " + x);
|
||||
});
|
||||
}
|
||||
|
||||
static void assertLoopbackAddress(Class<?> expectedType) {
|
||||
if (!LOOPBACK.getClass().isAssignableFrom(expectedType))
|
||||
throw new RuntimeException("Expected " + expectedType
|
||||
+ ", got " + LOOPBACK.getClass());
|
||||
}
|
||||
|
||||
static void assertAnyLocalAddress(Class<?> expectedType) {
|
||||
InetAddress anyAddr = (new InetSocketAddress(0)).getAddress();
|
||||
if (!anyAddr.getClass().isAssignableFrom(expectedType))
|
||||
throw new RuntimeException("Expected " + expectedType
|
||||
+ ", got " + anyAddr.getClass());
|
||||
}
|
||||
|
||||
static boolean IPv6Supported() throws IOException {
|
||||
try {
|
||||
DatagramChannel.open(StandardProtocolFamily.INET6);
|
||||
return true;
|
||||
} catch (UnsupportedOperationException x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user