diff options
| -rw-r--r-- | sys/src/boot/pc/pxe.c | 15 | ||||
| -rw-r--r-- | sys/src/cmd/ip/tftpd.c | 3 | ||||
| -rw-r--r-- | sys/src/cmd/ip/tftpfs.c | 52 |
3 files changed, 38 insertions, 32 deletions
diff --git a/sys/src/boot/pc/pxe.c b/sys/src/boot/pc/pxe.c index 97ee259cb..9f6d74b29 100644 --- a/sys/src/boot/pc/pxe.c +++ b/sys/src/boot/pc/pxe.c @@ -249,16 +249,21 @@ read(void *f, void *data, int len) switch(nhgets(t->pkt)){ case Tftp_DATA: seq = nhgets(t->pkt+2); - if(seq <= t->seq){ - putc('@'); + if(seq > t->seq){ + putc('?'); continue; } hnputs(t->pkt, Tftp_ACK); while(udpwrite(t->dip, t->gip, t->sport, t->dport, 4, t->pkt)) putc('!'); - t->seq = seq; + if(seq < t->seq){ + putc('@'); + continue; + } + t->seq = seq+1; + n -= 4; t->rp = t->pkt + 4; - t->ep = t->pkt + n; + t->ep = t->rp + n; t->eof = n < Segsize; break; case Tftp_ERROR: @@ -300,7 +305,7 @@ tftpopen(Tftp *t, char *path, IP4 sip, IP4 dip, IP4 gip) t->sport = xport++; t->dport = 0; t->rp = t->ep = 0; - t->seq = -1; + t->seq = 1; t->eof = 0; t->nul = 0; if(r = udpopen(t->sip)) diff --git a/sys/src/cmd/ip/tftpd.c b/sys/src/cmd/ip/tftpd.c index 9b543a29e..355e98340 100644 --- a/sys/src/cmd/ip/tftpd.c +++ b/sys/src/cmd/ip/tftpd.c @@ -340,9 +340,6 @@ options(int fd, char *buf, int bufsz, char *file, ushort oper, char *p, int dlen if (nopts == 0) return 0; /* no options actually seen */ - if (bp + 3 >= ep) - return -1; - if (write(fd, buf, bp - buf) < bp - buf) { syslog(dbg, flog, "tftpd network write error on oack to %s: %r", raddr); diff --git a/sys/src/cmd/ip/tftpfs.c b/sys/src/cmd/ip/tftpfs.c index 2e48d6cb4..55d8f496d 100644 --- a/sys/src/cmd/ip/tftpfs.c +++ b/sys/src/cmd/ip/tftpfs.c @@ -147,7 +147,7 @@ filereq(uchar *buf, char *path) static void download(void *aux) { - int fd, cfd, last, block, n, ndata; + int fd, cfd, last, block, seq, n, ndata; char *err, adir[40]; uchar *data; Channel *c; @@ -197,6 +197,7 @@ download(void *aux) notify(catch); + seq = 1; last = 0; while(!last){ alarm(5000); @@ -218,34 +219,37 @@ download(void *aux) if(n < 4) continue; block = nhgets(msg.buf+2); - if((n -= 4) > 0){ - data = erealloc9p(data, ndata + n); - memcpy(data + ndata, msg.buf+4, n); - ndata += n; - -rloop: /* hanlde read request while downloading */ - if((r != nil) && (r->ifcall.type == Tread) && (r->ifcall.offset < ndata)){ - readbuf(r, data, ndata); - respond(r, nil); - r = nil; - } - if((r == nil) && (nbrecv(c, &r) == 1)){ - if(r == nil){ - chanfree(c); - c = nil; - goto out; - } - goto rloop; - } - } - if(n < Segsize) - last = 1; + if(block > seq) + continue; hnputs(msg.buf, Tftp_ACK); - hnputs(msg.buf+2, block); if(write(fd, &msg, sizeof(Udphdr) + 4) < 0){ err = "send acknowledge: %r"; goto out; } + if(block < seq) + continue; + seq = block+1; + n -= 4; + if(n < Segsize) + last = 1; + data = erealloc9p(data, ndata + n); + memcpy(data + ndata, msg.buf+4, n); + ndata += n; + + rloop: /* hanlde read request while downloading */ + if((r != nil) && (r->ifcall.type == Tread) && (r->ifcall.offset < ndata)){ + readbuf(r, data, ndata); + respond(r, nil); + r = nil; + } + if((r == nil) && (nbrecv(c, &r) == 1)){ + if(r == nil){ + chanfree(c); + c = nil; + goto out; + } + goto rloop; + } break; } } |
