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

Connection timed out when connecting to loopback address other than 127.0.0.1

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Tested on Windows 10 with Adoptium OpenJDK 15,16,17 and 20, and Oracle JDK 17, and Zulu JDK 17.

      A DESCRIPTION OF THE PROBLEM :
      Since Java 17 it is not possible anymore to connect to a ServerSocket that is opened on another localhost address than 127.0.0.1! Windows does not have a single localhost IP but many, and in fact all 127.0.0.0/8 IPs are DIFFERENT localhost IPs. The problem on the TCP level is that the Port is opened on 127.0.0.x, but the answer package always seems to come from 127.0.0.1! This leads to a java.net.ConnectException: Connection timed out: connect, which is also wrongly named. In Wireshark one can see the SYN for connection setup, and a SYN,ACK answer, but the answer is from the wrong IP.

      We require this feature because we have many client programs that just can connect to a fixed port, but have to run in parallel. And we need to redirect these connections. So we open a bunch of ServerSockets on different local IPs with the same port. This is not possible if you assume a machine would only have a single localhost address, like Java wrongly does now! This might be wrong even on Linux, but I didn't test it there, althought I am sure one would be able to create a bunch of lo interfaces there.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create a ServerSocket on e.g. 127.0.0.101:
      ServerSocket serverSocket = new ServerSocket(11111, 100, InetAddress.getByAddress(new byte[] { 127,0,0,101 }))
      Now connect to it:
      Socket s = new Socket(InetAddress.getByAddress(new byte[] { 127,0,0,101 }),11111);


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      A fine TCP connection that works like a connection to 127.0.0.1
      ACTUAL -
      java.net.ConnectException: Connection timed out: connect

      ---------- BEGIN SOURCE ----------
      HelloServer.java:

      import java.io.IOException;
      import java.io.OutputStreamWriter;
      import java.io.PrintWriter;
      import java.net.InetAddress;
      import java.net.ServerSocket;
      import java.net.Socket;

      public class HelloServer {

      public static void main(String[] args) throws IOException {
      try (
      ServerSocket serverSocket = new ServerSocket(11111, 100, InetAddress.getByAddress(new byte[] { 127,0,0,101 }))
      ) {
      while( true ) {
      System.out.println("Waiting for connections now...");
      Socket s = serverSocket.accept();
      System.out.println("Got connection from "+s.getRemoteSocketAddress());
      try (
      PrintWriter pw = new PrintWriter( new OutputStreamWriter( s.getOutputStream() ));
      ) {
      pw.println("Nice to see you!");
      }
      }
      }
      }

      }

      HelloClient.java:

      import java.io.BufferedReader;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.net.InetAddress;
      import java.net.Socket;

      public class HelloClient {

      public static void main(String[] args) throws IOException {
      try (
      Socket s = new Socket(InetAddress.getByAddress(new byte[] { 127,0,0,101 }),11111);
      BufferedReader in = new BufferedReader(new InputStreamReader( s.getInputStream() ));
      ) {
      System.out.println(">>> "+in.readLine());
      }
      }

      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      None.

      FREQUENCY : always


            michaelm Michael McMahon
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: