summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2002-10-23 21:21:46 +0000
committerhpa <hpa>2002-10-23 21:21:46 +0000
commit82eae1bcd6f7b4edfe6364670a403e40ba7a33f9 (patch)
tree0a5c514c0b0409f61dd522c1025ef7c2789d99d5
parentebc8f1f89df9875909b63f84a19ee0a90c70773a (diff)
downloadtftp-hpa-82eae1bcd6f7b4edfe6364670a403e40ba7a33f9.tar.gz
Fix some timeout-related bugs; allow the user to set the default timeout.tftp-hpa-0.31
-rw-r--r--CHANGES9
-rw-r--r--tftpd/tftpd.8.in57
-rw-r--r--tftpd/tftpd.c42
3 files changed, 78 insertions, 30 deletions
diff --git a/CHANGES b/CHANGES
index 77689d7..b39b502 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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.
diff --git a/tftpd/tftpd.8.in b/tftpd/tftpd.8.in
index 388da0a..aab8bf6 100644
--- a/tftpd/tftpd.8.in
+++ b/tftpd/tftpd.8.in
@@ -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
diff --git a/tftpd/tftpd.c b/tftpd/tftpd.c
index 052a450..2865f35 100644
--- a/tftpd/tftpd.c
+++ b/tftpd/tftpd.c
@@ -79,17 +79,17 @@ 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;
-int peer;
-int timeout = TIMEOUT; /* Current timeout value */
-int timeout_quit = 0;
-int rexmtval = TIMEOUT; /* Basic timeout value */
-int maxtimeout = TIMEOUT_LIMIT*TIMEOUT;
-sigjmp_buf timeoutbuf;
+const char *__progname;
+int peer;
+unsigned long timeout = TIMEOUT; /* Current timeout value */
+unsigned long rexmtval = TIMEOUT; /* Basic timeout value */
+unsigned long maxtimeout = TIMEOUT_LIMIT*TIMEOUT;
+int timeout_quit = 0;
+sigjmp_buf timeoutbuf;
#define PKTSIZE MAX_SEGSIZE+4
char buf[PKTSIZE];
@@ -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);