From 5b459b24696419c8747c506c26a813288ef899f5 Mon Sep 17 00:00:00 2001 From: Jacob Champion Date: Fri, 18 Jul 2025 10:06:13 -0700 Subject: [PATCH 1/2] WIP: extend "TLS read pending" concept to GSS too pgtls_read_pending() is renamed to pgtls_read_is_pending(), to avoid conflation with the forthcoming pgtls_drain_pending(). --- src/interfaces/libpq/fe-misc.c | 6 ++---- src/interfaces/libpq/fe-secure-gssapi.c | 6 ++++++ src/interfaces/libpq/fe-secure-openssl.c | 2 +- src/interfaces/libpq/fe-secure.c | 19 +++++++++++++++++++ src/interfaces/libpq/libpq-int.h | 4 +++- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index dca44fdc5d2..434216ff89f 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -1099,14 +1099,12 @@ pqSocketCheck(PGconn *conn, int forRead, int forWrite, pg_usec_time_t end_time) return -1; } -#ifdef USE_SSL - /* Check for SSL library buffering read bytes */ - if (forRead && conn->ssl_in_use && pgtls_read_pending(conn)) + /* Check for SSL/GSS library buffering read bytes */ + if (forRead && pqsecure_read_is_pending(conn)) { /* short-circuit the select */ return 1; } -#endif } /* We will retry as long as we get EINTR */ diff --git a/src/interfaces/libpq/fe-secure-gssapi.c b/src/interfaces/libpq/fe-secure-gssapi.c index bc9e1ce06fa..7c88e64cfd2 100644 --- a/src/interfaces/libpq/fe-secure-gssapi.c +++ b/src/interfaces/libpq/fe-secure-gssapi.c @@ -469,6 +469,12 @@ gss_read(PGconn *conn, void *recv_buffer, size_t length, ssize_t *ret) return PGRES_POLLING_OK; } +bool +pg_GSS_read_is_pending(PGconn *conn) +{ + return PqGSSResultLength > PqGSSResultNext; +} + /* * Negotiate GSSAPI transport for a connection. When complete, returns * PGRES_POLLING_OK. Will return PGRES_POLLING_READING or diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 51dd7b9fec0..8f975561e51 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -231,7 +231,7 @@ rloop: } bool -pgtls_read_pending(PGconn *conn) +pgtls_read_is_pending(PGconn *conn) { return SSL_pending(conn->ssl) > 0; } diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c index e686681ba15..94c97ec26fb 100644 --- a/src/interfaces/libpq/fe-secure.c +++ b/src/interfaces/libpq/fe-secure.c @@ -243,6 +243,25 @@ pqsecure_raw_read(PGconn *conn, void *ptr, size_t len) return n; } +/* + * Returns true if there are any bytes available in the transport buffer. + */ +bool +pqsecure_read_is_pending(PGconn *conn) +{ +#ifdef USE_SSL + if (conn->ssl_in_use) + return pgtls_read_is_pending(conn); +#endif +#ifdef ENABLE_GSS + if (conn->gssenc) + return pg_GSS_read_is_pending(conn); +#endif + + /* Plaintext connections have no transport buffer. */ + return 0; +} + /* * Write data to a secure connection. * diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index 70c28f2ffca..51bc2d3b740 100644 --- a/src/interfaces/libpq/libpq-int.h +++ b/src/interfaces/libpq/libpq-int.h @@ -809,6 +809,7 @@ extern int pqWriteReady(PGconn *conn); extern PostgresPollingStatusType pqsecure_open_client(PGconn *); extern void pqsecure_close(PGconn *); extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len); +extern bool pqsecure_read_is_pending(PGconn *); extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len); extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len); extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len); @@ -847,7 +848,7 @@ extern ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len); /* * Is there unread data waiting in the SSL read buffer? */ -extern bool pgtls_read_pending(PGconn *conn); +extern bool pgtls_read_is_pending(PGconn *conn); /* * Write data to a secure connection. @@ -895,6 +896,7 @@ extern PostgresPollingStatusType pqsecure_open_gss(PGconn *conn); */ extern ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len); extern ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len); +extern bool pg_GSS_read_is_pending(PGconn *conn); #endif /* === in fe-trace.c === */ -- 2.34.1