summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/boot/pc/pxe.c15
-rw-r--r--sys/src/cmd/ip/tftpd.c3
-rw-r--r--sys/src/cmd/ip/tftpfs.c52
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;
}
}