From 86113cfb3cde412682f01ec46cdf1a088cf43264 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 25 Oct 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-10-25 --- port/devip.c | 11 +++-- port/devproc.c | 6 +++ port/ipdat.h | 2 +- port/stil.c | 122 ++++++++++++++++++++++++++++++++----------------- 4 files changed, 96 insertions(+), 45 deletions(-) diff --git a/port/devip.c b/port/devip.c index 9aa9b7e19a2cd79a730c799b4d15ce3ba39323f8..eddb6518524cdfb7790167887b503b604bc614b4 100644 --- a/port/devip.c +++ b/port/devip.c @@ -365,7 +365,7 @@ ipwrite(Chan *c, char *a, long n, ulong offset) if(m != 2) error(Ebadarg); - switch(m = getfields(field[1], ctlarg, 5, '!')) { + switch(getfields(field[1], ctlarg, 5, '!')) { default: error(Ebadarg); case 2: @@ -676,10 +676,15 @@ iplisten(Chan *c, Ipconv *s, Ipconv *base) Ipconv *etab, *new; qlock(&s->listenq); - + if(waserror()) { + qunlock(&s->listenq); + nexterror(); + } +print("listener on %lux R 0x%lux\n", s, &s->listenr); for(;;) { sleep(&s->listenr, iphavecon, s); - + poperror(); +print("listen awoke\n"); new = base; for(etab = &base[conf.ip]; new < etab; new++) { if(new->newcon) { diff --git a/port/devproc.c b/port/devproc.c index 071c5c44ba34da37f7a5f9deeda498ef93b9b55b..923f8358e540d885e3051b3c2835a2e0532a3b48 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -313,6 +313,12 @@ procread(Chan *c, void *va, long n, ulong offset) memmove(a, (char*)offset, n); return n; } + if(offset>=KZERO && offset KZERO+conf.base1+conf.npage1*BY2PG) + n = KZERO+conf.base1+conf.npage1*BY2PG - offset; + memmove(a, (char*)offset, n); + return n; + } return 0; break; diff --git a/port/ipdat.h b/port/ipdat.h index a6b3919739535a1b4a0554b0e978d5d0725d83b9..9aeec925ee24f84e6b0aa74a5529ee4deb07997f 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -102,7 +102,6 @@ struct Ilcb /* Control block */ Block *unacked; Block *unackedtail; Block *outoforder; - Block *outofordertail; ulong sent; ulong recvd; ulong lastack; @@ -508,6 +507,7 @@ void tcp_timeout(void *); void tcp_acktimer(void *); Ipconv *ipclonecon(Chan *); void iplisten(Chan *, Ipconv *, Ipconv *); +void iloutoforder(Ipconv*, Ilhdr*, Block*); #define fmtaddr(xx) (xx>>24)&0xff,(xx>>16)&0xff,(xx>>8)&0xff,xx&0xff #define MIN(a, b) ((a) < (b) ? (a) : (b)) diff --git a/port/stil.c b/port/stil.c index 6691c7156d8a3a6bdafd4d8cf520d9b38238a875..5fe3d7f0ae7660a59053ae4369e2e879162ddebd 100644 --- a/port/stil.c +++ b/port/stil.c @@ -135,7 +135,6 @@ ilackq(Ilcb *ic, Block *bp) /* Enqueue a copy on the unacked queue in case this one gets lost */ np = copyb(bp, blen(bp)); - lock(ic); if(ic->unacked) { ic->unackedtail->next = np; ic->unackedtail = np; @@ -145,7 +144,6 @@ ilackq(Ilcb *ic, Block *bp) ic->unackedtail = np; } np->next = 0; - unlock(ic); } void @@ -154,23 +152,13 @@ ilackto(Ilcb *ic, ulong ackto) Ilhdr *h; Block *bp; - for(;;) { - lock(ic); - if(ic->unacked) { - h = (Ilhdr *)ic->unacked->rptr; - if(ackto < nhgetl(h->ilack)) { - unlock(ic); - break; - } - bp = ic->unacked; - ic->unacked = bp->next; - unlock(ic); - freeb(bp); - } - else { - unlock(ic); - break; - } + while(ic->unacked) { + h = (Ilhdr *)ic->unacked->rptr; + if(ackto < nhgetl(h->ilack)) + break; + bp = ic->unacked; + ic->unacked = bp->next; + freeb(bp); } } @@ -215,29 +203,28 @@ print("got packet from %d.%d.%d.%d %d %d\n", fmtaddr(dst), sp, dp); } - if(s->curlog > s->backlog) { -print("Backlog\n"); + if(s->curlog > s->backlog) goto reset; - } for(s = ipc; s < etab; s++) { - if(s->ilctl.state == Illistening && s->pdst == 0) { + if(s->ilctl.state == Illistening && s->pdst == 0 && s->dst == 0) { /* Do the listener stuff */ new = ipincoming(ipc); - if(new == 0) + if(new == 0) goto reset; - if(ih->type != Ilsync) + if(ih->iltype != Ilsync) goto reset; new->newcon = 1; new->ipinterface = s->ipinterface; - s->ipinterface->ref++; - s->curlog++; new->psrc = sp; new->pdst = dp; + new->ilctl.state = Ilsyncee; new->dst = nhgetl(ih->src); ilprocess(new, ih, bp); + s->ipinterface->ref++; + s->curlog++; wakeup(&s->listenr); return; } @@ -252,22 +239,32 @@ void ilprocess(Ipconv *s, Ilhdr *h, Block *bp) { Block *nb; + ulong id, ack; + /* Active transition machine - this tracks connection state */ switch(s->ilctl.state) { + case Ilsyncee: + switch(h->iltype) { + case Ilsync: + ilsendctl(s, 0, Ilsync, 0); + break; + case Ilack: + s->ilctl.state = Ilestablished; + break; + } + break; case Ilclosed: case Ilclosing: - case Illistening: - error(Ehungup); + goto hungup; } + /* Passive actions based on packet type */ switch(h->iltype) { - case Ilsync: - if(s->ilctl.state == Ilsync) - s->ilctl.state = Ilestablished; - freeb(bp); - break; case Ilack: - ilackto(&s->ilctl, nhgetl(h->ilack)); + ack = nhgetl(h->ilack); + if(s->ilctl.recvd+1 == ack) + s->ilctl.recvd = ack; + ilackto(&s->ilctl, ack); freeb(bp); break; case Ilquerey: @@ -277,19 +274,62 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp) case Ildataquery: case Ildata: ilackto(&s->ilctl, nhgetl(h->ilack)); - bp->rptr += IL_EHSIZE+IL_HDRSIZE; -/* Check and trim to length */ - PUTNEXT(s->readq, bp); + switch(s->ilctl.state) { + default: + iloutoforder(s, h, bp); + break; + case Ilestablished: + id = nhgetl(h->ilid); + if(id < s->ilctl.recvd) + freeb(bp); + else if(id > s->ilctl.recvd) + iloutoforder(s, h, bp); + else { + bp->rptr += IL_EHSIZE+IL_HDRSIZE; + PUTNEXT(s->readq, bp); + } + } break; case Ilreset: s->ilctl.state = Ilclosed; - nb = allocb(0); - nb->type = M_HANGUP; - PUTNEXT(s->readq, nb); + hungup: + if(s->readq) { + nb = allocb(0); + nb->type = M_HANGUP; + PUTNEXT(s->readq, nb); + } freeb(bp); } } +void +iloutoforder(Ipconv *s, Ilhdr *h, Block *bp) +{ + Block *f, **l; + Ilcb *ic; + ulong id; + uchar *lid; + + ic = &s->ilctl; + + if(ic->outoforder == 0) { + ic->outoforder = bp; + bp->next = 0; + return; + } + + id = nhgetl(h->id); + l = &ic->outoforder; + for(f = *l; f; f = f->next) { + lid = ((Ilhdr*)(bp->rptr))->ilid; + if(id < nhgetl(lid)) + break; + l = &f->next; + } + bp->next = *l; + *l = bp; +} + void ilsendctl(Ipconv *ipc, Ilhdr *inih, int type, int ack) {