Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ DEFVOLUME=PUB001
- `SSLPROXY=YES` is only for a TLS-terminating proxy in front of FTPD. Run bare
it promises clients a confidentiality it does not deliver; the member's own
comments spell this out.
- `BINDTRIES`/`BINDWAIT` (both 1–100, both default 10) decide how long FTPD
- `BINDTRIES`/`BINDWAIT` (both 1–100, defaulting to 3 and 5) decide how long FTPD
keeps trying a listener port it cannot have yet — a port still held, or a
stack that is not up. Giving up ends the started task, so raise `BINDTRIES`
if `/S FTPD` runs early in an IPL.
Expand Down
8 changes: 4 additions & 4 deletions samplib/ftpdprm0
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ PASVPORTS=22000-22200
#
# A bind() that fails for a reason waiting can fix -- the port still held
# by something, or the stack not up yet at IPL -- is retried BINDTRIES
# times, BINDWAIT seconds apart. Both 1-100, both default 10, so FTPD
# waits up to 100 seconds before giving up.
# times, BINDWAIT seconds apart. Both 1-100; the defaults 3 and 5 give
# FTPD 15 seconds before it gives up.
#
# Giving up ends the started task (FTPD056E): an FTPD that cannot listen
# has nothing left to do, and no console command re-tries the bind. So
# these two decide how much transient trouble a start survives. Raise
# BINDTRIES where FTPD is started before TCP/IP is reliably up.
#
BINDTRIES=10
BINDWAIT=10
BINDTRIES=3
BINDWAIT=5
#
# PASVBIND is where the passive listener binds, PASVADR is what the
# client is told to connect to -- they are only the same by default.
Expand Down
20 changes: 17 additions & 3 deletions src/ftpd#cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,23 @@ ftpdcfg_defaults(ftpd_config_t *cfg)
strcpy(cfg->pasv_bind, "ANY"); /* bind every address, as before */
cfg->pasv_lo = 22000;
cfg->pasv_hi = 22200;
cfg->bind_tries = 10; /* HTTPD's defaults: up to 100s of
** patience before the STC ends */
cfg->bind_wait = 10;
/* 15 seconds of patience, not HTTPD's 100. HTTPD's number predates a
** stale port sweep: there, a repeated bind was the only defence against
** a port a dead instance still held. Here close_stale_port() has
** already cleared that case before the retry loop is reached (#109), so
** what still answers EADDRINUSE afterwards is most likely a LIVE foreign
** listener -- and waiting on one does not help, it does not go away.
**
** The cost of waiting also changed: since #111 a bind that never
** succeeds ends the STC, so the operator who typed /S and is watching
** the console waits out the whole budget for a verdict. 15 seconds
** covers TIME_WAIT and a tight restart; a failed start is recognisable
** as one while someone is still looking at it.
**
** The one case that wants far more patience is EADDRNOTAVAIL early in an
** IPL, and that is what raising BINDTRIES is for. */
cfg->bind_tries = 3;
cfg->bind_wait = 5;
/* Limits */
cfg->max_sessions = 10;
cfg->idle_timeout = 300;
Expand Down
10 changes: 6 additions & 4 deletions src/ftpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,12 @@ bind_retryable(int err)
** give up early when the server is being stopped.
**
** The step is what makes /P work during a retry run. BINDTRIES x
** BINDWAIT can now be 100 seconds; terminate() waits 10 for the socket
** thread and then says FTPD095W SOCKET THREAD DID NOT TERMINATE, so a
** thread asleep in one long STIMER would make every longer retry setting
** worse for the operator than the short one it replaced.
** BINDWAIT is 15 seconds by default but goes to 100 x 100 -- and the
** sites that raise it are exactly the ones that will need to interrupt
** it. terminate() waits 10 seconds for the socket thread and then says
** FTPD095W SOCKET THREAD DID NOT TERMINATE, so a thread asleep in one
** long STIMER would make every longer retry setting worse for the
** operator than the short one it replaced.
**
** Returns 0 when the wait completed, -1 when shutdown was signalled.
** ----------------------------------------------------------------- */
Expand Down