forked from mirrors/tftp-hpa-google
Fix some timeout-related bugs; allow the user to set the default timeout.
This commit is contained in:
parent
ebc8f1f89d
commit
82eae1bcd6
3 changed files with 78 additions and 30 deletions
9
CHANGES
9
CHANGES
|
@ -1,5 +1,14 @@
|
||||||
$Id$
|
$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:
|
Changes in 0.30:
|
||||||
(Hopefully) better timeout algorithm.
|
(Hopefully) better timeout algorithm.
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
.\" SUCH DAMAGE.
|
.\" 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
|
.SH NAME
|
||||||
.B tftpd
|
.B tftpd
|
||||||
\- IPv4 Trivial File Transfer Protocol server
|
\- 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
|
will then respawn the server when another request comes in. The
|
||||||
default is 900 (15 minutes.)
|
default is 900 (15 minutes.)
|
||||||
.TP
|
.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
|
\fB\-m\fP \fIremap-file\fP
|
||||||
Specify the use of filename remapping. The
|
Specify the use of filename remapping. The
|
||||||
.I remap-file
|
.I remap-file
|
||||||
|
@ -149,25 +157,44 @@ exit gracefully.
|
||||||
This version of
|
This version of
|
||||||
.B tftpd
|
.B tftpd
|
||||||
supports RFC 2347 option negotation. Currently implemented options
|
supports RFC 2347 option negotation. Currently implemented options
|
||||||
are
|
are:
|
||||||
.B blksize
|
.TP
|
||||||
(RFC 2348),
|
\fBblksize\fP (RFC 2348)
|
||||||
.B blksize2
|
Set the transfer block size to anything less than or equal to the
|
||||||
(nonstandard),
|
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
|
.B tsize
|
||||||
(RFC 2349), and
|
option for binary (octet) mode transfers.
|
||||||
.B timeout
|
.TP
|
||||||
(RFC 2349). The nonstandard
|
\fBtimeout\fP (RFC 2349)
|
||||||
.B blksize2
|
Set the time before the server retransmits a packet, in seconds.
|
||||||
TFTP option is functionally identical to the
|
.TP
|
||||||
.B blksize
|
\fButimeout\fP (nonstandard)
|
||||||
option, with the additional constraint that the
|
Set the time before the server retransmits a packet, in microseconds.
|
||||||
blocksize is constrained to be a power of 2.
|
and
|
||||||
.PP
|
.PP
|
||||||
The
|
The
|
||||||
.B \-r
|
.B \-r
|
||||||
option can be used to disable specific options; this may be necessary
|
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"
|
.SH "FILENAME REMAPPING"
|
||||||
The
|
The
|
||||||
.B \-m
|
.B \-m
|
||||||
|
|
|
@ -79,16 +79,16 @@ int allow_severity = -1; /* Don't log at all */
|
||||||
struct request_info wrap_request;
|
struct request_info wrap_request;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TIMEOUT 1000 /* Default timeout (ms) */
|
#define TIMEOUT 1000000 /* Default timeout (us) */
|
||||||
#define TRIES 6 /* Number of attempts to send each packet */
|
#define TRIES 6 /* Number of attempts to send each packet */
|
||||||
#define TIMEOUT_LIMIT ((1 << TRIES)-1)
|
#define TIMEOUT_LIMIT ((1 << TRIES)-1)
|
||||||
|
|
||||||
char *__progname;
|
const char *__progname;
|
||||||
int peer;
|
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 timeout_quit = 0;
|
||||||
int rexmtval = TIMEOUT; /* Basic timeout value */
|
|
||||||
int maxtimeout = TIMEOUT_LIMIT*TIMEOUT;
|
|
||||||
sigjmp_buf timeoutbuf;
|
sigjmp_buf timeoutbuf;
|
||||||
|
|
||||||
#define PKTSIZE MAX_SEGSIZE+4
|
#define PKTSIZE MAX_SEGSIZE+4
|
||||||
|
@ -160,7 +160,7 @@ timer(int sig)
|
||||||
static void
|
static void
|
||||||
usage(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);
|
__progname);
|
||||||
exit(EX_USAGE);
|
exit(EX_USAGE);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ set_socket_nonblock(int fd, int flag)
|
||||||
* Receive packet with synchronous timeout
|
* Receive packet with synchronous timeout
|
||||||
*/
|
*/
|
||||||
static int recv_time(int s, void *rbuf, int len, unsigned int flags,
|
static int recv_time(int s, void *rbuf, int len, unsigned int flags,
|
||||||
unsigned long timeout_ms)
|
unsigned long timeout_us)
|
||||||
{
|
{
|
||||||
fd_set fdset;
|
fd_set fdset;
|
||||||
struct timeval tmv;
|
struct timeval tmv;
|
||||||
|
@ -218,8 +218,8 @@ static int recv_time(int s, void *rbuf, int len, unsigned int flags,
|
||||||
FD_ZERO(&fdset);
|
FD_ZERO(&fdset);
|
||||||
FD_SET(s, &fdset);
|
FD_SET(s, &fdset);
|
||||||
|
|
||||||
tmv.tv_sec = timeout_ms/1000;
|
tmv.tv_sec = timeout_us / 1000000;
|
||||||
tmv.tv_usec = (timeout_ms%1000)*1000;
|
tmv.tv_usec = timeout_us % 1000000;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
rv = select(s+1, &fdset, NULL, NULL, &tmv);
|
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);
|
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) {
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
cancreate = 1;
|
cancreate = 1;
|
||||||
|
@ -298,6 +298,18 @@ main(int argc, char **argv)
|
||||||
case 't':
|
case 't':
|
||||||
waittime = atoi(optarg);
|
waittime = atoi(optarg);
|
||||||
break;
|
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':
|
case 'u':
|
||||||
user = optarg;
|
user = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -888,7 +900,7 @@ set_timeout(char *val, char **ret)
|
||||||
if ( to < 1 || to > 255 || *vend )
|
if ( to < 1 || to > 255 || *vend )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rexmtval = timeout = to;
|
rexmtval = timeout = to*1000000UL;
|
||||||
maxtimeout = rexmtval*TIMEOUT_LIMIT;
|
maxtimeout = rexmtval*TIMEOUT_LIMIT;
|
||||||
|
|
||||||
sprintf(*ret = b_ret, "%lu", to);
|
sprintf(*ret = b_ret, "%lu", to);
|
||||||
|
@ -908,7 +920,7 @@ set_utimeout(char *val, char **ret)
|
||||||
if ( to < 10000UL || to > 255000000UL || *vend )
|
if ( to < 10000UL || to > 255000000UL || *vend )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rexmtval = timeout = to/1000UL;
|
rexmtval = timeout = to;
|
||||||
maxtimeout = rexmtval*TIMEOUT_LIMIT;
|
maxtimeout = rexmtval*TIMEOUT_LIMIT;
|
||||||
|
|
||||||
sprintf(*ret = b_ret, "%lu", to);
|
sprintf(*ret = b_ret, "%lu", to);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue