]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
ftp: fix teardown of DATA connection in done
authorStefan Eissing <stefan@eissing.org>
Fri, 30 May 2025 10:05:14 +0000 (12:05 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 31 May 2025 13:15:05 +0000 (15:15 +0200)
When ftp_done() is called to terminate the transfer, it needs to tear
down any open SECONDARY filter chain. The condition on when to do that
was relying on there to be a valid socket. This is not sufficient as the
socket is only set *after* happy eyeballing has decided on one.

Instead of checking for a valid conn->sock, check if any connection
filter is installed.

Fixes #17482
Reported-by: Rasmus Melchior Jacobsen
Closes #17491

lib/cfilters.c
lib/cfilters.h
lib/ftp.c

index a9de86a462610ef4166359402470867e8e0c9897..00090f0c719891b2f7f15a1f2a70b69f05c7af63 100644 (file)
@@ -497,6 +497,11 @@ out:
   return result;
 }
 
+bool Curl_conn_is_setup(struct connectdata *conn, int sockindex)
+{
+  return (conn->cfilter[sockindex] != NULL);
+}
+
 bool Curl_conn_is_connected(struct connectdata *conn, int sockindex)
 {
   struct Curl_cfilter *cf;
index 646aabf37d0bfaba743c2db7af85843d646b3d99..4c604db38f7cbd84818e9e4ae455ec140b36609e 100644 (file)
@@ -370,6 +370,11 @@ bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf,
 CURLcode Curl_conn_connect(struct Curl_easy *data, int sockindex,
                            bool blocking, bool *done);
 
+/**
+ * Check if a filter chain at `sockindex` for connection `conn` exists.
+ */
+bool Curl_conn_is_setup(struct connectdata *conn, int sockindex);
+
 /**
  * Check if the filter chain at `sockindex` for connection `conn` is
  * completely connected.
index 0aa19262f7eacd37c835be392690e2c5d2a774ff..2c6138e98020e1a859118a97e221883afe41028e 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1752,8 +1752,7 @@ static CURLcode ftp_epsv_disable(struct Curl_easy *data,
   infof(data, "Failed EPSV attempt. Disabling EPSV");
   /* disable it for next transfer */
   conn->bits.ftp_use_epsv = FALSE;
-  Curl_conn_close(data, SECONDARYSOCKET);
-  Curl_conn_cf_discard_all(data, conn, SECONDARYSOCKET);
+  close_secondarysocket(data, ftpc);
   data->state.errorbuf = FALSE; /* allow error message to get
                                          rewritten */
   result = Curl_pp_sendf(data, &ftpc->pp, "%s", "PASV");
@@ -3322,7 +3321,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
   shutdown(conn->sock[SECONDARYSOCKET], 2);  /* SD_BOTH */
 #endif
 
-  if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
+  if(Curl_conn_is_setup(conn, SECONDARYSOCKET)) {
     if(!result && ftpc->dont_check && data->req.maxdownload > 0) {
       /* partial download completed */
       result = Curl_pp_sendf(data, pp, "%s", "ABOR");