diff options
author | Azat Khuzhin <azat@libevent.org> | 2023-05-14 16:53:13 +0200 |
---|---|---|
committer | Azat Khuzhin <azat@libevent.org> | 2023-05-14 16:53:13 +0200 |
commit | 7652cf4068f77905a56b9165455ec7e90917ec31 (patch) | |
tree | d8069f294310ef5c1dee9b318edafae57ae53d47 | |
parent | 6375dcb46db4bb05c9c19c980f3ed6d0ff9b1065 (diff) | |
download | libevent-7652cf4068f77905a56b9165455ec7e90917ec31.tar.gz |
ssl: do not triger EOF if some data had been successfully read
Previously in case when evbuffer_reserve_space() returns > 1, but
it was able to read only 1 IO vector, it will try to read the next one,
got 0 (EOF for mbedTLS or SSL_ERROR_ZERO_RETURN for OpenSSL) and will
trigger EOF, while instead, it should trigger EV_READ w/o EOF and only
after EOF.
-rw-r--r-- | bufferevent_mbedtls.c | 6 | ||||
-rw-r--r-- | bufferevent_openssl.c | 8 | ||||
-rw-r--r-- | bufferevent_ssl.c | 5 | ||||
-rw-r--r-- | ssl-compat.h | 1 |
4 files changed, 19 insertions, 1 deletions
diff --git a/bufferevent_mbedtls.c b/bufferevent_mbedtls.c index b0e960fa..765d00be 100644 --- a/bufferevent_mbedtls.c +++ b/bufferevent_mbedtls.c @@ -136,6 +136,11 @@ mbedtls_is_want_write(int err) { return err == MBEDTLS_ERR_SSL_WANT_WRITE; } +static int mbedtls_err_is_ok(int err) +{ + /* What mbedtls_ssl_read() returns when the we can proceed existing data */ + return err == 0; +} static evutil_socket_t be_mbedtls_get_fd(void *ssl) @@ -324,6 +329,7 @@ static struct le_ssl_ops le_mbedtls_ops = { mbedtls_handshake_is_ok, mbedtls_is_want_read, mbedtls_is_want_write, + mbedtls_err_is_ok, be_mbedtls_get_fd, be_mbedtls_bio_set_fd, (void (*)(struct bufferevent_ssl *))mbedtls_set_ssl_noops, diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c index f5d0808c..4ef3925a 100644 --- a/bufferevent_openssl.c +++ b/bufferevent_openssl.c @@ -346,6 +346,13 @@ SSL_handshake_is_ok(int err) } static int +SSL_err_is_ok(int err) +{ + /* What SSL_read() returns when the we can proceed existing data */ + return err == SSL_ERROR_ZERO_RETURN; +} + +static int SSL_is_want_read(int err) { return err == SSL_ERROR_WANT_READ; @@ -417,6 +424,7 @@ static struct le_ssl_ops le_openssl_ops = { SSL_handshake_is_ok, SSL_is_want_read, SSL_is_want_write, + SSL_err_is_ok, (int (*)(void *))be_openssl_get_fd, be_openssl_bio_set_fd, init_bio_counts, diff --git a/bufferevent_ssl.c b/bufferevent_ssl.c index 847c8b67..17046b82 100644 --- a/bufferevent_ssl.c +++ b/bufferevent_ssl.c @@ -284,7 +284,10 @@ do_read(struct bufferevent_ssl *bev_ssl, int n_to_read) { } else { int err = bev_ssl->ssl_ops->get_error(bev_ssl->ssl, r); bev_ssl->ssl_ops->print_err(err); - if (bev_ssl->ssl_ops->err_is_want_read(err)) { + if (bev_ssl->ssl_ops->err_is_ok(err) && result & OP_MADE_PROGRESS) { + /* Process existing data */ + break; + } else if (bev_ssl->ssl_ops->err_is_want_read(err)) { /* Can't read until underlying has more data. */ if (bev_ssl->read_blocked_on_write) if (clear_rbow(bev_ssl) < 0) diff --git a/ssl-compat.h b/ssl-compat.h index a556f4c0..146fdaf3 100644 --- a/ssl-compat.h +++ b/ssl-compat.h @@ -23,6 +23,7 @@ struct le_ssl_ops { int (*handshake_is_ok)(int err); int (*err_is_want_read)(int err); int (*err_is_want_write)(int err); + int (*err_is_ok)(int err); evutil_socket_t (*get_fd)(void *ssl); int (*bio_set_fd)(struct bufferevent_ssl *ssl, evutil_socket_t fd); void (*init_bio_counts)(struct bufferevent_ssl *bev); |