cfilter: re-add `conn` as parameter to cfilter setup methods

- `Curl_ssl_get_config()` now returns the first config if no SSL proxy
  filter is active

- socket filter starts connection only on first invocation of its
  connect method

Fixes #9982
Closes #9983
This commit is contained in:
Stefan Eissing 2022-11-26 12:43:56 +01:00 коммит произвёл Daniel Stenberg
Родитель 3e33681eaf
Коммит f18956d0ca
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
16 изменённых файлов: 68 добавлений и 47 удалений

Просмотреть файл

@ -226,20 +226,22 @@ out:
return result;
}
void Curl_conn_cf_add(struct Curl_easy *data, int index,
void Curl_conn_cf_add(struct Curl_easy *data,
struct connectdata *conn,
int index,
struct Curl_cfilter *cf)
{
(void)data;
DEBUGF(infof(data, DMSGI(data, index, "cf_add(filter=%s)"),
cf->cft->name));
DEBUGASSERT(data->conn);
DEBUGASSERT(conn);
DEBUGASSERT(!cf->conn);
DEBUGASSERT(!cf->next);
cf->next = data->conn->cfilter[index];
cf->conn = data->conn;
DEBUGF(infof(data, CMSGI(conn, index, "cf_add(filter=%s)"),
cf->cft->name));
cf->next = conn->cfilter[index];
cf->conn = conn;
cf->sockindex = index;
data->conn->cfilter[index] = cf;
conn->cfilter[index] = cf;
}
void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data)
@ -260,11 +262,11 @@ void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data)
}
CURLcode Curl_conn_setup(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
const struct Curl_dns_entry *remotehost,
int ssl_mode)
{
struct connectdata *conn = data->conn;
struct Curl_cfilter *cf;
CURLcode result;
@ -281,13 +283,13 @@ CURLcode Curl_conn_setup(struct Curl_easy *data,
*/
if(!conn->cfilter[sockindex]) {
DEBUGF(infof(data, DMSGI(data, sockindex, "setup, init filter chain")));
result = Curl_conn_socket_set(data, sockindex);
result = Curl_conn_socket_set(data, conn, sockindex);
if(result)
goto out;
#ifndef CURL_DISABLE_PROXY
if(conn->bits.socksproxy) {
result = Curl_conn_socks_proxy_add(data, sockindex);
result = Curl_conn_socks_proxy_add(data, conn, sockindex);
if(result)
goto out;
}
@ -295,7 +297,7 @@ CURLcode Curl_conn_setup(struct Curl_easy *data,
if(conn->bits.httpproxy) {
#ifdef USE_SSL
if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
result = Curl_ssl_cfilter_proxy_add(data, sockindex);
result = Curl_ssl_cfilter_proxy_add(data, conn, sockindex);
if(result)
goto out;
}
@ -303,7 +305,7 @@ CURLcode Curl_conn_setup(struct Curl_easy *data,
#if !defined(CURL_DISABLE_HTTP)
if(conn->bits.tunnel_proxy) {
result = Curl_conn_http_proxy_add(data, sockindex);
result = Curl_conn_http_proxy_add(data, conn, sockindex);
if(result)
goto out;
}
@ -315,7 +317,7 @@ CURLcode Curl_conn_setup(struct Curl_easy *data,
if(ssl_mode == CURL_CF_SSL_ENABLE
|| (ssl_mode != CURL_CF_SSL_DISABLE
&& conn->handler->flags & PROTOPT_SSL)) {
result = Curl_ssl_cfilter_add(data, sockindex);
result = Curl_ssl_cfilter_add(data, conn, sockindex);
if(result)
goto out;
}
@ -325,7 +327,7 @@ CURLcode Curl_conn_setup(struct Curl_easy *data,
#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
if(data->set.haproxyprotocol) {
result = Curl_conn_haproxy_add(data, sockindex);
result = Curl_conn_haproxy_add(data, conn, sockindex);
if(result)
goto out;
}

Просмотреть файл

@ -180,6 +180,7 @@ CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
* the start of the chain (top).
*/
void Curl_conn_cf_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
struct Curl_cfilter *cf);
@ -208,6 +209,7 @@ void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data);
* suitable filter chain.
*/
CURLcode Curl_conn_setup(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
const struct Curl_dns_entry *remotehost,
int ssl_mode);

Просмотреть файл

@ -1721,8 +1721,8 @@ static CURLcode socket_cf_setup(struct Curl_cfilter *cf,
const struct Curl_dns_entry *remotehost)
{
struct socket_cf_ctx *ctx = cf->ctx;
bool done;
(void)data;
DEBUGASSERT(ctx);
if(ctx->remotehost != remotehost) {
if(ctx->remotehost) {
@ -1730,10 +1730,9 @@ static CURLcode socket_cf_setup(struct Curl_cfilter *cf,
}
ctx->remotehost = remotehost;
}
/* we start connecting right on setup */
DEBUGF(infof(data, CFMSG(cf, "setup(remotehost=%s)"),
cf->conn->hostname_resolve));
return socket_cf_connect(cf, data, FALSE, &done);
return CURLE_OK;
}
static void socket_cf_close(struct Curl_cfilter *cf,
@ -1828,6 +1827,7 @@ static const struct Curl_cftype cft_socket = {
};
CURLcode Curl_conn_socket_set(struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
CURLcode result;
@ -1835,7 +1835,8 @@ CURLcode Curl_conn_socket_set(struct Curl_easy *data,
struct socket_cf_ctx *scf_ctx = NULL;
/* Need to be first */
DEBUGASSERT(!data->conn->cfilter[sockindex]);
DEBUGASSERT(conn);
DEBUGASSERT(!conn->cfilter[sockindex]);
scf_ctx = calloc(sizeof(*scf_ctx), 1);
if(!scf_ctx) {
result = CURLE_OUT_OF_MEMORY;
@ -1844,7 +1845,7 @@ CURLcode Curl_conn_socket_set(struct Curl_easy *data,
result = Curl_cf_create(&cf, &cft_socket, scf_ctx);
if(result)
goto out;
Curl_conn_cf_add(data, sockindex, cf);
Curl_conn_cf_add(data, conn, sockindex, cf);
out:
if(result) {
@ -1898,9 +1899,9 @@ static const struct Curl_cftype cft_socket_accept = {
};
CURLcode Curl_conn_socket_accepted_set(struct Curl_easy *data,
struct connectdata *conn,
int sockindex, curl_socket_t *s)
{
struct connectdata *conn = data->conn;
CURLcode result;
struct Curl_cfilter *cf = NULL;
struct socket_cf_ctx *scf_ctx = NULL;
@ -1922,7 +1923,7 @@ CURLcode Curl_conn_socket_accepted_set(struct Curl_easy *data,
result = Curl_cf_create(&cf, &cft_socket_accept, scf_ctx);
if(result)
goto out;
Curl_conn_cf_add(data, sockindex, cf);
Curl_conn_cf_add(data, conn, sockindex, cf);
}
/* close any existing socket and replace */

Просмотреть файл

@ -149,9 +149,12 @@ void Curl_conncontrol(struct connectdata *conn,
#endif
CURLcode Curl_conn_socket_set(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
CURLcode Curl_conn_socket_accepted_set(struct Curl_easy *data,
int sockindex, curl_socket_t *s);
struct connectdata *conn,
int sockindex,
curl_socket_t *s);
#endif /* HEADER_CURL_CONNECT_H */

Просмотреть файл

@ -286,7 +286,7 @@ static CURLcode AcceptServerConnect(struct Curl_easy *data)
(void)curlx_nonblock(s, TRUE); /* enable non-blocking */
/* Replace any filter on SECONDARY with one listeing on this socket */
result = Curl_conn_socket_accepted_set(data, SECONDARYSOCKET, &s);
result = Curl_conn_socket_accepted_set(data, conn, SECONDARYSOCKET, &s);
if(result)
return result;
@ -1267,7 +1267,8 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
ftpc->count1 = fcmd;
/* Replace any filter on SECONDARY with one listeing on this socket */
result = Curl_conn_socket_accepted_set(data, SECONDARYSOCKET, &portsock);
result = Curl_conn_socket_accepted_set(data, conn, SECONDARYSOCKET,
&portsock);
if(result)
goto out;
portsock = CURL_SOCKET_BAD; /* now held in filter */
@ -1973,7 +1974,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
}
}
result = Curl_conn_setup(data, SECONDARYSOCKET, addr,
result = Curl_conn_setup(data, conn, SECONDARYSOCKET, addr,
conn->bits.ftp_use_data_ssl?
CURL_CF_SSL_ENABLE : CURL_CF_SSL_DISABLE);
@ -2741,7 +2742,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
/* this was BLOCKING, keep it so for now */
bool done;
if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) {
result = Curl_ssl_cfilter_add(data, FIRSTSOCKET);
result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET);
if(result) {
/* we failed and bail out */
return CURLE_USE_SSL_FAILED;

Просмотреть файл

@ -243,7 +243,7 @@ static CURLcode h3_setup_conn(struct Curl_easy *data,
DEBUGF(infof(data, "HTTP/3 direct conn setup(conn #%ld, index=%d)",
conn->connection_id, FIRSTSOCKET));
return Curl_conn_socket_set(data, FIRSTSOCKET);
return Curl_conn_socket_set(data, conn, FIRSTSOCKET);
#else /* ENABLE_QUIC */
(void)conn;

Просмотреть файл

@ -1191,6 +1191,7 @@ static const struct Curl_cftype cft_http_proxy = {
};
CURLcode Curl_conn_http_proxy_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
struct Curl_cfilter *cf;
@ -1198,7 +1199,7 @@ CURLcode Curl_conn_http_proxy_add(struct Curl_easy *data,
result = Curl_cf_create(&cf, &cft_http_proxy, NULL);
if(!result)
Curl_conn_cf_add(data, sockindex, cf);
Curl_conn_cf_add(data, conn, sockindex, cf);
return result;
}
@ -1275,6 +1276,7 @@ static const struct Curl_cftype cft_haproxy = {
};
CURLcode Curl_conn_haproxy_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
struct Curl_cfilter *cf;
@ -1282,7 +1284,7 @@ CURLcode Curl_conn_haproxy_add(struct Curl_easy *data,
result = Curl_cf_create(&cf, &cft_haproxy, NULL);
if(!result)
Curl_conn_cf_add(data, sockindex, cf);
Curl_conn_cf_add(data, conn, sockindex, cf);
return result;
}

Просмотреть файл

@ -33,9 +33,11 @@
#define PROXY_TIMEOUT (3600*1000)
CURLcode Curl_conn_http_proxy_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
CURLcode Curl_conn_haproxy_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */

Просмотреть файл

@ -477,7 +477,7 @@ static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data,
CURLcode result;
if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) {
result = Curl_ssl_cfilter_add(data, FIRSTSOCKET);
result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET);
if(result)
goto out;
}

Просмотреть файл

@ -372,7 +372,7 @@ static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data,
CURLcode result;
if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) {
result = Curl_ssl_cfilter_add(data, FIRSTSOCKET);
result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET);
if(result)
goto out;
}

Просмотреть файл

@ -399,7 +399,7 @@ static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data)
CURLcode result;
if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) {
result = Curl_ssl_cfilter_add(data, FIRSTSOCKET);
result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET);
if(result)
goto out;
}

Просмотреть файл

@ -1245,6 +1245,7 @@ static const struct Curl_cftype cft_socks_proxy = {
};
CURLcode Curl_conn_socks_proxy_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
struct Curl_cfilter *cf;
@ -1252,7 +1253,7 @@ CURLcode Curl_conn_socks_proxy_add(struct Curl_easy *data,
result = Curl_cf_create(&cf, &cft_socks_proxy, NULL);
if(!result)
Curl_conn_cf_add(data, sockindex, cf);
Curl_conn_cf_add(data, conn, sockindex, cf);
return result;
}

Просмотреть файл

@ -52,6 +52,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
#endif
CURLcode Curl_conn_socks_proxy_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
#endif /* CURL_DISABLE_PROXY */

Просмотреть файл

@ -4041,7 +4041,7 @@ CURLcode Curl_setup_conn(struct Curl_easy *data,
is later set again for the progress meter purpose */
conn->now = Curl_now();
if(!conn->bits.reuse)
result = Curl_conn_setup(data, FIRSTSOCKET, conn->dns_entry,
result = Curl_conn_setup(data, conn, FIRSTSOCKET, conn->dns_entry,
CURL_CF_SSL_DEFAULT);
/* not sure we need this flag to be passed around any more */
*protocol_done = FALSE;

Просмотреть файл

@ -1462,6 +1462,7 @@ static void reinit_hostname(struct Curl_cfilter *cf)
connssl->port = (int)cf->conn->remote_port;
}
}
DEBUGASSERT(connssl->hostname);
}
static void ssl_cf_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
@ -1504,17 +1505,20 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
}
(void)connssl;
DEBUGASSERT(data->conn);
DEBUGASSERT(data->conn == cf->conn);
DEBUGASSERT(connssl);
/* TODO: right now we do not fully control when hostname is set, but
* copy it over again on each connect call. Esp. secondary chains seems
* to set it after the filters have been added */
reinit_hostname(cf);
DEBUGASSERT(cf->conn->host.name);
result = cf->next->cft->connect(cf->next, data, blocking, done);
if(result || !*done)
return result;
/* TODO: right now we do not fully control when hostname is set,
* assign it on each connect call. */
reinit_hostname(cf);
*done = FALSE;
if(blocking) {
result = ssl_connect(cf, data);
*done = (result == CURLE_OK);
@ -1628,6 +1632,7 @@ static const struct Curl_cftype cft_ssl_proxy = {
};
CURLcode Curl_ssl_cfilter_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
struct Curl_cfilter *cf;
@ -1645,9 +1650,8 @@ CURLcode Curl_ssl_cfilter_add(struct Curl_easy *data,
if(result)
goto out;
Curl_conn_cf_add(data, sockindex, cf);
Curl_conn_cf_add(data, conn, sockindex, cf);
reinit_hostname(cf);
result = CURLE_OK;
out:
@ -1658,6 +1662,7 @@ out:
#ifndef CURL_DISABLE_PROXY
CURLcode Curl_ssl_cfilter_proxy_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
struct Curl_cfilter *cf;
@ -1674,9 +1679,8 @@ CURLcode Curl_ssl_cfilter_proxy_add(struct Curl_easy *data,
if(result)
goto out;
Curl_conn_cf_add(data, sockindex, cf);
Curl_conn_cf_add(data, conn, sockindex, cf);
reinit_hostname(cf);
result = CURLE_OK;
out:
@ -1793,7 +1797,7 @@ Curl_ssl_get_config(struct Curl_easy *data, int sockindex)
(void)data;
DEBUGASSERT(data->conn);
cf = get_ssl_cf_engaged(data->conn, sockindex);
return cf? Curl_ssl_cf_get_config(cf, data) : NULL;
return cf? Curl_ssl_cf_get_config(cf, data) : &data->set.ssl;
}
struct ssl_primary_config *

Просмотреть файл

@ -153,6 +153,7 @@ void Curl_free_multi_ssl_backend_data(struct multi_ssl_backend_data *mbackend);
#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
CURLcode Curl_ssl_cfilter_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
CURLcode Curl_ssl_cfilter_remove(struct Curl_easy *data,
@ -160,6 +161,7 @@ CURLcode Curl_ssl_cfilter_remove(struct Curl_easy *data,
#ifndef CURL_DISABLE_PROXY
CURLcode Curl_ssl_cfilter_proxy_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
#endif /* !CURL_DISABLE_PROXY */
@ -239,8 +241,8 @@ bool Curl_ssl_use(struct connectdata *conn, int sockindex);
#define Curl_ssl_get_backend_data_size(a) 0
#define Curl_ssl_use(a,b) FALSE
#define Curl_ssl_conn_is_ssl(a,b) FALSE
#define Curl_ssl_cfilter_add(a,b) CURLE_NOT_BUILT_IN
#define Curl_ssl_cfilter_proxy_add(a,b) CURLE_NOT_BUILT_IN
#define Curl_ssl_cfilter_add(a,b,c) CURLE_NOT_BUILT_IN
#define Curl_ssl_cfilter_proxy_add(a,b,c) CURLE_NOT_BUILT_IN
#define Curl_ssl_get_config(a,b) NULL
#define Curl_ssl_cfilter_remove(a,b) CURLE_OK
#endif