From 71b7e0161032927cdfb4e75ea40f65b8898b3956 Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Fri, 30 Dec 2022 09:14:55 +0100 Subject: lib: connect/h2/h3 refactor Refactoring of connection setup and happy eyeballing. Move nghttp2. ngtcp2, quiche and msh3 into connection filters. - eyeballing cfilter that uses sub-filters for performing parallel connects - socket cfilter for all transport types, including QUIC - QUIC implementations in cfilter, can now participate in eyeballing - connection setup is more dynamic in order to adapt to what filter did really connect. Relevant to see if a SSL filter needs to be added or if SSL has already been provided - HTTP/3 test cases similar to HTTP/2 - multiuse of parallel transfers for HTTP/3, tested for ngtcp2 and quiche - Fix for data attach/detach in VTLS filters that could lead to crashes during parallel transfers. - Eliminating setup() methods in cfilters, no longer needed. - Improving Curl_conn_is_alive() to replace Curl_connalive() and integrated ssl alive checks into cfilter. - Adding CF_CNTRL_CONN_INFO_UPDATE to tell filters to update connection into and persist it at the easy handle. - Several more cfilter related cleanups and moves: - stream_weigth and dependency info is now wrapped in struct Curl_data_priority - Curl_data_priority members depend is available in HTTP2|HTTP3 - Curl_data_priority members depend on NGHTTP2 support - handling init/reset/cleanup of priority part of url.c - data->state.priority same struct, but shallow copy for compares only - PROTOPT_STREAM has been removed - Curl_conn_is_mulitplex() now available to check on capability - Adding query method to connection filters. - ngtcp2+quiche: implementing query for max concurrent transfers. - Adding is_alive and keep_alive cfilter methods. Adding DATA_SETUP event. - setting keepalive timestamp on connect - DATA_SETUP is called after the connection has been completely setup (but may not connected yet) to allow filters to initialize data members they use. - there is no socket to be had with msh3, it is unclear how select shall work - manual test via "curl --http3 https://curl.se" fail with "empty reply from server". - Various socket/conn related cleanups: - Curl_socket is now Curl_socket_open and in cf-socket.c - Curl_closesocket is now Curl_socket_close and in cf-socket.c - Curl_ssl_use has been replaced with Cur_conn_is_ssl - Curl_conn_tcp_accepted_set has been split into Curl_conn_tcp_listen_set and Curl_conn_tcp_accepted_set with a clearer purpose Closes #10141 --- lib/urldata.h | 68 +++++++++++++++++++++++++---------------------------------- 1 file changed, 29 insertions(+), 39 deletions(-) (limited to 'lib/urldata.h') diff --git a/lib/urldata.h b/lib/urldata.h index 82cc340d1..a70729c7e 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -123,9 +123,9 @@ typedef unsigned int curl_prot_t; #define DMSGI(d,i,msg) \ "[CONN-%ld-%d] "msg, (d)->conn->connection_id, (i) #define CMSG(c,msg) \ - "[CONN-%ld] "msg, (conn)->connection_id + "[CONN-%ld] "msg, (c)->connection_id #define CMSGI(c,i,msg) \ - "[CONN-%ld-%d] "msg, (conn)->connection_id, (i) + "[CONN-%ld-%d] "msg, (c)->connection_id, (i) #define CFMSG(cf,msg) \ "[CONN-%ld-%d][CF-%s] "msg, (cf)->conn->connection_id, \ (cf)->sockindex, (cf)->cft->name @@ -187,7 +187,6 @@ typedef CURLcode (*Curl_datastream)(struct Curl_easy *data, #include "mqtt.h" #include "wildcard.h" #include "multihandle.h" -#include "quic.h" #include "c-hyper.h" #ifdef HAVE_GSSAPI @@ -830,7 +829,7 @@ struct Curl_handler { #define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login credentials per request instead of per connection */ #define PROTOPT_ALPN (1<<8) /* set ALPN for this */ -#define PROTOPT_STREAM (1<<9) /* a protocol with individual logical streams */ +/* (1<<9) was PROTOPT_STREAM, now free */ #define PROTOPT_URLOPTIONS (1<<10) /* allow options part in the userinfo field of the URL */ #define PROTOPT_PROXY_AS_HTTP (1<<11) /* allow this non-HTTP scheme over a @@ -912,13 +911,7 @@ struct connectdata { /* 'ip_addr' is the particular IP we connected to. It points to a struct within the DNS cache, so this pointer is only valid as long as the DNS cache entry remains locked. It gets unlocked in multi_done() */ - struct Curl_addrinfo *ip_addr; - struct Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */ - -#ifdef ENABLE_QUIC - struct quicsocket hequic[2]; /* two, for happy eyeballs! */ - struct quicsocket *quic; -#endif + const struct Curl_addrinfo *ip_addr; struct hostname host; char *hostname_resolve; /* host name to resolve to address, allocated */ @@ -947,8 +940,6 @@ struct connectdata { struct curltime lastused; /* when returned to the connection cache */ curl_socket_t sock[2]; /* two sockets, the second is used for the data transfer when doing FTP */ - curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */ - int tempfamily[2]; /* family used for the temp sockets */ Curl_recv *recv[2]; Curl_send *send[2]; struct Curl_cfilter *cfilter[2]; /* connection filters */ @@ -962,16 +953,6 @@ struct connectdata { #endif struct ConnectBits bits; /* various state-flags for this connection */ - /* connecttime: when connect() is called on the current IP address. Used to - be able to track when to move on to try next IP - but only when the multi - interface is used. */ - struct curltime connecttime; - - /* The field below gets set in Curl_connecthost */ - /* how long time in milliseconds to spend on trying to connect to each IP - address, per family */ - timediff_t timeoutms_per_addr[2]; - const struct Curl_handler *handler; /* Connection's protocol handler */ const struct Curl_handler *given; /* The protocol first given */ @@ -1043,9 +1024,6 @@ struct connectdata { #ifndef CURL_DISABLE_FTP struct ftp_conn ftpc; #endif -#ifndef CURL_DISABLE_HTTP - struct http_conn httpc; -#endif #ifdef USE_SSH struct ssh_conn sshc; #endif @@ -1094,7 +1072,7 @@ struct connectdata { #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) int socks5_gssapi_enctype; #endif - /* The field below gets set in Curl_connecthost */ + /* The field below gets set in connect.c:connecthost() */ int num_addr; /* number of addresses to try to connect to */ int port; /* which port to use locally - to connect to */ int remote_port; /* the remote port, not the proxy port! */ @@ -1240,10 +1218,29 @@ struct auth { should be RFC compliant */ }; -struct Curl_http2_dep { - struct Curl_http2_dep *next; +#ifdef USE_NGHTTP2 +struct Curl_data_prio_node { + struct Curl_data_prio_node *next; struct Curl_easy *data; }; +#endif + +/** + * Priority information for an easy handle in relation to others + * on the same connection. + * TODO: we need to adapt it to the new priority scheme as defined in RFC 9218 + */ +struct Curl_data_priority { +#ifdef USE_NGHTTP2 + /* tree like dependencies only implemented in nghttp2 */ + struct Curl_easy *parent; + struct Curl_data_prio_node *children; +#endif + int weight; +#ifdef USE_NGHTTP2 + BIT(exclusive); +#endif +}; /* * This struct is for holding data that was attempted to get sent to the user's @@ -1391,14 +1388,11 @@ struct UrlState { size_t drain; /* Increased when this stream has data to read, even if its socket is not necessarily is readable. Decreased when checked. */ + struct Curl_data_priority priority; /* shallow coyp of data->set */ #endif curl_read_callback fread_func; /* read callback/function */ void *in; /* CURLOPT_READDATA */ -#ifdef USE_HTTP2 - struct Curl_easy *stream_depends_on; - int stream_weight; -#endif CURLU *uh; /* URL handle for the current parsed URL */ struct urlpieces up; unsigned char httpreq; /* Curl_HttpReq; what kind of HTTP request (if any) @@ -1469,7 +1463,6 @@ struct UrlState { BIT(done); /* set to FALSE when Curl_init_do() is called and set to TRUE when multi_done() is called, to prevent multi_done() to get invoked twice when the multi interface is used. */ - BIT(stream_depends_e); /* set or don't set the Exclusive bit */ BIT(previouslypending); /* this transfer WAS in the multi->pending queue */ BIT(cookie_engine); BIT(prefer_ascii); /* ASCII rather than binary */ @@ -1789,10 +1782,8 @@ struct UserDefined { size_t maxconnects; /* Max idle connections in the connection cache */ long expect_100_timeout; /* in milliseconds */ -#ifdef USE_HTTP2 - struct Curl_easy *stream_depends_on; - int stream_weight; - struct Curl_http2_dep *stream_dependents; +#if defined(USE_HTTP2) || defined(USE_HTTP3) + struct Curl_data_priority priority; #endif curl_resolver_start_callback resolver_start; /* optional callback called before resolver start */ @@ -1884,7 +1875,6 @@ struct UserDefined { BIT(suppress_connect_headers); /* suppress proxy CONNECT response headers from user callbacks */ BIT(dns_shuffle_addresses); /* whether to shuffle addresses before use */ - BIT(stream_depends_e); /* set or don't set the Exclusive bit */ BIT(haproxyprotocol); /* whether to send HAProxy PROXY protocol v1 header */ BIT(abstract_unix_socket); -- cgit v1.2.1