From 7cc00d9a832c42a330888aa5c11a2abad1bd5ac0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Aug 2013 23:49:53 +0200 Subject: FTP: when EPSV gets a 229 but fails to connect, retry with PASV This is a regression as this logic used to work. It isn't clear when it broke, but I'm assuming in 7.28.0 when we went all-multi internally. This likely never worked with the multi interface. As the failed connection is detected once the multi state has reached DO_MORE, the Curl_do_more() function was now expanded somewhat so that the ftp_do_more() function can request to go "back" to the previous state when it makes another attempt - using PASV. Added test case 1233 to verify this fix. It has the little issue that it assumes no service is listening/accepting connections on port 1... Reported-by: byte_bucket in the #curl IRC channel --- lib/multi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'lib/multi.c') diff --git a/lib/multi.c b/lib/multi.c index 774e80841..9653554f8 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -929,6 +929,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, struct SingleRequest *k; struct SessionHandle *data; long timeout_ms; + int control; if(!GOOD_EASY_HANDLE(easy)) return CURLM_BAD_EASY_HANDLE; @@ -1359,13 +1360,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* * When we are connected, DO MORE and then go DO_DONE */ - easy->result = Curl_do_more(easy->easy_conn, &dophase_done); + easy->result = Curl_do_more(easy->easy_conn, &control); /* No need to remove this handle from the send pipeline here since that is done in Curl_done() */ if(CURLE_OK == easy->result) { - if(dophase_done) { - multistate(easy, CURLM_STATE_DO_DONE); + if(control) { + /* if positive, advance to DO_DONE + if negative, go back to DOING */ + multistate(easy, control==1? + CURLM_STATE_DO_DONE: + CURLM_STATE_DOING); result = CURLM_CALL_MULTI_PERFORM; } else -- cgit v1.2.3