diff options
author | Stefan Eissing <stefan@eissing.org> | 2022-11-21 15:40:26 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2022-11-22 08:20:38 +0100 |
commit | 4a8b4a1b6635f1dc811b65a9355b89f0277da1f2 (patch) | |
tree | 4f1a03fd881b915e6cae0f3a08ccc6303e5cc7ca | |
parent | b7413a66bd01cd5b6f7acbfffa5e39ec9db99d42 (diff) | |
download | curl-4a8b4a1b6635f1dc811b65a9355b89f0277da1f2.tar.gz |
cfiler: filter types have flags indicating what they do
- Adding Curl_conn_is_ip_connected() to check if network connectivity
has been reached
- having ftp wait for network connectivity before proceeding with
transfers.
Fixes test failures 1631 and 1632 with hyper.
Closes #9952
-rw-r--r-- | lib/cfilters.c | 15 | ||||
-rw-r--r-- | lib/cfilters.h | 10 | ||||
-rw-r--r-- | lib/connect.c | 2 | ||||
-rw-r--r-- | lib/ftp.c | 10 | ||||
-rw-r--r-- | lib/http_proxy.c | 2 | ||||
-rw-r--r-- | lib/socks.c | 1 | ||||
-rw-r--r-- | lib/vtls/vtls.c | 2 |
7 files changed, 39 insertions, 3 deletions
diff --git a/lib/cfilters.c b/lib/cfilters.c index 5b5b08ecf..8bc02c92f 100644 --- a/lib/cfilters.c +++ b/lib/cfilters.c @@ -374,6 +374,21 @@ bool Curl_cfilter_is_connected(struct Curl_easy *data, return cf && cf->connected; } +bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex) +{ + struct Curl_cfilter *cf; + + cf = data->conn->cfilter[sockindex]; + while(cf) { + if(cf->connected) + return TRUE; + if(cf->cft->flags & CF_TYPE_IP_CONNECT) + return FALSE; + cf = cf->next; + } + return FALSE; +} + bool Curl_cfilter_data_pending(const struct Curl_easy *data, struct connectdata *conn, int sockindex) { diff --git a/lib/cfilters.h b/lib/cfilters.h index 6fb031eca..9950b6656 100644 --- a/lib/cfilters.h +++ b/lib/cfilters.h @@ -83,9 +83,13 @@ typedef void Curl_cf_detach_data(struct Curl_cfilter *cf, */ void Curl_cfilter_detach(struct connectdata *conn, struct Curl_easy *data); +#define CF_TYPE_IP_CONNECT (1 << 0) +#define CF_TYPE_SSL (1 << 1) + /* A connection filter type, e.g. specific implementation. */ struct Curl_cftype { const char *name; /* name of the filter type */ + long flags; /* flags of filter type */ Curl_cf_destroy *destroy; /* destroy resources held */ Curl_cf_attach_data *attach_data; /* data is being handled here */ Curl_cf_detach_data *detach_data; /* data is no longer handled here */ @@ -164,6 +168,12 @@ CURLcode Curl_cfilter_connect(struct Curl_easy *data, bool blocking, bool *done); bool Curl_cfilter_is_connected(struct Curl_easy *data, struct connectdata *conn, int sockindex); +/** + * Determine if we have reached the remote host on IP level, e.g. + * have a TCP connection. This turns TRUE before a possible SSL + * handshake has been started/done. + */ +bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex); void Curl_cfilter_close(struct Curl_easy *data, struct connectdata *conn, int index); diff --git a/lib/connect.c b/lib/connect.c index fbb8e86ee..6fc711533 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -1822,6 +1822,7 @@ static void socket_cf_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) static const struct Curl_cftype cft_socket = { "SOCKET", + CF_TYPE_IP_CONNECT, socket_cf_destroy, Curl_cf_def_attach_data, Curl_cf_def_detach_data, @@ -1892,6 +1893,7 @@ static CURLcode socket_accept_cf_setup(struct Curl_cfilter *cf, static const struct Curl_cftype cft_socket_accept = { "SOCKET-ACCEPT", + CF_TYPE_IP_CONNECT, socket_cf_destroy, Curl_cf_def_attach_data, Curl_cf_def_detach_data, @@ -3560,12 +3560,16 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) * complete */ struct FTP *ftp = NULL; - /* if the second connection isn't done yet, wait for it */ + /* if the second connection isn't done yet, wait for it to have + * connected to the remote host. When using proxy tunneling, this + * means the tunnel needs to have been establish. However, we + * can not expect the remote host to talk to us in any way yet. + * So, when using ftps: the SSL handshake will not start until we + * tell the remote server that we are there. */ if(conn->cfilter[SECONDARYSOCKET]) { result = Curl_cfilter_connect(data, conn, SECONDARYSOCKET, FALSE, &connected); - if(result || - (!connected && conn->sock[SECONDARYSOCKET] == CURL_SOCKET_BAD)) { + if(result || !Curl_conn_is_ip_connected(data, SECONDARYSOCKET)) { if(result && (ftpc->count1 == 0)) { *completep = -1; /* go back to DOING please */ /* this is a EPSV connect failing, try PASV instead */ diff --git a/lib/http_proxy.c b/lib/http_proxy.c index bb5f04f90..0ba99d0f6 100644 --- a/lib/http_proxy.c +++ b/lib/http_proxy.c @@ -1162,6 +1162,7 @@ static void http_proxy_cf_close(struct Curl_cfilter *cf, static const struct Curl_cftype cft_http_proxy = { "HTTP-PROXY", + CF_TYPE_IP_CONNECT, http_proxy_cf_destroy, Curl_cf_def_attach_data, http_proxy_cf_detach_data, @@ -1246,6 +1247,7 @@ static CURLcode haproxy_cf_connect(struct Curl_cfilter *cf, static const struct Curl_cftype cft_haproxy = { "HAPROXY", + 0, Curl_cf_def_destroy, Curl_cf_def_attach_data, Curl_cf_def_detach_data, diff --git a/lib/socks.c b/lib/socks.c index e1f6dbbb2..4cd86f4cc 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -1214,6 +1214,7 @@ static void socks_proxy_cf_detach_data(struct Curl_cfilter *cf, static const struct Curl_cftype cft_socks_proxy = { "SOCKS-PROXYY", + CF_TYPE_IP_CONNECT, socks_proxy_cf_destroy, Curl_cf_def_attach_data, socks_proxy_cf_detach_data, diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index c6203b805..67b378402 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -1655,6 +1655,7 @@ static void ssl_cf_def_detach_data(struct Curl_cfilter *cf, static const struct Curl_cftype cft_ssl = { "SSL", + CF_TYPE_SSL, ssl_cf_destroy, ssl_cf_def_attach_data, ssl_cf_def_detach_data, @@ -1670,6 +1671,7 @@ static const struct Curl_cftype cft_ssl = { #ifndef CURL_DISABLE_PROXY static const struct Curl_cftype cft_ssl_proxy = { "SSL-PROXY", + CF_TYPE_SSL, ssl_cf_destroy, ssl_cf_def_attach_data, ssl_cf_def_detach_data, |