While testing the resume capabilities of wput 0.6, I
found a rather nasty bug. It goes like this:
1) A file upload starts
2) I unplug the network in the middle of the upload
3) After a while, wput timeouts and closes data and
control conections, but the send buffer of the socket
is still full
4) I plug the network back
5) wput re-establishes a connection and resumes the upload
6) A few seconds later, the socket is flushed to the
server and then closed
7) The server mixes both writes to the same file and
thus corrupts it.
This happens very reliably with vsftpd. I haven't
tested with other FTP servers, so I don't know how the
handle this "multiple simultaneous writes" problem.
I thought I could avoid the problem with the
--dont-continue option, but it still happens (with
vsftpd again) because the file is not removed but only
truncated, and thus the stale write still reaches it.
So in order to make it "work", I made a small patch
that actually deletes a file before overwriting it, so
that a new inode is created and the stale data is not
mixed with it. The patch is attached. Of course, this
doesn't apply to the case where actual resuming is
used. I realize this is a clumsy solution, but I really
don't know where or how to correct this problem and I
needed to get it to work fast.
Here is a small netstat extract to show what is
happening:
The network is interrupted:
tcp 0 66368 client:40915 server:21143
ESTABLISHED5707/wput
tcp 0 0 client:37636 server:21
ESTABLISHED5707/wput
wput tries to send the ABOR command:
tcp 0 66368 client:40915 server:21143
ESTABLISHED5707/wput
tcp 0 6 client:37636 server:21
ESTABLISHED5707/wput
wput closes the connections, but the data buffer is
still full:
tcp 0 66369 client:40915 server:21143
FIN_WAIT1 -
tcp 0 13 client:37636 server:21
FIN_WAIT1 -
A new connection is established:
tcp 0 57920 client:49806 server:32538
ESTABLISHED5707/wput
tcp 0 0 client:37641 server:21
ESTABLISHED5707/wput
tcp 0 66369 client:40915 server:21143
FIN_WAIT1 -
tcp 0 13 client:37636 server:21
FIN_WAIT1 -
And then, after a while, the stale buffer is sent
out. Does anyone know how to "clear" a socket buffer?
Mikael
My config:
* wput 0.6
* vsftpd 2.0.1 (on the server side)
* linux 2.6.16.19
Delete a file before overwriting