|
1 | 1 | diff --strip-trailing-cr -Naur curl-8.10.1.old/lib/vtls/mbedtls.c curl-8.10.1.new/lib/vtls/mbedtls.c
|
2 |
| ---- curl-8.10.1.old/lib/vtls/mbedtls.c 2024-12-22 20:24:54.944116200 +0100 |
3 |
| -+++ curl-8.10.1.new/lib/vtls/mbedtls.c 2024-12-22 20:22:04.927962100 +0100 |
4 |
| -@@ -113,6 +113,11 @@ |
| 2 | +--- curl-8.10.1.old/lib/vtls/mbedtls.c 2025-01-05 21:12:50.543969206 +0100 |
| 3 | ++++ curl-8.10.1.new/lib/vtls/mbedtls.c 2025-01-05 21:12:50.583970677 +0100 |
| 4 | +@@ -111,8 +111,10 @@ |
| 5 | + const char *protocols[3]; |
| 6 | + #endif |
5 | 7 | int *ciphersuites;
|
| 8 | ++ size_t send_blocked_len; |
6 | 9 | BIT(initialized); /* mbedtls_ssl_context is initialized */
|
7 | 10 | BIT(sent_shutdown);
|
8 |
| -+ BIT(ww_buffer_valid); |
9 |
| -+ unsigned char *ww_buffer; |
10 |
| -+ size_t ww_buffer_size; |
11 |
| -+ size_t ww_buffer_used; |
12 |
| -+ size_t ww_buffer_from; |
| 11 | ++ BIT(send_blocked); |
13 | 12 | };
|
14 | 13 |
|
15 | 14 | /* apply threading? */
|
16 |
| -@@ -1174,14 +1179,73 @@ |
17 |
| - struct mbed_ssl_backend_data *backend = |
18 |
| - (struct mbed_ssl_backend_data *)connssl->backend; |
19 |
| - int ret = -1; |
20 |
| -+ size_t orig_len = len; |
21 |
| -+ |
22 |
| -+ if(backend->ww_buffer_valid) { |
23 |
| -+ if(backend->ww_buffer_used) { |
24 |
| -+ // if there were bytes in the fragment, match the last byte against what |
25 |
| -+ // libcurl is retrying to get us to send |
26 |
| -+ DEBUGASSERT(len); |
27 |
| -+ DEBUGASSERT(*(unsigned char *)mem == backend->ww_buffer[backend->ww_buffer_used - 1]); |
28 |
| -+ } |
29 |
| -+ // restore the same arguments as were passed to the last call (functionally |
30 |
| -+ // speaking anyway; the pointer will be different but the data it points to |
31 |
| -+ // will be the same) |
32 |
| -+ len = backend->ww_buffer_used - backend->ww_buffer_from; |
33 |
| -+ mem = backend->ww_buffer + backend->ww_buffer_from; |
34 |
| -+ } |
| 15 | +@@ -1177,6 +1179,17 @@ |
35 | 16 |
|
36 | 17 | (void)data;
|
37 | 18 | DEBUGASSERT(backend);
|
38 |
| - ret = mbedtls_ssl_write(&backend->ssl, (unsigned char *)mem, len); |
39 |
| - |
40 |
| -+ if(ret >= 0 && backend->ww_buffer_valid) { |
41 |
| -+ // some of the data we stashed away is done sending, but we can't fully give |
42 |
| -+ // control back to libcurl until all this data is done sending, and it may |
43 |
| -+ // very well yet result in MBEDTLS_ERR_SSL_WANT_WRITE returns from mbedtls |
44 |
| -+ DEBUGASSERT(backend->ww_buffer_from + ret <= backend->ww_buffer_used); |
45 |
| -+ backend->ww_buffer_from += ret; |
46 |
| -+ if(backend->ww_buffer_from < backend->ww_buffer_used) |
47 |
| -+ // if we're not done sending the data we stashed away, tell libcurl that |
48 |
| -+ // we're still working on it |
49 |
| -+ ret = MBEDTLS_ERR_SSL_WANT_WRITE; |
50 |
| -+ } |
51 |
| -+ if(ret != MBEDTLS_ERR_SSL_WANT_WRITE && backend->ww_buffer_valid && backend->ww_buffer_from == backend->ww_buffer_used) { |
52 |
| -+ // if there were bytes in the fragment, tell libcurl that we have finally |
53 |
| -+ // managed to send that one last byte that we kept for matching against; if |
54 |
| -+ // not, tell it that the lack of bytes has been successfully sent |
55 |
| -+ ret = backend->ww_buffer_used ? 1 : 0; |
56 |
| -+ backend->ww_buffer_from = 0; |
57 |
| -+ backend->ww_buffer_used = 0; |
58 |
| -+ backend->ww_buffer_valid = FALSE; |
59 |
| -+ } |
60 |
| -+ if(ret == MBEDTLS_ERR_SSL_WANT_WRITE && !backend->ww_buffer_valid) { |
61 |
| -+ if(backend->ww_buffer_size < len) { |
62 |
| -+ backend->ww_buffer_size = len; |
63 |
| -+ Curl_safefree(backend->ww_buffer); |
64 |
| -+ backend->ww_buffer = malloc(backend->ww_buffer_size); |
65 |
| -+ if(!backend->ww_buffer) |
66 |
| -+ return CURLE_OUT_OF_MEMORY; |
67 |
| -+ } |
68 |
| -+ memcpy(backend->ww_buffer, mem, len); |
69 |
| -+ backend->ww_buffer_used = len; |
70 |
| -+ backend->ww_buffer_valid = TRUE; |
71 |
| -+ if(len) { |
72 |
| -+ // if there were bytes in the fragment, report that all of them but the |
73 |
| -+ // last one has been sent (any number could be reported that is less than |
74 |
| -+ // len, but the remaining bytes will be attempted to sent again later and |
75 |
| -+ // we have to match them against what is already committed inside mbedtls; |
76 |
| -+ // it's by far the easiest to hold on to just one, which is fast to match) |
77 |
| -+ ret = len - 1; |
78 |
| -+ } |
79 |
| -+ // if there were no bytes in the fragment, let the original logic return |
80 |
| -+ // CURLE_AGAIN, as this is the only way to make libcurl keep trying to send |
81 |
| -+ // the lack of bytes |
| 19 | ++ /* mbedtls is picky when a mbedtls_ssl_write) was previously blocked. |
| 20 | ++ * It requires to be called with the same amount of bytes again, or it |
| 21 | ++ * will lose bytes, e.g. reporting all was sent but they were not. |
| 22 | ++ * Remember the blocked length and use that when set. */ |
| 23 | ++ if(backend->send_blocked) { |
| 24 | ++ DEBUGASSERT(backend->send_blocked_len <= len); |
| 25 | ++ CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> previously blocked " |
| 26 | ++ "on %zu bytes", len, backend->send_blocked_len); |
| 27 | ++ len = backend->send_blocked_len; |
82 | 28 | + }
|
83 | 29 | +
|
| 30 | + ret = mbedtls_ssl_write(&backend->ssl, (unsigned char *)mem, len); |
| 31 | + |
84 | 32 | if(ret < 0) {
|
85 |
| - CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> -0x%04X", |
86 |
| -- len, -ret); |
87 |
| -+ orig_len, -ret); |
88 |
| - *curlcode = ((ret == MBEDTLS_ERR_SSL_WANT_WRITE) |
89 |
| - #ifdef TLS13_SUPPORT |
90 |
| - || (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) |
91 |
| -@@ -1304,6 +1368,11 @@ |
92 |
| - mbedtls_x509_crl_free(&backend->crl); |
| 33 | +@@ -1188,6 +1201,14 @@ |
93 | 34 | #endif
|
94 |
| - Curl_safefree(backend->ciphersuites); |
95 |
| -+ Curl_safefree(backend->ww_buffer); |
96 |
| -+ backend->ww_buffer_size = 0; |
97 |
| -+ backend->ww_buffer_used = 0; |
98 |
| -+ backend->ww_buffer_from = 0; |
99 |
| -+ backend->ww_buffer_valid = FALSE; |
100 |
| - mbedtls_ssl_config_free(&backend->config); |
101 |
| - mbedtls_ssl_free(&backend->ssl); |
102 |
| - mbedtls_ctr_drbg_free(&backend->ctr_drbg); |
| 35 | + )? CURLE_AGAIN : CURLE_SEND_ERROR; |
| 36 | + ret = -1; |
| 37 | ++ if((*curlcode == CURLE_AGAIN) && !backend->send_blocked) { |
| 38 | ++ backend->send_blocked = TRUE; |
| 39 | ++ backend->send_blocked_len = len; |
| 40 | ++ } |
| 41 | ++ } |
| 42 | ++ else { |
| 43 | ++ CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> %d", len, ret); |
| 44 | ++ backend->send_blocked = FALSE; |
| 45 | + } |
| 46 | + |
| 47 | + return ret; |
0 commit comments