United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6599750 InetAddress.isReachable implementation not completely thread safe
JDK-6599750 : InetAddress.isReachable implementation not completely thread safe

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

Related Reports
Backport:
Backport:
Relates:

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 :
  Even with the fix for 6595834 the return value of InetAddress.isReachable() may
  represent the results of another thread's call to isReachable. The reason for this
  is that the change for 6595834 uses a random 16 bit value for the sequence number. If
  you have one thread blocked in an isReachable call (to an unreachable host) with a
  long timeout, another thread in a loop calling isReachable on a reachable host, it is
  possible that the sequence number may repeat itself and that the thread in the loop may
  eventually use a sequence number the same as the one used by the blocked isReachable
  call. This will result in the isReachable call on the unreachable host returning true.

REPRODUCIBILITY :
  This bug can be reproduced always.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
---------- BEGIN SOURCE ----------
import java.net.*;
import java.io.IOException;

class LoopIsReachable {
    static volatile int count;
    static volatile boolean found = false;

    static byte[] ipv4LoopbackAddr = new byte[] {(byte)127, (byte)0, (byte)0, (byte)1};
    static byte[] unReachableAddr =  new byte[] {(byte)1, (byte)1, (byte)1, (byte)1};

    public static void main(String args[]) {
        Thread thread = new Thread(new UnReachableRunnable());
        thread.start();

        try {
            InetAddress ia = InetAddress.getByAddress(ipv4LoopbackAddr);
            while (!found) {
                ia.isReachable(60 * 1000);
                count++;
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    static class UnReachableRunnable implements Runnable {
        public void run() {
            try {
                InetAddress ia = InetAddress.getByAddress(unReachableAddr);

                if(ia.isReachable(60 * 1000) == true) {
                    System.out.println(ia  + " is reachable! It should NOT" +
					" be reachable.");
                    found = true;
                } else  {
                    System.out.println(ia  + " is NOT reachable, OK");
                }
            } catch(IOException e) {
                e.printStackTrace();
            }
            System.out.println("It took " + count + " iterations to find the" +
				" unreachable address");
        }
    }
}
---------- END SOURCE ----------

                                    

Comments
EVALUATION

As well as (or possibly instead of) checking the sequence number we should also check the senders address. The IP packet will contain the sender address of the ICMP ECHO reply.
                                     
2007-08-31
EVALUATION

We no longer check the sequence number in the ICMP ECHO reply, this effectively backouts the changes made by 6595834. We now simply check the process id (pid) and the senders address. 

The reason for removing the sequence number check is that any reply from the host being pinged, destined for our process, is sufficient to determine that it is reachable.
                                     
2007-09-06



Hardware and Software, Engineered to Work Together