-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect mbedtls_ssl_write usage causes ranges of bytes to get lost #15801
Comments
See curl/curl#15801 This would cause ranges of bytes to simply disappear from HTTP/2 streams >_>
All that said, if it can be guaranteed that any data ever presented to |
@LBPHacker nice find. I think we'll need to adapt the repeated write behaviour for that backend. |
Thanks for confirming. Does this mean that this repeated write behaviour is already present somewhere in the codebase? |
No, we have to adapt our mbedtls backend implementation. |
mbedtls is picky when a mbedtls_ssl_write) was previously blocked. It requires to be called with the same amount of bytes again, or it will lose bytes, e.g. reporting all was sent but they were not. Remember the blocked length and use that when set. refs curl#15801
I propose a fix for this in #15846. I was able to reproduce the problem with a special, local setup, but could not make it into a reliable test case. Would be nice if you could verify that the PR works for you. |
Thank you, I will test this in a bit. However, I have concerns regarding the fix. As far as I can tell, it is essentially what I proposed in my second comment, but I have as yet been unable to confirm that libcurl in any way prevents passing Further, calling Are these concerns valid? Am I missing context here? |
Regarding the use of I think we need to document in KNOWN BUGS, that a As to 0-length writes, I think they should semantically be a NOP, meaning |
That is reasonable, thanks. I have just confirmed that the proposed fix makes my very specific use case of large requests over h2 work. |
Just pushed the change to the PR. If your system is still hot, would be nice to get a verification. Thanks! |
Nope, that last change broke it. Most likely because this line: Line 1223 in 6d416d6
still uses |
Arg, my bad. Just pushed a fix. |
Working as intended now 👍 |
I did this
Using mbedtls 3.6.2 = Mbed-TLS/mbedtls@107ea89daaef and nghttp2 1.50.0 = nghttp2/nghttp2@87fef4ab71be, HTTP/2 requests with large-ish (600kB+) request bodies often fail with
HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
. Wireshark traces I have taken show that the data stream ends sooner than the content-length header would suggest, and the server gives up after some inactivity and fails the request. Matching up frames with known data shows that ranges of bytes inside the TLS stream occasionally get lost.This has prompted me to look at how data is passed to mbedtls:
curl/lib/vtls/mbedtls.c
Lines 1169 to 1194 in 7eb8c04
Given the documentation on mbedtls_ssl_write, which states that when
MBEDTLS_ERR_SSL_WANT_WRITE
is returned, the same arguments must be passed the next time, this seems incorrect: simply returningCURLE_AGAIN
allows for more data to be given to this function than the amount given at the previous call.I have made a change locally that makes sure that when
MBEDTLS_ERR_SSL_WANT_WRITE
is returned, the exact same arguments are passed the next time around, even ifmbed_send
has more data to send than the last time (and return an appropriateret
), and indeed, this fixes my issue.This is not a pull request because the underlying issue seems to be one of design, and I am not willing to tackle fixing it: as far as I can tell, libcurl is designed with write(2)-like behaviour in mind, i.e. ranges of bytes that are reported sent have been sent (or the stream breaks later, etc.), and ranges reported to have been left unsent are not sent, but also not committed anywhere. The issue with mbedtls seems to be that it effectively commits ranges of bytes internally, which is not compatible with this design.
I expected the following
I expected the aforementioned requests to succeed. Excuse me for filling this field with such an abstract answer; the issue I am facing is also abstract.
curl/libcurl version
curl 8.10.1 = 7eb8c04
operating system
Windows 10.0.19045.3570
The text was updated successfully, but these errors were encountered: