[botanist][tftp] Fix over-send causing timeout during paving

First, for reference, window size is always 256.

For a given window, botanist is currently sending blocks in the range of
the window base (called "seq" in tftp.go), let's say 100 here, so from
[101..357] inclusive (see the changed line in this CL).

This is one more than seems to be required by the protocol. Typically
this is fine, the last block (index 357 here) would typically either be
consumed anyway, or if it arrives out of order, it'll just be dropped.

In one very specific situation though, it causes problems. If the target
is receiving blocks in order and advancing through the window normally,
it will eventually get to a point where it receives block 356 (i.e. the
second last one that botanist will send in this attempt).

At that point, the target has received a full window of 256 (that is,
blocks 101..356 have been received), so it replies with an Ack saying
it's OK to move to the next window. Botanist has to wait on this Ack to
move to the next window, and otherwise continues repeating its send from
[101..357]. If this Ack for block 356 is dropped (this is all UDP so
eventually this will happen), AND the "bonus" 357 block is subsequently
received on the target, then the target will have moved on to the next
window block.

The target is now sitting waiting for block 358, thinking that both
sides have moved on to the next window. Botanist is still sending
[101..357] waiting for an Ack, but the target will never resend an Ack
for an old window. On a timeout, the target Acks 357 to attempt to
resync, but that will be ignored by botanist, because it does not fall
within the range check in window advancement (an indeed it is in the
next window).

So, two fixes are possible: botanist could accept that resync ack that's
one-past the end of the window (but I think that's wrong). Instead, it
should just not be sending block 357, and the loop should be [0..256),
that is, exclusive at the end of the range.

I've tried testing this by artificially making the target drop Acks and
paving now recovers and continues as expected even when that happens,
after this botanist change.

ZX-4146 #comment [botanist][tftp] Fix over-send causing timeout during paving

Change-Id: I85faccf45a1a7b173db5d357ba427a22c4b9205c
diff --git a/tftp/tftp.go b/tftp/tftp.go
index 6d5399f..980c5d8 100644
--- a/tftp/tftp.go
+++ b/tftp/tftp.go
@@ -171,7 +171,7 @@
 	for {
 	Attempt:
 		for attempt := 0; attempt < s.retry; attempt++ {
-			for i := uint16(0); uint16(i) <= s.opts.windowSize; i++ {
+			for i := uint16(0); uint16(i) < s.opts.windowSize; i++ {
 				block := uint16(seq + uint64(i+1))
 				// Fill the first byte of the command with an arbitrary value to
 				// work around the issue where certain ethernet adapters would