From: Stefan Eissing Date: Fri, 30 May 2025 10:05:14 +0000 (+0200) Subject: ftp: fix teardown of DATA connection in done X-Git-Tag: curl-8_14_1~28 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4977747f0da325f5ba4e7f346ce1db8eb6899885;p=thirdparty%2Fcurl.git ftp: fix teardown of DATA connection in done 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 --- diff --git a/lib/cfilters.c b/lib/cfilters.c index a9de86a462..00090f0c71 100644 --- a/lib/cfilters.c +++ b/lib/cfilters.c @@ -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; diff --git a/lib/cfilters.h b/lib/cfilters.h index 646aabf37d..4c604db38f 100644 --- a/lib/cfilters.h +++ b/lib/cfilters.h @@ -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. diff --git a/lib/ftp.c b/lib/ftp.c index 0aa19262f7..2c6138e980 100644 --- 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");