Date: Thu, 26 Aug 1999 17:07:34 -0600 (MDT) From: David G Andersen <danderse@cs.utah.edu> To: FreeBSD-gnats-submit@freebsd.org Subject: bin/13401: tftp client bad behavior with large packet delays or extra packets Message-ID: <199908262307.RAA17439@torrey.cs.utah.edu>
next in thread | raw e-mail | index | archive | help
>Number: 13401
>Category: bin
>Synopsis: tftp will ack duplicate packets with large delays
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Aug 26 16:10:01 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator: David G Andersen
>Release: FreeBSD 3.2-STABLE i386
>Organization:
University of Utah
>Environment:
TFTP'ing between two machines with a potentially greater than 5 second
latency. OR, a hostile environment in which an intruder can spoof a
tftp packet.
>Description:
When /usr/bin/tftp waits more than 5 seconds for a packet, it re-ACKs the
previous packet. If that previous packet was only delayed, then two
copies of the packet will arrive at the client. The client will then send
an ACK for *both* packets, which causes the server to send two of the next
packet, and so on - doubling the data sent. As this continues, eventually
you can get many many copies of each packet flowing.
>How-To-Repeat:
tftp with > 5 second latency. We encountered it testing some router code
which was misbehaving, but I have a packet latency inducer using divert
sockets with which I can reproduce this at will. Contact me for the code.
>Fix:
Instead of ACK'ing clearly duplicate packets, only re-ACK if we've
actually flushed packets out of the stream.
Index: tftp.c
===================================================================
RCS file: /n/marker/usr/lsrc/FreeBSD/CVS/src/usr.bin/tftp/tftp.c,v
retrieving revision 1.4
diff -u -r1.4 tftp.c
--- tftp.c 1998/10/30 16:17:50 1.4
+++ tftp.c 1999/08/26 20:40:07
@@ -239,6 +239,7 @@
warn("sendto");
goto abort;
}
+no_send_ack:
write_behind(file, convert);
for ( ; ; ) {
alarm(rexmtval);
@@ -277,7 +278,14 @@
printf("discarded %d packets\n", j);
}
if (dp->th_block == (block-1)) {
- goto send_ack; /* resend ack */
+ if (j) {
+ goto send_ack; /* resend ack */
+ } else {
+ /* We didn't discard any
+ * packets; we got a duplicate
+ */
+ goto no_send_ack;
+ }
}
}
}
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199908262307.RAA17439>
