8209333: Socket reset issue for TLS 1.3 socket close

Reviewed-by: jnimeh
This commit is contained in:
Xue-Lei Andrew Fan 2018-12-18 15:18:44 -08:00
parent d1597bb1cb
commit ad47b4c4cc
5 changed files with 349 additions and 3 deletions

View file

@ -29,8 +29,6 @@ import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.AlgorithmConstraints;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

View file

@ -608,7 +608,12 @@ public final class SSLSocketImpl
}
} else {
if (!conContext.isInboundClosed()) {
conContext.inputRecord.close();
try (conContext.inputRecord) {
// Try the best to use up the input records and close the
// socket gracefully, without impact the performance too
// much.
appInput.deplete();
}
}
if ((autoClose || !isLayered()) && !super.isInputShutdown()) {
@ -907,6 +912,30 @@ public final class SSLSocketImpl
return false;
}
/**
* Try the best to use up the input records so as to close the
* socket gracefully, without impact the performance too much.
*/
private synchronized void deplete() {
if (!conContext.isInboundClosed()) {
if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) {
return;
}
SSLSocketInputRecord socketInputRecord =
(SSLSocketInputRecord)conContext.inputRecord;
try {
socketInputRecord.deplete(
conContext.isNegotiated && (getSoTimeout() > 0));
} catch (IOException ioe) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
SSLLogger.warning(
"input stream close depletion failed", ioe);
}
}
}
}
}
@Override

View file

@ -463,4 +463,17 @@ final class SSLSocketInputRecord extends InputRecord implements SSLRecord {
return n;
}
// Try to use up the input stream without impact the performance too much.
void deplete(boolean tryToRead) throws IOException {
int remaining = is.available();
if (tryToRead && (remaining == 0)) {
// try to wait and read one byte if no buffered input
is.read();
}
while ((remaining = is.available()) != 0) {
is.skip(remaining);
}
}
}