On Fri, 12 Feb 2010, Stuart Henderson wrote:
> On 2010/02/11 23:44, Daniel Dickman wrote:
> > ftp(1) will reliably stall for me when doing uploads. I tracked the
> > problem down to the keep-alive option. Not sure how widespread this issue
> > is as I'd imagine it depends on what server is on the receiving end. But
> > here's a sample transcript which gets stuck every time and requires me to
> > kill the process... the patch below turns off this functionality by
> > default as it doesn't really work all that well for me for uploads.
> > (Downloads on this same server work fine though).
>
> ftp(1) doesn't read until after the transfer finishes, so the
> server has to queue a big batch of "200 NOOP command successful"
> or similar replies and send them in a batch at the end of the
> transfer.
>
> Every other ftp client that I've investigated which has this
> option reads the replies after each line, which is more friendly
> to the server. I'm not sure if it's implicated in this problem,
> but I think it's fairly likely.
>
> I've played around with moving getreply() into send_noop_char()
> but something more than this is needed as it freezes after trying
> to read the first response.
>
> One problem with disabling keepalive is that some people behind
> crappy nat gateways need it, and there's no easy way to set this
> from the installer (without adding ugly questions, anyway), but
> OTOH pushing them towards using http might be a more sane work-
> around there...
>
>
Ok. What about the following defaults:
- interactive mode: disable keep-alive by default.
- auto-fetch mode: preserve current behaviour (60s between NOOPs by
default) since I haven't seen any issues with keep-alive when doing
downloads. This should keep the installer working as before.
At least until the problem can be diagnosed and fixed properly...
Index: ftp.1
===================================================================
RCS file: /usr/cvs/src/usr.bin/ftp/ftp.1,v
retrieving revision 1.79
diff -u -r1.79 ftp.1
--- ftp.1 9 Aug 2009 20:16:39 -0000 1.79
+++ ftp.1 12 Feb 2010 10:46:15 -0000
@@ -174,9 +174,10 @@
the control connection during a transfer.
Well-behaved servers queue those commands, and process them after the
transfer.
-By default,
+By default, this functionality is turned off unless auto-fetching.
+In that case, the default is for
.Nm
-will send a byte every 60 seconds.
+to send a byte every 60 seconds.
.It Fl m
Causes
.Nm
Index: ftp.c
===================================================================
RCS file: /usr/cvs/src/usr.bin/ftp/ftp.c,v
retrieving revision 1.79
diff -u -r1.79 ftp.c
--- ftp.c 6 Jun 2009 23:14:44 -0000 1.79
+++ ftp.c 12 Feb 2010 09:59:56 -0000
@@ -325,7 +325,7 @@
return (r);
}
-int keep_alive_timeout = 60; /* 0 -> no timeout */
+int keep_alive_timeout = -1; /* 0 -> no timeout */
static int full_noops_sent = 0;
static time_t last_timestamp = 0; /* 0 -> no measurement yet */
Index: main.c
===================================================================
RCS file: /usr/cvs/src/usr.bin/ftp/main.c,v
retrieving revision 1.80
diff -u -r1.80 main.c
--- main.c 9 Aug 2009 18:36:11 -0000 1.80
+++ main.c 12 Feb 2010 11:05:59 -0000
@@ -314,6 +314,8 @@
if (argc > 0) {
if (isurl(argv[0])) {
+ if (keep_alive_timeout < 0)
+ keep_alive_timeout = 60;
rval = auto_fetch(argc, argv, outfile);
if (rval >= 0) /* -1 == connected and cd-ed */
exit(rval);
@@ -321,6 +323,9 @@
#ifndef SMALL
char *xargv[5];
+ if (keep_alive_timeout < 0)
+ keep_alive_timeout = 0;
+
if (setjmp(toplevel))
exit(0);
(void)signal(SIGINT, (sig_t)intr);
@@ -345,6 +350,9 @@
}
}
#ifndef SMALL
+ if (keep_alive_timeout < 0)
+ keep_alive_timeout = 0;
+
controlediting();
top = setjmp(toplevel) == 0;
if (top) {