Skip to content

Commit 6f171b9

Browse files
Alexey BakhtinVladimir Kempik
Alexey Bakhtin
authored and
Vladimir Kempik
committedJul 8, 2021
8268965: TCP Connection Reset when connecting simple socket to SSL server
Reviewed-by: xuelei
1 parent 4f322a9 commit 6f171b9

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed
 

‎src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java

+12
Original file line numberDiff line numberDiff line change
@@ -1777,6 +1777,18 @@ private void closeSocket(boolean selfInitiated) throws IOException {
17771777
}
17781778

17791779
if (autoClose || !isLayered()) {
1780+
// Try to clear the kernel buffer to avoid TCP connection resets.
1781+
if (conContext.inputRecord instanceof
1782+
SSLSocketInputRecord inputRecord && isConnected) {
1783+
if (appInput.readLock.tryLock()) {
1784+
try {
1785+
inputRecord.deplete(false);
1786+
} finally {
1787+
appInput.readLock.unlock();
1788+
}
1789+
}
1790+
}
1791+
17801792
super.close();
17811793
} else if (selfInitiated) {
17821794
if (!conContext.isInboundClosed() && !isInputShutdown()) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright (c) 2021, Azul, Inc. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
//
25+
// Please run in othervm mode. SunJSSE does not support dynamic system
26+
// properties, no way to re-use system properties in samevm/agentvm mode.
27+
//
28+
29+
/*
30+
* @test
31+
* @bug 8268965
32+
* @summary Socket reset issue for TLS socket close
33+
* @run main/othervm -Djdk.net.usePlainSocketImpl=true SSLSocketReset
34+
*/
35+
36+
import javax.net.ssl.*;
37+
import java.io.*;
38+
import java.net.*;
39+
40+
public class SSLSocketReset {
41+
42+
public static void main(String[] args){
43+
ServerThread serverThread = null;
44+
Exception clientException = null;
45+
try {
46+
SSLServerSocketFactory sslserversocketfactory =
47+
SSLContext.getDefault().getServerSocketFactory();
48+
SSLServerSocket sslServerSocket =
49+
(SSLServerSocket) sslserversocketfactory.createServerSocket(0);
50+
serverThread = new ServerThread(sslServerSocket);
51+
serverThread.start();
52+
try {
53+
Socket socket = new Socket(sslServerSocket.getInetAddress(), sslServerSocket.getLocalPort());
54+
DataInputStream in = new DataInputStream(socket.getInputStream());
55+
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
56+
57+
String msg = "Hello";
58+
out.writeUTF(msg);
59+
out.flush();
60+
msg = in.readUTF();
61+
} catch(Exception e) {
62+
clientException = e;
63+
e.printStackTrace();
64+
}
65+
serverThread.join();
66+
} catch(Exception e) {
67+
throw new RuntimeException("Fails to start SSL server");
68+
}
69+
if (serverThread.exception instanceof SSLException &&
70+
serverThread.exception.getMessage().equals("Unsupported or unrecognized SSL message") &&
71+
!(clientException instanceof SocketException &&
72+
clientException.getMessage().equals("Connection reset"))) {
73+
System.out.println("Test PASSED");
74+
} else {
75+
throw new RuntimeException("TCP connection reset");
76+
}
77+
}
78+
79+
// Thread handling the server socket
80+
private static class ServerThread extends Thread {
81+
private SSLServerSocket sslServerSocket = null;
82+
private SSLSocket sslSocket = null;
83+
Exception exception;
84+
85+
ServerThread(SSLServerSocket sslServerSocket){
86+
this.sslServerSocket = sslServerSocket;
87+
}
88+
89+
public void run(){
90+
try {
91+
SSLSocket sslsocket = null;
92+
while (true) {
93+
sslsocket = (SSLSocket) sslServerSocket.accept();
94+
DataInputStream in = new DataInputStream(sslsocket.getInputStream());
95+
DataOutputStream out = new DataOutputStream(sslsocket.getOutputStream());
96+
String string;
97+
while ((string = in.readUTF()) != null) {
98+
out.writeUTF(string);
99+
out.flush();
100+
}
101+
}
102+
} catch(Exception e) {
103+
exception = e;
104+
e.printStackTrace();
105+
}
106+
}
107+
}
108+
}

0 commit comments

Comments
 (0)
Please sign in to comment.