diff options
Diffstat (limited to 'modules/ssl/ssl_engine_io.c')
-rw-r--r-- | modules/ssl/ssl_engine_io.c | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 47e3f30cdc..4445b1f787 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -323,6 +323,7 @@ typedef struct { } char_buffer_t; typedef struct { + conn_rec *c; SSL *ssl; BIO *bio_out; ap_filter_t *f; @@ -795,6 +796,32 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx, * (This is usually the case when the client forces an SSL * renegotiation which is handled implicitly by OpenSSL.) */ + if (inctx->c->cs) { + inctx->c->cs->sense = CONN_SENSE_WANT_READ; + } + inctx->rc = APR_EAGAIN; + + if (*len > 0) { + inctx->rc = APR_SUCCESS; + break; + } + if (inctx->block == APR_NONBLOCK_READ) { + break; + } + continue; /* Blocking and nothing yet? Try again. */ + } + if (ssl_err == SSL_ERROR_WANT_WRITE) { + /* + * If OpenSSL wants to write during read, and we were + * nonblocking, report as an EAGAIN. Otherwise loop, + * pulling more data from network filter. + * + * (This is usually the case when the client forces an SSL + * renegotiation which is handled implicitly by OpenSSL.) + */ + if (inctx->c->cs) { + inctx->c->cs->sense = CONN_SENSE_WANT_WRITE; + } inctx->rc = APR_EAGAIN; if (*len > 0) { @@ -960,7 +987,9 @@ static apr_status_t ssl_filter_write(ap_filter_t *f, * (This is usually the case when the client forces an SSL * renegotiation which is handled implicitly by OpenSSL.) */ - outctx->c->cs->sense = CONN_SENSE_WANT_READ; + if (outctx->c->cs) { + outctx->c->cs->sense = CONN_SENSE_WANT_READ; + } outctx->rc = APR_EAGAIN; ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c, "Want read during nonblocking write"); @@ -1489,10 +1518,25 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx) } else if (ssl_err == SSL_ERROR_WANT_READ) { /* - * This is in addition to what was present earlier. It is - * borrowed from openssl_state_machine.c [mod_tls]. - * TBD. + * Call us back when ready to read *\/ */ + ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c, + "Want read during nonblocking accept"); + if (outctx->c->cs) { + outctx->c->cs->sense = CONN_SENSE_WANT_READ; + } + outctx->rc = APR_EAGAIN; + return APR_EAGAIN; + } + else if (ssl_err == SSL_ERROR_WANT_WRITE) { + /* + * Call us back when ready to write *\/ + */ + ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c, + "Want write during nonblocking accept"); + if (outctx->c->cs) { + outctx->c->cs->sense = CONN_SENSE_WANT_WRITE; + } outctx->rc = APR_EAGAIN; return APR_EAGAIN; } @@ -2295,6 +2339,7 @@ static apr_status_t ssl_io_input_add_filter(ssl_filter_ctx_t *filter_ctx, conn_r } BIO_set_data(filter_ctx->pbioRead, (void *)inctx); + inctx->c = c; inctx->ssl = ssl; inctx->bio_out = filter_ctx->pbioWrite; inctx->f = filter_ctx->pInputFilter; |