United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6601686 InetAddress.isReachable(timeout) may not return after timout milliseconds
JDK-6601686 : InetAddress.isReachable(timeout) may not return after timout milliseconds

Details
Type:
Bug
Submit Date:
2007-09-06
Status:
Closed
Updated Date:
2010-12-06
Project Name:
JDK
Resolved Date:
2010-01-11
Component:
core-libs
OS:
solaris
Sub-Component:
java.net
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6u2
Fixed Versions:

Related Reports
Backport:
Backport:

Sub Tasks

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
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.
                                     
2007-09-06
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;
         }
                                     
2007-09-07



Hardware and Software, Engineered to Work Together