diff options
author | Toomas Soome <tsoome@me.com> | 2018-09-04 14:29:36 +0300 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2018-09-21 20:21:52 +0000 |
commit | 1bb0ebc19aa99ecdb4a9bff9d5972a8320407a25 (patch) | |
tree | 9a54f1a55bafc2e69d1d8584da5a125c146c238e | |
parent | 2017dcb08b21dd2f977954ddb50394ba3010137c (diff) | |
download | illumos-joyent-1bb0ebc19aa99ecdb4a9bff9d5972a8320407a25.tar.gz |
9795 libstand: re-send ACK for older data packets
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Andy Fiddaman <omnios@citrus-it.co.uk>
Reviewed by: Igor Kozhukhov <igor@dilos.org>
Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r-- | usr/src/boot/lib/libstand/tftp.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/usr/src/boot/lib/libstand/tftp.c b/usr/src/boot/lib/libstand/tftp.c index 46ce5f16b2..c6d519d2ec 100644 --- a/usr/src/boot/lib/libstand/tftp.c +++ b/usr/src/boot/lib/libstand/tftp.c @@ -162,7 +162,7 @@ tftp_senderr(struct tftp_handle *h, u_short errcode, const char *msg) } static void -tftp_sendack(struct tftp_handle *h) +tftp_sendack(struct tftp_handle *h, ushort_t block) { struct { u_char header[HEADER_SIZE]; @@ -172,7 +172,7 @@ tftp_sendack(struct tftp_handle *h) wbuf.t.th_opcode = htons((u_short) ACK); wtail = (char *) &wbuf.t.th_block; - wbuf.t.th_block = htons((u_short) h->currblock); + wbuf.t.th_block = htons(block); wtail += 2; sendudp(h->iodesc, &wbuf.t, wtail - (char *) &wbuf.t); @@ -204,9 +204,17 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, case DATA: { int got; + if (htons(t->th_block) < (ushort_t) d->xid) { + /* + * Apparently our ACK was missed, re-send. + */ + tftp_sendack(h, htons(t->th_block)); + free(ptr); + return (-1); + } if (htons(t->th_block) != (u_short) d->xid) { /* - * Expected block? + * Packet from the future, drop this. */ free(ptr); return (-1); @@ -218,7 +226,7 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, struct udphdr *uh; uh = (struct udphdr *) t - 1; d->destport = uh->uh_sport; - } /* else check uh_sport has not changed??? */ + } got = len - (t->th_data - (char *)t); *pkt = ptr; *payload = t; @@ -363,7 +371,7 @@ tftp_makereq(struct tftp_handle *h) h->islastblock = 0; if (res < h->tftp_blksize) { h->islastblock = 1; /* very short file */ - tftp_sendack(h); + tftp_sendack(h, h->currblock); } return (0); } |