Skip to content

Commit

Permalink
Improved retry logic for intermittent TLS1.2 issue (#882)
Browse files Browse the repository at this point in the history
  • Loading branch information
ulvii committed Nov 30, 2018
1 parent a2b669f commit 5dfeaab
Showing 1 changed file with 27 additions and 18 deletions.
45 changes: 27 additions & 18 deletions src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Expand Up @@ -1794,31 +1794,40 @@ else if (con.getTrustManagerClass() != null) {
+ tmfDefaultAlgorithm + "\n") : "")
+ ((null != ksProvider) ? ("KeyStore provider info: " + ksProvider.getInfo() + "\n") : "")
+ "java.ext.dirs: " + System.getProperty("java.ext.dirs"));
// Retrieve the localized error message if possible.
String localizedMessage = e.getLocalizedMessage();
String errMsg = (localizedMessage != null) ? localizedMessage : e.getMessage();
/*
* Retrieve the error message of the cause too because actual error message can be wrapped into a different
* message when re-thrown from underlying InputStream.
*/
String causeErrMsg = null;
Throwable cause = e.getCause();
if (cause != null) {
String causeLocalizedMessage = cause.getLocalizedMessage();
causeErrMsg = (causeLocalizedMessage != null) ? causeLocalizedMessage : cause.getMessage();
}

MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_sslFailed"));
Object[] msgArgs = {e.getMessage()};

// It is important to get the localized message here, otherwise error messages won't match for different
// locales.
String errMsg = e.getLocalizedMessage();
// If the message is null replace it with the non-localized message or a dummy string. This can happen if a
// custom
// TrustManager implementation is specified that does not provide localized messages.
if (errMsg == null) {
errMsg = e.getMessage();
}
if (errMsg == null) {
errMsg = "";
}
// The error message may have a connection id appended to it. Extract the message only for comparison.
// This client connection id is appended in method checkAndAppendClientConnId().
if (errMsg.contains(SQLServerException.LOG_CLIENT_CONNECTION_ID_PREFIX)) {
Object[] msgArgs = {errMsg};

/*
* The error message may have a connection id appended to it. Extract the message only for comparison. This
* client connection id is appended in method checkAndAppendClientConnId().
*/
if (errMsg != null && errMsg.contains(SQLServerException.LOG_CLIENT_CONNECTION_ID_PREFIX)) {
errMsg = errMsg.substring(0, errMsg.indexOf(SQLServerException.LOG_CLIENT_CONNECTION_ID_PREFIX));
}

if (causeErrMsg != null && causeErrMsg.contains(SQLServerException.LOG_CLIENT_CONNECTION_ID_PREFIX)) {
causeErrMsg = causeErrMsg.substring(0,
causeErrMsg.indexOf(SQLServerException.LOG_CLIENT_CONNECTION_ID_PREFIX));
}

// Isolate the TLS1.2 intermittent connection error.
if (e instanceof IOException && (SSLHandhsakeState.SSL_HANDHSAKE_STARTED == handshakeState)
&& (errMsg.equals(SQLServerException.getErrString("R_truncatedServerResponse")))) {
&& (SQLServerException.getErrString("R_truncatedServerResponse").equals(errMsg)
|| SQLServerException.getErrString("R_truncatedServerResponse").equals(causeErrMsg))) {
con.terminate(SQLServerException.DRIVER_ERROR_INTERMITTENT_TLS_FAILED, form.format(msgArgs), e);
} else {
con.terminate(SQLServerException.DRIVER_ERROR_SSL_FAILED, form.format(msgArgs), e);
Expand Down

0 comments on commit 5dfeaab

Please sign in to comment.