JDK-4921816 : InetAddress.isReachable returns true for unreachable addresses
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2003-09-12
  • Updated: 2004-09-20
  • Resolved: 2004-09-20
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 b22Fixed
Related Reports
Relates :  
Description
Name: akR10050			Date: 09/12/2003



InetAddress.isReachable(int) returns true for unreachable addresses.

Here is the testcase:
------------------- Test31.java ---------------------

import java.net.InetAddress;
import java.io.IOException;

public class Test31 {
    public static void main(String[] args) {
        /* STEP 1: get an unreachable host. */
        InetAddress ia = null;
        try {
            ia = InetAddress.getByName("2.2.2.1");
        } catch (IOException ioe) {
            System.err.println("WRONG: " + ioe);
        }

        /* STEP 2: declare the timeout value. 5 seconds is more than enough to
         * access a host on LAN. */
        int timeout = 5;

        /* STEP 3: test reachability of the host. */
        try {
            if ( ia.isReachable(timeout) ) {
                System.err.println("WRONG: true returned with timeout value "
                        + timeout + " for host " + ia);
            } else {
                System.err.println("CORRECT: false returned");
            }
        } catch (IOException ioe) {
            System.err.println("WRONG: " + ioe);
        }
    }
}
-----------------------------------------------------

The following is the output running the test:

----------------- sample output ---------------------

$ java -version
java version "1.5.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b18)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b18, mixed mode)

$ java Test31
WRONG: true returned with timeout value 5 for host /2.2.2.1

$ ping 2.2.2.1 5
no answer from 2.2.2.1

-----------------------------------------------------

This output was achieved on a solaris box (therefore ping command is one of
solaris). However, isReachable(int) exposes the same behaviour on other
platforms.

======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger-beta FIXED IN: tiger-beta INTEGRATED IN: tiger-b22 tiger-beta VERIFIED IN: 1.5.0_01
22-09-2004

EVALUATION Not a bug. The problem is in the test. isReachable() is not ping. As it says in it's documentation depending on permissions it will try to connect to the TCP port 7 or do an ICMP request. Since the test doesn't have permission to create raw sockets (needs to be root), it can't use ICMP, therefore attempts to connect to port 7. The result is a "connection refused" which means: the machine is there but refuses connection on that particular port. That's why it returns true. This can be verified on Solaris with the following test: $ telnet 2.2.2.1 7 Trying 2.2.2.1... telnet: Unable to connect to remote host: Connection refused and a snoop shows: # snoop 2.2.2.1 port 7 Using device /dev/hme (promiscuous mode) hoth -> 2.2.2.1 ECHO C port=47081 2.2.2.1 -> hoth ECHO R port=47081 Bottom line, 2.2.2.1 does exist and shouldn't be used as an asummed non-existing machine. ###@###.### 2003-09-12 On second examination there is a bug in isReachable that can produce a false positive, at least on Solaris. re-opening the bug and will fix for tiger. ###@###.### 2003-09-12 The false positive is a Solaris only issue. getsockopt, for some reasons, fails to set errno to EINPROGRESS, but sets it to 0 which, normally means the connection has been established. Solution is to not trust errno when timeouts occurs. ###@###.### 2003-09-12 ========================================= After the fix isReachable throws ConnectException due to unreachability of the host instead of returning false silently. Attached is an example demonstrating the behaviour. ###@###.### 2003-10-22 Trying to ping 255.255.255.255!!!! It's a broadcast address. and there is already a bug filed against the ConnectException in isReachable (see 4938744). ###@###.### 2003-10-24
24-10-2003