diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/libpq/pqcomm.c | 94 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-connect.c | 60 |
2 files changed, 66 insertions, 88 deletions
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index c62f7e9ab33..4452ea4228c 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -97,6 +97,25 @@ #include "utils/memutils.h" /* + * Cope with the various platform-specific ways to spell TCP keepalive socket + * options. This doesn't cover Windows, which as usual does its own thing. + */ +#if defined(TCP_KEEPIDLE) +/* TCP_KEEPIDLE is the name of this option on Linux and *BSD */ +#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPIDLE +#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPIDLE" +#elif defined(TCP_KEEPALIVE_THRESHOLD) +/* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris >= 11 */ +#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE_THRESHOLD +#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE_THRESHOLD" +#elif defined(TCP_KEEPALIVE) && defined(__darwin__) +/* TCP_KEEPALIVE is the name of this option on macOS */ +/* Caution: Solaris has this symbol but it means something different */ +#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE +#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE" +#endif + +/* * Configuration options */ int Unix_socket_permissions; @@ -742,7 +761,7 @@ StreamConnection(pgsocket server_fd, Port *port) if (setsockopt(port->sock, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) { - elog(LOG, "setsockopt(TCP_NODELAY) failed: %m"); + elog(LOG, "setsockopt(%s) failed: %m", "TCP_NODELAY"); return STATUS_ERROR; } #endif @@ -750,7 +769,7 @@ StreamConnection(pgsocket server_fd, Port *port) if (setsockopt(port->sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) { - elog(LOG, "setsockopt(SO_KEEPALIVE) failed: %m"); + elog(LOG, "setsockopt(%s) failed: %m", "SO_KEEPALIVE"); return STATUS_ERROR; } @@ -781,7 +800,7 @@ StreamConnection(pgsocket server_fd, Port *port) if (getsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &oldopt, &optlen) < 0) { - elog(LOG, "getsockopt(SO_SNDBUF) failed: %m"); + elog(LOG, "getsockopt(%s) failed: %m", "SO_SNDBUF"); return STATUS_ERROR; } newopt = PQ_SEND_BUFFER_SIZE * 4; @@ -790,7 +809,7 @@ StreamConnection(pgsocket server_fd, Port *port) if (setsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &newopt, sizeof(newopt)) < 0) { - elog(LOG, "setsockopt(SO_SNDBUF) failed: %m"); + elog(LOG, "setsockopt(%s) failed: %m", "SO_SNDBUF"); return STATUS_ERROR; } } @@ -1676,7 +1695,7 @@ pq_setkeepaliveswin32(Port *port, int idle, int interval) int pq_getkeepalivesidle(Port *port) { -#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE_THRESHOLD) || defined(TCP_KEEPALIVE) || defined(WIN32) +#if defined(PG_TCP_KEEPALIVE_IDLE) || defined(SIO_KEEPALIVE_VALS) if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family)) return 0; @@ -1688,34 +1707,13 @@ pq_getkeepalivesidle(Port *port) #ifndef WIN32 ACCEPT_TYPE_ARG3 size = sizeof(port->default_keepalives_idle); -#if defined(TCP_KEEPIDLE) - /* TCP_KEEPIDLE is the name of this option on Linux and *BSD */ - if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE, - (char *) &port->default_keepalives_idle, - &size) < 0) - { - elog(LOG, "getsockopt(TCP_KEEPIDLE) failed: %m"); - port->default_keepalives_idle = -1; /* don't know */ - } -#elif defined(TCP_KEEPALIVE_THRESHOLD) - /* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */ - if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, + if (getsockopt(port->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE, (char *) &port->default_keepalives_idle, &size) < 0) { - elog(LOG, "getsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %m"); + elog(LOG, "getsockopt(%s) failed: %m", PG_TCP_KEEPALIVE_IDLE_STR); port->default_keepalives_idle = -1; /* don't know */ } -#else /* must have TCP_KEEPALIVE */ - /* TCP_KEEPALIVE is the name of this option on macOS */ - if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE, - (char *) &port->default_keepalives_idle, - &size) < 0) - { - elog(LOG, "getsockopt(TCP_KEEPALIVE) failed: %m"); - port->default_keepalives_idle = -1; /* don't know */ - } -#endif /* KEEPIDLE/KEEPALIVE_THRESHOLD/KEEPALIVE */ #else /* WIN32 */ /* We can't get the defaults on Windows, so return "don't know" */ port->default_keepalives_idle = -1; @@ -1735,7 +1733,7 @@ pq_setkeepalivesidle(int idle, Port *port) return STATUS_OK; /* check SIO_KEEPALIVE_VALS here, not just WIN32, as some toolchains lack it */ -#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE_THRESHOLD) || defined(TCP_KEEPALIVE) || defined(SIO_KEEPALIVE_VALS) +#if defined(PG_TCP_KEEPALIVE_IDLE) || defined(SIO_KEEPALIVE_VALS) if (idle == port->keepalives_idle) return STATUS_OK; @@ -1754,43 +1752,25 @@ pq_setkeepalivesidle(int idle, Port *port) if (idle == 0) idle = port->default_keepalives_idle; -#if defined(TCP_KEEPIDLE) - /* TCP_KEEPIDLE is the name of this option on Linux and *BSD */ - if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE, - (char *) &idle, sizeof(idle)) < 0) - { - elog(LOG, "setsockopt(TCP_KEEPIDLE) failed: %m"); - return STATUS_ERROR; - } -#elif defined(TCP_KEEPALIVE_THRESHOLD) - /* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */ - if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, + if (setsockopt(port->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE, (char *) &idle, sizeof(idle)) < 0) { - elog(LOG, "setsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %m"); + elog(LOG, "setsockopt(%s) failed: %m", PG_TCP_KEEPALIVE_IDLE_STR); return STATUS_ERROR; } -#else /* must have TCP_KEEPALIVE */ - /* TCP_KEEPALIVE is the name of this option on macOS */ - if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE, - (char *) &idle, sizeof(idle)) < 0) - { - elog(LOG, "setsockopt(TCP_KEEPALIVE) failed: %m"); - return STATUS_ERROR; - } -#endif port->keepalives_idle = idle; #else /* WIN32 */ return pq_setkeepaliveswin32(port, idle, port->keepalives_interval); #endif -#else /* no way to set it */ +#else if (idle != 0) { elog(LOG, "setting the keepalive idle time is not supported"); return STATUS_ERROR; } #endif + return STATUS_OK; } @@ -1813,7 +1793,7 @@ pq_getkeepalivesinterval(Port *port) (char *) &port->default_keepalives_interval, &size) < 0) { - elog(LOG, "getsockopt(TCP_KEEPINTVL) failed: %m"); + elog(LOG, "getsockopt(%s) failed: %m", "TCP_KEEPINTVL"); port->default_keepalives_interval = -1; /* don't know */ } #else @@ -1856,7 +1836,7 @@ pq_setkeepalivesinterval(int interval, Port *port) if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPINTVL, (char *) &interval, sizeof(interval)) < 0) { - elog(LOG, "setsockopt(TCP_KEEPINTVL) failed: %m"); + elog(LOG, "setsockopt(%s) failed: %m", "TCP_KEEPINTVL"); return STATUS_ERROR; } @@ -1867,7 +1847,7 @@ pq_setkeepalivesinterval(int interval, Port *port) #else if (interval != 0) { - elog(LOG, "setsockopt(TCP_KEEPINTVL) not supported"); + elog(LOG, "setsockopt(%s) not supported", "TCP_KEEPINTVL"); return STATUS_ERROR; } #endif @@ -1893,7 +1873,7 @@ pq_getkeepalivescount(Port *port) (char *) &port->default_keepalives_count, &size) < 0) { - elog(LOG, "getsockopt(TCP_KEEPCNT) failed: %m"); + elog(LOG, "getsockopt(%s) failed: %m", "TCP_KEEPCNT"); port->default_keepalives_count = -1; /* don't know */ } } @@ -1931,7 +1911,7 @@ pq_setkeepalivescount(int count, Port *port) if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPCNT, (char *) &count, sizeof(count)) < 0) { - elog(LOG, "setsockopt(TCP_KEEPCNT) failed: %m"); + elog(LOG, "setsockopt(%s) failed: %m", "TCP_KEEPCNT"); return STATUS_ERROR; } @@ -1939,7 +1919,7 @@ pq_setkeepalivescount(int count, Port *port) #else if (count != 0) { - elog(LOG, "setsockopt(TCP_KEEPCNT) not supported"); + elog(LOG, "setsockopt(%s) not supported", "TCP_KEEPCNT"); return STATUS_ERROR; } #endif diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index e32c42b4b6b..2f7b4060df0 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -95,6 +95,25 @@ static int ldapServiceLookup(const char *purl, PQconninfoOption *options, #define ERRCODE_CANNOT_CONNECT_NOW "57P03" /* + * Cope with the various platform-specific ways to spell TCP keepalive socket + * options. This doesn't cover Windows, which as usual does its own thing. + */ +#if defined(TCP_KEEPIDLE) +/* TCP_KEEPIDLE is the name of this option on Linux and *BSD */ +#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPIDLE +#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPIDLE" +#elif defined(TCP_KEEPALIVE_THRESHOLD) +/* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris >= 11 */ +#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE_THRESHOLD +#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE_THRESHOLD" +#elif defined(TCP_KEEPALIVE) && defined(__darwin__) +/* TCP_KEEPALIVE is the name of this option on macOS */ +/* Caution: Solaris has this symbol but it means something different */ +#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE +#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE" +#endif + +/* * fall back options if they are not specified by arguments or defined * by environment variables */ @@ -1470,39 +1489,15 @@ setKeepalivesIdle(PGconn *conn) if (idle < 0) idle = 0; -#if defined(TCP_KEEPIDLE) - /* TCP_KEEPIDLE is the name of this option on Linux and *BSD */ - if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPIDLE, - (char *) &idle, sizeof(idle)) < 0) - { - char sebuf[256]; - - appendPQExpBuffer(&conn->errorMessage, - libpq_gettext("setsockopt(TCP_KEEPIDLE) failed: %s\n"), - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - return 0; - } -#elif defined(TCP_KEEPALIVE_THRESHOLD) - /* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */ - if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, - (char *) &idle, sizeof(idle)) < 0) - { - char sebuf[256]; - - appendPQExpBuffer(&conn->errorMessage, - libpq_gettext("setsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %s\n"), - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - return 0; - } -#elif defined(TCP_KEEPALIVE) - /* TCP_KEEPALIVE is the name of this option on macOS */ - if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPALIVE, +#ifdef PG_TCP_KEEPALIVE_IDLE + if (setsockopt(conn->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE, (char *) &idle, sizeof(idle)) < 0) { char sebuf[256]; appendPQExpBuffer(&conn->errorMessage, - libpq_gettext("setsockopt(TCP_KEEPALIVE) failed: %s\n"), + libpq_gettext("setsockopt(%s) failed: %s\n"), + PG_TCP_KEEPALIVE_IDLE_STR, SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); return 0; } @@ -1533,7 +1528,8 @@ setKeepalivesInterval(PGconn *conn) char sebuf[256]; appendPQExpBuffer(&conn->errorMessage, - libpq_gettext("setsockopt(TCP_KEEPINTVL) failed: %s\n"), + libpq_gettext("setsockopt(%s) failed: %s\n"), + "TCP_KEEPINTVL", SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); return 0; } @@ -1565,7 +1561,8 @@ setKeepalivesCount(PGconn *conn) char sebuf[256]; appendPQExpBuffer(&conn->errorMessage, - libpq_gettext("setsockopt(TCP_KEEPCNT) failed: %s\n"), + libpq_gettext("setsockopt(%s) failed: %s\n"), + "TCP_KEEPCNT", SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); return 0; } @@ -2123,7 +2120,8 @@ keep_going: /* We will come back to here until there is (char *) &on, sizeof(on)) < 0) { appendPQExpBuffer(&conn->errorMessage, - libpq_gettext("setsockopt(SO_KEEPALIVE) failed: %s\n"), + libpq_gettext("setsockopt(%s) failed: %s\n"), + "SO_KEEPALIVE", SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); err = 1; } |