Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/libpq/fe-connect.c')
-rw-r--r--src/interfaces/libpq/fe-connect.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 5dcc7d76922..87df79880af 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -270,6 +270,10 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
"TCP-Keepalives-Count", "", 10, /* strlen(INT32_MAX) == 10 */
offsetof(struct pg_conn, keepalives_count)},
+ {"tcp_user_timeout", NULL, NULL, NULL,
+ "TCP-User-Timeout", "", 10, /* strlen(INT32_MAX) == 10 */
+ offsetof(struct pg_conn, pgtcp_user_timeout)},
+
/*
* ssl options are allowed even without client SSL support because the
* client can still handle SSL modes "disable" and "allow". Other
@@ -1833,6 +1837,41 @@ setKeepalivesWin32(PGconn *conn)
#endif /* SIO_KEEPALIVE_VALS */
#endif /* WIN32 */
+/*
+ * Set the TCP user timeout.
+ */
+static int
+setTCPUserTimeout(PGconn *conn)
+{
+ int timeout;
+
+ if (conn->pgtcp_user_timeout == NULL)
+ return 1;
+
+ if (!parse_int_param(conn->pgtcp_user_timeout, &timeout, conn,
+ "tcp_user_timeout"))
+ return 0;
+
+ if (timeout < 0)
+ timeout = 0;
+
+#ifdef TCP_USER_TIMEOUT
+ if (setsockopt(conn->sock, IPPROTO_TCP, TCP_USER_TIMEOUT,
+ (char *) &timeout, sizeof(timeout)) < 0)
+ {
+ char sebuf[256];
+
+ appendPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("setsockopt(%s) failed: %s\n"),
+ "TCP_USER_TIMEOUT",
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
+ return 0;
+ }
+#endif
+
+ return 1;
+}
+
/* ----------
* connectDBStart -
* Begin the process of making a connection to the backend.
@@ -2480,6 +2519,8 @@ keep_going: /* We will come back to here until there is
err = 1;
#endif /* SIO_KEEPALIVE_VALS */
#endif /* WIN32 */
+ else if (!setTCPUserTimeout(conn))
+ err = 1;
if (err)
{
@@ -3863,6 +3904,8 @@ freePGconn(PGconn *conn)
free(conn->pgtty);
if (conn->connect_timeout)
free(conn->connect_timeout);
+ if (conn->pgtcp_user_timeout)
+ free(conn->pgtcp_user_timeout);
if (conn->pgoptions)
free(conn->pgoptions);
if (conn->appname)