ftpget triggering TCP RST at end of download
Glenn L. McGrath
bug1 at iinet.net.au
Sat Sep 24 06:10:05 UTC 2005
On Fri, 23 Sep 2005 22:01:45 -0600
Stephen Warren <swarren at wwwdotorg.org> wrote:
> I have discovered a difference between busybox's ftpget and other FTP
> clients, such as wget and /usr/bin/ftp, in their implementation of FTP
> "get".
>
> Most clients seem to do this:
>
> 1) Send RETR command
> 2) Open data connection
> 3) Read from data connection until EOF, saving data
> 4) Close data connection
> 5) Read status response from command conenction
>
> However, busybox's ftpget (1.00 by testing, latest subversion by code
> reading) seem to do this:
>
> 1) Send SIZE command to determine how much to downoad
> 2) Send RETR command
> 3) Open data connection
> 4) Read from data connection exactly $SIZE bytes, saving data
> 5) Close data connection; note EOF won't be seen
> 6) Read status response from command conenction
>
> The problem is that sometimes the kernel seems to send a TCP RST packet
> when ftpget calls close(). I believe this is something to do with the
> kernel thinking that ftpget hasn't read all the data from the socket,
> and is thus sending an error message to the server that all data was not
> reliably delivered.
>
> This causes the FTP server (MS IIS 5.0 at least) to send back an error
> status message, and ftpget hence exits with a non-zero status.
>
> If I modify ftpget to use bb_copyfd_eof instead of bb_copyfd_size, then
> everything works just fine (because the last thing ftpget does is read
> from the socket, which returns zero indicating EOF, satisfying the
> kernel that all data has been read)
>
> Now, I know the server is sending exactly the number of bytes SIZE
> returns, since if I insert an extra read call after bb_copyfd_size, then
> no data is ever returned; zero is returned by read, indicating EOF. This
> change also causes the TCP RST to never get sent.
>
> So, my question is - is this an application issue; is one supposed to
> always read until EOF is returned, or is reading the actual exact
> number of bytes sent enough?
>
> Without this fix (bb_copyfd_eof), then ftpget fails from 10-50% of the time.
>
> In the packet traces I took with tcpdump (1 OK, 1 failure), I note that
> in the failure case, all packets were delivered to the ftpget machine in
> order without retries (at least the last few packets). However, in the
> OK case, the last but one packet was dropped, the last packet got
> through, and then the last but one packet was then resent and got
> through. Is this triggering the kernel to know earlier than usual that
> the socket was closed, and the exact byte count, hence causing things to
> work where the otherwise wouldn't?
>
> We're running stock kernel.org kernel 2.6.10, with a few non-networking
> patches built for x86 (athlon optimizations) and running on what is
> practically a standard PC.
>
> --
> Stephen Warren, Software Engineer, NVIDIA, Fort Collins, CO
> swarren at wwwdotorg.org http://www.wwwdotorg.org/pgp.html
>
Interesting problem, it sounds like it could be fixed in ftpget, but
also i think current behaviour should work.
If the kernel (or could it be libc?) is behaving eratically with this
code, maybe other applications could have this same problem.
Have you tried a few different kernel, say a 2.4.x kernel, or a
different libc ?
Glenn
More information about the busybox
mailing list