mirror of
https://github.com/curl/curl.git
synced 2026-08-25 11:13:32 +03:00
ngtcp2: share common functionality
Share common functions/structs between ngtcp2 HTTP/3 and the proxy version. Fix bugs in proxy implementation when it comes to stream and pollset handling and transfer lifetimes. Curl_multi_xfer_sockbuf_borrow: work without multi When a connection gets shutdown by a share, the easy handle used is share->admin and it does not have a multi handle. In that case let Curl_multi_xfer_sockbuf_borrow() allocate a buffer to be freed on release. This happens when a TLS filter sends its last notify through a HTTP/3 proxy tunnel. Closes #21871
This commit is contained in:
parent
4fcf9c8f59
commit
f924489b25
43 changed files with 3254 additions and 4970 deletions
|
|
@ -413,7 +413,8 @@ static CURLcode cf_setup_add_http_proxy(struct Curl_cfilter *cf,
|
|||
#ifdef USE_SSL
|
||||
if(IS_HTTPS_PROXY(cf->conn->http_proxy.proxytype) &&
|
||||
!Curl_conn_is_ssl(cf->conn, cf->sockindex)) {
|
||||
result = Curl_cf_ssl_proxy_insert_after(cf, data);
|
||||
result = Curl_cf_ssl_proxy_insert_after(
|
||||
cf, data, cf->conn->http_proxy.peer);
|
||||
if(result) {
|
||||
CURL_TRC_CF(data, cf, "adding SSL filter for HTTP proxy failed -> %d",
|
||||
result);
|
||||
|
|
@ -424,10 +425,12 @@ static CURLcode cf_setup_add_http_proxy(struct Curl_cfilter *cf,
|
|||
#endif /* USE_SSL */
|
||||
|
||||
if(cf->conn->bits.tunnel_proxy) {
|
||||
struct Curl_peer *dest; /* where HTTP should tunnel to */
|
||||
dest = Curl_conn_get_destination(cf->conn, cf->sockindex);
|
||||
struct Curl_peer *peer = cf->conn->http_proxy.peer;
|
||||
struct Curl_peer *tunnel_peer; /* where HTTP should tunnel to */
|
||||
tunnel_peer = Curl_conn_get_destination(cf->conn, cf->sockindex);
|
||||
result = Curl_cf_http_proxy_insert_after(
|
||||
cf, data, dest, ctx->transport, cf->conn->http_proxy.proxytype);
|
||||
cf, data, peer, tunnel_peer,
|
||||
ctx->transport, cf->conn->http_proxy.proxytype);
|
||||
if(result) {
|
||||
CURL_TRC_CF(data, cf, "adding HTTP proxy tunnel filter failed -> %d",
|
||||
result);
|
||||
|
|
@ -449,41 +452,47 @@ static CURLcode cf_setup_add_ip_happy(struct Curl_cfilter *cf,
|
|||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(ctx->state < CF_SETUP_CNNCT_EYEBALLS) {
|
||||
/* What is the fist hop we directly connect to and what transport
|
||||
* do we use for it? Only on the first hop we can do Happy Eyeballs. */
|
||||
/* What is the first hop we directly connect to and what transport
|
||||
* do we use for it? Only on the first hop we can do Happy Eyeballs.
|
||||
* first_origin and first_peer differ on --connect-to. */
|
||||
struct Curl_peer *first_origin =
|
||||
Curl_conn_get_first_origin(cf->conn, cf->sockindex);
|
||||
struct Curl_peer *first_peer =
|
||||
Curl_conn_get_first_peer(cf->conn, cf->sockindex);
|
||||
struct Curl_peer *tunnel_peer = NULL;
|
||||
uint8_t first_transport = ctx->transport;
|
||||
bool tunnel_proxy = FALSE;
|
||||
|
||||
if(!first_peer)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
|
||||
if(cf->conn->bits.httpproxy && cf->conn->bits.tunnel_proxy) {
|
||||
first_transport =
|
||||
Curl_http_proxy_transport(cf->conn->http_proxy.proxytype);
|
||||
tunnel_peer = Curl_conn_get_destination(cf->conn, cf->sockindex);
|
||||
if((first_transport == TRNSPRT_QUIC) && (cf->conn->bits.socksproxy)) {
|
||||
failf(data, "HTTP/3 proxy not possible via SOCKS");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
tunnel_proxy = TRUE;
|
||||
}
|
||||
#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */
|
||||
|
||||
result = cf_ip_happy_insert_after(cf, data, first_peer,
|
||||
ctx->transport, first_transport,
|
||||
tunnel_proxy);
|
||||
result = cf_ip_happy_insert_after(cf, data, first_origin, first_peer,
|
||||
first_transport,
|
||||
tunnel_peer, ctx->transport);
|
||||
if(result) {
|
||||
CURL_TRC_CF(data, cf, "adding happy eyeballs failed -> %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if(tunnel_proxy && (first_transport == TRNSPRT_QUIC)) {
|
||||
if(tunnel_peer && (first_transport == TRNSPRT_QUIC)) {
|
||||
CURL_TRC_CF(data, cf, "happy eyeballing to HTTP/3 proxy %s:%u",
|
||||
first_peer->hostname, first_peer->port);
|
||||
ctx->state = CF_SETUP_CNNCT_HTTP_PROXY;
|
||||
}
|
||||
else {
|
||||
CURL_TRC_CF(data, cf, "happy eyeballing to %s %s:%u",
|
||||
tunnel_proxy ? "proxy" : "origin",
|
||||
tunnel_peer ? "proxy" : "origin",
|
||||
first_peer->hostname, first_peer->port);
|
||||
ctx->state = CF_SETUP_CNNCT_EYEBALLS;
|
||||
}
|
||||
|
|
@ -501,17 +510,22 @@ static CURLcode cf_setup_add_origin_filters(struct Curl_cfilter *cf,
|
|||
if(ctx->state < CF_SETUP_CNNCT_SSL) {
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) && \
|
||||
!defined(CURL_DISABLE_PROXY)
|
||||
|
||||
/* Wanting QUIC with a HTTP tunneling filter, we now need to add
|
||||
* the QUIC filter on top. Without tunneling, this has already
|
||||
* happened in the Happy Eyeball filter. */
|
||||
if(ctx->transport == TRNSPRT_QUIC && cf->conn->bits.httpproxy &&
|
||||
cf->conn->bits.tunnel_proxy) {
|
||||
struct Curl_peer *origin = Curl_conn_get_origin(cf->conn, cf->sockindex);
|
||||
struct Curl_peer *peer =
|
||||
Curl_conn_get_destination(cf->conn, cf->sockindex);
|
||||
|
||||
result = Curl_cf_capsule_insert_after(cf, data);
|
||||
if(result) {
|
||||
CURL_TRC_CF(data, cf, "adding capsule filter failed -> %d", result);
|
||||
return result;
|
||||
}
|
||||
result = Curl_cf_quic_insert_after(cf);
|
||||
result = Curl_cf_quic_insert_after(cf, origin, peer);
|
||||
if(result) {
|
||||
CURL_TRC_CF(data, cf, "adding QUIC filter failed -> %d", result);
|
||||
return result;
|
||||
|
|
@ -525,7 +539,13 @@ static CURLcode cf_setup_add_origin_filters(struct Curl_cfilter *cf,
|
|||
(ctx->ssl_mode != CURL_CF_SSL_DISABLE &&
|
||||
cf->conn->scheme->flags & PROTOPT_SSL)) && /* we want SSL */
|
||||
!Curl_conn_is_ssl(cf->conn, cf->sockindex)) { /* it is missing */
|
||||
result = Curl_cf_ssl_insert_after(cf, data);
|
||||
/* Another FTP quirk: when adding SSL verification, to a DATA
|
||||
* connection, always verify against the control's origin */
|
||||
struct Curl_peer *origin = Curl_conn_get_origin(cf->conn, FIRSTSOCKET);
|
||||
struct Curl_peer *peer =
|
||||
Curl_conn_get_destination(cf->conn, cf->sockindex);
|
||||
|
||||
result = Curl_cf_ssl_insert_after(cf, data, origin, peer);
|
||||
if(result) {
|
||||
CURL_TRC_CF(data, cf, "adding SSL filter for origin failed -> %d",
|
||||
result);
|
||||
|
|
@ -777,6 +797,13 @@ void Curl_conn_set_multiplex(struct connectdata *conn)
|
|||
}
|
||||
}
|
||||
|
||||
struct Curl_peer *Curl_conn_get_origin(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
return (sockindex == SECONDARYSOCKET) ?
|
||||
conn->origin2 : conn->origin;
|
||||
}
|
||||
|
||||
struct Curl_peer *Curl_conn_get_destination(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
|
|
@ -789,6 +816,18 @@ struct Curl_peer *Curl_conn_get_destination(struct connectdata *conn,
|
|||
(conn->via_peer ? conn->via_peer : conn->origin);
|
||||
}
|
||||
|
||||
struct Curl_peer *Curl_conn_get_first_origin(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->socks_proxy.peer)
|
||||
return conn->socks_proxy.peer;
|
||||
if(conn->http_proxy.peer)
|
||||
return conn->http_proxy.peer;
|
||||
#endif
|
||||
return (sockindex == SECONDARYSOCKET) ? conn->origin2 : conn->origin;
|
||||
}
|
||||
|
||||
struct Curl_peer *Curl_conn_get_first_peer(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue