Skip to content

Commit

Permalink
[Backport] SocketTimeout should be unbounded by loginTimeout after a …
Browse files Browse the repository at this point in the history
…successful connection open (2355) (#2431)

* socketTimeout should reset to original value after a successful connection open (#2355)

* SocketTimeout should be unbounded by loginTimeout after a successful connection open
  • Loading branch information
tkyc committed May 23, 2024
1 parent d9c6cdb commit 17caf22
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
- Clear prepared statement handle before reconnect [#2422](https://github.com/microsoft/mssql-jdbc/pull/2422)
- RPC calls for CallableStatements will be executed directly [#2427](https://github.com/microsoft/mssql-jdbc/pull/2427)
- Corrected authentication token object to accept expiration in milliseconds [#2428](https://github.com/microsoft/mssql-jdbc/pull/2428)
- SocketTimeout should be unbounded by loginTimeout after a successful connection open [#2431](https://github.com/microsoft/mssql-jdbc/pull/2431)

## [12.6.1] Hotfix & Stable Release
### Fixed issues
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2366,6 +2366,10 @@ final int getNetworkTimeout() throws IOException {
final void setNetworkTimeout(int timeout) throws IOException {
tcpSocket.setSoTimeout(timeout);
}

void resetTcpSocketTimeout() throws SocketException {
this.tcpSocket.setSoTimeout(con.getSocketTimeoutMilliseconds());
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3225,9 +3225,15 @@ else if (0 == requestedPacketSize)

state = State.OPENED;

// Socket timeout is bounded by loginTimeout during the login phase.
// Reset socket timeout back to the original value.
tdsChannel.resetTcpSocketTimeout();

if (connectionlogger.isLoggable(Level.FINER)) {
connectionlogger.finer(toString() + " End of connect");
}
} catch (SocketException e) {
throw new SQLServerException(e.getMessage(), null);
} finally {
// once we exit the connect function, the connection can be only in one of two
// states, Opened or Closed(if an exception occurred)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,18 @@ public void testConnectRetryTimeout() {
"total time: " + totalTime + " interval: " + TimeUnit.SECONDS.toMillis(interval));
}

@Test
public void testSocketTimeoutBoundedByLoginTimeoutReset() throws Exception {
try (Connection con = PrepUtil.getConnection(connectionString + ";socketTimeout=90000;loginTimeout=10;");
Statement stmt = con.createStatement()) {
// Login timeout (10s) is less than the 15s sec WAITFOR DELAY. Upon a login attempt, socketTimeout should be bounded
// by loginTimeout. After a successful login, when executing a query, socketTimeout should be reset to the
// original 90000ms timeout. The statement below should successfully execute as socketTimeout should not be bounded
// by loginTimeout, otherwise the test fails with a socket read timeout error.
stmt.execute("WAITFOR DELAY '00:00:15';");
}
}

// Test for detecting Azure server for connection retries
@Test
public void testAzureEndpointRetry() {
Expand Down

0 comments on commit 17caf22

Please sign in to comment.