JDK-6601686 : InetAddress.isReachable(timeout) may not return after timout milliseconds
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 6u2
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris
  • CPU: generic
  • Submitted: 2007-09-06
  • Updated: 2010-12-06
  • Resolved: 2010-01-11
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 JDK 6 JDK 7
5.0u14Fixed 6u4Fixed 7 b21Fixed
Description
FULL PRODUCT VERSION :
  java version "1.6.0_01"
  Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
  Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)

  This issue is also reproducible with Java SE 5, and Open JDK 7 b18.

ADDITIONAL OS VERSION INFORMATION :
   Solaris 10, but should be reproducible on any unix system.

EXTRA RELEVANT SYSTEM CONFIGURATION :
  MUST run as root. You must be root to have priviliges to create raw sockets
  over which to send the ICMP ECHO. If you are not root then this problem
  cannot be reproduced.

A DESCRIPTION OF THE PROBLEM :
  A java process that continuously loops for a reachable host will impact on the 
  timeout of another java process that is in an isReachable call. That is, the
  call can be observed to not timeout after the said timeout time has elapsed. 

REPRODUCIBILITY :
  This bug can be reproduced always.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
  With root priviliges run:
   # java Loop <a reachable host>

   # java TimeoutTest <an unreachable host, e.g. 1.1.1.1>

   TimeoutTest will never exit!


---------- BEGIN SOURCE  ----------
/**
 * Loop.java
 */
class Loop {
    public static void main(String[] args) throws Exception {

        InetAddress addr = InetAddress.getByName(args[0]);
        while( true ) {
            addr.isReachable(1000);
        }
    }
}

/**
 * TimeoutTest.java
 */
class TimeoutTest {
    public static void main(String[] args) throws Exception {
        InetAddress addr = InetAddress.getByName(args[0]);
        System.out.println("Start (timeout 5sec)");

        if (addr.isReachable(5000)) {
            System.out.println("isReachable() : true");
        } else {
            System.out.println("isReachable() : false");
        }
        System.out.println("Finish");
    }
}
---------- END SOURCE ----------

Comments
SUGGESTED FIX src/solaris/native/java/net/net_util_md.c @@ -1318,11 +1318,11 @@ * NET_WAIT_READ, NET_WAIT_WRITE & NET_WAIT_CONNECT. * * The function will return when either the socket is ready for one * of the specified operation or the timeout expired. * - * It returns the time left from the timeout, or -1 if it expired. + * It returns the time left from the timeout (possibly 0), or -1 if it expired. */ jint NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout) { @@ -1371,14 +1371,10 @@ errno = 0; read_rv = NET_Select(fd+1, &rd, &wr, &ex, &t); } #endif - if (read_rv > 0) { - break; - } - newTime = JVM_CurrentTimeMillis(env, 0); timeout -= (newTime - prevTime); if (timeout <= 0) { return read_rv > 0 ? 0 : -1; }
07-09-2007

EVALUATION Both the ping4 and ping6 implementations use the private native function, NET_Wait, to poll for incoming events on the socket. The Net_Wait function will return when either the socket is ready for one of the specified events or the timeout has expired. It is specified to return the time left from the timeout (possibly 0) or -1 if it has expired, but currently if an event has been received it returns the timeout as passed into the function. This leads to the timeout in both the IPv4 and IPv6 ping implementations to never be decremented if there are any incoming ICMP packets. This is as a consequence of the raw socket seeing all ICMP packets received by the interface.
06-09-2007