Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6599750

InetAddress.isReachable implementation not completely thread safe

XMLWordPrintable

    • b21
    • generic
    • solaris_10
    • Verified

        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 ----------

              chegar Chris Hegarty
              chegar Chris Hegarty
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: