diff options
author | thegeorg <thegeorg@yandex-team.com> | 2024-10-11 21:07:18 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2024-10-11 21:17:24 +0300 |
commit | 1df197e6035ea9826bfedee7d48812e318ba9c7a (patch) | |
tree | 76b8e9de41820755adf209854d06a84a8b5a1988 /contrib/libs/curl/patches | |
parent | f9c007ea1b59b960201def74990810b26ecdfd48 (diff) | |
download | ydb-1df197e6035ea9826bfedee7d48812e318ba9c7a.tar.gz |
Revert "Update contrib/libs/curl to 8.10.1" to fix
Revert "Update contrib/libs/curl to 8.10.1"
This reverts commit 428ef806a15515cdaa325530aa8cc6903fac5fb6, reversing
changes made to 40e46e6394df409d1545a3771c8a47a86ed55eac.
Revert "Fix formatting after rXXXXXX"
This reverts commit a73689311a92e195d14136c5a0049ef1e40b1f3e, reversing
changes made to 17980b8756d1f74d3dacddc7ca4945c30f35611c.
commit_hash:5c5194831e5455b61fbee61619066396626beab1
Diffstat (limited to 'contrib/libs/curl/patches')
-rw-r--r-- | contrib/libs/curl/patches/pr12562-nghttp2-segfault-fix.patch | 120 | ||||
-rw-r--r-- | contrib/libs/curl/patches/pr12633-fix-mpd-streaming.patch | 74 |
2 files changed, 194 insertions, 0 deletions
diff --git a/contrib/libs/curl/patches/pr12562-nghttp2-segfault-fix.patch b/contrib/libs/curl/patches/pr12562-nghttp2-segfault-fix.patch new file mode 100644 index 0000000000..e60c53fff2 --- /dev/null +++ b/contrib/libs/curl/patches/pr12562-nghttp2-segfault-fix.patch @@ -0,0 +1,120 @@ +From 35380273b9311cf0741e386284310fa7ca4d005e Mon Sep 17 00:00:00 2001 +From: Stefan Eissing <stefan@eissing.org> +Date: Tue, 19 Dec 2023 12:57:40 +0100 +Subject: [PATCH] http2: improved on_stream_close/data_done handling + +- there seems to be a code path that cleans up easy handles without + triggering DONE or DETACH events to the connection filters. This + would explain wh nghttp2 still holds stream user data +- add GOOD check to easy handle used in on_close_callback to + prevent crashes, ASSERTs in debug builds. +- NULL the stream user data early before submitting RST +- add checks in on_stream_close() to identify UNGOOD easy handles + +Reported-by: Hans-Christian Egtvedt +Fixes #10936 +Closes #12562 +--- + lib/http2.c | 50 ++++++++++++++++++++++++------------ + tests/http/test_07_upload.py | 17 ++++++++++++ + tests/http/testenv/curl.py | 2 +- + 3 files changed, 51 insertions(+), 18 deletions(-) + +diff --git a/lib/http2.c b/lib/http2.c +index 59903cfa72d250..dcc24ea102302c 100644 +--- a/lib/http2.c ++++ b/lib/http2.c +@@ -283,13 +283,20 @@ static void http2_data_done(struct Curl_cfilter *cf, + return; + + if(ctx->h2) { ++ bool flush_egress = FALSE; ++ /* returns error if stream not known, which is fine here */ ++ (void)nghttp2_session_set_stream_user_data(ctx->h2, stream->id, NULL); ++ + if(!stream->closed && stream->id > 0) { + /* RST_STREAM */ + CURL_TRC_CF(data, cf, "[%d] premature DATA_DONE, RST stream", + stream->id); +- if(!nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE, +- stream->id, NGHTTP2_STREAM_CLOSED)) +- (void)nghttp2_session_send(ctx->h2); ++ stream->closed = TRUE; ++ stream->reset = TRUE; ++ stream->send_closed = TRUE; ++ nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE, ++ stream->id, NGHTTP2_STREAM_CLOSED); ++ flush_egress = TRUE; + } + if(!Curl_bufq_is_empty(&stream->recvbuf)) { + /* Anything in the recvbuf is still being counted +@@ -299,19 +306,11 @@ static void http2_data_done(struct Curl_cfilter *cf, + nghttp2_session_consume(ctx->h2, stream->id, + Curl_bufq_len(&stream->recvbuf)); + /* give WINDOW_UPATE a chance to be sent, but ignore any error */ +- (void)h2_progress_egress(cf, data); ++ flush_egress = TRUE; + } + +- /* -1 means unassigned and 0 means cleared */ +- if(nghttp2_session_get_stream_user_data(ctx->h2, stream->id)) { +- int rv = nghttp2_session_set_stream_user_data(ctx->h2, +- stream->id, 0); +- if(rv) { +- infof(data, "http/2: failed to clear user_data for stream %u", +- stream->id); +- DEBUGASSERT(0); +- } +- } ++ if(flush_egress) ++ nghttp2_session_send(ctx->h2); + } + + Curl_bufq_free(&stream->sendbuf); +@@ -1316,26 +1315,43 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, + uint32_t error_code, void *userp) + { + struct Curl_cfilter *cf = userp; +- struct Curl_easy *data_s; ++ struct Curl_easy *data_s, *call_data = CF_DATA_CURRENT(cf); + struct stream_ctx *stream; + int rv; + (void)session; + ++ DEBUGASSERT(call_data); + /* get the stream from the hash based on Stream ID, stream ID zero is for + connection-oriented stuff */ + data_s = stream_id? + nghttp2_session_get_stream_user_data(session, stream_id) : NULL; + if(!data_s) { ++ CURL_TRC_CF(call_data, cf, ++ "[%d] on_stream_close, no easy set on stream", stream_id); + return 0; + } ++ if(!GOOD_EASY_HANDLE(data_s)) { ++ /* nghttp2 still has an easy registered for the stream which has ++ * been freed be libcurl. This points to a code path that does not ++ * trigger DONE or DETACH events as it must. */ ++ CURL_TRC_CF(call_data, cf, ++ "[%d] on_stream_close, not a GOOD easy on stream", stream_id); ++ (void)nghttp2_session_set_stream_user_data(session, stream_id, 0); ++ return NGHTTP2_ERR_CALLBACK_FAILURE; ++ } + stream = H2_STREAM_CTX(data_s); +- if(!stream) ++ if(!stream) { ++ CURL_TRC_CF(data_s, cf, ++ "[%d] on_stream_close, GOOD easy but no stream", stream_id); + return NGHTTP2_ERR_CALLBACK_FAILURE; ++ } + + stream->closed = TRUE; + stream->error = error_code; +- if(stream->error) ++ if(stream->error) { + stream->reset = TRUE; ++ stream->send_closed = TRUE; ++ } + + if(stream->error) + CURL_TRC_CF(data_s, cf, "[%d] RESET: %s (err %d)", diff --git a/contrib/libs/curl/patches/pr12633-fix-mpd-streaming.patch b/contrib/libs/curl/patches/pr12633-fix-mpd-streaming.patch new file mode 100644 index 0000000000..a57512b2a2 --- /dev/null +++ b/contrib/libs/curl/patches/pr12633-fix-mpd-streaming.patch @@ -0,0 +1,74 @@ +From 3a24ef09af5fe7fdd672dee72ff760f871105a03 Mon Sep 17 00:00:00 2001 +From: Stefan Eissing <stefan@eissing.org> +Date: Thu, 4 Jan 2024 10:06:17 +0100 +Subject: [PATCH] adjust_pollset fix + +- do not add a socket for POLLIN when the transfer does not + want to send (for example is paused). +- refs #12632 +--- + lib/cf-socket.c | 2 +- + lib/http2.c | 4 ++-- + lib/vquic/curl_ngtcp2.c | 7 ++++--- + lib/vquic/curl_quiche.c | 2 +- + 4 files changed, 8 insertions(+), 7 deletions(-) + +diff --git a/lib/cf-socket.c b/lib/cf-socket.c +index bd4f0d1e97e2d3..c86aa7e7c2a969 100644 +--- a/lib/cf-socket.c ++++ b/lib/cf-socket.c +@@ -1243,7 +1243,7 @@ static void cf_socket_adjust_pollset(struct Curl_cfilter *cf, + if(ctx->sock != CURL_SOCKET_BAD) { + if(!cf->connected) + Curl_pollset_set_out_only(data, ps, ctx->sock); +- else ++ else if(CURL_WANT_RECV(data)) + Curl_pollset_add_in(data, ps, ctx->sock); + CURL_TRC_CF(data, cf, "adjust_pollset -> %d socks", ps->num); + } +diff --git a/lib/http2.c b/lib/http2.c +index dcc24ea102302c..b7a08607945357 100644 +--- a/lib/http2.c ++++ b/lib/http2.c +@@ -2341,8 +2341,8 @@ static void cf_h2_adjust_pollset(struct Curl_cfilter *cf, + bool c_exhaust, s_exhaust; + + CF_DATA_SAVE(save, cf, data); +- c_exhaust = !nghttp2_session_get_remote_window_size(ctx->h2); +- s_exhaust = stream && stream->id >= 0 && ++ c_exhaust = want_send && !nghttp2_session_get_remote_window_size(ctx->h2); ++ s_exhaust = want_send && stream && stream->id >= 0 && + !nghttp2_session_get_stream_remote_window_size(ctx->h2, + stream->id); + want_recv = (want_recv || c_exhaust || s_exhaust); +diff --git a/lib/vquic/curl_ngtcp2.c b/lib/vquic/curl_ngtcp2.c +index f4edf2d636ef93..89f690462d640b 100644 +--- a/lib/vquic/curl_ngtcp2.c ++++ b/lib/vquic/curl_ngtcp2.c +@@ -1166,9 +1166,10 @@ static void cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf, + bool c_exhaust, s_exhaust; + + CF_DATA_SAVE(save, cf, data); +- c_exhaust = !ngtcp2_conn_get_cwnd_left(ctx->qconn) || +- !ngtcp2_conn_get_max_data_left(ctx->qconn); +- s_exhaust = stream && stream->id >= 0 && stream->quic_flow_blocked; ++ c_exhaust = want_send && (!ngtcp2_conn_get_cwnd_left(ctx->qconn) || ++ !ngtcp2_conn_get_max_data_left(ctx->qconn)); ++ s_exhaust = want_send && stream && stream->id >= 0 && ++ stream->quic_flow_blocked; + want_recv = (want_recv || c_exhaust || s_exhaust); + want_send = (!s_exhaust && want_send) || + !Curl_bufq_is_empty(&ctx->q.sendbuf); +diff --git a/lib/vquic/curl_quiche.c b/lib/vquic/curl_quiche.c +index 33c2621dc8bf63..9c4df2df0f6955 100644 +--- a/lib/vquic/curl_quiche.c ++++ b/lib/vquic/curl_quiche.c +@@ -1189,7 +1189,7 @@ static void cf_quiche_adjust_pollset(struct Curl_cfilter *cf, + + c_exhaust = FALSE; /* Have not found any call in quiche that tells + us if the connection itself is blocked */ +- s_exhaust = stream && stream->id >= 0 && ++ s_exhaust = want_send && stream && stream->id >= 0 && + (stream->quic_flow_blocked || !stream_is_writeable(cf, data)); + want_recv = (want_recv || c_exhaust || s_exhaust); + want_send = (!s_exhaust && want_send) || |