Skip to content

8275319 java.net.NetworkInterface throws java.lang.Error instead of SocketException #5956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions src/java.base/windows/native/libnet/NetworkInterface.c
Original file line number Diff line number Diff line change
@@ -112,7 +112,7 @@ MIB_IFROW *getIF(jint index) {
return NULL;

count = GetIfTable(tableP, &size, TRUE);
if (count == ERROR_INSUFFICIENT_BUFFER || count == ERROR_BUFFER_OVERFLOW) {
if (count == ERROR_INSUFFICIENT_BUFFER) {
MIB_IFTABLE* newTableP = (MIB_IFTABLE *)realloc(tableP, size);
if (newTableP == NULL) {
free(tableP);
@@ -187,7 +187,7 @@ int enumInterfaces(JNIEnv *env, netif **netifPP)
}

ret = GetIfTable(tableP, &size, TRUE);
if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW) {
if (ret == ERROR_INSUFFICIENT_BUFFER) {
MIB_IFTABLE * newTableP = (MIB_IFTABLE *)realloc(tableP, size);
if (newTableP == NULL) {
free(tableP);
@@ -200,9 +200,16 @@ int enumInterfaces(JNIEnv *env, netif **netifPP)

if (ret != NO_ERROR) {
free(tableP);

JNU_ThrowByName(env, "java/lang/Error",
"IP Helper Library GetIfTable function failed");
switch (ret) {
case ERROR_INVALID_PARAMETER:
JNU_ThrowInternalError(env, "IP Helper Library GetIfTable function failed: invalid parameter");
break;
default:
SetLastError(ret);
JNU_ThrowByNameWithMessageAndLastError(env, JNU_JAVANETPKG "SocketException",
"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;
@@ -308,8 +315,7 @@ int enumInterfaces(JNIEnv *env, netif **netifPP)
// it should not fail, because we have called it once before
if (MultiByteToWideChar(CP_OEMCP, 0, ifrowP->bDescr,
ifrowP->dwDescrLen, curr->displayName, wlen) == 0) {
JNU_ThrowByName(env, "java/lang/Error",
"Cannot get multibyte char for interface display name");
JNU_ThrowInternalError(env, "Cannot get multibyte char for interface display name");
free_netif(netifP);
free(tableP);
free(curr->name);
@@ -374,7 +380,7 @@ int lookupIPAddrTable(JNIEnv *env, MIB_IPADDRTABLE **tablePP)
}

ret = GetIpAddrTable(tableP, &size, FALSE);
if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW) {
if (ret == ERROR_INSUFFICIENT_BUFFER) {
MIB_IPADDRTABLE * newTableP = (MIB_IPADDRTABLE *)realloc(tableP, size);
if (newTableP == NULL) {
free(tableP);
@@ -389,8 +395,16 @@ int lookupIPAddrTable(JNIEnv *env, MIB_IPADDRTABLE **tablePP)
if (tableP != NULL) {
free(tableP);
}
JNU_ThrowByName(env, "java/lang/Error",
"IP Helper Library GetIpAddrTable function failed");
switch (ret) {
case ERROR_INVALID_PARAMETER:
JNU_ThrowInternalError(env, "IP Helper Library GetIpAddrTable function failed: invalid parameter");
break;
default:
SetLastError(ret);
JNU_ThrowByNameWithMessageAndLastError(env, JNU_JAVANETPKG "SocketException",
"IP Helper Library GetIpAddrTable function failed");
break;
}
// this different error code is to handle the case when we call
// GetIpAddrTable in pure IPv6 environment
return -2;
74 changes: 33 additions & 41 deletions src/java.base/windows/native/libnet/NetworkInterface_winXP.c
Original file line number Diff line number Diff line change
@@ -110,27 +110,24 @@ int getAdapters (JNIEnv *env, int flags, IP_ADAPTER_ADDRESSES **adapters) {

if (ret != ERROR_SUCCESS) {
free (adapterInfo);
if (ret == ERROR_INSUFFICIENT_BUFFER) {
JNU_ThrowByName(env, "java/lang/Error",
"IP Helper Library GetAdaptersAddresses function failed "
"with ERROR_INSUFFICIENT_BUFFER");
} else if (ret == ERROR_ADDRESS_NOT_ASSOCIATED ) {
JNU_ThrowByName(env, "java/lang/Error",
"IP Helper Library GetAdaptersAddresses function failed "
"with ERROR_ADDRESS_NOT_ASSOCIATED");
} else {
char error_msg_buf[100];
int _sr;
_sr = _snprintf_s(error_msg_buf, sizeof(error_msg_buf),
_TRUNCATE, "IP Helper Library GetAdaptersAddresses "
"function failed with error == %d", ret);
if (_sr != -1) {
JNU_ThrowByName(env, "java/lang/Error", error_msg_buf);
} else {
JNU_ThrowByName(env, "java/lang/Error",
"IP Helper Library GetAdaptersAddresses function failure");
}
switch (ret) {
case ERROR_INVALID_PARAMETER:
JNU_ThrowInternalError(env, "IP Helper Library GetAdaptersAddresses function failed: invalid parameter");
break;
case ERROR_NOT_ENOUGH_MEMORY:
JNU_ThrowOutOfMemoryError(env, "IP Helper Library GetAdaptersAddresses function failed: not enough memory");
break;
case ERROR_NO_DATA:
// not an error
*adapters = NULL;
return ERROR_SUCCESS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mapping ERROR_NO_DATA to ERROR_SUCCESS is probably correct here. Could this explain bug reports that seem to be from configurations with no IP addresses plumbed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose it could. But in order to get ERROR_NO_DATA here one would need to disable loopback interface. I couldn't find how to do that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There has been one or two reports from configurations that appear to have no interface or no IP addresses. I don't think we've been able to create those configurations to duplicate. In any case, treat NO_DATA as SUCCESS seems correct here.

default:
SetLastError(ret);
JNU_ThrowByNameWithMessageAndLastError(env, JNU_JAVANETPKG "SocketException",
"IP Helper Library GetAdaptersAddresses function failed");
break;
}

return -1;
}
*adapters = adapterInfo;
@@ -179,26 +176,21 @@ IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) {

if (val != ERROR_SUCCESS) {
free (adapterInfo);
if (val == ERROR_INSUFFICIENT_BUFFER) {
JNU_ThrowByName(env, "java/lang/Error",
"IP Helper Library GetAdaptersAddresses function failed "
"with ERROR_INSUFFICIENT_BUFFER");
} else if (val == ERROR_ADDRESS_NOT_ASSOCIATED ) {
JNU_ThrowByName(env, "java/lang/Error",
"IP Helper Library GetAdaptersAddresses function failed "
"with ERROR_ADDRESS_NOT_ASSOCIATED");
} else {
char error_msg_buf[100];
int _sr;
_sr = _snprintf_s(error_msg_buf, sizeof(error_msg_buf),
_TRUNCATE, "IP Helper Library GetAdaptersAddresses function failed "
"with error == %d", val);
if (_sr != -1) {
JNU_ThrowByName(env, "java/lang/Error", error_msg_buf);
} else {
JNU_ThrowByName(env, "java/lang/Error",
"IP Helper Library GetAdaptersAddresses function failure");
}
switch (val) {
case ERROR_INVALID_PARAMETER:
JNU_ThrowInternalError(env, "IP Helper Library GetAdaptersAddresses function failed: invalid parameter");
break;
case ERROR_NOT_ENOUGH_MEMORY:
JNU_ThrowOutOfMemoryError(env, "IP Helper Library GetAdaptersAddresses function failed: not enough memory");
break;
case ERROR_NO_DATA:
// not an error
break;
default:
SetLastError(val);
JNU_ThrowByNameWithMessageAndLastError(env, JNU_JAVANETPKG "SocketException",
"IP Helper Library GetAdaptersAddresses function failed");
break;
}
return NULL;
}
@@ -237,7 +229,7 @@ static int ipinflen = 2048;
*/
int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
{
DWORD ret, flags;
int ret, flags;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks right but I can't relate this to your comment about the crash.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me try to explain this clang-style:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, I hadn't spotted the broken code that tests if loopupIPAddrTable fails.

MIB_IPADDRTABLE *tableP;
IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL;
ULONG len=ipinflen, count=0;