summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzat Khuzhin <azat@libevent.org>2023-05-14 20:04:34 +0200
committerAzat Khuzhin <azat@libevent.org>2023-05-14 20:04:44 +0200
commite8cbe7b6e12a7b43dde726dfe08922c300fd9430 (patch)
treed8069f294310ef5c1dee9b318edafae57ae53d47
parentd06e573c600c46d1c4585be78f4329b300fb4a65 (diff)
parent7652cf4068f77905a56b9165455ec7e90917ec31 (diff)
downloadlibevent-e8cbe7b6e12a7b43dde726dfe08922c300fd9430.tar.gz
Merge branch 'ssl/fix-partial-read' - #1451
* ssl/fix-partial-read: ssl: do not triger EOF if some data had been successfully read ssl: rename err_is_ok to handshake_is_ok (internal API)
-rw-r--r--bufferevent_mbedtls.c11
-rw-r--r--bufferevent_openssl.c13
-rw-r--r--bufferevent_ssl.c7
-rw-r--r--ssl-compat.h3
4 files changed, 27 insertions, 7 deletions
diff --git a/bufferevent_mbedtls.c b/bufferevent_mbedtls.c
index 95859bd3..765d00be 100644
--- a/bufferevent_mbedtls.c
+++ b/bufferevent_mbedtls.c
@@ -121,8 +121,9 @@ mbedtls_set_ssl_noops(void *ssl)
{
}
static int
-mbedtls_is_ok(int err)
+mbedtls_handshake_is_ok(int err)
{
+ /* What mbedtls_ssl_handshake() return on success */
return err == 0;
}
static int
@@ -135,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)
@@ -320,9 +326,10 @@ static struct le_ssl_ops le_mbedtls_ops = {
mbedtls_clear,
mbedtls_set_ssl_noops,
mbedtls_set_ssl_noops,
- mbedtls_is_ok,
+ 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 c74a76e4..4ef3925a 100644
--- a/bufferevent_openssl.c
+++ b/bufferevent_openssl.c
@@ -339,12 +339,20 @@ SSL_context_free(void *ssl, int flags)
}
static int
-SSL_is_ok(int err)
+SSL_handshake_is_ok(int err)
{
+ /* What SSL_do_handshake() return on success */
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)
{
return err == SSL_ERROR_WANT_READ;
@@ -413,9 +421,10 @@ static struct le_ssl_ops le_openssl_ops = {
(int (*)(void *))SSL_clear,
(void (*)(void *))SSL_set_connect_state,
(void (*)(void *))SSL_set_accept_state,
- SSL_is_ok,
+ 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 64c36ae6..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)
@@ -706,7 +709,7 @@ do_handshake(struct bufferevent_ssl *bev_ssl)
}
bev_ssl->ssl_ops->decrement_buckets(bev_ssl);
- if (bev_ssl->ssl_ops->err_is_ok(r)) {
+ if (bev_ssl->ssl_ops->handshake_is_ok(r)) {
evutil_socket_t fd = event_get_fd(&bev_ssl->bev.bev.ev_read);
/* We're done! */
bev_ssl->state = BUFFEREVENT_SSL_OPEN;
diff --git a/ssl-compat.h b/ssl-compat.h
index 4dccb52a..146fdaf3 100644
--- a/ssl-compat.h
+++ b/ssl-compat.h
@@ -20,9 +20,10 @@ struct le_ssl_ops {
int (*clear)(void *ssl);
void (*set_connect_state)(void *ssl);
void (*set_accept_state)(void *ssl);
- int (*err_is_ok)(int err);
+ 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);