summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Hoffman-Andrews <github@hoffman-andrews.com>2021-11-12 19:33:19 -0800
committerDaniel Stenberg <daniel@haxx.se>2021-11-13 22:57:51 +0100
commit00f4ed2aadfb17960432b2948560381dca3ecf40 (patch)
tree8ca5b560e70c7c86a1ab640077718ca8f2e54e63
parentbe8d77b14634081a6031cf1acdc0887797840f2a (diff)
downloadcurl-00f4ed2aadfb17960432b2948560381dca3ecf40.tar.gz
rustls: read of zero bytes might be okay
When we're reading out plaintext from rustls' internal buffers, we might get a read of zero bytes (meaning a clean TCP close, including close_notify). However, we shouldn't return immediately when that happens, since we may have already copied out some plaintext bytes. Break out of the loop when we get a read of zero bytes, and figure out which path we're dealing with. Acked-by: Kevin Burke Closes #8003
-rw-r--r--lib/vtls/rustls.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/lib/vtls/rustls.c b/lib/vtls/rustls.c
index 76519b2ae..da1c252dc 100644
--- a/lib/vtls/rustls.c
+++ b/lib/vtls/rustls.c
@@ -157,7 +157,7 @@ cr_recv(struct Curl_easy *data, int sockindex,
plainlen - plain_bytes_copied,
&n);
if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) {
- infof(data, "cr_recv got 0 bytes of plaintext");
+ infof(data, "cr_recv got PLAINTEXT_EMPTY. will try again later.");
backend->data_pending = FALSE;
break;
}
@@ -168,8 +168,10 @@ cr_recv(struct Curl_easy *data, int sockindex,
return -1;
}
else if(n == 0) {
- *err = CURLE_OK;
- return 0;
+ /* n == 0 indicates clean EOF, but we may have read some other
+ plaintext bytes before we reached this. Break out of the loop
+ so we can figure out whether to return success or EOF. */
+ break;
}
else {
infof(data, "cr_recv copied out %ld bytes of plaintext", n);
@@ -177,15 +179,23 @@ cr_recv(struct Curl_easy *data, int sockindex,
}
}
- /* If we wrote out 0 plaintext bytes, it might just mean we haven't yet
- read a full TLS record. Return CURLE_AGAIN so curl doesn't treat this
- as EOF. */
- if(plain_bytes_copied == 0) {
+ if(plain_bytes_copied) {
+ *err = CURLE_OK;
+ return plain_bytes_copied;
+ }
+
+ /* If we wrote out 0 plaintext bytes, that means either we hit a clean EOF,
+ OR we got a RUSTLS_RESULT_PLAINTEXT_EMPTY.
+ If the latter, return CURLE_AGAIN so curl doesn't treat this as EOF. */
+ if(!backend->data_pending) {
*err = CURLE_AGAIN;
return -1;
}
- return plain_bytes_copied;
+ /* Zero bytes read, and no RUSTLS_RESULT_PLAINTEXT_EMPTY, means the TCP
+ connection was cleanly closed (with a close_notify alert). */
+ *err = CURLE_OK;
+ return 0;
}
/*