]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
rustls: only return CURLE_AGAIN when TLS session is fully drained
authorJavier Blazquez <jblazquez@riotgames.com>
Wed, 14 Apr 2021 21:55:12 +0000 (14:55 -0700)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 15 Apr 2021 06:19:49 +0000 (08:19 +0200)
The code in cr_recv was returning prematurely as soon as the socket
reported no more data to read. However, this could be leaving some
unread plaintext data in the rustls session from a previous call,
causing causing the transfer to hang if the socket never receives
further data.

We need to ensure that the session is fully drained of plaintext data
before returning CURLE_AGAIN to the caller.

Reviewed-by: Jacob Hoffman-Andrews
Closes #6894

lib/vtls/rustls.c

index e4f589de57ae2786078e34fbb22cafd99cdf430a..c12794af5f147d6008aebe2b5d3cfe1543016817 100644 (file)
@@ -119,18 +119,21 @@ cr_recv(struct Curl_easy *data, int sockindex,
   else if(tls_bytes_read < 0) {
     if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
       infof(data, "sread: EAGAIN or EWOULDBLOCK\n");
-      *err = CURLE_AGAIN;
+      /* There is no data in the socket right now, but there could still be
+         some data in the rustls session, so we need to read from it below. */
+      tls_bytes_read = 0;
+    }
+    else {
+      failf(data, "reading from socket: %s", strerror(SOCKERRNO));
+      *err = CURLE_READ_ERROR;
       return -1;
     }
-    failf(data, "reading from socket: %s", strerror(SOCKERRNO));
-    *err = CURLE_READ_ERROR;
-    return -1;
   }
 
   /*
   * Now pull those bytes from the buffer into ClientSession.
   */
-  DEBUGASSERT(tls_bytes_read > 0);
+  DEBUGASSERT(tls_bytes_read >= 0);
   while(tls_bytes_processed < (size_t)tls_bytes_read) {
     rresult = rustls_client_session_read_tls(session,
       backend->tlsbuf + tls_bytes_processed,