diff options
author | Rainer Jung <rjung@apache.org> | 2018-10-15 23:14:21 +0200 |
---|---|---|
committer | Rainer Jung <rjung@apache.org> | 2018-10-15 23:14:21 +0200 |
commit | 5bfbbcf9a23c01f2a6219d00121bcf89cfba1252 (patch) | |
tree | a7ffebb2ed3fd86cdce3ec2510c938a2afb8a687 /modules | |
parent | * Ensure that aborted connections are logged as such. (diff) | |
download | apache2-5bfbbcf9a23c01f2a6219d00121bcf89cfba1252.tar.xz apache2-5bfbbcf9a23c01f2a6219d00121bcf89cfba1252.zip |
SSL_read() doesn't distinguish between return value 0 and <0,
at least not for OpenSSL 1.1.1. This is documented in the man
page for SSL_read and let to h2 failures when using OpenSSL 1.1.1.
When no data could be read, our code returned EAGAIN up until
OpenSSL 1.1.0, but APR_EOF for OpenSSL 1.1.1.
Now instead check SSL_get_error() also when SSL_read() returns 0.
To keep changes small, this change should not influence behavior,
when (rc=SSL_read()):
- rc < 0
- rc == 0 && *len > 0
- rc == 0 &&
(APR_STATUS_IS_EAGAIN(inctx->rc) || APR_STATUS_IS_EINTR(inctx->rc) &&
inctx->block == APR_NONBLOCK_READ
Behavior changes if
- rc == 0 &&
!(APR_STATUS_IS_EAGAIN(inctx->rc) || APR_STATUS_IS_EINTR(inctx->rc) &&
!*len > 0
Instead of APR_EOF:
- same behavior as rc < 0 for SSL_ERROR_WANT_READ
- same behavior as rc < 0 for SSL_ERROR_SYSCALL && APR_STATUS_IS_EAGAIN(inctx->rc)
Another change is that rc == 0 && ssl_err == SSL_ERROR_ZERO_RETURN
also results in APR_EOF.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1843954 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r-- | modules/ssl/ssl_engine_io.c | 59 |
1 files changed, 33 insertions, 26 deletions
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 204b7f5481..5f7d10457a 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -715,37 +715,36 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx, } return inctx->rc; } - else if (rc == 0) { - /* If EAGAIN, we will loop given a blocking read, - * otherwise consider ourselves at EOF. - */ - if (APR_STATUS_IS_EAGAIN(inctx->rc) - || APR_STATUS_IS_EINTR(inctx->rc)) { - /* Already read something, return APR_SUCCESS instead. - * On win32 in particular, but perhaps on other kernels, - * a blocking call isn't 'always' blocking. + else /* (rc <= 0) */ { + int ssl_err; + conn_rec *c; + if (rc == 0) { + /* If EAGAIN, we will loop given a blocking read, + * otherwise consider ourselves at EOF. */ - if (*len > 0) { - inctx->rc = APR_SUCCESS; - break; - } - if (inctx->block == APR_NONBLOCK_READ) { - break; - } - } - else { - if (*len > 0) { - inctx->rc = APR_SUCCESS; + if (APR_STATUS_IS_EAGAIN(inctx->rc) + || APR_STATUS_IS_EINTR(inctx->rc)) { + /* Already read something, return APR_SUCCESS instead. + * On win32 in particular, but perhaps on other kernels, + * a blocking call isn't 'always' blocking. + */ + if (*len > 0) { + inctx->rc = APR_SUCCESS; + break; + } + if (inctx->block == APR_NONBLOCK_READ) { + break; + } } else { - inctx->rc = APR_EOF; + if (*len > 0) { + inctx->rc = APR_SUCCESS; + break; + } } - break; } - } - else /* (rc < 0) */ { - int ssl_err = SSL_get_error(inctx->filter_ctx->pssl, rc); - conn_rec *c = (conn_rec*)SSL_get_app_data(inctx->filter_ctx->pssl); + ssl_err = SSL_get_error(inctx->filter_ctx->pssl, rc); + c = (conn_rec*)SSL_get_app_data(inctx->filter_ctx->pssl); if (ssl_err == SSL_ERROR_WANT_READ) { /* @@ -789,6 +788,10 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx, "SSL input filter read failed."); } } + else if (rc == 0 && ssl_err == SSL_ERROR_ZERO_RETURN) { + inctx->rc = APR_EOF; + break; + } else /* if (ssl_err == SSL_ERROR_SSL) */ { /* * Log SSL errors and any unexpected conditions. @@ -798,6 +801,10 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx, ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, mySrvFromConn(c)); } + if (rc == 0) { + inctx->rc = APR_EOF; + break; + } if (inctx->rc == APR_SUCCESS) { inctx->rc = APR_EGENERAL; } |