cfilter: unlink and discard
No binary (build failed)
—
(log yok)
| @@ -383,29 +383,26 @@ void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at, | |
| *pnext = tail; | |
| } | |
| - | bool Curl_conn_cf_discard_sub(struct Curl_cfilter *cf, |
| - | struct Curl_cfilter *discard, |
| - | struct Curl_easy *data, |
| - | bool destroy_always) |
| + | bool Curl_conn_cf_discard(struct Curl_cfilter **pcf, |
| + | struct Curl_easy *data) |
| { | |
| - | struct Curl_cfilter **pprev = &cf->next; |
| + | struct Curl_cfilter *cf = pcf ? *pcf : NULL; |
| bool found = FALSE; | |
| - | |
| - | /* remove from sub-chain and destroy */ |
| - | DEBUGASSERT(cf); |
| - | while(*pprev) { |
| - | if(*pprev == cf) { |
| - | *pprev = discard->next; |
| - | discard->next = NULL; |
| - | found = TRUE; |
| - | break; |
| + | if(cf) { |
| + | if(cf->conn) { |
| + | /* unlink if present in connection filter chain */ |
| + | struct Curl_cfilter **pprev = &cf->conn->cfilter[cf->sockindex]; |
| + | while(*pprev) { |
| + | if(*pprev == *pcf) { |
| + | *pprev = (*pcf)->next; |
| + | cf->next = NULL; |
| + | found = TRUE; |
| + | break; |
| + | } |
| + | pprev = &((*pprev)->next); |
| + | } |
| } | |
| - | pprev = &((*pprev)->next); |
| - | } |
| - | if(found || destroy_always) { |
| - | discard->next = NULL; |
| - | discard->cft->destroy(discard, data); |
| - | free(discard); |
| + | Curl_conn_cf_discard_chain(pcf, data); |
| } | |
| return found; | |
| } | |
| @@ -297,16 +297,12 @@ void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at, | |
| struct Curl_cfilter *cf_new); | |
| /** | |
| - | * Discard, e.g. remove and destroy `discard` iff |
| - | * it still is in the filter chain below `cf`. If `discard` |
| - | * is no longer found beneath `cf` return FALSE. |
| - | * if `destroy_always` is TRUE, will call `discard`s destroy |
| - | * function and free it even if not found in the subchain. |
| - | */ |
| - | bool Curl_conn_cf_discard_sub(struct Curl_cfilter *cf, |
| - | struct Curl_cfilter *discard, |
| - | struct Curl_easy *data, |
| - | bool destroy_always); |
| + | * Extract filter `*pcf` from its connection filter chain. |
| + | * Destroy `*pcf`, even if it was not part of the chain and NULL it. |
| + | * Returns TRUE of cf has been part of chain. |
| + | */ |
| + | bool Curl_conn_cf_discard(struct Curl_cfilter **pcf, |
| + | struct Curl_easy *data); |
| /** | |
| * Discard all cfilters starting with `*pcf` and clearing it afterwards. | |
| @@ -215,9 +215,8 @@ CURLcode Curl_http_proxy_get_destination(struct Curl_cfilter *cf, | |
| } | |
| struct cf_proxy_ctx { | |
| - | /* the protocol specific sub-filter we install during connect */ |
| - | struct Curl_cfilter *cf_protocol; |
| int httpversion; /* HTTP version used to CONNECT */ | |
| + | BIT(sub_filter_installed); |
| }; | |
| CURLcode Curl_http_proxy_create_CONNECT(struct httpreq **preq, | |
| @@ -317,8 +316,7 @@ connect_sub: | |
| return result; | |
| *done = FALSE; | |
| - | if(!ctx->cf_protocol) { |
| - | struct Curl_cfilter *cf_protocol = NULL; |
| + | if(!ctx->sub_filter_installed) { |
| int httpversion = 0; | |
| const char *alpn = Curl_conn_cf_get_alpn_negotiated(cf->next, data); | |
| @@ -332,7 +330,6 @@ connect_sub: | |
| result = Curl_cf_h1_proxy_insert_after(cf, data); | |
| if(result) | |
| goto out; | |
| - | cf_protocol = cf->next; |
| httpversion = 10; | |
| } | |
| else if(!alpn || !strcmp(alpn, "http/1.1")) { | |
| @@ -340,7 +337,6 @@ connect_sub: | |
| result = Curl_cf_h1_proxy_insert_after(cf, data); | |
| if(result) | |
| goto out; | |
| - | cf_protocol = cf->next; |
| /* Assume that without an ALPN, we are talking to an ancient one */ | |
| httpversion = 11; | |
| } | |
| @@ -350,7 +346,6 @@ connect_sub: | |
| result = Curl_cf_h2_proxy_insert_after(cf, data); | |
| if(result) | |
| goto out; | |
| - | cf_protocol = cf->next; |
| httpversion = 20; | |
| } | |
| #endif | |
| @@ -360,7 +355,7 @@ connect_sub: | |
| goto out; | |
| } | |
| - | ctx->cf_protocol = cf_protocol; |
| + | ctx->sub_filter_installed = TRUE; |
| ctx->httpversion = httpversion; | |
| /* after we installed the filter "below" us, we call connect | |
| * on out sub-chain again. | |
| @@ -371,7 +366,7 @@ connect_sub: | |
| /* subchain connected and we had already installed the protocol filter. | |
| * This means the protocol tunnel is established, we are done. | |
| */ | |
| - | DEBUGASSERT(ctx->cf_protocol); |
| + | DEBUGASSERT(ctx->sub_filter_installed); |
| result = CURLE_OK; | |
| } | |
| @@ -419,23 +414,8 @@ static void http_proxy_cf_destroy(struct Curl_cfilter *cf, | |
| static void http_proxy_cf_close(struct Curl_cfilter *cf, | |
| struct Curl_easy *data) | |
| { | |
| - | struct cf_proxy_ctx *ctx = cf->ctx; |
| - | |
| CURL_TRC_CF(data, cf, "close"); | |
| cf->connected = FALSE; | |
| - | if(ctx->cf_protocol) { |
| - | struct Curl_cfilter *f; |
| - | /* if someone already removed it, we assume he also |
| - | * took care of destroying it. */ |
| - | for(f = cf->next; f; f = f->next) { |
| - | if(f == ctx->cf_protocol) { |
| - | /* still in our sub-chain */ |
| - | Curl_conn_cf_discard_sub(cf, ctx->cf_protocol, data, FALSE); |
| - | break; |
| - | } |
| - | } |
| - | ctx->cf_protocol = NULL; |
| - | } |
| if(cf->next) | |
| cf->next->cft->do_close(cf->next, data); | |
| } | |
| @@ -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; | |
| } | |
| @@ -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; | |
| } | |
| @@ -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; | |
| @@ -1862,7 +1862,7 @@ CURLcode Curl_ssl_cfilter_remove(struct Curl_easy *data, | |
| Curl_shutdown_clear(data, sockindex); | |
| if(!result && !done) /* blocking failed? */ | |
| result = CURLE_SSL_SHUTDOWN_FAILED; | |
| - | Curl_conn_cf_discard_sub(head, cf, data, FALSE); |
| + | Curl_conn_cf_discard(&cf, data); |
| CURL_TRC_CF(data, cf, "shutdown and remove SSL, done -> %d", result); | |
| break; | |
| } | |