Subject: bin/10375: ftp connection is lost when client detects an error
To: None <>
From: None <>
List: netbsd-bugs
Date: 06/15/2000 13:23:14
>Number:         10375
>Category:       bin
>Synopsis:       ftp connection is lost when client detects an error
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jun 15 13:24:00 PDT 2000
>Originator:     Trevin Beattie
>Release:        1.4.2
Eyring Corporation
NetBSD 1.4.2 NetBSD 1.4.2 (TUKTU) #0: Thu Mar 23 09:25:10 MST 2000 i386 unknown

I don't know whether this is correct behavior, but it seems like it isn't.

When the ftp client is downloading a file, if an error occurs before
the file is finished the client will print out its error message, close
the data connection, and wait for a reply from the server.  If the
server is still sending data, however, it will receive a SIGPIPE
(because it is writing to a socket with no reader).  The server then
logs "lost connection" and exits, closing the control connection.  The
client, reading an EOF from the control connection, then spits out
error 421 (remote server has closed connection).

Contrast this with an interrupted transfer.  The client will send an
out-of-band message and the ABOR command to the server.  It will then
read from *both* the control and data connections, discarding any data,
until the abort is acknowledged.  Only afterwards will it close the
data connection.  The control connection remains open.

Shouldn't the control connection remain open if the ftp client detects
an error?  If so, what should be the proper fix: having the server
treat a severed data connection differently than a severed control
connection, or having the client send an ABOR command and read any
remaining data before closing the data connection?  Or maybe both?

Create a small RAM disk:
	% mkdir /tmp/mfs
	% mount_mfs -b 8192 -f 1024 -s 1024 swap /tmp/mfs
	% cd /tmp/mfs
Connect to the ftp server on the local machine, and grab a huge file:
	% ftp localhost
	Connected to localhost.
	ftp> cd /pub/gnu
	250 CWD command successful.
	ftp> get gcc-2.95.tar.gz
	local: gcc-2.95.tar.gz remote: gcc-2.95.tar.gz
	227 Entering Passive Mode (127,0,0,1,229,77)
	150 Opening BINARY mode data connection for 'gcc-2.95.tar.gz' (12864284 bytes).
	  0% |                                     |     0       0.00 KB/s    --:-- ETA
	/tmp/mfs: write failed, file system is full
	ftp: local: gcc-2.95.tar.gz: No space left on device
	  3% |*                                    |   432 KB    3.78 MB/s    00:03 ETA
	421 Service not available, remote server has closed connection.
	442368 bytes received in 00:00 (3.67 MB/s)
	ftp: No control connection for command.

ftp client: between progressmeter(-1) and progressmeter(1), in every
instance which calls for warn() or warnx(), you would have to call
progressmeter(1) and jump to the abort: tag instead of a normal break.

ftp server: in send_data() (before sending the reply), set up an
alternate signal handler for SIGPIPE which ignores the signal.