cfilter: unlink and discard

Rewrite the code that removes a filter from the connection and discards
it. Always look at the connection, otherwise it will not work of the
filter is at the top of the chain.

Change QUIC filter setup code to always tear down the chain in
construction when an error occured.

HTTP proxy, do not remove the h1/h2 sub filter on close. Leave it to be
discarded with the connection. Avoids keeping an additional pointer that
might become dangling.

Triggered by a reported on a code bug in discard method.

Reported-by: Joshua Rogers
Closes #18596
This commit is contained in:
Stefan Eissing 2025-09-18 11:10:45 +02:00 committed by Daniel Stenberg
parent ca034e839c
commit 0f08211330
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
7 changed files with 54 additions and 85 deletions

View file

@ -2767,7 +2767,7 @@ CURLcode Curl_cf_ngtcp2_create(struct Curl_cfilter **pcf,
const struct Curl_addrinfo *ai)
{
struct cf_ngtcp2_ctx *ctx = NULL;
struct Curl_cfilter *cf = NULL, *udp_cf = NULL;
struct Curl_cfilter *cf = NULL;
CURLcode result;
(void)data;
@ -2781,23 +2781,21 @@ CURLcode Curl_cf_ngtcp2_create(struct Curl_cfilter **pcf,
result = Curl_cf_create(&cf, &Curl_cft_http3, ctx);
if(result)
goto out;
cf->conn = conn;
result = Curl_cf_udp_create(&udp_cf, data, conn, ai, TRNSPRT_QUIC);
result = Curl_cf_udp_create(&cf->next, data, conn, ai, TRNSPRT_QUIC);
if(result)
goto out;
cf->conn = conn;
udp_cf->conn = cf->conn;
udp_cf->sockindex = cf->sockindex;
cf->next = udp_cf;
cf->next->conn = cf->conn;
cf->next->sockindex = cf->sockindex;
out:
*pcf = (!result) ? cf : NULL;
if(result) {
if(udp_cf)
Curl_conn_cf_discard_sub(cf, udp_cf, data, TRUE);
Curl_safefree(cf);
cf_ngtcp2_ctx_free(ctx);
if(cf)
Curl_conn_cf_discard_chain(&cf, data);
else if(ctx)
cf_ngtcp2_ctx_free(ctx);
}
return result;
}

View file

@ -2398,7 +2398,7 @@ CURLcode Curl_cf_osslq_create(struct Curl_cfilter **pcf,
const struct Curl_addrinfo *ai)
{
struct cf_osslq_ctx *ctx = NULL;
struct Curl_cfilter *cf = NULL, *udp_cf = NULL;
struct Curl_cfilter *cf = NULL;
CURLcode result;
(void)data;
@ -2412,23 +2412,22 @@ CURLcode Curl_cf_osslq_create(struct Curl_cfilter **pcf,
result = Curl_cf_create(&cf, &Curl_cft_http3, ctx);
if(result)
goto out;
cf->conn = conn;
result = Curl_cf_udp_create(&udp_cf, data, conn, ai, TRNSPRT_QUIC);
result = Curl_cf_udp_create(&cf->next, data, conn, ai, TRNSPRT_QUIC);
if(result)
goto out;
cf->conn = conn;
udp_cf->conn = cf->conn;
udp_cf->sockindex = cf->sockindex;
cf->next = udp_cf;
cf->next->conn = cf->conn;
cf->next->sockindex = cf->sockindex;
out:
*pcf = (!result) ? cf : NULL;
if(result) {
if(udp_cf)
Curl_conn_cf_discard_sub(cf, udp_cf, data, TRUE);
Curl_safefree(cf);
cf_osslq_ctx_free(ctx);
if(cf)
Curl_conn_cf_discard_chain(&cf, data);
else if(ctx)
cf_osslq_ctx_free(ctx);
}
return result;
}

View file

@ -1636,7 +1636,7 @@ CURLcode Curl_cf_quiche_create(struct Curl_cfilter **pcf,
const struct Curl_addrinfo *ai)
{
struct cf_quiche_ctx *ctx = NULL;
struct Curl_cfilter *cf = NULL, *udp_cf = NULL;
struct Curl_cfilter *cf = NULL;
CURLcode result;
(void)data;
@ -1651,22 +1651,21 @@ CURLcode Curl_cf_quiche_create(struct Curl_cfilter **pcf,
result = Curl_cf_create(&cf, &Curl_cft_http3, ctx);
if(result)
goto out;
cf->conn = conn;
result = Curl_cf_udp_create(&udp_cf, data, conn, ai, TRNSPRT_QUIC);
result = Curl_cf_udp_create(&cf->next, data, conn, ai, TRNSPRT_QUIC);
if(result)
goto out;
udp_cf->conn = cf->conn;
udp_cf->sockindex = cf->sockindex;
cf->next = udp_cf;
cf->next->conn = cf->conn;
cf->next->sockindex = cf->sockindex;
out:
*pcf = (!result) ? cf : NULL;
if(result) {
if(udp_cf)
Curl_conn_cf_discard_sub(cf, udp_cf, data, TRUE);
Curl_safefree(cf);
cf_quiche_ctx_free(ctx);
if(cf)
Curl_conn_cf_discard_chain(&cf, data);
else if(ctx)
cf_quiche_ctx_free(ctx);
}
return result;