diff options
author | Jacob Hoffman-Andrews <github@hoffman-andrews.com> | 2021-11-12 19:33:19 -0800 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2021-11-13 22:57:51 +0100 |
commit | 00f4ed2aadfb17960432b2948560381dca3ecf40 (patch) | |
tree | 8ca5b560e70c7c86a1ab640077718ca8f2e54e63 /lib | |
parent | be8d77b14634081a6031cf1acdc0887797840f2a (diff) | |
download | curl-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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/vtls/rustls.c | 26 |
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; } /* |