Fix some timeout-related bugs; allow the user to set the default timeout.

This commit is contained in:
hpa 2002-10-23 21:21:46 +00:00
parent ebc8f1f89d
commit 82eae1bcd6
3 changed files with 78 additions and 30 deletions

View file

@ -1,5 +1,14 @@
$Id$
Changes in 0.31:
Put in a check to make sure xinetd (in particular) doesn't
pass us an IPv6 socket.
Fix some problems related to timeout negotiation.
Allow the user to set the default timeout speed.
Changes in 0.30:
(Hopefully) better timeout algorithm.

View file

@ -31,7 +31,7 @@
.\" SUCH DAMAGE.
.\"
.\"----------------------------------------------------------------------- */
.TH TFTPD 8 "16 November 2001" "tftp-hpa @@VERSION@@" "UNIX System Manager's Manual"
.TH TFTPD 8 "23 October 2002" "tftp-hpa @@VERSION@@" "System Manager's Manual"
.SH NAME
.B tftpd
\- IPv4 Trivial File Transfer Protocol server
@ -125,6 +125,14 @@ before terminating the server.
will then respawn the server when another request comes in. The
default is 900 (15 minutes.)
.TP
\fB\-T\fP \fItimeout\fP
Determine the default timeout, in microseconds, before the first
packet is retransmitted. This can be modified by the client if the
.B timeout
or
.B utimeout
option is negotiated. The default is 1000000 (1 second.)
.TP
\fB\-m\fP \fIremap-file\fP
Specify the use of filename remapping. The
.I remap-file
@ -149,25 +157,44 @@ exit gracefully.
This version of
.B tftpd
supports RFC 2347 option negotation. Currently implemented options
are
.B blksize
(RFC 2348),
.B blksize2
(nonstandard),
are:
.TP
\fBblksize\fP (RFC 2348)
Set the transfer block size to anything less than or equal to the
specified option. This version of
.B tftpd
can support any block size up to the theoretical maximum of 65464
bytes.
.TP
\fBblksize2\fP (nonstandard)
Set the transfer block size to anything less than or equal to the
specified option, but restrict the possible responses to powers of 2.
The maximum is 32768 bytes (the largest power of 2 less than or equal
to 65464.)
.TP
\fBtsize\fP (RFC 2349)
Report the size of the file that is about to be transferred. This
version of
.B tftpd
only supports the
.B tsize
(RFC 2349), and
.B timeout
(RFC 2349). The nonstandard
.B blksize2
TFTP option is functionally identical to the
.B blksize
option, with the additional constraint that the
blocksize is constrained to be a power of 2.
option for binary (octet) mode transfers.
.TP
\fBtimeout\fP (RFC 2349)
Set the time before the server retransmits a packet, in seconds.
.TP
\fButimeout\fP (nonstandard)
Set the time before the server retransmits a packet, in microseconds.
and
.PP
The
.B \-r
option can be used to disable specific options; this may be necessary
to work around bugs in specific TFTP client implementations.
to work around bugs in specific TFTP client implementations. For
example, some TFTP clients have been found to request the
.B blksize
option, but crash with an error if they actually get the option
accepted by the server.
.SH "FILENAME REMAPPING"
The
.B \-m

View file

@ -79,16 +79,16 @@ int allow_severity = -1; /* Don't log at all */
struct request_info wrap_request;
#endif
#define TIMEOUT 1000 /* Default timeout (ms) */
#define TIMEOUT 1000000 /* Default timeout (us) */
#define TRIES 6 /* Number of attempts to send each packet */
#define TIMEOUT_LIMIT ((1 << TRIES)-1)
char *__progname;
const char *__progname;
int peer;
int timeout = TIMEOUT; /* Current timeout value */
unsigned long timeout = TIMEOUT; /* Current timeout value */
unsigned long rexmtval = TIMEOUT; /* Basic timeout value */
unsigned long maxtimeout = TIMEOUT_LIMIT*TIMEOUT;
int timeout_quit = 0;
int rexmtval = TIMEOUT; /* Basic timeout value */
int maxtimeout = TIMEOUT_LIMIT*TIMEOUT;
sigjmp_buf timeoutbuf;
#define PKTSIZE MAX_SEGSIZE+4
@ -160,7 +160,7 @@ timer(int sig)
static void
usage(void)
{
syslog(LOG_ERR, "Usage: %s [-vcl][-a address][-m mappings][-u user][-t timeout][-r option...] [-s] [directory ...]",
syslog(LOG_ERR, "Usage: %s [-vcl][-a address][-m mappings][-u user][-t inetd_timeout][-T pkt_timeout][-r option...] [-s] [directory ...]",
__progname);
exit(EX_USAGE);
}
@ -208,7 +208,7 @@ set_socket_nonblock(int fd, int flag)
* Receive packet with synchronous timeout
*/
static int recv_time(int s, void *rbuf, int len, unsigned int flags,
unsigned long timeout_ms)
unsigned long timeout_us)
{
fd_set fdset;
struct timeval tmv;
@ -218,8 +218,8 @@ static int recv_time(int s, void *rbuf, int len, unsigned int flags,
FD_ZERO(&fdset);
FD_SET(s, &fdset);
tmv.tv_sec = timeout_ms/1000;
tmv.tv_usec = (timeout_ms%1000)*1000;
tmv.tv_sec = timeout_us / 1000000;
tmv.tv_usec = timeout_us % 1000000;
do {
rv = select(s+1, &fdset, NULL, NULL, &tmv);
@ -278,7 +278,7 @@ main(int argc, char **argv)
openlog(__progname, LOG_PID|LOG_NDELAY, LOG_DAEMON);
while ((c = getopt(argc, argv, "cspvVla:u:U:r:t:m:")) != -1)
while ((c = getopt(argc, argv, "cspvVla:u:U:r:t:T:m:")) != -1)
switch (c) {
case 'c':
cancreate = 1;
@ -298,6 +298,18 @@ main(int argc, char **argv)
case 't':
waittime = atoi(optarg);
break;
case 'T':
{
char *vp;
unsigned long tov = strtoul(optarg, &vp, 10);
if ( tov < 10000UL || tov > 255000000UL || *vp ) {
syslog(LOG_ERR, "Bad timeout value: %s", optarg);
exit(EX_USAGE);
}
rexmtval = timeout = tov;
maxtimeout = rexmtval*TIMEOUT_LIMIT;
}
break;
case 'u':
user = optarg;
break;
@ -888,7 +900,7 @@ set_timeout(char *val, char **ret)
if ( to < 1 || to > 255 || *vend )
return 0;
rexmtval = timeout = to;
rexmtval = timeout = to*1000000UL;
maxtimeout = rexmtval*TIMEOUT_LIMIT;
sprintf(*ret = b_ret, "%lu", to);
@ -908,7 +920,7 @@ set_utimeout(char *val, char **ret)
if ( to < 10000UL || to > 255000000UL || *vend )
return 0;
rexmtval = timeout = to/1000UL;
rexmtval = timeout = to;
maxtimeout = rexmtval*TIMEOUT_LIMIT;
sprintf(*ret = b_ret, "%lu", to);