summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Eissing <stefan@eissing.org>2022-11-21 15:40:26 +0100
committerDaniel Stenberg <daniel@haxx.se>2022-11-22 08:20:38 +0100
commit4a8b4a1b6635f1dc811b65a9355b89f0277da1f2 (patch)
tree4f1a03fd881b915e6cae0f3a08ccc6303e5cc7ca
parentb7413a66bd01cd5b6f7acbfffa5e39ec9db99d42 (diff)
downloadcurl-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.c15
-rw-r--r--lib/cfilters.h10
-rw-r--r--lib/connect.c2
-rw-r--r--lib/ftp.c10
-rw-r--r--lib/http_proxy.c2
-rw-r--r--lib/socks.c1
-rw-r--r--lib/vtls/vtls.c2
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,
diff --git a/lib/ftp.c b/lib/ftp.c
index f25d17a7a..00e906687 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -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,