8236464: SO_LINGER option is ignored by SSLSocket in JDK 11

Reviewed-by: ascarpino
This commit is contained in:
Xue-Lei Andrew Fan 2020-04-24 13:30:47 -07:00
parent 88f3861cb7
commit bfcb340606
2 changed files with 42 additions and 37 deletions

View file

@ -238,7 +238,7 @@ final class TransportContext implements ConnectionContext {
(handshakeContext instanceof PostHandshakeContext);
}
// Note: close_notify is delivered as a warning alert.
// Note: Don't use this method for close_nofity, use closeNotify() instead.
void warning(Alert alert) {
// For initial handshaking, don't send a warning alert message to peer
// if handshaker has not started.
@ -254,6 +254,33 @@ final class TransportContext implements ConnectionContext {
}
}
// Note: close_notify is delivered as a warning alert.
void closeNotify(boolean isUserCanceled) throws IOException {
// Socket transport is special because of the SO_LINGER impact.
if (transport instanceof SSLSocketImpl) {
((SSLSocketImpl)transport).closeNotify(isUserCanceled);
} else {
// Need a lock here so that the user_canceled alert and the
// close_notify alert can be delivered together.
outputRecord.recordLock.lock();
try {
try {
// send a user_canceled alert if needed.
if (isUserCanceled) {
warning(Alert.USER_CANCELED);
}
// send a close_notify alert
warning(Alert.CLOSE_NOTIFY);
} finally {
outputRecord.close();
}
} finally {
outputRecord.recordLock.unlock();
}
}
}
SSLException fatal(Alert alert,
String diagnostic) throws SSLException {
return fatal(alert, diagnostic, null);
@ -501,17 +528,7 @@ final class TransportContext implements ConnectionContext {
}
if (needCloseNotify) {
outputRecord.recordLock.lock();
try {
try {
// send a close_notify alert
warning(Alert.CLOSE_NOTIFY);
} finally {
outputRecord.close();
}
} finally {
outputRecord.recordLock.unlock();
}
closeNotify(false);
}
}
}
@ -547,24 +564,7 @@ final class TransportContext implements ConnectionContext {
useUserCanceled = true;
}
// Need a lock here so that the user_canceled alert and the
// close_notify alert can be delivered together.
outputRecord.recordLock.lock();
try {
try {
// send a user_canceled alert if needed.
if (useUserCanceled) {
warning(Alert.USER_CANCELED);
}
// send a close_notify alert
warning(Alert.CLOSE_NOTIFY);
} finally {
outputRecord.close();
}
} finally {
outputRecord.recordLock.unlock();
}
closeNotify(useUserCanceled);
}
// Note; HandshakeStatus.FINISHED status is retrieved in other places.