From: Stefan Eissing Date: Fri, 10 Mar 2023 12:00:15 +0000 (+0100) Subject: vlts: use full buffer size when receiving data if possible X-Git-Tag: curl-8_1_0~275 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b74bba9aad024f20bf105b5d23618f1ff876ab3d;p=thirdparty%2Fcurl.git 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 --- 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,