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

Socket creation on Windows takes a long time if web proxy does not have a DNS entry

    Details

    • Subcomponent:
    • Introduced In Version:
      5.0
    • Resolved In Build:
      b03
    • CPU:
      x86
    • OS:
      windows_xp
    • Verification:
      Verified

      Backports

        Description

        When creating URLs in an applet I experience 5 second delays. This is because the JVM is attempting to do a DNS lookup of my webproxy but my webproxy doesn't have a DNS entry. This is a fairly typical setup for corporate web proxies.

        The problem is in sun.net.www.HttpClient.priviledgedOpenServer() which makes a call to InetSocketAddress.getHostName().

        This is a new issue that has appered in 1.5.0. I can't see any reason why the JVM would need to resolve the name of the proxy. So I think this is a bug.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        1. Configure your web browser to use an HTTP proxy which you specify by ip and port (not by hostname).
        2. Host the applet below on a webside accessed through the web proxy.
        3. Arrange some method of detecting network lookups.
        4. Load the applet in the browser

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        I'd expect the URL connections to be instantanious. I'd expect no name lookups to take place.
        ACTUAL -
        Name lookups of the web proxy take place. On an incorrectly configured system this causes the URL connection to take 4 seconds or longer.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.applet.Applet;
        import java.io.IOException;
        import java.net.URL;
        import java.net.URLConnection;

        public class Minimal extends Applet {

        public void start()
        {
        try {
        for (int i = 0; i < 5; i++) {

        long time_start = System.currentTimeMillis();
        URLConnection uc;
        URL url = new URL("http://foo.com");
        uc = url.openConnection();
        uc.connect();
        long time_end = System.currentTimeMillis();
        System.out.println("Time to open socket (ms): " + (time_end - time_start));
        }
        } catch (IOException e) {
        System.out.println(e);
        }
        }

        }

        This issue is separate to 5092063 even though it looks similar. I have
        recently tested the 1.5.0_08 JVM and the issue is still there.

        The good news is, thanks to SUN's open source code policy, I can tell
        you exactly where the bug is: It is in sun/net/www/HttpClient.java in
        the privilegedOpenServer() method. In here there is a call to
        server.getHostName() which forces the InetSocketAddr object to resolve
        its name (if it hasn't done so already).

        Backtracking a little... The problem is when someone is using a java
        applet to connect through a web proxy. On some networks the proxy has
        been specified by ip address but does not resolve into a host name (I
        reproduce this by using a Perl proxy for an ipaddress which doesn't have
        a DNS record on our LAN). I suspect the issue exists on many platforms
        but it is particularly accute on windows since when a DNS lookup fails
        windows attempts to lookup via NetBIOS (or something simlar) which
        results in a failed lookup taking 4.5 seconds!

        The problem is that with the new Proxy code in 1.5, the
        priviledgedOpenServer() method is called whenever an applet makes a
        connection. It isn't possible to bypass this call or bypass / alter the
        Proxy code without generating security exceptions.

        There are two obvious fixes that could be applied:

        1. Fix priviledgedOpenSever() so that it doesn't call getHostName(). I
        see no reason why it should resolve the name, it seems like a bug to me.
        If the proxy is specified by ip address then ip addresses only should be
        used for connecting to the proxy.

        2. Fix the ProxySelector stuff so that it returns the same
        InetSocketAddress object each time it is queried. I couldn't find the
        source for this since some of it is native, but it appears that each
        time you query the ProxySelector for the proxy details it returns a new
        InetSocketAddress object. InetSocketAddress objects cache their name if
        you attempt to look it up, so if the ProxySelector returned the same
        object each time then the lookup failure would only need to be performed
        once (I still can't see any reason why it should be performed at all,
        but this would at least be an acceptable workaround).

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  jccollet Jean-Christophe Collet (Inactive)
                  Reporter:
                  arfox Andrew Fox (Inactive)
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  0 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved:
                    Imported:
                    Indexed: