TCP_USER_TIMEOUT_in_interface.patch
application/octet-stream
Filename: TCP_USER_TIMEOUT_in_interface.patch
Type: application/octet-stream
Part: 2
Message:
Timeout parameters
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/interfaces/libpq/fe-connect.c | 49 | 0 |
| src/interfaces/libpq/libpq-int.h | 1 | 0 |
| src/interfaces/libpq/tcpusertimeout.patch | 75 | 0 |
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index d001bc513d..379a381193 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -325,6 +325,10 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
"Target-Session-Attrs", "", 11, /* sizeof("read-write") = 11 */
offsetof(struct pg_conn, target_session_attrs)},
+ {"tcp_user_timeout",NULL,NULL,NULL,
+ "TCP-user-timeout","",10, /* strlen(INT32_MAX) == 10 */
+ offsetof(struct pg_conn,pgtcp_user_timeout)},
+
/* Terminating entry --- MUST BE LAST */
{NULL, NULL, NULL, NULL,
NULL, NULL, 0}
@@ -1771,6 +1775,38 @@ setKeepalivesWin32(PGconn *conn)
#endif /* SIO_KEEPALIVE_VALS */
#endif /* WIN32 */
+/* set TCP user timeout */
+static int
+setTCPUserTimeout(PGconn *conn)
+{
+ int timeout;
+
+ if (conn->pgtcp_user_timeout)
+ {
+ timeout = atoi(conn->pgtcp_user_timeout);
+ if (timeout < 0)
+ timeout = 0;
+ }
+ else
+ timeout = 12000;
+
+#ifdef __linux__
+ /* TCP_USER_TIMEOUT macro is not available on older Linux distros */
+ if (setsockopt(conn->sock, IPPROTO_TCP, 18,
+ (char *) &timeout, sizeof(timeout)) < 0 && errno != ENOPROTOOPT)
+ {
+ char sebuf[256];
+
+ appendPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("setsockopt(TCP_USER_TIMEOUT) failed: %s\n"),
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
+ return 0;
+ }
+#endif
+
+ return 1;
+}
+
/* ----------
* connectDBStart -
* Begin the process of making a connection to the backend.
@@ -2346,6 +2382,17 @@ keep_going: /* We will come back to here until there is
goto keep_going;
}
+ if (!IS_AF_UNIX(addr_cur->ai_family))
+ {
+ if (!setTCPUserTimeout(conn))
+ {
+ closesocket(conn->sock);
+ conn->sock = -1;
+ conn->addr_cur = addr_cur->ai_next;
+ goto keep_going;
+ }
+ }
+
#ifdef F_SETFD
if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
{
@@ -3627,6 +3674,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)
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 975ab33d02..596db78380 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -336,6 +336,7 @@ struct pg_conn
char *pgtty; /* tty on which the backend messages is
* displayed (OBSOLETE, NOT USED) */
char *connect_timeout; /* connection timeout (numeric string) */
+ char *pgtcp_user_timeout; /* TCP user timeout (numeric string) */
char *client_encoding_initial; /* encoding to use */
char *pgoptions; /* options to start the backend with */
char *appname; /* application name */
diff --git a/src/interfaces/libpq/tcpusertimeout.patch b/src/interfaces/libpq/tcpusertimeout.patch
new file mode 100644
index 0000000000..8199bf2e91
--- /dev/null
+++ b/src/interfaces/libpq/tcpusertimeout.patch
@@ -0,0 +1,75 @@
+diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
+index 8141e49719..d001bc513d 100644
+--- a/src/interfaces/libpq/fe-connect.c
++++ b/src/interfaces/libpq/fe-connect.c
+@@ -325,10 +325,6 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
+ "Target-Session-Attrs", "", 11, /* sizeof("read-write") = 11 */
+ offsetof(struct pg_conn, target_session_attrs)},
+
+- {"tcp_user_timeout",NULL,NULL,NULL,
+- "TCP-user-timeout",""10, /* strlen(INT32_MAX) == 10 */
+- offsetof(struct pg_conn,pgtcp_tcp_user_timeout)},
+-
+ /* Terminating entry --- MUST BE LAST */
+ {NULL, NULL, NULL, NULL,
+ NULL, NULL, 0}
+@@ -1775,38 +1771,6 @@ setKeepalivesWin32(PGconn *conn)
+ #endif /* SIO_KEEPALIVE_VALS */
+ #endif /* WIN32 */
+
+-/* set TCP user timeout */
+-static int
+-setTCPUserTimeout(PGconn *conn)
+-{
+- int timeout;
+-
+- if (conn->pgtcp_user_timeout)
+- {
+- timeout = atoi(conn->pgtcp_user_timeout);
+- if (timeout < 0)
+- tiemout = 0;
+- }
+- else
+- timeout = 12000;
+-
+-#ifdef __linux__
+- /* TCP_USER_TIMEOUT macro is not available on older Linux distros */
+- if (setsockopt(sonn->sock, IPPROTO_TCP, 18,
+- (cha *) &timeout, sizeof(timeout)) < 0 && errno != ENOPROTOOPT)
+- {
+- char sebuf[256];
+-
+- appendPQExpBuffer(&conn->errorMessage,
+- libpq_gettext("setsockopt(TCP_USER_TIMEOUT) failed: %s\n"),
+- SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
+- return 0;
+- }
+-#endif
+-
+- return 1;
+-}
+-
+ /* ----------
+ * connectDBStart -
+ * Begin the process of making a connection to the backend.
+@@ -3663,8 +3627,6 @@ freePGconn(PGconn *conn)
+ free(conn->pgtty);
+ if (conn->connect_timeout)
+ free(conn->connect_timeout);
+- if (conn->pgtcp_user_timeout)
+- free(pgtcp_user_timeout);
+ if (conn->pgoptions)
+ free(conn->pgoptions);
+ if (conn->appname)
+diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
+index 596db78380..975ab33d02 100644
+--- a/src/interfaces/libpq/libpq-int.h
++++ b/src/interfaces/libpq/libpq-int.h
+@@ -336,7 +336,6 @@ struct pg_conn
+ char *pgtty; /* tty on which the backend messages is
+ * displayed (OBSOLETE, NOT USED) */
+ char *connect_timeout; /* connection timeout (numeric string) */
+- char *pgtcp_user_timeout; /* TCP user timeout (numeric string) */
+ char *client_encoding_initial; /* encoding to use */
+ char *pgoptions; /* options to start the backend with */
+ char *appname; /* application name */