Skip to content

Commit a6044d0

Browse files
authored
set a timeout to get the return from requesting SSL upgrade. (#2572)
* set a timeout to get the return from requesting SSL upgrade. * Make the SSL Response timeout a configurable property * fix docs and change logic to use lesser of current socket timeout or sslresponse timeout
1 parent 58d6fa0 commit a6044d0

File tree

5 files changed

+45
-0
lines changed

5 files changed

+45
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ In addition to the standard connection parameters the driver supports a number o
118118
| loginTimeout | Integer | 0 | Specify how long to wait for establishment of a database connection.|
119119
| connectTimeout | Integer | 10 | The timeout value used for socket connect operations. |
120120
| socketTimeout | Integer | 0 | The timeout value used for socket read operations. |
121+
| sslResponseTimeout | Integer | 5000 | Socket timeout waiting for a response from a request for SSL upgrade from the server. |
121122
| tcpKeepAlive | Boolean | false | Enable or disable TCP keep-alive. |
122123
| tcpNoDelay | Boolean | true | Enable or disable TCP no delay. |
123124
| 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 |

docs/documentation/head/connect.md

+4
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,10 @@ Connection conn = DriverManager.getConnection(url);
327327
detecting network problems. The timeout is specified in seconds and a
328328
value of zero means that it is disabled.
329329

330+
* **sslResponseTimeout** = int
331+
The timeout value in milliseconds that we wait for a response from the server
332+
after requesting the connection be upgraded to SSL.
333+
330334
* **cancelSignalTimeout** = int
331335

332336
Cancel command is sent out of band over its own connection, so cancel message can itself get

pgjdbc/src/main/java/org/postgresql/PGProperty.java

+9
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,15 @@ public enum PGProperty {
672672
null,
673673
"A class, implementing javax.security.auth.callback.CallbackHandler that can handle PassworCallback for the ssl password."),
674674

675+
/**
676+
* <p>After requesting an upgrade to SSL from the server there are reports of the server not responding due to a failover
677+
* without a timeout here, the client can wait forever. This timeout will be set before the request and reset after </p>
678+
*/
679+
SSL_RESPONSE_TIMEOUT(
680+
"sslResponseTimeout",
681+
"5000",
682+
"Time in milliseconds we wait for a response from the server after requesting SSL upgrade"),
683+
675684
/**
676685
* File containing the root certificate when validating server ({@code sslmode} = {@code
677686
* verify-ca} or {@code verify-full}). Default will be the file {@code root.crt} in {@code

pgjdbc/src/main/java/org/postgresql/core/v3/ConnectionFactoryImpl.java

+13
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,17 @@ private PGStream enableSSL(PGStream pgStream, SslMode sslMode, Properties info,
532532

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

535+
int sslTimeout = PGProperty.SSL_RESPONSE_TIMEOUT.getInt(info);
536+
int currentTimeout = pgStream.getSocket().getSoTimeout();
537+
538+
// if the current timeout is less than sslTimeout then
539+
// use the smaller timeout. We could do something tricky
540+
// here to not set it in that case but this is pretty readable
541+
if (currentTimeout > 0 && currentTimeout < sslTimeout) {
542+
sslTimeout = currentTimeout;
543+
}
544+
545+
pgStream.getSocket().setSoTimeout(sslTimeout);
535546
// Send SSL request packet
536547
pgStream.sendInteger4(8);
537548
pgStream.sendInteger2(1234);
@@ -540,6 +551,8 @@ private PGStream enableSSL(PGStream pgStream, SslMode sslMode, Properties info,
540551

541552
// Now get the response from the backend, one of N, E, S.
542553
int beresp = pgStream.receiveChar();
554+
pgStream.getSocket().setSoTimeout(currentTimeout);
555+
543556
switch (beresp) {
544557
case 'E':
545558
LOGGER.log(Level.FINEST, " <=BE SSLError");

pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java

+18
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,24 @@ public void setConnectTimeout(int connectTimeout) {
354354
PGProperty.CONNECT_TIMEOUT.set(properties, connectTimeout);
355355
}
356356

357+
/**
358+
*
359+
* @return SSL ResponseTimeout
360+
* @see PGProperty#SSL_RESPONSE_TIMEOUT
361+
*/
362+
public int getSslResponseTimeout() {
363+
return PGProperty.SSL_RESPONSE_TIMEOUT.getIntNoCheck(properties);
364+
}
365+
366+
/**
367+
*
368+
* @param sslResponseTimeout ssl response timeout
369+
* @see PGProperty#SSL_RESPONSE_TIMEOUT
370+
*/
371+
public void setSslResponseTimeout(int sslResponseTimeout) {
372+
PGProperty.SSL_RESPONSE_TIMEOUT.set(properties,sslResponseTimeout);
373+
}
374+
357375
/**
358376
* @return protocol version
359377
* @see PGProperty#PROTOCOL_VERSION

0 commit comments

Comments
 (0)