8275640: (win) java.net.NetworkInterface issues with IPv6-only environments

Reviewed-by: msheppar, dfuchs
This commit is contained in:
Daniel Jeliński 2022-03-08 16:15:24 +00:00 committed by Daniel Fuchs
parent 3e4dfc63e7
commit 2549e55038
2 changed files with 48 additions and 33 deletions

View File

@ -176,6 +176,8 @@ int enumInterfaces(JNIEnv *env, netif **netifPP)
DWORD i;
int lo=0, eth=0, tr=0, fddi=0, ppp=0, sl=0, wlan=0, net=0, wlen=0;
*netifPP = NULL;
/*
* Ask the IP Helper library to enumerate the adapters
*/
@ -213,9 +215,7 @@ int enumInterfaces(JNIEnv *env, netif **netifPP)
"IP Helper Library GetIfTable function failed");
break;
}
// this different error code is to handle the case when we call
// GetIpAddrTable in pure IPv6 environment
return -2;
return -1;
}
/*
@ -373,6 +373,9 @@ int lookupIPAddrTable(JNIEnv *env, MIB_IPADDRTABLE **tablePP)
MIB_IPADDRTABLE *tableP;
ULONG size;
DWORD ret;
*tablePP = NULL;
/*
* Use GetIpAddrTable to enumerate the IP Addresses
*/
@ -434,12 +437,15 @@ int enumAddresses_win_ipaddrtable(JNIEnv *env, netif *netifP, netaddr **netaddrP
int count = 0;
unsigned long mask;
*netaddrPP = NULL;
/*
* Iterate through the table to find the addresses with the
* matching dwIndex. Ignore 0.0.0.0 addresses.
*/
if (tableP == NULL)
if (tableP == NULL) {
return 0;
}
count = 0;
netaddrP = NULL;
@ -452,7 +458,6 @@ int enumAddresses_win_ipaddrtable(JNIEnv *env, netif *netifP, netaddr **netaddrP
if (curr == NULL) {
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
free_netaddr(netaddrP);
free(tableP);
return -1;
}
@ -518,9 +523,12 @@ int enumAddresses_win_ipaddrtable(JNIEnv *env, netif *netifP, netaddr **netaddrP
int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP) {
MIB_IPADDRTABLE *tableP;
int count;
*netaddrPP = NULL;
int ret = lookupIPAddrTable(env, &tableP);
if (ret < 0) {
return NULL;
return ret;
}
count = enumAddresses_win_ipaddrtable(env, netifP, netaddrPP, tableP);
free(tableP);
@ -850,9 +858,7 @@ JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_boundInetAddress0
break;
}
}
}
if (tableP != NULL) {
free(tableP);
free(tableP);
}
return found;
} else {
@ -922,16 +928,16 @@ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
/* createNetworkInterface will free addrList */
netifObj = createNetworkInterface(env, curr, count, addrList);
break;
} else {
free_netaddr(addrList);
}
/* on next interface */
curr = curr->next;
}
}
/* release the IP address table */
if (tableP != NULL)
/* release the IP address table */
free(tableP);
}
/* release the interface list */
free_netif(ifList);
@ -948,7 +954,7 @@ JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll
(JNIEnv *env, jclass cls)
{
int count;
netif *ifList = NULL, *curr;
netif *ifList, *curr;
jobjectArray netIFArr;
jint arr_index;

View File

@ -79,6 +79,8 @@ int getAdapters (JNIEnv *env, int flags, IP_ADAPTER_ADDRESSES **adapters) {
ULONG len;
int try;
*adapters = NULL;
adapterInfo = (IP_ADAPTER_ADDRESSES *) malloc(BUFF_SIZE);
if (adapterInfo == NULL) {
JNU_ThrowByName(env, "java/lang/OutOfMemoryError",
@ -233,8 +235,6 @@ IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) {
return ret;
}
static int ipinflen = 2048;
/*
*/
int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
@ -242,23 +242,18 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
int ret, flags;
MIB_IPADDRTABLE *tableP;
IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL;
ULONG len=ipinflen, count=0;
ULONG count=0;
netif *nif=NULL, *dup_nif, *last=NULL, *loopif=NULL, *curr;
int tun=0, net=0;
*netifPP = NULL;
/*
* Get the IPv4 interfaces. This information is the same
* as what previous JDK versions would return.
*/
ret = enumInterfaces(env, netifPP);
if (ret == -1) {
if (ret < 0) {
return -1;
} else if( ret == -2){
if ((*env)->ExceptionCheck(env)) {
(*env)->ExceptionClear(env);
}
} else {
count = ret;
}
@ -274,20 +269,23 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
// Retrieve IPv4 addresses with the IP Helper API
curr = *netifPP;
ret = lookupIPAddrTable(env, &tableP);
if (ret < 0) {
if (ret == -1) {
free_netif(*netifPP);
return -1;
} else if (ret == -2) {
// Clear the exception and continue.
if ((*env)->ExceptionCheck(env)) {
(*env)->ExceptionClear(env);
}
tableP = NULL;
}
while (curr != NULL) {
netaddr *netaddrP;
ret = enumAddresses_win_ipaddrtable(env, curr, &netaddrP, tableP);
if (ret == -1) {
if (ret < 0) {
free_netif(*netifPP);
free(tableP);
return -1;
} else if (ret == -2) {
if ((*env)->ExceptionCheck(env)) {
(*env)->ExceptionClear(env);
}
break;
} else{
curr->addrs = netaddrP;
curr->naddrs += ret;
@ -301,7 +299,8 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
flags |= GAA_FLAG_INCLUDE_PREFIX;
ret = getAdapters (env, flags, &adapters);
if (ret != ERROR_SUCCESS) {
goto err;
free_netif(*netifPP);
return -1;
}
/* Now get the IPv6 information. This includes:
@ -340,6 +339,9 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
*/
nif->ipv6Index = ptr->Ipv6IfIndex;
c = getAddrsFromAdapter(ptr, &nif->addrs);
if (c == -1) {
goto err;
}
nif->naddrs += c;
break;
}
@ -378,6 +380,7 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
nif->name = malloc (strlen(newname)+1);
nif->displayName = malloc (wcslen(ptr->FriendlyName)*2+2);
if (nif->name == 0 || nif->displayName == 0) {
free(nif);
goto err;
}
strcpy (nif->name, newname);
@ -390,7 +393,11 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
nif->ipv6Index = ptr->Ipv6IfIndex;
nif->hasIpv6Address = TRUE;
last->next = nif;
if (last) {
last->next = nif;
} else {
*netifPP = nif;
}
last = nif;
count++;
c = getAddrsFromAdapter(ptr, &nif->addrs);
@ -585,6 +592,8 @@ static jobject createNetworkInterfaceXP(JNIEnv *env, netif *ifs)
if ((*env)->ExceptionCheck(env)) {
(*env)->ExceptionClear(env);
}
netaddrCount = 0;
netaddrPToFree = NULL;
}
netaddrP = netaddrPToFree;
}
@ -826,7 +835,7 @@ JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll_XP
(JNIEnv *env, jclass cls)
{
int count;
netif *ifList = NULL, *curr;
netif *ifList, *curr;
jobjectArray netIFArr;
jint arr_index;