Skip to content

Commit f8a1dbd

Browse files
fcanovaihackorum
authored andcommitted
Support TCP_SYNCNT in libpq
Add a tcp_syn_count parameter to libpq. This will allow the user to define the maximum amount of retransmission that TCP will send before aborting the attempt to establish a connection. This can be used only on systems where TCP_SYNCNT is available.
1 parent d29d469 commit f8a1dbd

3 files changed

Lines changed: 65 additions & 0 deletions

File tree

doc/src/sgml/libpq.sgml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,21 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
15761576
</listitem>
15771577
</varlistentry>
15781578

1579+
<varlistentry id="libpq-tcp-syn-count" xreflabel="tcp_syn_count">
1580+
<term><literal>tcp_syn_count</literal></term>
1581+
<listitem>
1582+
<para>
1583+
Controls the maximum number of SYN retransmissions that TCP
1584+
will send before aborting the attempt to establish a connection.
1585+
A higher value increases the number of retries before giving up,
1586+
while a lower value results in faster failure detection.
1587+
This parameter is only effective on systems where
1588+
<symbol>TCP_SYNCNT</symbol> is available; on other systems,
1589+
it has no effect.
1590+
</para>
1591+
</listitem>
1592+
</varlistentry>
1593+
15791594
<varlistentry id="libpq-connect-replication" xreflabel="replication">
15801595
<term><literal>replication</literal></term>
15811596
<listitem>

src/interfaces/libpq/fe-connect.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,10 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
279279
"TCP-User-Timeout", "", 10, /* strlen(INT32_MAX) == 10 */
280280
offsetof(struct pg_conn, pgtcp_user_timeout)},
281281

282+
{"tcp_syn_count", NULL, NULL, NULL,
283+
"TCP-SYN-Count", "", 10, /* strlen(INT32_MAX) == 10 */
284+
offsetof(struct pg_conn, tcp_syn_count)},
285+
282286
/*
283287
* ssl options are allowed even without client SSL support because the
284288
* client can still handle SSL modes "disable" and "allow". Other
@@ -2713,6 +2717,41 @@ setTCPUserTimeout(PGconn *conn)
27132717
return 1;
27142718
}
27152719

2720+
/*
2721+
* Set the maximum number of SYN retransmissions.
2722+
*/
2723+
static int
2724+
setTCPSynCnt(PGconn *conn)
2725+
{
2726+
int count;
2727+
2728+
if (conn->tcp_syn_count == NULL)
2729+
return 1;
2730+
2731+
if (!pqParseIntParam(conn->tcp_syn_count, &count, conn,
2732+
"tcp_syn_count"))
2733+
return 0;
2734+
2735+
if (count < 0)
2736+
count = 0;
2737+
2738+
#ifdef TCP_SYNCNT
2739+
if (setsockopt(conn->sock, IPPROTO_TCP, TCP_SYNCNT,
2740+
(char *) &count, sizeof(count)) < 0)
2741+
{
2742+
char sebuf[PG_STRERROR_R_BUFLEN];
2743+
2744+
libpq_append_conn_error(conn, "%s(%s) failed: %s",
2745+
"setsockopt",
2746+
"TCP_SYNCNT",
2747+
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2748+
return 0;
2749+
}
2750+
#endif
2751+
2752+
return 1;
2753+
}
2754+
27162755
/* ----------
27172756
* pqConnectDBStart -
27182757
* Begin the process of making a connection to the backend.
@@ -3454,6 +3493,15 @@ PQconnectPoll(PGconn *conn)
34543493
}
34553494
}
34563495

3496+
if (addr_cur->family != AF_UNIX)
3497+
{
3498+
if (!setTCPSynCnt(conn))
3499+
{
3500+
conn->try_next_addr = true;
3501+
goto keep_going;
3502+
}
3503+
}
3504+
34573505
/*----------
34583506
* We have three methods of blocking SIGPIPE during
34593507
* send() calls to this socket:
@@ -5130,6 +5178,7 @@ freePGconn(PGconn *conn)
51305178
free(conn->keepalives_idle);
51315179
free(conn->keepalives_interval);
51325180
free(conn->keepalives_count);
5181+
free(conn->tcp_syn_count);
51335182
free(conn->sslmode);
51345183
free(conn->sslnegotiation);
51355184
free(conn->sslcompression);

src/interfaces/libpq/libpq-int.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ struct pg_conn
405405
* retransmits */
406406
char *keepalives_count; /* maximum number of TCP keepalive
407407
* retransmits */
408+
char *tcp_syn_count; /* maximum number of TCP SYN retransmits */
408409
char *sslmode; /* SSL mode (require,prefer,allow,disable) */
409410
char *sslnegotiation; /* SSL initiation style (postgres,direct) */
410411
char *sslcompression; /* SSL compression (0 or 1) */

0 commit comments

Comments
 (0)