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

set a timeout to get the return from requesting SSL upgrade. #2572

Merged
merged 6 commits into from Jul 19, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -118,6 +118,7 @@ In addition to the standard connection parameters the driver supports a number o
| loginTimeout | Integer | 0 | Specify how long to wait for establishment of a database connection.|
| connectTimeout | Integer | 10 | The timeout value used for socket connect operations. |
| socketTimeout | Integer | 0 | The timeout value used for socket read operations. |
| sslResponseTimeout | Integer | 5000 | Socket timeout waiting for a response from a request for SSL upgrade from the server. |
| tcpKeepAlive | Boolean | false | Enable or disable TCP keep-alive. |
| tcpNoDelay | Boolean | true | Enable or disable TCP no delay. |
| ApplicationName | String | PostgreSQL JDBC Driver | The application name (require server version >= 9.0). If assumeMinServerVersion is set to >= 9.0 this will be sent in the startup packets, otherwise after the connection is made |
Expand Down
4 changes: 4 additions & 0 deletions docs/documentation/head/connect.md
Expand Up @@ -327,6 +327,10 @@ Connection conn = DriverManager.getConnection(url);
detecting network problems. The timeout is specified in seconds and a
value of zero means that it is disabled.

* **sslResponseTimeout** = int
The timeout value in milliseconds that we wait for a response from the server
after requesting the connection be upgraded to SSL.

* **cancelSignalTimeout** = int

Cancel command is sent out of band over its own connection, so cancel message can itself get
Expand Down
9 changes: 9 additions & 0 deletions pgjdbc/src/main/java/org/postgresql/PGProperty.java
Expand Up @@ -672,6 +672,15 @@ public enum PGProperty {
null,
"A class, implementing javax.security.auth.callback.CallbackHandler that can handle PassworCallback for the ssl password."),

/**
* <p>After requesting an upgrade to SSL from the server there are reports of the server not responding due to a failover
* without a timeout here, the client can wait forever. This timeout will be set before the request and reset after </p>
*/
SSL_RESPONSE_TIMEOUT(
"sslResponseTimeout",
"5000",
"Time in milliseconds we wait for a response from the server after requesting SSL upgrade"),

/**
* File containing the root certificate when validating server ({@code sslmode} = {@code
* verify-ca} or {@code verify-full}). Default will be the file {@code root.crt} in {@code
Expand Down
Expand Up @@ -532,6 +532,17 @@ private PGStream enableSSL(PGStream pgStream, SslMode sslMode, Properties info,

LOGGER.log(Level.FINEST, " FE=> SSLRequest");

int sslTimeout = PGProperty.SSL_RESPONSE_TIMEOUT.getInt(info);
int currentTimeout = pgStream.getSocket().getSoTimeout();
davecramer marked this conversation as resolved.
Show resolved Hide resolved

// if the current timeout is less than sslTimeout then
// use the smaller timeout. We could do something tricky
// here to not set it in that case but this is pretty readable
if (currentTimeout > 0 && currentTimeout < sslTimeout) {
sslTimeout = currentTimeout;
}

pgStream.getSocket().setSoTimeout(sslTimeout);
// Send SSL request packet
pgStream.sendInteger4(8);
pgStream.sendInteger2(1234);
Expand All @@ -540,6 +551,8 @@ private PGStream enableSSL(PGStream pgStream, SslMode sslMode, Properties info,

// Now get the response from the backend, one of N, E, S.
int beresp = pgStream.receiveChar();
pgStream.getSocket().setSoTimeout(currentTimeout);

switch (beresp) {
case 'E':
LOGGER.log(Level.FINEST, " <=BE SSLError");
Expand Down
18 changes: 18 additions & 0 deletions pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java
Expand Up @@ -354,6 +354,24 @@ public void setConnectTimeout(int connectTimeout) {
PGProperty.CONNECT_TIMEOUT.set(properties, connectTimeout);
}

/**
*
* @return SSL ResponseTimeout
* @see PGProperty#SSL_RESPONSE_TIMEOUT
*/
public int getSslResponseTimeout() {
return PGProperty.SSL_RESPONSE_TIMEOUT.getIntNoCheck(properties);
}

/**
*
* @param sslResponseTimeout ssl response timeout
* @see PGProperty#SSL_RESPONSE_TIMEOUT
*/
public void setSslResponseTimeout(int sslResponseTimeout) {
PGProperty.SSL_RESPONSE_TIMEOUT.set(properties,sslResponseTimeout);
}

/**
* @return protocol version
* @see PGProperty#PROTOCOL_VERSION
Expand Down