From b74bba9aad024f20bf105b5d23618f1ff876ab3d Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Fri, 10 Mar 2023 13:00:15 +0100 Subject: [PATCH] vlts: use full buffer size when receiving data if possible SSL backends like OpenSSL/wolfSSL and other return the content of one TLS record on read, but usually there are more available. Change the vtls cfilter recv() function to fill the given buffer until a read would block. Closes #10736 --- lib/vtls/vtls.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index 144e6ee5b8..2d62cebc71 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -1578,13 +1578,45 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf, CURLcode *err) { struct cf_call_data save; - ssize_t nread; + ssize_t nread, n; CF_DATA_SAVE(save, cf, data); + /* SSL backends like OpenSSL/wolfSSL prefer to give us 1 TLS record content + * at a time when reading. But commonly, more data is available. + * So we try to fill the buffer we are called with until we + * are full or no more data is available. */ *err = CURLE_OK; - nread = Curl_ssl->recv_plain(cf, data, buf, len, err); - CF_DATA_RESTORE(cf, save); - return nread; + nread = 0; + while(len) { + n = Curl_ssl->recv_plain(cf, data, buf, len, err); + if(n < 0) { + if(*err != CURLE_AGAIN) { + /* serious err, fail */ + nread = -1; + goto out; + } + /* would block, return this to caller if we have read nothing so far, + * otherwise return amount read without error. */ + if(nread == 0) + nread = -1; + else + *err = CURLE_OK; + goto out; + } + else if(n == 0) { + /* eof */ + break; + } + else { + DEBUGASSERT((size_t)n <= len); + nread += (size_t)n; + buf += (size_t)n; + len -= (size_t)n; + } + } +out: + CF_DATA_RESTORE(cf, save); + return nread; } static int ssl_cf_get_select_socks(struct Curl_cfilter *cf, -- 2.47.3