aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2018-09-10 18:57:39 +0300
committerMaxim Dounin <mdounin@mdounin.ru>2018-09-10 18:57:39 +0300
commit05029e775fb0053e14a0b0b84d0c16f8e5d9d6a8 (patch)
treeb67a8eef1a7630a7910023fc04a552f4a4d0acfd
parentc2f90de0c56866bb4ef0630f89cee7904e687fba (diff)
downloadnginx-05029e775fb0053e14a0b0b84d0c16f8e5d9d6a8.tar.gz
nginx-05029e775fb0053e14a0b0b84d0c16f8e5d9d6a8.zip
SSL: restore handlers after blocking.
It is possible that after SSL_read() will return SSL_ERROR_WANT_WRITE, further calls will return SSL_ERROR_WANT_READ without reading any application data. We have to call ngx_handle_write_event() and switch back to normal write handling much like we do if there are some application data, or the write there will be reported again and again. Similarly, we have to switch back to normal read handling if there is saved read handler and SSL_write() returns SSL_ERROR_WANT_WRITE.
-rw-r--r--src/event/ngx_event_openssl.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index c9cae89d2..dead92806 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -1675,6 +1675,20 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
if (sslerr == SSL_ERROR_WANT_READ) {
+
+ if (c->ssl->saved_write_handler) {
+
+ c->write->handler = c->ssl->saved_write_handler;
+ c->ssl->saved_write_handler = NULL;
+ c->write->ready = 1;
+
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ ngx_post_event(c->write, &ngx_posted_events);
+ }
+
c->read->ready = 0;
return NGX_AGAIN;
}
@@ -1934,6 +1948,20 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
if (sslerr == SSL_ERROR_WANT_WRITE) {
+
+ if (c->ssl->saved_read_handler) {
+
+ c->read->handler = c->ssl->saved_read_handler;
+ c->ssl->saved_read_handler = NULL;
+ c->read->ready = 1;
+
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ ngx_post_event(c->read, &ngx_posted_events);
+ }
+
c->write->ready = 0;
return NGX_AGAIN;
}