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
This commit is contained in:
Daniel Stenberg
2013-08-05 23:49:53 +02:00
parent 230e16dc03
commit 7cc00d9a83
7 changed files with 101 additions and 39 deletions

View File

@@ -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