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

(so) Failed non-blocking connects not reported or reported incorrectly (win)

XMLWordPrintable

    • hopper
    • x86
    • windows_2000
    • Verified



      Name: nt126004 Date: 03/11/2002


      FULL PRODUCT VERSION :
      java version "1.4.0-rc"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-rc-b91)
      Java HotSpot(TM) Server VM (build 1.4.0-rc-b91, mixed mode)

      Also in:
      java version "1.4.0-rc"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-rc-b91)
      Java HotSpot(TM) Client VM (build 1.4.0-rc-b91, mixed mode)

      FULL OPERATING SYSTEM VERSION :
      Microsoft Windows 2000 [Version 5.00.2195]

      ADDITIONAL OPERATING SYSTEMS :

        Bug has also been observed, though in different form, on
      Windows XP, version information is:
      Microsoft Windows XP [Version 5.1.2600]


      A DESCRIPTION OF THE PROBLEM :
      When issuing a non-blocking client-side connect using
      SocketChannel and Selector, with the SocketChannel
      registered for OP_CONNECT on the selector, if the host
      specified in the connect is either non-existent or not
      accepting connections (but is resolvable), the following is
      seen:

      - On Windows 2000 the selector never wakes up again with
      the SelectionKey for the connecting channel selected. The
      correct behavior would be that upon TCP failing the
      connection, the selector would wakeup with that selection
      key selected, marked isConnectable, and finishConnect would
      then throw an exception such as NoRouteToHostException or
      ConnectException. What in fact happens though is that the
      aforementioned connect attempt is never heard from again.

      - On Windows XP the selector does in fact wake up, and
      finishConnect() completes successfully. This is in some
      ways even worse, because you now think you have a valid
      connection to a remote host that doesn't even exist. The
      connection is furthermore even successfully writable, all
      to a non-existent host.

      In both cases I tested both attempting to connect to hosts
      that were real but not accepting connections (such as
      another machine on the same LAN), and to unassigned
      addresses (in my case, I used 192.168.0.25), a private
      address I know is unassigned, verified by attempting to
      ping that address.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      The attached source code is for a class called
      TestNIOClient, which takes a hostname or dotted-decimal IP
      address as a command line-parameter. Run it four times,
      with the specified argument as follows in each case:

      1. Specify the hostname of a known good web server. Try
      www.google.com or java.sun.com
      2. Specify an invalid hostname that you know won't
      resolve. Try www.bogus.com
      3. Specify a hostname of a device that is resolvable and
      real, but is not running a web server or listening at port
      80.
      4. Specify a hostname or IP address that is resolvable, but
      does not correspond to an actual physical device that could
      be contacted. Try a private unassigned address. I used
      192.168.0.25, but what you choose will have to depend on
      your network configuration.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      1. Works correctly. Expected and actual result is:
      Got event for our selection key.
      Successful connect.
      SUCCESS! Entire buffer contents were sent.

      2. Works correctly. Expected and actual result is:
      Connection failed:
      java.net.UnknownHostException: www.bogus.com
              at java.net.InetAddress.getAllByName0(InetAddress.java:920)
              at java.net.InetAddress.getAllByName0(InetAddress.java:890)
              at java.net.InetAddress.getAllByName(InetAddress.java:884)
              at java.net.InetAddress.getByName(InetAddress.java:814)
              at TestNIOClient.run(TestNIOClient.java:27)
              at java.lang.Thread.run(Thread.java:536)

      3. Fails differently on Win 2000 and Win XP. Expected
      result on both platforms is that after a short interval,
      the selector wakes up, and finishConnect() throws a
      java.net.ConnnectException.

      Actual results:
      -Win 2K: No response ever. Program output as follows:
      Elapsed time without response: 30 seconds.
      Elapsed time without response: 60 seconds.
      Elapsed time without response: 90 seconds.
      Elapsed time without response: 120 seconds.
      Elapsed time without response: 150 seconds.
      Elapsed time without response: 180 seconds.

      And so on forever. I have let this go as long as 17000
      seconds just to see if it might eventually give up.

      - On Win XP, false successful connect is seen. Output is:
      Got event for our selection key.
      Successful connect.
      SUCCESS! Entire buffer contents were sent.

      4. Fails differently on Win 2K and Windows XP. Expected
      bahavior is that after a short interval, the selector wakes
      up, and finishConnect() throws a java.net.NoRouteToHostException.

      Actual behavior on each platform is as in 3.

      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.nio.*;
      import java.nio.channels.*;
      import java.net.InetSocketAddress;
      import java.net.InetAddress;
      import java.util.*;

      public class TestNIOClient implements Runnable
      {
          private Selector selector;
          private SocketChannel sc;
          private SelectionKey sk;
          private String hostname;

          private static final long INCREMENTAL_DELAY = 30L * 1000L; // Wakeup
      interval of 30 seconds (30,000 ms)

          private TestNIOClient(String hostname)
          {
              this.hostname = hostname;

              new Thread(this).start();
          }

          public void run()
          {
              try
              {
                  InetSocketAddress isa = new InetSocketAddress(InetAddress.getByName
      (hostname), 80);

                  sc = SocketChannel.open();
                  sc.configureBlocking(false);

                  selector = Selector.open();
                  sk = sc.register(selector, SelectionKey.OP_CONNECT);
                  if(sc.connect(isa))
                  {
                      System.out.println("Connected immediately!");
                      sc.close();
                      selector.close();
                      return;
                  }
                  else
                  {
                      ByteBuffer buf = ByteBuffer.allocateDirect(100);
                      buf.asCharBuffer().put(new String("The quick brown fox jumped
      over the lazy dog.").toCharArray());
                      buf.flip();
                      long startTime = System.currentTimeMillis();
                      while(true)
                      {
                          selector.select(INCREMENTAL_DELAY);

                          Set selectedKeys = selector.selectedKeys();

                          if(selectedKeys.isEmpty())
                          {
                              System.out.println("Elapsed time without response: " +
                                                 (System.currentTimeMillis() -
      startTime) / 1000L + " seconds.");
                          }
                          else if(!selectedKeys.contains(sk))
                          {
                              System.out.println("Got event about selection key other
      than one we registered!");
                          }
                          else
                          {
                              System.out.println("Got event for our selection key.");
                              if(sk.isConnectable())
                              {
                                  if(sc.finishConnect())
                                  {
                                      if(sc.isConnected())
                                      {
                                          System.out.println("Successful connect.");
                                          sk.interestOps(SelectionKey.OP_WRITE);

                                          sc.write(buf);
                                      }
                                      else
                                      {
                                          System.out.println("Finish connect
      completed, but socket is not actually connected.");
                                      }
                                  }
                                  else
                                  {
                                      System.out.println("Selection key incorrectly
      indicated that socket channel was connectable.");
                                  }
                              }
                              if(sk.isWritable() && (buf.remaining() > 0))
                              {
                                  sc.write(buf);
                              }
                              if(buf.remaining() == 0)
                              {
                                  System.out.println("SUCCESS! Entire buffer
      contents were sent.");
                                  sc.close();
                                  selector.close();
                                  return;
                              }
                          }

                          selectedKeys.clear();
                      }
                  }
              }
              catch(Exception e)
              {
                  System.out.println("Connection failed:");
                  e.printStackTrace();
              }
          }

          public static void main(String args[])
          {
              if(args.length > 0)
              {
                  new TestNIOClient(args[0]);
              }
              else
              {
                  System.out.println("\tUsage: TestNIOClient <hostname>");
              }
          }
      }
      ---------- END SOURCE ----------
      (Review ID: 139754)
      ======================================================================

            mmcclosksunw Michael Mccloskey (Inactive)
            nthompsosunw Nathanael Thompson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: