JDK-8236464 : SO_LINGER option is ignored by SSLSocket in JDK 11
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: openjdk8u272,11.0.5
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2019-12-19
  • Updated: 2020-12-08
  • Resolved: 2020-04-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 15 JDK 8
11.0.9-oracleFixed 15 b21Fixed 8u271Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
A DESCRIPTION OF THE PROBLEM :
We have been setting SO_LINGER to 0 so we can close a secure connection promptly. This has been working well for us in JDK 9 and JDK 10. But it stops working when we move to JDK 11. In JDK 11, it can take 30 seconds to one minute to have a socket really closed (close_notify sent) even with SO_LINGER set to 0.

Comparing source code of JDK 10 and JDK 11, it seems that the SO_LINGER option is ignored in JDK 11.


CUSTOMER SUBMITTED WORKAROUND :
We have done quite some research but can't find a workaround.

FREQUENCY : always



Comments
Requested the submitter verify the fix with latest version of JDK 15 and 16.
19-10-2020

Fix request (11u) -- will label after testing completed. I would like to downport this for parity with 11.0.9-oracle. I had to adapt the change: http://mail.openjdk.java.net/pipermail/jdk-updates-dev/2020-July/003455.html
08-07-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/c783b60f48db User: xuelei Date: 2020-04-24 20:31:06 +0000
24-04-2020

Further information from the submitter: The test consists of a server and a client. The server will stop receiving for 20 seconds and eventually cause the client block on sending. While sending is blocked on the client, it tries to close the connection. Since sending is blocked, close_notify can't get through and closing handshake can't finish. It has to wait for about 20 seconds for the server to resume receiving before the connection is closed. This is the expected behavior when SOLINGER is disabled. When we enable SOLINGER and set the timeout to 0, the connection is closed immediately as expected with JDK 9 and JDK 10. However, with JDK 11, it again takes about 20 seconds to close the connection. We went through the JDK 11 source code and believe that SOLINGER option is not checked: https://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/share/classes/sun/security/ssl/TransportContext.java#l545 Reproducing Steps: 1. starting the server using java in JDK 10: "$ java SSLSocketServer" 2. on the same machine, starting the client using java in JDK 10: "$ java -Djavax.net.ssl.trustStore=samplecacerts SSLSocketClient" 3. the client terminal will show "Takes 6ms to close the socket" 4. repeat 1-3 but using java in JDK 11, the client terminal will show "Takes 19863ms to close the socket". Results: C:\Users\tongwan\Documents\JDK-8236464>c:\jdk-11\bin\java -Djavax.net.ssl.trustStore=samplecacerts SSLSocketClient Sent 1000 packets asynchronously. Closing the socket Takes 19926ms to close the socket C:\Users\tongwan\Documents\JDK-8236464>c:\jdk-10.0.2\bin\java -Djavax.net.ssl.trustStore=samplecacerts SSLSocketClient Sent 1000 packets asynchronously. Closing the socket Takes 4ms to close the socket C:\Users\tongwan\Documents\JDK-8236464>c:\jdk-11\bin\java SSLSocketServer ServerSocket started [SSL: ServerSocket[addr=0.0.0.0/0.0.0.0,localport=2001]] Connection accepted. receive buf size is: 100 Stop receiving for 20 seconds Exiting... C:\Users\tongwan\Documents\JDK-8236464>c:\jdk-10.0.2\bin\java SSLSocketServer ServerSocket started [SSL: ServerSocket[addr=0.0.0.0/0.0.0.0,localport=2001]] Connection accepted. receive buf size is: 100 Stop receiving for 20 seconds Connection reset
24-04-2020

The result of the fix build on Windows 10: C:\Users\tongwan\Documents\JDK-8236464>c:\jdk-15-fix\bin\java -Djavax.net.ssl.trustStore=samplecacerts SSLSocketClient Sent 1000 packets asynchronously. Closing the socket Takes 1ms to close the socket C:\Users\tongwan\Documents\JDK-8236464>c:\jdk-15-fix\bin\java SSLSocketServer ServerSocket started [SSL: ServerSocket[addr=0.0.0.0/0.0.0.0,localport=2001]] Connection accepted. receive buf size is: 100 Stop receiving for 20 seconds Exiting...
24-04-2020

[~tongwan] I can confirm there is an issue in the socket close code. However, I cannot reproduce the issue with the attached test case. Would you mind help to check if the following build fixes the issue? https://mach5.us.oracle.com/mdash/buildIds/2020-04-23-1813214.xuelei.fan.jdk-dev
23-04-2020

Further feedback from the submitter: I don't have a clean self-contained test to show the problem. It happens from time to time in our application when there is a network issue. We are able to reliably reproduce this in our application following these steps: 1.generate heavy network traffic on the connection 2.use iptables to drop 70% of the packets (so packets pile up in the send buffer) 3.call socket.close() at one side of the connection, and the call takes 30 seconds or more to come back even with SO_LINGER set to 0. We find in JDK 10 source code where SO_LINGER is honored: https://hg.openjdk.java.net/jdk/jdk10/file/b09e56145e11/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java#l842 In JDK 11 source code, looks like SO_LINGER is not checked when sending close_notify: https://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/share/classes/sun/security/ssl/TransportContext.java#l545
21-12-2019