diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/FailOverInfo.java b/src/main/java/com/microsoft/sqlserver/jdbc/FailOverInfo.java index 5098ac70b..97e66e136 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/FailOverInfo.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/FailOverInfo.java @@ -5,7 +5,6 @@ package com.microsoft.sqlserver.jdbc; -import java.io.Serializable; import java.text.MessageFormat; import java.util.logging.Level; @@ -108,49 +107,3 @@ synchronized void failoverAdd(SQLServerConnection connection, boolean actualUseF } } } - - -// A simple readonly placeholder class to store the current server info. -// We need this class so during a connection open we can keep a copy of the current failover info stable -// This is also used to keep the standalone primary server connection information. -// -final class ServerPortPlaceHolder implements Serializable { - /** - * Always update serialVersionUID when prompted. - */ - private static final long serialVersionUID = 7393779415545731523L; - - private final String serverName; - private final int port; - private final String instanceName; - private final boolean checkLink; - private final SQLServerConnectionSecurityManager securityManager; - - ServerPortPlaceHolder(String name, int conPort, String instance, boolean fLink) { - serverName = name; - port = conPort; - instanceName = instance; - checkLink = fLink; - securityManager = new SQLServerConnectionSecurityManager(serverName, port); - doSecurityCheck(); - } - - // accessors - int getPortNumber() { - return port; - } - - String getServerName() { - return serverName; - } - - String getInstanceName() { - return instanceName; - } - - void doSecurityCheck() { - securityManager.checkConnect(); - if (checkLink) - securityManager.checkLink(); - } -} diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java b/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java index f29922965..d4bc29abb 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java @@ -4030,8 +4030,7 @@ void writeNonUnicodeReader(Reader reader, long advertisedLength, boolean isDestB do { // Read in next chunk - for (charsToWrite = 0; -1 != charsRead && charsToWrite < currentPacketSize; - charsToWrite += charsRead) { + for (charsToWrite = 0; -1 != charsRead && charsToWrite < currentPacketSize; charsToWrite += charsRead) { try { charsRead = reader.read(streamCharBuffer, charsToWrite, currentPacketSize - charsToWrite); } catch (IOException e) { diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java index 2d5676bdc..5b18f0a1e 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java @@ -2815,9 +2815,9 @@ private InetSocketAddress connectHelper(ServerPortPlaceHolder serverInfo, int ti // if the timeout is infinite slices are infinite too. tdsChannel = new TDSChannel(this); - InetSocketAddress inetSocketAddress = tdsChannel.open(serverInfo.getServerName(), serverInfo.getPortNumber(), - (0 == timeOutFullInSeconds) ? 0 : timeOutSliceInMillis, useParallel, useTnir, isTnirFirstAttempt, - timeOutsliceInMillisForFullTimeout); + InetSocketAddress inetSocketAddress = tdsChannel.open(serverInfo.getParsedServerName(), + serverInfo.getPortNumber(), (0 == timeOutFullInSeconds) ? 0 : timeOutSliceInMillis, useParallel, + useTnir, isTnirFirstAttempt, timeOutsliceInMillisForFullTimeout); setState(State.Connected); @@ -2828,8 +2828,8 @@ private InetSocketAddress connectHelper(ServerPortPlaceHolder serverInfo, int ti // If prelogin negotiated SSL encryption then, enable it on the TDS channel. if (TDS.ENCRYPT_NOT_SUP != negotiatedEncryptionLevel) { - tdsChannel.enableSSL(serverInfo.getServerName(), serverInfo.getPortNumber(), clientCertificate, clientKey, - clientKeyPassword); + tdsChannel.enableSSL(serverInfo.getParsedServerName(), serverInfo.getPortNumber(), clientCertificate, + clientKey, clientKeyPassword); clientKeyPassword = ""; } @@ -4365,13 +4365,20 @@ final void processEnvChange(TDSReader tdsReader) throws SQLServerException { } } - isRoutedInCurrentAttempt = true; - routingInfo = new ServerPortPlaceHolder(routingServerName, routingPortNumber, null, integratedSecurity); + int px = routingServerName.indexOf('\\'); + String routingInstanceName = null; + if (px >= 0) { + routingInstanceName = routingServerName.substring(px + 1, routingServerName.length()); + } + isRoutedInCurrentAttempt = true; + routingInfo = new ServerPortPlaceHolder(routingServerName, routingPortNumber, routingInstanceName, + integratedSecurity); break; // Error on unrecognized, unused ENVCHANGES default: + if (connectionlogger.isLoggable(Level.WARNING)) { connectionlogger.warning(toString() + " Unknown environment change: " + envchange); } @@ -5228,10 +5235,10 @@ final boolean complete(LogonCommand logonCommand, TDSReader tdsReader) throws SQ // fails TDS.LOGIN_OPTION2_ODBC_ON | // Use ODBC defaults (ANSI_DEFAULTS ON, IMPLICIT_TRANSACTIONS OFF, TEXTSIZE // inf, ROWCOUNT inf) - (replication ? TDS.LOGIN_OPTION2_USER_SQLREPL_ON : TDS.LOGIN_OPTION2_USER_SQLREPL_OFF) | - (integratedSecurity ? // integrated security if integratedSecurity requested - TDS.LOGIN_OPTION2_INTEGRATED_SECURITY_ON - : TDS.LOGIN_OPTION2_INTEGRATED_SECURITY_OFF))); + (replication ? TDS.LOGIN_OPTION2_USER_SQLREPL_ON : TDS.LOGIN_OPTION2_USER_SQLREPL_OFF) + | (integratedSecurity ? // integrated security if integratedSecurity requested + TDS.LOGIN_OPTION2_INTEGRATED_SECURITY_ON + : TDS.LOGIN_OPTION2_INTEGRATED_SECURITY_OFF))); // TypeFlags tdsWriter.writeByte((byte) (TDS.LOGIN_SQLTYPE_DEFAULT | (applicationIntent != null diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ServerPortPlaceHolder.java b/src/main/java/com/microsoft/sqlserver/jdbc/ServerPortPlaceHolder.java new file mode 100644 index 000000000..1570fb3bb --- /dev/null +++ b/src/main/java/com/microsoft/sqlserver/jdbc/ServerPortPlaceHolder.java @@ -0,0 +1,65 @@ +/* + * Microsoft JDBC Driver for SQL Server Copyright(c) Microsoft Corporation All rights reserved. This program is made + * available under the terms of the MIT License. See the LICENSE file in the project root for more information. + */ + +package com.microsoft.sqlserver.jdbc; + +import java.io.Serializable; + + +/** + * A simple readonly placeholder class to store the current server info. We need this class so during a connection open + * we can keep a copy of the current failover info stable This is also used to keep the standalone primary server + * connection information. + */ +final class ServerPortPlaceHolder implements Serializable { + /** + * Always update serialVersionUID when prompted. + */ + private static final long serialVersionUID = 7393779415545731523L; + + private final String serverName; + private final String parsedServerName; + private final int port; + private final String instanceName; + private final boolean checkLink; + private final SQLServerConnectionSecurityManager securityManager; + + ServerPortPlaceHolder(String name, int conPort, String instance, boolean fLink) { + serverName = name; + + // serverName without named instance + int px = serverName.indexOf('\\'); + parsedServerName = (px >= 0) ? serverName.substring(0, px) : serverName; + + port = conPort; + instanceName = instance; + checkLink = fLink; + securityManager = new SQLServerConnectionSecurityManager(serverName, port); + doSecurityCheck(); + } + + // accessors + int getPortNumber() { + return port; + } + + String getServerName() { + return serverName; + } + + String getInstanceName() { + return instanceName; + } + + String getParsedServerName() { + return parsedServerName; + } + + void doSecurityCheck() { + securityManager.checkConnect(); + if (checkLink) + securityManager.checkLink(); + } +}