This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Inetutils 1.3.2: Problem running ftpd server under windows 4.0


I have found what appears to be a bug in the ftpd server from the
inetutils 1.3.2.  I am using the server to download an embedded
processor.  The embedded client FTPs 2 files in quick succession
requesting the same TCP PORT for both.  When the server attempts the
second download, it gets an EADDRINUSE error from Windows.  It retries
the connect for 90 seconds before returning an error to the FTP client.

I don't know if the error is because the first iteration of the FTP
server didn't properly close the socket or if Windows NT is slow to
clean up the resource.  In either event, I believe that the correct
behavior would be to return the error to the client without retrying.
The code looks like this:

        while (connect(data, (struct sockaddr *)&data_dest,
            sizeof(data_dest)) < 0) {
                if (errno == EADDRINUSE && retry < swaitmax) {
                        sleep((unsigned) swaitint);
                        retry += swaitint;
                        continue;
                }
                perror_reply(425, "Can't build data connection");
                (void) fclose(file);
                data = -1;
                return (NULL);
        }

At the FTP level the interaction looks like this:

FTP Client                      FTP Server
(embedded system)               (ftpd from inetutils 1.3.2)
=====================           ===========================
PORT 10,1,120,81,4,1     --->
                        <---    200 PORT command successful.
RETR thefile             --->

                                Server attempts a connect command to
                                port 1025, which returns an EADDRINUSE
                                error.  The server then retries the
                                connect every swaitint seconds for a
                                total of swaitmax seconds.  Since the
                                connect never succeeds, the server
                                blocks for SWAITMAX (i.e. 90 seconds).

                        <---    REPLY 425 Can't build data connection:
                                Address already in use.
PORT 10,1,120,81,4,2     --->
                        <---    200 PORT command successful
RETR thefile             --->

                                Server attempts a connect command to
                                the new port number (1026) which is
                                successful.

                        <---    150 Opening BINARY mode data connection
                                for 'thefile' (203664 bytes).

                                The server starts sending data packets
                                to the client.


I would like to propose the follow change to the code.

The code which reads:


        while ((ch = getopt(argc, argv, "dlt:T:u:v")) != EOF) {
                switch (ch) {
                case 'd':
                        debug = 1;
                        break;

                case 'l':
                        logging++;      /* > 1 == extra logging */
                        break;

                case 't':
        .
        .
        .
        }

Could be changed to:


        while ((ch = getopt(argc, argv, "dlr:t:T:u:v")) != EOF) {
                switch (ch) {
                case 'd':
                        debug = 1;
                        break;

                case 'l':
                        logging++;      /* > 1 == extra logging */
                        break;

                case 'r':
                        /* Maximum time to spend retrying */
                        /* an EADDRINUSE error.            */
                        swaitmax = atoi(optarg);
                        break;

                case 't':
        .
        .
        .
        }


This would allow the server to default to the existing behavior, but let
the user specify the maximum time to spend retrying an EADDRINUSE error.
In my case, I would use the flag -r 0 to indicate that EADDRINUSE errors
would never be retried.

Thank you.

Jon Marcus
MMC Networks, Inc.

--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]