summaryrefslogtreecommitdiff
path: root/modules/ssl/ssl_engine_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/ssl/ssl_engine_io.c')
-rw-r--r--modules/ssl/ssl_engine_io.c53
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;