JDK-8239788 : SSLSocket not usable after SSLSocket.setSoTimeout is exceeded
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 11.0.6,13.0.2,14,15
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2020-02-21
  • Updated: 2020-02-21
  • Resolved: 2020-02-21
Related Reports
Duplicate :  
Description
JDK closes underlying SSLSocket during TLS client handshake in case of SO_TIMEOUT  exceeded. SSLSocket becames unusable.
The same application on JDK8 throws IOException but does not close underlying socket. SSLSocket still can be used to continue client handshake.

For example, let's set the timeout to 1 by SSLSocket.setSoTimeout(1) on the client side before handshake is started.  
According to Socket.setSoTimeout specification implementation should throw  java.net.SocketTimeoutException if read timeout expires, though the Socket should be still valid. Actual JDK behaviour shows that SO_TIMEOUT causes abort of TLS handshake and closes the underlying socket.
In contrast, JDK8 just throws java.net.SocketTimeoutException without closing the underlying socket.

Reproducer:
        SocketFactory factory = SSLSocketFactory.getDefault();
        try (SSLSocket connection = (SSLSocket)factory.createSocket(host, port)) {
            connection.setSoTimeout(1);
            while (!connection.isClosed()) {
                try {
                    connection.startHandshake();
                    break;
                } catch (IOException e) {
                    // Do nothing
                }
            }
            System.out.println("Connection isClosed: " + connection.isClosed());
            SSLSession s = connection.getSession();
            System.out.println("Protocol " + s.getProtocol());
        } catch (Exception e) {
            e.printStackTrace();
        }

Output for JDK8:
Connection isClosed: false
Protocol TLSv1.2

Output for JDK11 and higher:
Connection isClosed: true
Protocol NONE