--- a/src/java.base/share/classes/java/net/Inet6AddressImpl.java Fri Jul 05 12:55:54 2019 +0300
+++ b/src/java.base/share/classes/java/net/Inet6AddressImpl.java Fri Jul 05 13:40:29 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -25,6 +25,8 @@
package java.net;
import java.io.IOException;
+
+import static java.net.InetAddress.IPv6;
import static java.net.InetAddress.PREFER_IPV6_VALUE;
import static java.net.InetAddress.PREFER_SYSTEM_VALUE;
@@ -70,7 +72,7 @@
* stack system).
*/
java.util.Enumeration<InetAddress> it = netif.getInetAddresses();
- InetAddress inetaddr = null;
+ InetAddress inetaddr;
while (it.hasMoreElements()) {
inetaddr = it.nextElement();
if (inetaddr.getClass().isInstance(addr)) {
@@ -110,20 +112,23 @@
boolean preferIPv6Address =
InetAddress.preferIPv6Address == PREFER_IPV6_VALUE ||
InetAddress.preferIPv6Address == PREFER_SYSTEM_VALUE;
- InetAddress loopback4 = (new Inet4AddressImpl()).loopbackAddress();
- InetAddress loopback6 = new Inet6Address("localhost",
- new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01});
- // Order the candidate addresses by preference.
- InetAddress[] addresses = preferIPv6Address
- ? new InetAddress[] {loopback6, loopback4}
- : new InetAddress[] {loopback4, loopback6};
- // In case of failure, default to the preferred address.
- loopbackAddress = addresses[0];
- // Pick the first candidate address that actually exists.
- for (InetAddress address : addresses) {
+
+ for (int i = 0; i < 2; i++) {
+ InetAddress address;
+ // Order the candidate addresses by preference.
+ if (i == (preferIPv6Address ? 0 : 1)) {
+ address = new Inet6Address("localhost",
+ new byte[]{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01});
+ } else {
+ address = new Inet4Address("localhost", new byte[]{ 0x7f,0x00,0x00,0x01 });
+ }
+ if (i == 0) {
+ // In case of failure, default to the preferred address.
+ loopbackAddress = address;
+ }
try {
- if (NetworkInterface.getByInetAddress(address) == null) {
+ if (!NetworkInterface.isBoundInetAddress(address)) {
continue;
}
} catch (SocketException e) {
--- a/src/java.base/share/classes/java/net/InetAddress.java Fri Jul 05 12:55:54 2019 +0300
+++ b/src/java.base/share/classes/java/net/InetAddress.java Fri Jul 05 13:40:29 2019 +0200
@@ -290,7 +290,7 @@
}
/* Used to store the name service provider */
- private static transient NameService nameService = null;
+ private static transient NameService nameService;
/**
* Used to store the best available hostname.
@@ -305,8 +305,7 @@
* Load net library into runtime, and perform initializations.
*/
static {
- String str = java.security.AccessController.doPrivileged(
- new GetPropertyAction("java.net.preferIPv6Addresses"));
+ String str = GetPropertyAction.privilegedGetProperty("java.net.preferIPv6Addresses");
if (str == null) {
preferIPv6Address = PREFER_IPV4_VALUE;
} else if (str.equalsIgnoreCase("true")) {
--- a/src/java.base/share/classes/java/net/NetworkInterface.java Fri Jul 05 12:55:54 2019 +0300
+++ b/src/java.base/share/classes/java/net/NetworkInterface.java Fri Jul 05 13:40:29 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -321,17 +321,16 @@
if (addr == null) {
throw new NullPointerException();
}
- if (addr instanceof Inet4Address) {
- Inet4Address inet4Address = (Inet4Address) addr;
- if (inet4Address.holder.family != InetAddress.IPv4) {
+
+ if (addr.holder.family == InetAddress.IPv4) {
+ if (!(addr instanceof Inet4Address)) {
throw new IllegalArgumentException("invalid family type: "
- + inet4Address.holder.family);
+ + addr.holder.family);
}
- } else if (addr instanceof Inet6Address) {
- Inet6Address inet6Address = (Inet6Address) addr;
- if (inet6Address.holder.family != InetAddress.IPv6) {
+ } else if (addr.holder.family == InetAddress.IPv6) {
+ if (!(addr instanceof Inet6Address)) {
throw new IllegalArgumentException("invalid family type: "
- + inet6Address.holder.family);
+ + addr.holder.family);
}
} else {
throw new IllegalArgumentException("invalid address type: " + addr);
@@ -394,6 +393,23 @@
}
}
+ /**
+ * Checks if the given address is bound to any of the interfaces on this
+ * machine.
+ *
+ * @param addr
+ * The {@code InetAddress} to search with.
+ * @return true iff the addr parameter is currently bound to one of
+ * the interfaces on this machine.
+ *
+ * @throws SocketException
+ * If an I/O error occurs.
+ */
+ /* package-private */ static boolean isBoundInetAddress(InetAddress addr)
+ throws SocketException {
+ return boundInetAddress0(addr);
+ }
+
private static <T> Enumeration<T> enumerationFromArray(T[] a) {
return new Enumeration<>() {
int i = 0;
@@ -431,6 +447,9 @@
private static native NetworkInterface getByIndex0(int index)
throws SocketException;
+ private static native boolean boundInetAddress0(InetAddress addr)
+ throws SocketException;
+
private static native NetworkInterface getByInetAddress0(InetAddress addr)
throws SocketException;
--- a/src/java.base/unix/native/libnet/NetworkInterface.c Fri Jul 05 12:55:54 2019 +0300
+++ b/src/java.base/unix/native/libnet/NetworkInterface.c Fri Jul 05 13:40:29 2019 +0200
@@ -320,33 +320,9 @@
return obj;
}
-/*
- * Class: java_net_NetworkInterface
- * Method: getByInetAddress0
- * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
- */
-JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
- (JNIEnv *env, jclass cls, jobject iaObj)
-{
- netif *ifs, *curr;
- jobject obj = NULL;
- jboolean match = JNI_FALSE;
- int family = getInetAddress_family(env, iaObj);
- JNU_CHECK_EXCEPTION_RETURN(env, NULL);
-
- if (family == java_net_InetAddress_IPv4) {
- family = AF_INET;
- } else if (family == java_net_InetAddress_IPv6) {
- family = AF_INET6;
- } else {
- return NULL; // Invalid family
- }
- ifs = enumInterfaces(env);
- if (ifs == NULL) {
- return NULL;
- }
-
- curr = ifs;
+// Return the interface in ifs that iaObj is bound to, if any - otherwise NULL
+static netif* find_bound_interface(JNIEnv *env, netif* ifs, jobject iaObj, int family) {
+ netif* curr = ifs;
while (curr != NULL) {
netaddr *addrP = curr->addr;
@@ -359,11 +335,10 @@
((struct sockaddr_in *)addrP->addr)->sin_addr.s_addr);
int address2 = getInetAddress_addr(env, iaObj);
if ((*env)->ExceptionCheck(env)) {
- goto cleanup;
+ return NULL;
}
if (address1 == address2) {
- match = JNI_TRUE;
- break;
+ return curr;
}
} else if (family == AF_INET6) {
jbyte *bytes = (jbyte *)&(
@@ -383,30 +358,117 @@
i++;
}
if (i >= 16) {
- match = JNI_TRUE;
- break;
+ return curr;
}
}
}
- if (match) {
- break;
- }
addrP = addrP->next;
}
-
- if (match) {
- break;
- }
curr = curr->next;
}
+ return NULL;
+}
+
+/*
+ * Class: java_net_NetworkInterface
+ * Method: boundInetAddress0
+ * Signature: (Ljava/net/InetAddress;)boundInetAddress;
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_boundInetAddress0
+ (JNIEnv *env, jclass cls, jobject iaObj)
+{
+ netif *ifs = NULL;
+ jboolean bound = JNI_FALSE;
+ int sock;
+
+ int family = getInetAddress_family(env, iaObj);
+ JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+
+ if (family == java_net_InetAddress_IPv4) {
+ family = AF_INET;
+ } else if (family == java_net_InetAddress_IPv6) {
+ family = AF_INET6;
+ } else {
+ return JNI_FALSE; // Invalid family
+ }
+
+ if (family == AF_INET) {
+ sock = openSocket(env, AF_INET);
+ if (sock < 0 && (*env)->ExceptionOccurred(env)) {
+ return JNI_FALSE;
+ }
+
+ // enumerate IPv4 addresses
+ if (sock >= 0) {
+ ifs = enumIPv4Interfaces(env, sock, ifs);
+ close(sock);
+
+ if ((*env)->ExceptionOccurred(env)) {
+ goto cleanup;
+ }
+ }
+ if (find_bound_interface(env, ifs, iaObj, family) != NULL)
+ bound = JNI_TRUE;
+ } else if (ipv6_available()) {
+ // If IPv6 is available then enumerate IPv6 addresses.
+ // User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true,
+ // so we have to call ipv6_available()
+ sock = openSocket(env, AF_INET6);
+ if (sock < 0) {
+ return JNI_FALSE;
+ }
+
+ ifs = enumIPv6Interfaces(env, sock, ifs);
+ close(sock);
+
+ if ((*env)->ExceptionOccurred(env)) {
+ goto cleanup;
+ }
+
+ if (find_bound_interface(env, ifs, iaObj, family) != NULL)
+ bound = JNI_TRUE;
+ }
+
+cleanup:
+ freeif(ifs);
+
+ return bound;
+}
+
+/*
+ * Class: java_net_NetworkInterface
+ * Method: getByInetAddress0
+ * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
+ */
+JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
+ (JNIEnv *env, jclass cls, jobject iaObj)
+{
+ netif *ifs, *curr;
+ jobject obj = NULL;
+ int family = getInetAddress_family(env, iaObj);
+ JNU_CHECK_EXCEPTION_RETURN(env, NULL);
+
+ if (family == java_net_InetAddress_IPv4) {
+ family = AF_INET;
+ } else if (family == java_net_InetAddress_IPv6) {
+ family = AF_INET6;
+ } else {
+ return NULL; // Invalid family
+ }
+ ifs = enumInterfaces(env);
+ if (ifs == NULL) {
+ return NULL;
+ }
+
+ curr = find_bound_interface(env, ifs, iaObj, family);
+
// if found create a NetworkInterface
- if (match) {
+ if (curr != NULL) {
obj = createNetworkInterface(env, curr);
}
-cleanup:
// release the interface list
freeif(ifs);
--- a/src/java.base/windows/native/libnet/NetworkInterface.c Fri Jul 05 12:55:54 2019 +0300
+++ b/src/java.base/windows/native/libnet/NetworkInterface.c Fri Jul 05 13:40:29 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -25,6 +25,7 @@
#include "net_util.h"
#include "NetworkInterface.h"
+#include "java_net_InetAddress.h"
#include "java_net_NetworkInterface.h"
/*
@@ -347,7 +348,7 @@
/*
* Free the interface table and return the interface list
*/
- if (tableP) {
+ if (tableP != NULL) {
free(tableP);
}
*netifPP = netifP;
@@ -355,24 +356,13 @@
}
/*
- * Enumerate the IP addresses on an interface using the IP helper library
- * routine GetIfAddrTable and matching based on the index name. There are
- * more efficient routines but we use GetIfAddrTable because it's avaliable
- * on 98 and NT.
- *
- * Returns the count of addresses, or -1 if error. If no error occurs then
- * netaddrPP will return a list of netaddr structures with the IP addresses.
+ * Enumerate all addresses using the IP helper library
*/
-int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP)
+int lookupIPAddrTable(JNIEnv *env, MIB_IPADDRTABLE **tablePP)
{
MIB_IPADDRTABLE *tableP;
ULONG size;
DWORD ret;
- DWORD i;
- netaddr *netaddrP;
- int count = 0;
- unsigned long mask;
-
/*
* Use GetIpAddrTable to enumerate the IP Addresses
*/
@@ -396,7 +386,7 @@
ret = GetIpAddrTable(tableP, &size, FALSE);
}
if (ret != NO_ERROR) {
- if (tableP) {
+ if (tableP != NULL) {
free(tableP);
}
JNU_ThrowByName(env, "java/lang/Error",
@@ -405,16 +395,35 @@
// GetIpAddrTable in pure IPv6 environment
return -2;
}
+ *tablePP = tableP;
+ return 0;
+}
+
+/*
+ * Enumerate the IP addresses on an interface, given an IP address table
+ * and matching based on index.
+ *
+ * Returns the count of addresses, or -1 if error. If no error occurs then
+ * netaddrPP will return a list of netaddr structures with the IP addresses.
+ */
+int enumAddresses_win_ipaddrtable(JNIEnv *env, netif *netifP, netaddr **netaddrPP, MIB_IPADDRTABLE *tableP)
+{
+ DWORD i;
+ netaddr *netaddrP;
+ int count = 0;
+ unsigned long mask;
/*
* Iterate through the table to find the addresses with the
* matching dwIndex. Ignore 0.0.0.0 addresses.
*/
+ if (tableP == NULL)
+ return 0;
count = 0;
netaddrP = NULL;
i = 0;
- while (i<tableP->dwNumEntries) {
+ while (i < tableP->dwNumEntries) {
if (tableP->table[i].dwIndex == netifP->dwIndex &&
tableP->table[i].dwAddr != 0) {
@@ -437,33 +446,33 @@
case MIB_IF_TYPE_FDDI:
case MIB_IF_TYPE_LOOPBACK:
case IF_TYPE_IEEE80211:
- /**
- * Contrary to what it seems to indicate, dwBCastAddr doesn't
- * contain the broadcast address but 0 or 1 depending on whether
- * the broadcast address should set the bits of the host part
- * to 0 or 1.
- * Yes, I know it's stupid, but what can I say, it's MSFTs API.
- */
- curr->brdcast.sa4.sin_family = AF_INET;
- if (tableP->table[i].dwBCastAddr == 1)
- curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask) | (0xffffffff ^ tableP->table[i].dwMask);
- else
- curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask);
- mask = ntohl(tableP->table[i].dwMask);
- curr->mask = 0;
- while (mask) {
- mask <<= 1;
- curr->mask++;
- }
- break;
+ /**
+ * Contrary to what it seems to indicate, dwBCastAddr doesn't
+ * contain the broadcast address but 0 or 1 depending on whether
+ * the broadcast address should set the bits of the host part
+ * to 0 or 1.
+ * Yes, I know it's stupid, but what can I say, it's MSFTs API.
+ */
+ curr->brdcast.sa4.sin_family = AF_INET;
+ if (tableP->table[i].dwBCastAddr == 1)
+ curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask) | (0xffffffff ^ tableP->table[i].dwMask);
+ else
+ curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask);
+ mask = ntohl(tableP->table[i].dwMask);
+ curr->mask = 0;
+ while (mask) {
+ mask <<= 1;
+ curr->mask++;
+ }
+ break;
case MIB_IF_TYPE_PPP:
case MIB_IF_TYPE_SLIP:
default:
- /**
- * these don't have broadcast/subnet
- */
- curr->mask = -1;
- break;
+ /**
+ * these don't have broadcast/subnet
+ */
+ curr->mask = -1;
+ break;
}
curr->next = netaddrP;
@@ -474,10 +483,30 @@
}
*netaddrPP = netaddrP;
+ return count;
+}
+
+
+/*
+ * Enumerate the IP addresses on an interface, using an IP address table
+ * retrieved using GetIPAddrTable and matching based on index.
+ *
+ * Returns the count of addresses, or -1 if error. If no error occurs then
+ * netaddrPP will return a list of netaddr structures with the IP addresses.
+ */
+int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP) {
+ MIB_IPADDRTABLE *tableP;
+ int count;
+ int ret = lookupIPAddrTable(env, &tableP);
+ if (ret < 0) {
+ return NULL;
+ }
+ count = enumAddresses_win_ipaddrtable(env, netifP, netaddrPP, tableP);
free(tableP);
return count;
}
+
/*
* Class: java_net_NetworkInterface
* Method: init
@@ -758,6 +787,50 @@
return netifObj;
}
+
+/*
+ * Class: java_net_NetworkInterface
+ * Method: boundInetAddress0
+ * Signature: (Ljava/net/InetAddress;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_boundInetAddress0
+ (JNIEnv *env, jclass cls, jobject iaObj)
+{
+ jobject netifObj = NULL;
+ DWORD i;
+
+ int family = getInetAddress_family(env, iaObj);
+ JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+
+ if (family == java_net_InetAddress_IPv6) {
+ if (!ipv6_available())
+ return JNI_FALSE;
+ return Java_java_net_NetworkInterface_getByInetAddress0_XP(env, cls, iaObj) != NULL;
+ } else if (family == java_net_InetAddress_IPv4) {
+ jint addr = getInetAddress_addr(env, iaObj);
+ JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+
+ jboolean found = JNI_FALSE;
+ MIB_IPADDRTABLE *tableP;
+ if (lookupIPAddrTable(env, &tableP) >= 0 && tableP != NULL) {
+ for (i = 0; i < tableP->dwNumEntries; i++) {
+ if (tableP->table[i].dwAddr != 0 &&
+ (unsigned long)addr == ntohl(tableP->table[i].dwAddr)) {
+ found = JNI_TRUE;
+ break;
+ }
+ }
+ }
+ if (tableP != NULL) {
+ free(tableP);
+ }
+ return found;
+ } else {
+ // Unknown address family
+ return JNI_FALSE;
+ }
+}
+
/*
* Class: java_net_NetworkInterface
* Method: getByInetAddress0
@@ -767,11 +840,11 @@
(JNIEnv *env, jclass cls, jobject iaObj)
{
netif *ifList, *curr;
+ MIB_IPADDRTABLE *tableP;
jobject netifObj = NULL;
jint addr = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
- // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
if (ipv6_available()) {
return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj);
}
@@ -785,42 +858,50 @@
* Enumerate the addresses on each interface until we find a
* matching address.
*/
- curr = ifList;
- while (curr != NULL) {
- int count;
- netaddr *addrList;
- netaddr *addrP;
+ tableP = NULL;
+ if (lookupIPAddrTable(env, &tableP) >= 0) {
+ curr = ifList;
+ while (curr != NULL) {
+ int count;
+ netaddr *addrList;
+ netaddr *addrP;
+
+ /* enumerate the addresses on this interface */
+ count = enumAddresses_win_ipaddrtable(env, curr, &addrList, tableP);
+ if (count < 0) {
+ free_netif(ifList);
+ free(tableP);
+ return NULL;
+ }
- /* enumerate the addresses on this interface */
- count = enumAddresses_win(env, curr, &addrList);
- if (count < 0) {
- free_netif(ifList);
- return NULL;
- }
+ /* iterate through each address */
+ addrP = addrList;
- /* iterate through each address */
- addrP = addrList;
+ while (addrP != NULL) {
+ if ((unsigned long)addr == ntohl(addrP->addr.sa4.sin_addr.s_addr)) {
+ break;
+ }
+ addrP = addrP->next;
+ }
- while (addrP != NULL) {
- if ((unsigned long)addr == ntohl(addrP->addr.sa4.sin_addr.s_addr)) {
+ /*
+ * Address matched so create NetworkInterface for this interface
+ * and address list.
+ */
+ if (addrP != NULL) {
+ /* createNetworkInterface will free addrList */
+ netifObj = createNetworkInterface(env, curr, count, addrList);
break;
}
- addrP = addrP->next;
- }
- /*
- * Address matched so create NetworkInterface for this interface
- * and address list.
- */
- if (addrP != NULL) {
- /* createNetworkInterface will free addrList */
- netifObj = createNetworkInterface(env, curr, count, addrList);
- break;
+ /* on next interface */
+ curr = curr->next;
}
+ }
- /* on next interface */
- curr = curr->next;
- }
+ /* release the IP address table */
+ if (tableP != NULL)
+ free(tableP);
/* release the interface list */
free_netif(ifList);
--- a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Fri Jul 05 12:55:54 2019 +0300
+++ b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Fri Jul 05 13:40:29 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -33,7 +33,9 @@
* and getByAddress.
*/
+extern int enumAddresses_win_ipaddrtable(JNIEnv *env, netif *netifP, netaddr **netaddrPP, MIB_IPADDRTABLE *tableP);
extern int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP);
+extern int lookupIPAddrTable(JNIEnv *env, MIB_IPADDRTABLE **tablePP);
int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP);
#ifdef DEBUG
@@ -239,6 +241,7 @@
int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
{
DWORD ret;
+ MIB_IPADDRTABLE *tableP;
IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL;
ULONG len=ipinflen, count=0;
netif *nif=NULL, *dup_nif, *last=NULL, *loopif=NULL, *curr;
@@ -271,10 +274,15 @@
// Retrieve IPv4 addresses with the IP Helper API
curr = *netifPP;
+ ret = lookupIPAddrTable(env, &tableP);
+ if (ret < 0) {
+ return -1;
+ }
while (curr != NULL) {
netaddr *netaddrP;
- ret = enumAddresses_win(env, curr, &netaddrP);
+ ret = enumAddresses_win_ipaddrtable(env, curr, &netaddrP, tableP);
if (ret == -1) {
+ free(tableP);
return -1;
} else if (ret == -2) {
if ((*env)->ExceptionCheck(env)) {
@@ -287,7 +295,7 @@
curr = curr->next;
}
}
-
+ free(tableP);
ret = getAdapters (env, &adapters);
if (ret != ERROR_SUCCESS) {
goto err;
--- a/test/jdk/java/net/NetworkInterface/NetworkInterfaceRetrievalTests.java Fri Jul 05 12:55:54 2019 +0300
+++ b/test/jdk/java/net/NetworkInterface/NetworkInterfaceRetrievalTests.java Fri Jul 05 13:40:29 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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,17 +23,21 @@
/**
* @test
- * @bug 8179559
+ * @bug 8179559 8225239
*/
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
+import java.lang.reflect.Method;
public class NetworkInterfaceRetrievalTests {
public static void main(String[] args) throws Exception {
int checkFailureCount = 0;
+ Method isBound = NetworkInterface.class.getDeclaredMethod("isBoundInetAddress", InetAddress.class);
+ isBound.setAccessible(true);
+
try {
Enumeration<NetworkInterface> en = NetworkInterface
.getNetworkInterfaces();
@@ -58,6 +62,13 @@
checkFailureCount++;
}
+ // Any bound address should return true when calling isBoundInetAddress
+ if (!((boolean)isBound.invoke(null, addr))) {
+ System.out.println("Retreived net if bound addr " + addr
+ + "NOT shown as bound using NetworkInterface.isBoundAddress "
+ + "***********");
+ checkFailureCount++;
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/NetworkInterfaceLookup.java Fri Jul 05 13:40:29 2019 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+package org.openjdk.bench.java.net;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Assess time to perform native NetworkInterface lookups; uses
+ * reflection to access both package-private isBoundInetAddress and
+ * public getByInetAddress (to get comparable numbers)
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+@Fork(2)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 10, time = 2)
+public class NetworkInterfaceLookup {
+
+ static final InetAddress address = InetAddress.getLoopbackAddress();
+
+ static final Method isBoundInetAddress_method;
+
+ static final Method getByInetAddress_method;
+
+ static {
+ Method isBound = null;
+ Method getByInet = null;
+
+ try {
+ isBound = NetworkInterface.class.getDeclaredMethod("isBoundInetAddress", InetAddress.class);
+ isBound.setAccessible(true);
+ } catch (Exception e) {
+ System.out.println("NetworkInterface.isBoundInetAddress not found");
+ }
+
+ try {
+ getByInet = NetworkInterface.class.getDeclaredMethod("getByInetAddress", InetAddress.class);
+ } catch (Exception e) {
+ System.out.println("NetworkInterface.getByInetAddress not found");
+ }
+ isBoundInetAddress_method = isBound;
+ getByInetAddress_method = getByInet;
+ }
+
+ @Benchmark
+ public boolean bound() throws Exception {
+ return (boolean)isBoundInetAddress_method.invoke(null, address);
+ }
+
+ @Benchmark
+ public NetworkInterface getByInetAddress() throws Exception {
+ return (NetworkInterface)getByInetAddress_method.invoke(null, address);
+ }
+}