cURL / Mailing Lists / curl-library / Single Mail

curl-library

Active FTP failures while lacking available file handles

From: Gokhan Sengun <gokhansengun_at_gmail.com>
Date: Tue, 29 Nov 2011 13:34:00 +0200

Hi there,

I started to test my FTP client application which uses libcurl for extreme
conditions.

In the beginning, I leaked all file handles but three (one for control
connection socket, one for the local file to dump retrieved content, and
one for listening data connection for FTP server). So no socket is left to
accept the incoming connection.

FTP server could not appreciate the failure in opening the data connection,
therefore sending file content (of course it gets a RST from the client),
it also sends "226 Transfer OK" from ctrl connection. Or FTP server
appreciates the failure and sends "421 xxx" regarding the failure.

Since curl does not read the "last" message from the control connection, in
an attempt to connect again to the same server next time and reuse the
connection, "SocketIsDead" function concludes that the control connection
is dead, however it is still there and pretty much fine. That is because
"poll" sees that read flag is set. I think this is wrong and it needs to be
more clever but this is a different story and not easy to implement in a
platform independent manner!

Short of the story, connection reuse is not possible if accept fails for
some reason.

In order to prevent that from happening, I introduced the fix given below
and it seemed to fix the issue for me. Now the questions are:

1- How smart is this fix? Is there something I am missing?
2- Are there other similar error paths we expect a message from control
connection while failing on data connection for FTP?

ps 1: libcurl handles other cases (no avail sock, 1, 2 avail sockets)
perfectly.
ps 2: I do not have a linux environment right now. So I can not run git to
create a patch but since it is simple it is tagged with RED.

      if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) {
        size = sizeof(add);

        s=accept(sock, (struct sockaddr *) &add, &size);
      }
      Curl_closesocket(conn, sock); /* close the first socket */

      if(CURL_SOCKET_BAD == s) {
        failf(data, "Error accept()ing server connect");
        *conn->proto.ftpc.pp.pending_resp = TRUE; /* RED */*
        return CURLE_FTP_PORT_FAILED;
      }
      infof(data, "Connection accepted from server\n");

Thanks.

-- 
it is twice as difficult to debug a program as to write it. Therefore, if
you put all of your creativity and effort into writing the program, you are
not smart enough to debug it.

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2011-11-29