aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2013-12-05 12:48:31 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2013-12-05 12:48:31 -0500
commit2a6e1a55454bababea78af2db2f95c6eb7dd8ed5 (patch)
treeb397973cf6da5933718ac1683c17e33749ca0403 /src
parentc6cd27e36b9c58ceda8582ba81e37b6f9ad87d59 (diff)
downloadpostgresql-2a6e1a55454bababea78af2db2f95c6eb7dd8ed5.tar.gz
postgresql-2a6e1a55454bababea78af2db2f95c6eb7dd8ed5.zip
Clear retry flags properly in replacement OpenSSL sock_write function.
Current OpenSSL code includes a BIO_clear_retry_flags() step in the sock_write() function. Either we failed to copy the code correctly, or they added this since we copied it. In any case, lack of the clear step appears to be the cause of the server lockup after connection loss reported in bug #8647 from Valentine Gogichashvili. Assume that this is correct coding for all OpenSSL versions, and hence back-patch to all supported branches. Diagnosis and patch by Alexander Kukushkin.
Diffstat (limited to 'src')
-rw-r--r--src/backend/libpq/be-secure.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index cd088d2e0af..34f5b33c60b 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -411,7 +411,10 @@ wloop:
* non-reentrant libc facilities. We also need to call send() and recv()
* directly so it gets passed through the socket/signals layer on Win32.
*
- * They are closely modelled on the original socket implementations in OpenSSL.
+ * These functions are closely modelled on the standard socket BIO in OpenSSL;
+ * see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
+ * XXX OpenSSL 1.0.1e considers many more errcodes than just EINTR as reasons
+ * to retry; do we need to adopt their logic for that?
*/
static bool my_bio_initialized = false;
@@ -449,6 +452,7 @@ my_sock_write(BIO *h, const char *buf, int size)
int res = 0;
res = send(h->num, buf, size, 0);
+ BIO_clear_retry_flags(h);
if (res <= 0)
{
if (errno == EINTR)