From 7652cf4068f77905a56b9165455ec7e90917ec31 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 14 May 2023 16:53:13 +0200 Subject: 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. --- bufferevent_mbedtls.c | 6 ++++++ bufferevent_openssl.c | 8 ++++++++ bufferevent_ssl.c | 5 ++++- ssl-compat.h | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) 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 @@ -345,6 +345,13 @@ SSL_handshake_is_ok(int err) return err == 1; } +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) { @@ -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); -- cgit v1.2.1