Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport] SocketTimeout should be unbounded by loginTimeout after a successful connection open (2355) #2431

Merged
merged 2 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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