cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Graceful switch from PASV to PORT on failure (like 502)

From: Daniel Cater <djcater_at_gmail.com>
Date: Fri, 20 Jul 2007 16:25:25 +0100

On 19/07/07, Daniel Stenberg <daniel_at_haxx.se> wrote:
> 1) This behavior should be an option, not default behavior
>

OK, I'll look into that after I've got it working. Although, I don't
see much of a problem with changing behaviour from "PASV, 502, QUIT"
to "PASV, 502, PORT". Are people relying on PASV failures causing the
connection to close?

>
> 2) You MUST NOT change the options in data->set as that is where the app's
> choices are stored, dynamic changes internally in the lib must be stored
> elsewhere. This of course is needed to that subsequent uses of the easy
> handle all have the same options set as the app has set them to.
>

OK. I've left that as it is for now, but I guess I should add bits to
the ConnectBits struct in urldata.h?

> 3) data->reqdata.newurl must get a pointer to an allocated string, and...
>
> 4) ... if you want to clone the current URL, you should get it from
> data->change.url and not from data->set.set_url
>

I've changed this to "data->reqdata.newurl =
strdup(data->change.url);" Is that correct?

> Then, you should show us the FTP "trace" without cutting off interesting
> information. It seems it sent PORT but the server couldn't connect back to
> you?
>
> Are you running against a local server? It seems your client uses a 172.*
> address, and of course nothing outside your local network can connect back to
> that!
>
> It would be useful if you showed us a comparison with full logs with the
> "rever to PORT" option enabled and one log with PORT enabled manually.
>

Done. As you will see, both the client and server are on our internal
network. The are no connections to the outside world involved :-)
First, I used the following options:

curl_easy_setopt(curl, CURLOPT_URL, "ftp://172.17.110.43/");
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_USERPWD, "user:pass");
curl_easy_setopt(curl, CURLOPT_FTPPORT, "-");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "NLST");

Then I used the same options, apart from replacing "-" with NULL in
CURLOPT_FTPPORT.

The application outputs and Wireshark traces for each follow. I used
"(ip.src == 172.17.224.55 && ip.dst == 172.17.110.43) || (ip.src ==
172.17.110.43 && ip.dst == 172.17.224.55)" to filter out unwanted
traffic.

http://pastebin.com/m780d5c33 - Original output
http://pastebin.com/m2081b43f - Original trace

http://pastebin.com/m31f36b61 - Updated output
http://pastebin.com/m3b774ecf - Updated trace

Interesting points to note: The PORT command is never actually sent in
my patched version. After the NLST command is sent, the server sends a
150 and then tries to open a data connection to the _control_ port
(presumably because that's the only port it knows about since we
haven't sent a PORT message). This can be seen in packet 538. The PC
then sends a RST packet (539, because an unexpected packet arrived?)
and it all goes wrong from there. The server sends a 425 (543), but we
don't do anything for 60 seconds. Then we send QUIT (due to timeout),
get 221 and then sned another RST packet. In the application output,
the 425 response comes /after/ the QUIT, and the 221 message doesn't
appear.

I don't think I'm qualified to fix this! I'm enjoying trying though :-)
Received on 2007-07-20