From fc568ff045e6a8956221c3f095ed8e7200fa5f74 Mon Sep 17 00:00:00 2001 From: zhenhaonong Date: Fri, 17 Mar 2023 19:53:50 +0800 Subject: [PATCH] Deal with partial writes on SSL write SSL write may do partial writes in some cases. For example, document of mbedtls_ssl_write says: If the return value is non-negative but less than length, the function must be called again with updated arguments: buf + ret, len - ret (if ret is the return value) until it returns a value equal to the last 'len' argument. In case of partial writes, we should continue writing the same chain of buffer, not the next chain. --- bufferevent_ssl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bufferevent_ssl.c b/bufferevent_ssl.c index 837b84c4..64c36ae6 100644 --- a/bufferevent_ssl.c +++ b/bufferevent_ssl.c @@ -339,15 +339,17 @@ do_write(struct bufferevent_ssl *bev_ssl, int atmost) if (n > 8) n = 8; - for (i=0; i < n; ++i) { + for (i=0; i < n;) { if (bev_ssl->bev.write_suspended) break; /* SSL_write will (reasonably) return 0 if we tell it to send 0 data. Skip this case so we don't interpret the result as an error */ - if (space[i].iov_len == 0) + if (space[i].iov_len == 0) { + ++i; continue; + } bev_ssl->ssl_ops->clear_error(); r = bev_ssl->ssl_ops->write(bev_ssl->ssl, space[i].iov_base, @@ -360,6 +362,10 @@ do_write(struct bufferevent_ssl *bev_ssl, int atmost) n_written += r; bev_ssl->last_write = -1; bev_ssl->ssl_ops->decrement_buckets(bev_ssl); + space[i].iov_base = (unsigned char *)space[i].iov_base + r; + space[i].iov_len -= r; + if (space[i].iov_len == 0) + ++i; } else { int err = bev_ssl->ssl_ops->get_error(bev_ssl->ssl, r); bev_ssl->ssl_ops->print_err(err);