Summary
Refresh the native parts of NetworkInterface class on Windows
Problem
There are currently 2 distinct functional implementations. One is based on pre-WinXP APIs, the other on is based on WinXP APIs. The former is used when user defines system property java.net.preferIPv4Stack=true
and can't deal with IPv6, the latter is slow and hard to use. None of them provides persistent interface names; names are generated based on interface position in iteration order, and can change when the application is running.
Solution
Reimplement NetworkInterface using the new APIs introduced in Windows Vista, and use persistent interface names offered by the system.
The current implementation assigns names based on interface type and position in iteration order:
switch (ifrowP->dwType) {
case MIB_IF_TYPE_ETHERNET:
_snprintf_s(dev_name, 8, _TRUNCATE, "eth%d", eth++);
break;
case MIB_IF_TYPE_TOKENRING:
_snprintf_s(dev_name, 8, _TRUNCATE, "tr%d", tr++);
break;
...
This produces names like eth0
, ppp0
or wlan0
. All loopback interfaces were merged under the name lo
, which was a mixed blessing, see JDK-6798979.
The new implementation assigns names based on system-provided interface identifier (LUID):
// set the NetworkInterface's name
apiRetVal = ConvertInterfaceLuidToNameW(
&(ifRow->InterfaceLuid), ifName, NDIS_IF_MAX_BUFFER_SIZE);
This produces names like ethernet_32768
, ppp_32768
, wireless_32768
or loopback_0
. There's no overlap between the old and the new namespace.
The existing naming scheme is not predictable (except for the lo
interface), so it's unlikely that existing code stores interface names and reuses them. The more common use case is that the code enumerates all interfaces and picks instances out based on other characteristics like the interface address. That use case won't be affected by this change.
The interface names are used in the following places:
- Method NetworkInterface.getByName accepts the interface name and returns a NetworkInterface. It returns null if there's no interface with the specified name.
- Methods InetAddress.getByName and getAllByName resolve interface names when passed a scoped IPv6 address like "[fe80:0:0:0:ece8:3c63:68f9:a95b%wireless_32768]". The methods will throw when they receive an unrecognized interface name.
- Deserialization of Inet6Address will reset the scope to default if the serialized scope refers to an interface that cannot be resolved.
Other user-visible changes include:
- System interfaces are enumerated in a different order.
- Certain NetworkInterface methods like
isUp
,isPointToPoint
,isLoopback
,getHardwareAddress
,getMTU
andsupportsMulticast
may return different values on some interfaces. In the current XP implementation if you call these methods on a filter interface, you get bogus results because the code can't find the interface. The new return values reflect the interface state more adequately.
Specification
This is a behavioral change only; there is no update to the specification.
- csr of
-
JDK-8302659 Modernize Windows native code for NetworkInterface
- Resolved