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:
11
lib/multi.c
11
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
|
||||
|
||||
Reference in New Issue
Block a user