-
Bug
-
Resolution: Fixed
-
P4
-
8
-
b19
java.net.InetAddress has a getLocalHost() public API. The implementation of this method first determines the local host name, which on *nix translates to the "gethostname()" native library function call. For the returned local host name, the implementation of getLocalHost() then calls java.net.spi.InetAddressResolver.lookupByName(...) to resolve the InetAddress(es) for that name and then uses the first value from the Stream of returned InetAddress(es). This InetAddress is then returned by the InetAddress.getLocalHost() method.
The platform resolver implementation of the java.net.spi.InetAddressResolver.lookupByName(...) on *nix first does a "getaddrinfo()" native library function call. On macosx, if/when that getaddrinfo() call fails, then there is a specific additional piece of code that runs to determine the addresses for the local host name. This additional code is implemented in the "lookupIfLocalhost()" function and was introduced several releases back through https://bugs.openjdk.org/browse/JDK-7180557 (RFR mail: https://mail.openjdk.org/pipermail/net-dev/2013-September/007211.html).
The implementation of "lookupIfLocalhost()" calls the "getifaddrs()" native library function on macos and then iterates over each returned interface address to determine whether to use that interface address or to skip it. "getifaddrs()" can (and does) return interface addresses that may belong to an interface which is not UP. The current implementation in lookupIfLocalhost() doesn't check if the interface is UP and as a result can (and does) end up including addresses which may belong to an interface which is not UP. On some occasions, it has been noticed that the array returned from this lookupIfLocalhost() will have the address whose interface is not UP, as the first element of the array. Effectively what this means is that the address returned by InetAddress.getLocalHost() on macos is susceptible to returning an InetAddress which belongs to an interface which is not UP.
A subsequent use of that InetAddress can, and has shown on certain hosts, to lead to Java SE networking APIs failing with "Network is down" error.
For example, the following test program (Test.java) can run into an "Network is down" error on macos:
import java.net.*;
public class Test {
public static void main(final String[] args) throws Exception {
final InetAddress destAddr = InetAddress.getLocalHost();
final Socket socket = new Socket(destAddr, 12345); // arbitrary port, doesn't matter for this test
System.out.println("done");
}
}
When run as:
java -Djava.net.preferIPv6Addresses=true Test.java
may lead to the following exception on certain hosts:
Exception in thread "main" java.net.SocketException: Network is down
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:535)
at java.base/sun.nio.ch.Net.connect(Net.java:524)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:574)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:282)
at java.base/java.net.Socket.connect(Socket.java:665)
at java.base/java.net.Socket.connect(Socket.java:603)
at java.base/java.net.Socket.<init>(Socket.java:470)
at java.base/java.net.Socket.<init>(Socket.java:301)
at Test.main(Test.java:6)
The JDK's macos specific implementation in lookupIfLocalhost() should be fixed to not return addresses of interfaces that are not UP.
The platform resolver implementation of the java.net.spi.InetAddressResolver.lookupByName(...) on *nix first does a "getaddrinfo()" native library function call. On macosx, if/when that getaddrinfo() call fails, then there is a specific additional piece of code that runs to determine the addresses for the local host name. This additional code is implemented in the "lookupIfLocalhost()" function and was introduced several releases back through https://bugs.openjdk.org/browse/JDK-7180557 (RFR mail: https://mail.openjdk.org/pipermail/net-dev/2013-September/007211.html).
The implementation of "lookupIfLocalhost()" calls the "getifaddrs()" native library function on macos and then iterates over each returned interface address to determine whether to use that interface address or to skip it. "getifaddrs()" can (and does) return interface addresses that may belong to an interface which is not UP. The current implementation in lookupIfLocalhost() doesn't check if the interface is UP and as a result can (and does) end up including addresses which may belong to an interface which is not UP. On some occasions, it has been noticed that the array returned from this lookupIfLocalhost() will have the address whose interface is not UP, as the first element of the array. Effectively what this means is that the address returned by InetAddress.getLocalHost() on macos is susceptible to returning an InetAddress which belongs to an interface which is not UP.
A subsequent use of that InetAddress can, and has shown on certain hosts, to lead to Java SE networking APIs failing with "Network is down" error.
For example, the following test program (Test.java) can run into an "Network is down" error on macos:
import java.net.*;
public class Test {
public static void main(final String[] args) throws Exception {
final InetAddress destAddr = InetAddress.getLocalHost();
final Socket socket = new Socket(destAddr, 12345); // arbitrary port, doesn't matter for this test
System.out.println("done");
}
}
When run as:
java -Djava.net.preferIPv6Addresses=true Test.java
may lead to the following exception on certain hosts:
Exception in thread "main" java.net.SocketException: Network is down
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:535)
at java.base/sun.nio.ch.Net.connect(Net.java:524)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:574)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:282)
at java.base/java.net.Socket.connect(Socket.java:665)
at java.base/java.net.Socket.connect(Socket.java:603)
at java.base/java.net.Socket.<init>(Socket.java:470)
at java.base/java.net.Socket.<init>(Socket.java:301)
at Test.main(Test.java:6)
The JDK's macos specific implementation in lookupIfLocalhost() should be fixed to not return addresses of interfaces that are not UP.
- caused by
-
JDK-7180557 InetAddress.getLocalHost throws UnknownHostException on java7u5 on OSX
-
- Closed
-
- links to
-
Commit(master) openjdk/jdk/4c3c2b32
-
Review(master) openjdk/jdk/24653