diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2015-02-13 21:46:14 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2015-02-13 21:46:14 +0200 |
commit | 80788a431e9bff06314a054109fdea66ac538199 (patch) | |
tree | 0dc2e4ee11fef85bbc3a9b42e9644ffab50a9d2f /src/backend/libpq/be-secure-openssl.c | |
parent | 272923a0a6956187471df4f032eee06559520390 (diff) | |
download | postgresql-80788a431e9bff06314a054109fdea66ac538199.tar.gz postgresql-80788a431e9bff06314a054109fdea66ac538199.zip |
Simplify waiting logic in reading from / writing to client.
The client socket is always in non-blocking mode, and if we actually want
blocking behaviour, we emulate it by sleeping and retrying. But we have
retry loops at different layers for reads and writes, which was confusing.
To simplify, remove all the sleeping and retrying code from the lower
levels, from be_tls_read and secure_raw_read and secure_raw_write, and put
all the logic in secure_read() and secure_write().
Diffstat (limited to 'src/backend/libpq/be-secure-openssl.c')
-rw-r--r-- | src/backend/libpq/be-secure-openssl.c | 81 |
1 files changed, 18 insertions, 63 deletions
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index d13ce334ccc..37af6e4fdaf 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -511,14 +511,11 @@ be_tls_close(Port *port) * Read data from a secure connection. */ ssize_t -be_tls_read(Port *port, void *ptr, size_t len) +be_tls_read(Port *port, void *ptr, size_t len, int *waitfor) { ssize_t n; int err; - int waitfor; - int latchret; -rloop: errno = 0; n = SSL_read(port->ssl, ptr, len); err = SSL_get_error(port->ssl, n); @@ -528,39 +525,15 @@ rloop: port->count += n; break; case SSL_ERROR_WANT_READ: + *waitfor = WL_SOCKET_READABLE; + errno = EWOULDBLOCK; + n = -1; + break; case SSL_ERROR_WANT_WRITE: - /* Don't retry if the socket is in nonblocking mode. */ - if (port->noblock) - { - errno = EWOULDBLOCK; - n = -1; - break; - } - - waitfor = WL_LATCH_SET; - - if (err == SSL_ERROR_WANT_READ) - waitfor |= WL_SOCKET_READABLE; - else - waitfor |= WL_SOCKET_WRITEABLE; - - latchret = WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0); - - /* - * We'll, among other situations, get here if the low level - * routine doing the actual recv() via the socket got interrupted - * by a signal. That's so we can handle interrupts once outside - * openssl, so we don't jump out from underneath its covers. We - * can check this both, when reading and writing, because even - * when writing that's just openssl's doing, not a 'proper' write - * initiated by postgres. - */ - if (latchret & WL_LATCH_SET) - { - ResetLatch(MyLatch); - ProcessClientReadInterrupt(true); /* preserves errno */ - } - goto rloop; + *waitfor = WL_SOCKET_WRITEABLE; + errno = EWOULDBLOCK; + n = -1; + break; case SSL_ERROR_SYSCALL: /* leave it to caller to ereport the value of errno */ if (n != -1) @@ -595,12 +568,10 @@ rloop: * Write data to a secure connection. */ ssize_t -be_tls_write(Port *port, void *ptr, size_t len) +be_tls_write(Port *port, void *ptr, size_t len, int *waitfor) { ssize_t n; int err; - int waitfor; - int latchret; /* * If SSL renegotiations are enabled and we're getting close to the @@ -630,7 +601,6 @@ be_tls_write(Port *port, void *ptr, size_t len) errmsg("SSL failure during renegotiation start"))); } -wloop: errno = 0; n = SSL_write(port->ssl, ptr, len); err = SSL_get_error(port->ssl, n); @@ -640,30 +610,15 @@ wloop: port->count += n; break; case SSL_ERROR_WANT_READ: + *waitfor = WL_SOCKET_READABLE; + errno = EWOULDBLOCK; + n = -1; + break; case SSL_ERROR_WANT_WRITE: - - waitfor = WL_LATCH_SET; - - if (err == SSL_ERROR_WANT_READ) - waitfor |= WL_SOCKET_READABLE; - else - waitfor |= WL_SOCKET_WRITEABLE; - - latchret = WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0); - - /* - * Check for interrupts here, in addition to secure_write(), - * because an interrupted write in secure_raw_write() will return - * here, and we cannot return to secure_write() until we've - * written something. - */ - if (latchret & WL_LATCH_SET) - { - ResetLatch(MyLatch); - ProcessClientWriteInterrupt(true); /* preserves errno */ - } - - goto wloop; + *waitfor = WL_SOCKET_WRITEABLE; + errno = EWOULDBLOCK; + n = -1; + break; case SSL_ERROR_SYSCALL: /* leave it to caller to ereport the value of errno */ if (n != -1) |