From bce293e4a7b2a3d9d6518260c74dc3cb7233e342 Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Wed, 27 Jul 2016 02:24:53 -0400 Subject: [PATCH] [TLS] better handling of SSL_ERROR_WANT_READ/WRITE better handling of SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE --- src/connections-glue.c | 3 ++- src/connections.c | 9 +++++++++ src/network_openssl.c | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/connections-glue.c b/src/connections-glue.c index eee19071..2d60ec20 100644 --- a/src/connections-glue.c +++ b/src/connections-glue.c @@ -133,8 +133,9 @@ static int connection_handle_read_ssl(server *srv, connection *con) { if (len < 0) { int oerrno = errno; switch ((r = SSL_get_error(con->ssl, len))) { - case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: + con->is_writable = -1; + case SSL_ERROR_WANT_READ: con->is_readable = 0; /* the manual says we have to call SSL_read with the same arguments next time. diff --git a/src/connections.c b/src/connections.c index 790241ae..ac4a682e 100644 --- a/src/connections.c +++ b/src/connections.c @@ -207,6 +207,7 @@ static void connection_handle_shutdown(server *srv, connection *con) { case SSL_ERROR_ZERO_RETURN: break; case SSL_ERROR_WANT_WRITE: + /*con->is_writable = -1;*//*(no effect; shutdown() called below)*/ case SSL_ERROR_WANT_READ: break; case SSL_ERROR_SYSCALL: @@ -1400,6 +1401,14 @@ int connection_state_machine(server *srv, connection *con) { } if (-1 != con->fd) { const int events = fdevent_event_get_interest(srv->ev, con->fd); + if (con->is_readable < 0) { + con->is_readable = 0; + r |= FDEVENT_IN; + } + if (con->is_writable < 0) { + con->is_writable = 0; + r |= FDEVENT_OUT; + } if (r != events) { /* update timestamps when enabling interest in events */ if ((r & FDEVENT_IN) && !(events & FDEVENT_IN)) { diff --git a/src/network_openssl.c b/src/network_openssl.c index 4cf2cc48..9a9138ed 100644 --- a/src/network_openssl.c +++ b/src/network_openssl.c @@ -125,7 +125,11 @@ int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chu unsigned long err; switch ((ssl_r = SSL_get_error(ssl, r))) { + case SSL_ERROR_WANT_READ: + con->is_readable = -1; + return 0; /* try again later */ case SSL_ERROR_WANT_WRITE: + con->is_writable = -1; return 0; /* try again later */ case SSL_ERROR_SYSCALL: /* perhaps we have error waiting in our error-queue */