Browse Source

TFTP: allow for adjustable retransmission timout

So far, TFTP negotiated a fixed retransmission timeout of 5 seconds.
In some cases (busy networks, slow TFTP servers) this caused very
slow transfers. A new environment variable "tftptimeout" allows to
set this timeout. Lowering this value may make downloads succeed
faster in networks with high packet loss rates or with unreliable
TFTP servers.

Signed-off-by: Wolfgang Denk <wd@denx.de>
Cc: Ben Warren <biggerbadderben@gmail.com>
Signed-off-by: Ben Warren <biggerbadderben@gmail.com>
Wolfgang Denk 14 years ago
parent
commit
c96f86eefc
2 changed files with 34 additions and 8 deletions
  1. 16 3
      README
  2. 18 5
      net/tftp.c

+ 16 - 3
README

@@ -3005,7 +3005,9 @@ environment. As long as you don't save the environment you are
 working with an in-memory copy. In case the Flash area containing the
 environment is erased by accident, a default environment is provided.
 
-Some configuration options can be set using Environment Variables:
+Some configuration options can be set using Environment Variables.
+
+List of environment variables (most likely not complete):
 
   baudrate	- see CONFIG_BAUDRATE
 
@@ -3117,7 +3119,7 @@ Some configuration options can be set using Environment Variables:
 		  available network interfaces.
 		  It just stays at the currently selected interface.
 
-   netretry	- When set to "no" each network operation will
+  netretry	- When set to "no" each network operation will
 		  either succeed or fail without retrying.
 		  When set to "once" the network operation will
 		  fail when all the available network interfaces
@@ -3133,7 +3135,18 @@ Some configuration options can be set using Environment Variables:
   tftpdstport	- If this is set, the value is used for TFTP's UDP
 		  destination port instead of the Well Know Port 69.
 
-   vlan		- When set to a value < 4095 the traffic over
+  tftpblocksize - Block size to use for TFTP transfers; if not set,
+		  we use the TFTP server's default block size
+
+  tftptimeout	- Retransmission timeout for TFTP packets (in milli-
+		  seconds, minimum value is 1000 = 1 second). Defines
+		  when a packet is considered to be lost so it has to
+		  be retransmitted. The default is 5000 = 5 seconds.
+		  Lowering this value may make downloads succeed
+		  faster in networks with high packet loss rates or
+		  with unreliable TFTP servers.
+
+  vlan		- When set to a value < 4095 the traffic over
 		  Ethernet is encapsulated/received over 802.1q
 		  VLAN tagged frames.
 

+ 18 - 5
net/tftp.c

@@ -211,7 +211,7 @@ TftpSend (void)
 		pkt += 5 /*strlen("octet")*/ + 1;
 		strcpy ((char *)pkt, "timeout");
 		pkt += 7 /*strlen("timeout")*/ + 1;
-		sprintf((char *)pkt, "%lu", TIMEOUT / 1000);
+		sprintf((char *)pkt, "%lu", TftpTimeoutMSecs / 1000);
 		debug("send option \"timeout %s\"\n", (char *)pkt);
 		pkt += strlen((char *)pkt) + 1;
 #ifdef CONFIG_TFTP_TSIZE
@@ -413,7 +413,6 @@ TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
 		}
 
 		TftpLastBlock = TftpBlock;
-		TftpTimeoutMSecs = TIMEOUT;
 		TftpTimeoutCountMax = TIMEOUT_COUNT;
 		NetSetTimeout (TftpTimeoutMSecs, TftpTimeout);
 
@@ -528,10 +527,25 @@ TftpStart (void)
 {
 	char *ep;             /* Environment pointer */
 
-	/* Allow the user to choose tftpblocksize */
+	/*
+	 * Allow the user to choose TFTP blocksize and timeout.
+	 * TFTP protocol has a minimal timeout of 1 second.
+	 */
 	if ((ep = getenv("tftpblocksize")) != NULL)
 		TftpBlkSizeOption = simple_strtol(ep, NULL, 10);
-	debug("tftp block size is %i\n", TftpBlkSizeOption);
+
+	if ((ep = getenv("tftptimeout")) != NULL)
+		TftpTimeoutMSecs = simple_strtol(ep, NULL, 10);
+
+	if (TftpTimeoutMSecs < 1000) {
+		printf("TFTP timeout (%ld ms) too low, "
+			"set minimum = 1000 ms\n",
+			TftpTimeoutMSecs);
+		TftpTimeoutMSecs = 1000;
+	}
+
+	debug("TFTP blocksize = %i, timeout = %ld ms\n",
+		TftpBlkSizeOption, TftpTimeoutMSecs);
 
 	TftpServerIP = NetServerIP;
 	if (BootFile[0] == '\0') {
@@ -588,7 +602,6 @@ TftpStart (void)
 
 	puts ("Loading: *\b");
 
-	TftpTimeoutMSecs = TftpRRQTimeoutMSecs;
 	TftpTimeoutCountMax = TftpRRQTimeoutCountMax;
 
 	NetSetTimeout (TftpTimeoutMSecs, TftpTimeout);