Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site ucbvax.ARPA
Path: utzoo!watmath!clyde!cbosgd!ucbvax!nprdc.arpa!stanonik
From: stanonik@NPRDC.ARPA (Ron Stanonik)
Newsgroups: fa.tcp-ip
Subject: 4.2BSD tftp doesn't retransmit acks
Message-ID: <8510011831.AA02522@nprdc.arpa>
Date: Tue, 1-Oct-85 14:31:00 EDT
Article-I.D.: nprdc.8510011831.AA02522
Posted: Tue Oct  1 14:31:00 1985
Date-Received: Thu, 3-Oct-85 04:20:42 EDT
Sender: daemon@ucbvax.ARPA
Reply-To: tcp-ip@ucb-vax.arpa
Organization: The ARPA Internet
Lines: 122

Description:
	A RRQ on receiving a duplicate data packet doesn't retransmit
	the last ack.
Repeat-By:
	This would happen intermittently between our vax and a pc,
	but the problem can be reproduced by hacking tftpd.c to
	not advance its block count and then tftp'ing to yourself.
Fix:
	Move the retransmit code into the inner loop in recvfile().
	This actually causes tftp to retransmit on receiving anything
	but the next expected packet or an error packet.  I believe
	that's in keeping with RFC783, but at any rate it makes tftp
	"generous in what it accepts".
	
	We haven't really observed the corresponding WRQ problem with
	duplicate acks, but the logic is the same, so we fixed(?) it too.

	Oh, the diff will probably only make sense if you've already
	installed the fixes from mogul@gregorio and satz@joyce.

Ron Stanonik
stanonik@nprdc.arpa

RCS file: RCS/tftp.c,v
retrieving revision 1.3
diff -c -r1.3 tftp.c
*** /tmp/,RCSt1001512	Tue Oct  1 09:43:20 1985
--- tftp.c	Tue Oct  1 09:43:00 1985
***************
*** 73,85
  		}
  		timeout = 0;
  		(void) setjmp(timeoutbuf);
- 		if (trace)
- 			tpacket("sent", stp, size + 4);
- 		n = sendto(f, sbuf, size + 4, 0, (caddr_t)&sin, sizeof (sin));
- 		if (n != size + 4) {
- 			perror("tftp: sendto");
- 			goto abort;
- 		}
  		do {
  			alarm(rexmtval);
  			do {

--- 73,78 -----
  		}
  		timeout = 0;
  		(void) setjmp(timeoutbuf);
  		do {
  			if (trace)
  				tpacket("sent", stp, size + 4);
***************
*** 81,86
  			goto abort;
  		}
  		do {
  			alarm(rexmtval);
  			do {
  				fromlen = sizeof (from);

--- 74,86 -----
  		timeout = 0;
  		(void) setjmp(timeoutbuf);
  		do {
+ 			if (trace)
+ 				tpacket("sent", stp, size + 4);
+ 			n = sendto(f, sbuf, size + 4, 0, (caddr_t)&sin, sizeof (sin));
+ 			if (n != size + 4) {
+ 				perror("tftp: sendto");
+ 				goto abort;
+ 			}
  			alarm(rexmtval);
  			do {
  				fromlen = sizeof (from);
***************
*** 144,157
  		}
  		timeout = 0;
  		(void) setjmp(timeoutbuf);
- 		if (trace)
- 			tpacket("sent", stp, size);
- 		if (sendto(f, sbuf, size, 0, (caddr_t)&sin,
- 		    sizeof (sin)) != size) {
- 			alarm(0);
- 			perror("tftp: sendto");
- 			goto abort;
- 		}
  		do {
  			alarm(rexmtval);
  			do

--- 144,149 -----
  		}
  		timeout = 0;
  		(void) setjmp(timeoutbuf);
  		do {
  			if (trace)
  				tpacket("sent", stp, size);
***************
*** 153,158
  			goto abort;
  		}
  		do {
  			alarm(rexmtval);
  			do
  				n = recvfrom(f, rbuf, sizeof (rbuf), 0,

--- 145,158 -----
  		timeout = 0;
  		(void) setjmp(timeoutbuf);
  		do {
+ 			if (trace)
+ 				tpacket("sent", stp, size);
+ 			if (sendto(f, sbuf, size, 0, (caddr_t)&sin,
+ 			    sizeof (sin)) != size) {
+ 				alarm(0);
+ 				perror("tftp: sendto");
+ 				goto abort;
+ 			}
  			alarm(rexmtval);
  			do
  				n = recvfrom(f, rbuf, sizeof (rbuf), 0,