mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 09:10:28 +00:00
libsa: re-send ACK for older data packets in tftp
In current tftp code we drop out-of-order packets; however, we should play nice and re-send ACK for older data packets we are receiving. This will hopefully stop server repeating those packets we already have received. Note we do not answer duplicates from "previous" session (that is, session with different port number), those will eventually time out. Differential Revision: https://reviews.freebsd.org/D17087
This commit is contained in:
parent
8796e291f8
commit
bb489cd7ad
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=339651
|
@ -163,7 +163,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, u_short block)
|
||||
{
|
||||
struct {
|
||||
u_char header[HEADER_SIZE];
|
||||
|
@ -173,7 +173,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);
|
||||
|
@ -205,9 +205,17 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft,
|
|||
case DATA: {
|
||||
int got;
|
||||
|
||||
if (htons(t->th_block) < (u_short) 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);
|
||||
|
@ -219,7 +227,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;
|
||||
|
@ -364,7 +372,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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue