]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
gnutls: send all data
authorStefan Eissing <stefan@eissing.org>
Thu, 29 Aug 2024 10:53:57 +0000 (12:53 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 29 Aug 2024 14:46:56 +0000 (16:46 +0200)
Turns out `gnutls_record_send()` does really what the name says: it
sends exactly one TLS record. If more than 16k are there to send, it
needs to be called again with new buffer offset and length.

Continue sending record until the input is all sent or a EAGAIN (or
fatal error) is returned by gnutls.

Closes #14722

lib/vtls/gtls.c

index c7589d9d39bc81db8d2f660bf8aa3a70c760832d..ad9a6b9263bf933c52972177361fee7b7652eaff 100644 (file)
@@ -1778,28 +1778,44 @@ static bool gtls_data_pending(struct Curl_cfilter *cf,
 
 static ssize_t gtls_send(struct Curl_cfilter *cf,
                          struct Curl_easy *data,
-                         const void *mem,
-                         size_t len,
+                         const void *buf,
+                         size_t blen,
                          CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = cf->ctx;
   struct gtls_ssl_backend_data *backend =
     (struct gtls_ssl_backend_data *)connssl->backend;
   ssize_t rc;
+  size_t nwritten, total_written = 0;
 
   (void)data;
   DEBUGASSERT(backend);
-  backend->gtls.io_result = CURLE_OK;
-  rc = gnutls_record_send(backend->gtls.session, mem, len);
+  while(blen) {
+    backend->gtls.io_result = CURLE_OK;
+    rc = gnutls_record_send(backend->gtls.session, buf, blen);
 
-  if(rc < 0) {
-    *curlcode = (rc == GNUTLS_E_AGAIN)?
-      CURLE_AGAIN :
-      (backend->gtls.io_result? backend->gtls.io_result : CURLE_SEND_ERROR);
+    if(rc < 0) {
+      if(total_written && (rc == GNUTLS_E_AGAIN)) {
+        *curlcode = CURLE_OK;
+        rc = (ssize_t)total_written;
+        goto out;
+      }
+      *curlcode = (rc == GNUTLS_E_AGAIN)?
+        CURLE_AGAIN :
+        (backend->gtls.io_result? backend->gtls.io_result : CURLE_SEND_ERROR);
 
-    rc = -1;
+      rc = -1;
+      goto out;
+    }
+    nwritten = (size_t)rc;
+    total_written += nwritten;
+    DEBUGASSERT(nwritten <= blen);
+    buf = (char *)buf + nwritten;
+    blen -= nwritten;
   }
+  rc = total_written;
 
+out:
   return rc;
 }