]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
vlts: use full buffer size when receiving data if possible
authorStefan Eissing <stefan@eissing.org>
Fri, 10 Mar 2023 12:00:15 +0000 (13:00 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 30 Mar 2023 08:04:20 +0000 (10:04 +0200)
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

index 144e6ee5b80678c0a55c9b7602dfa8beabaf3efa..2d62cebc71975a90ebeebdb44ebff876ee2891df 100644 (file)
@@ -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,