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>