From 707615334890cdbe8b87292d8b2c308adbb95371 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 21 Nov 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-11-21 --- port/devenv.c | 7 +- port/devip.c | 3 +- port/devlance.c | 12 ++++ port/devnonet.c | 169 ++++++++++++++++++++++++++--------------------- port/ipdat.h | 1 - port/portfns.h | 1 + port/stil.c | 20 ++---- port/stnoether.c | 4 +- port/stream.c | 5 +- 9 files changed, 125 insertions(+), 97 deletions(-) diff --git a/port/devenv.c b/port/devenv.c index 51969f5b3805de7746beb8b21bc39bd5100fcf03..4def028b5f32f648932956193aedc3517d4a111e 100644 --- a/port/devenv.c +++ b/port/devenv.c @@ -268,7 +268,8 @@ envwrite(Chan *c, void *a, long n, ulong offset) if(n <= 0) return 0; - if(offset + n > MAXENV) + olen = (offset + n + ALIGN - 1) & ~(ALIGN - 1); + if(olen > MAXENV) error(Etoobig); eg = u->p->egrp; qlock(&eg->ev); @@ -338,8 +339,8 @@ evalloc(ulong n) char *b, *lim; ulong size; - n = (n - 1) / ALIGN; - size = (n + 1) * ALIGN; + size = (n + ALIGN - 1) & ~(ALIGN - 1); + n = (size - 1) / ALIGN; p = &envalloc.free[n < EVFREE ? n : EVFREE]; for(ev = *p; ev; ev = *p){ if(ev->len == size){ diff --git a/port/devip.c b/port/devip.c index 4a2f4674dc64a6e92d68bc08ffa39c821f67645d..103bc68b9d8ddfe0e9e10837a47aa50704cd4a48 100644 --- a/port/devip.c +++ b/port/devip.c @@ -616,6 +616,7 @@ iplisten(Chan *c) for(;;) { sleep(&s->listenr, iphavecon, s); + print("listen wakes\n"); poperror(); new = base; for(etab = &base[conf.ip]; new < etab; new++) { @@ -626,6 +627,7 @@ iplisten(Chan *c) return new - base; } } + print("no newcon\n"); } } @@ -713,7 +715,6 @@ ptcl_csum(Block *bp, int offset, int len) break; blen = BLEN(bp); addr = bp->rptr; - } losum += hisum>>8; diff --git a/port/devlance.c b/port/devlance.c index d312e75bda4e80d66d7ca1e4e81526901f4cbadc..63af56b5bca04025e27fb10abf78a5fcf9d6e413 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -112,6 +112,7 @@ typedef struct { Ethertype e[Ntypes]; int debug; int kstarted; + uchar bcast[6]; Queue self; /* packets turned around at the interface */ @@ -307,6 +308,15 @@ lanceoput(Queue *q, Block *bp ) } return; } + if(memcmp(l.bcast, p->d, sizeof(l.bcast)) == 0){ + len = blen(bp); + nbp = copyb(bp, len = len >= ETHERMINTU ? len : ETHERMINTU); + if(nbp){ + nbp->wptr = nbp->rptr+len; + putq(&l.self, nbp); + wakeup(&l.rr); + } + } /* * only one transmitter at a time @@ -387,6 +397,8 @@ lancereset(void) l.net.info[0].fill = lancestatsfill; l.net.info[1].name = "type"; l.net.info[1].fill = lancetypefill; + + memset(l.bcast, 0xff, sizeof l.bcast); } /* diff --git a/port/devnonet.c b/port/devnonet.c index 31ecd36abdce62f3ee03742ac10d785147825f7f..70ba3222137dd0168cb1f0b53fae5e54d12ab37d 100644 --- a/port/devnonet.c +++ b/port/devnonet.c @@ -312,10 +312,7 @@ nonetclose(Chan *c) { Noifc *ifc; - /* - * real closing happens in noclose - */ - if(c->qid.path != CHDIR) + if(c->stream) streamclose(c); /* @@ -446,7 +443,12 @@ noopen(Queue *q, Stream *s) RD(q)->ptr = WR(q)->ptr = (void *)cp; } - +/* + * wait until a hangup is received. + * then send a hangup message (until one is received). + * + * State Transitions: * -> Cclosed + */ static int ishungup(void *a) { @@ -461,12 +463,20 @@ ishungup(void *a) } return 0; } -/* - * wait until a hangup is received. - * then send a hangup message (until one is received). - * - * State Transitions: * -> Cclosed - */ +static int +isempty(void *a) +{ + Noconv *cp; + + cp = (Noconv *)a; + switch(cp->state){ + case Cconnecting: + case Cconnected: + return cp->first == cp->next; + default: + return 1; + } +} static void noclose(Queue *q) { @@ -476,39 +486,43 @@ noclose(Queue *q) cp = (Noconv *)q->ptr; - if(waserror()){ - cp->rcvcircuit = -1; - cp->state = Cclosed; - nexterror(); - } - - /* - * send hangup messages to the other side - * until it hangs up or we get tired. - */ - switch(cp->state){ - case Cconnected: + if(!waserror()){ /* - * send close till we get one back + * wait till we have nothing to transmit */ - nosendctl(cp, NO_HANGUP, 1); - for(i=0; i<10 && !ishungup(cp); i++){ - nosendctl(cp, NO_HANGUP, 0); - tsleep(&cp->r, ishungup, cp, MSrexmit); - } - break; - case Chungup: + while(!isempty(cp)) + tsleep(&cp->r, isempty, cp, MSrexmit); + /* - * ack any close + * send hangup messages to the other side + * until it hangs up or we get tired. */ - nosendctl(cp, NO_HANGUP, 1); - break; + switch(cp->state){ + case Cconnecting: + case Cconnected: + /* + * send close till we get one back + */ + nosendctl(cp, NO_HANGUP, 1); + for(i=0; i<10 && !ishungup(cp); i++){ + nosendctl(cp, NO_HANGUP, 0); + tsleep(&cp->r, ishungup, cp, MSrexmit); + } + break; + case Chungup: + /* + * ack any close + */ + nosendctl(cp, NO_HANGUP, 1); + break; + } + poperror(); } - qlock(cp); /* * we give up, ack any unacked messages */ + qlock(cp); for(i = cp->first; i != cp->next; i = MSUCC(i)) norack(cp, cp->out[i].mid); cp->rcvcircuit = -1; @@ -518,8 +532,6 @@ noclose(Queue *q) cp->media = 0; } qunlock(cp); - - poperror(); } /* @@ -791,6 +803,7 @@ nolisten(Chan *c, Noifc *ifc) char buf[2*NAMELEN+4]; char *user; long n; + Block *bp; call.msg = 0; @@ -841,31 +854,38 @@ nolisten(Chan *c, Noifc *ifc) * stuff the connect message into it */ f = ((Nohdr *)(call.msg->rptr))->flag; - DPRINT("call from %d %s\n", call.circuit, call.raddr); nostartconv(cp, call.circuit, call.raddr, Cconnecting); - DPRINT("rcving %d byte message\n", call.msg->wptr - call.msg->rptr); - nonetrcvmsg(cp, call.msg); + bp = call.msg; call.msg = 0; - - /* - * if a service and remote user were specified, - * grab them - */ - if(f & NO_SERVICE){ - DPRINT("reading service\n"); - c->qid.path = STREAMQID(cp - ifc->conv, Sdataqid); - n = streamread(c, buf, sizeof(buf)); - c->qid.path = STREAMQID(cp - ifc->conv, Sctlqid); - if(n <= 0) - error(Ebadctl); - buf[n] = 0; - user = strchr(buf, ' '); - if(user){ - *user++ = 0; - strncpy(cp->ruser, user, NAMELEN); - } else - strcpy(cp->ruser, "none"); - strncpy(cp->addr, buf, NAMELEN); + switch(nonetrcvmsg(cp, bp)){ + case -1: + print("bad call message"); + streamclose(c); + continue; + case 0: + if(f & NO_SERVICE){ + streamclose(c); + print("bad call message"); + continue; + } + break; + default: + if(f & NO_SERVICE){ + c->qid.path = STREAMQID(cp - ifc->conv, Sdataqid); + n = streamread(c, buf, sizeof(buf)); + c->qid.path = STREAMQID(cp - ifc->conv, Sctlqid); + if(n <= 0) + error(Ebadctl); + buf[n] = 0; + user = strchr(buf, ' '); + if(user){ + *user++ = 0; + strncpy(cp->ruser, user, NAMELEN); + } else + strcpy(cp->ruser, "none"); + strncpy(cp->addr, buf, NAMELEN); + } + break; } break; } @@ -1132,7 +1152,7 @@ nosendctl(Noconv *cp, int flag, int new) * * State Transition: (no NO_NEWCALL in msg) Cconnecting -> Cconnected */ -void +int nonetrcvmsg(Noconv *cp, Block *bp) { Block *nbp; @@ -1161,7 +1181,7 @@ nonetrcvmsg(Noconv *cp, Block *bp) DPRINT("reset received\n"); noreset(cp); freeb(bp); - return; + return -1; } /* @@ -1179,22 +1199,15 @@ nonetrcvmsg(Noconv *cp, Block *bp) case Creset: DPRINT("nonetrcvmsg %d %d\n", cp->rcvcircuit, cp - cp->ifc->conv); freeb(bp); - return; + return -1; case Chungup: case Cconnected: DPRINT("Nonet call on connected/hanging-up circ %d conv %d\n", cp->rcvcircuit, cp - cp->ifc->conv); freeb(bp); noreset(cp); - return; + return -1; case Cconnecting: - if(h->mid != mp->mid){ - DPRINT("Nonet call on connecting circ %d conv %d\n", - cp->rcvcircuit, cp - cp->ifc->conv); - freeb(bp); - noreset(cp); - return; - } break; } } @@ -1216,7 +1229,7 @@ nonetrcvmsg(Noconv *cp, Block *bp) cp->bad++; } freeb(bp); - return; + return -1; } if(r>=0){ @@ -1238,7 +1251,7 @@ nonetrcvmsg(Noconv *cp, Block *bp) DPRINT("mp->mid==%d mp->rem==%d r==%d\n", mp->mid, mp->rem, r); cp->bad++; freeb(bp); - return; + return -1; } } @@ -1268,6 +1281,7 @@ nonetrcvmsg(Noconv *cp, Block *bp) noqack(cp, h->mid); mp->last->flags |= S_DELIM; PUTNEXT(q, mp->first); + r = mp->len; mp->first = mp->last = 0; mp->len = 0; cp->rcvd++; @@ -1289,10 +1303,13 @@ nonetrcvmsg(Noconv *cp, Block *bp) if(f & NO_HANGUP){ DPRINT("hangup with message\n"); nohangup(cp); + return -1; } - } else + return r; + } else { mp->last->flags &= ~S_DELIM; - + return 0; + } } @@ -1453,7 +1470,7 @@ nokproc(void *arg) for(cp = ifc->conv; cp < ep; cp++){ if(cp->state<=Copen || !canqlock(cp)) continue; - if(cp->state <= Copen){ + if(cp->state != Cconnected && cp->state != Cconnecting){ qunlock(cp); continue; } diff --git a/port/ipdat.h b/port/ipdat.h index 2b8f1c99febf4194893b962bbc9c8869d71046a0..690207cf76ac329546a574be3eaceef34be08c4e 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -436,7 +436,6 @@ Fragq *ipfragallo(void); void ipfragfree(Fragq*); void iproute(uchar*, uchar*); void initfrag(int); -Block *copyb(Block*, int); int ntohtcp(Tcp*, Block**); void reset(Ipaddr, Ipaddr, char, ushort, Tcp*); void proc_syn(Ipconv*, char, Tcp*); diff --git a/port/portfns.h b/port/portfns.h index 6a7c797b7116abd64ee8e5de825880270ac22306..25c9a41d1734f7615c4268fdadc5b74f2b56c8f4 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -29,6 +29,7 @@ void closepgrp(Pgrp*); long clrfpintr(void); void confinit(void); int consactive(void); +Block *copyb(Block*, int); Env* copyenv(Env*, int); void copypage(Page*, Page*); int decref(Ref*); diff --git a/port/stil.c b/port/stil.c index e63ed8de07521ab2a4852b840639241366a0f199..f19ea90bc00fc7a14e974f5ef5aaedb8c68ac53f 100644 --- a/port/stil.c +++ b/port/stil.c @@ -154,10 +154,8 @@ iloput(Queue *q, Block *bp) /* Checksum of ilheader plus data (not ip & no pseudo header) */ if(ilcksum) hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, dlen+IL_HDRSIZE)); - ilackq(ic, bp); delay(100); - print("TX len = %d BLEN = %d IL %d\n", blen(bp), BLEN(bp), dlen+IL_HDRSIZE); PUTNEXT(q, bp); } @@ -214,7 +212,6 @@ ilrcvmsg(Ipconv *ipc, Block *bp) char *st; ih = (Ilhdr *)bp->rptr; - plen = blen(bp); if(plen < IL_EHSIZE+IL_HDRSIZE) goto drop; @@ -228,7 +225,6 @@ ilrcvmsg(Ipconv *ipc, Block *bp) dst = nhgetl(ih->src); if(ilcksum && ptcl_csum(bp, IL_EHSIZE, illen) != 0) { -print("len = %d BLEN = %d IL %d\n", blen(bp), BLEN(bp), illen); st = (ih->iltype < 0 || ih->iltype > Ilclose) ? "?" : iltype[ih->iltype]; print("il: cksum error, pkt(%s id %d ack %d %d.%d.%d.%d/%d->%d)\n", st, nhgetl(ih->ilid), nhgetl(ih->ilack), fmtaddr(dst), sp, dp); @@ -237,9 +233,7 @@ print("len = %d BLEN = %d IL %d\n", blen(bp), BLEN(bp), illen); etab = &ipc[conf.ip]; for(s = ipc; s < etab; s++) - if(s->psrc == sp) - if(s->pdst == dp) - if(s->dst == dst) { + if(s->psrc == sp && s->pdst == dp && s->dst == dst) { ilprocess(s, ih, bp); return; } @@ -315,8 +309,8 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp) break; case Ilsync: if(ack != ic->start) { - ilhangup(s); ic->state = Ilclosed; + ilhangup(s); } else { ic->recvd = id; @@ -405,7 +399,7 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp) h->ilsum[0] = 0; h->ilsum[1] = 0; if(ilcksum) - hnputs(h->ilsum, ptcl_csum(nb, IL_EHSIZE, IL_HDRSIZE)); + hnputs(h->ilsum, ptcl_csum(nb, IL_EHSIZE, nhgets(h->illen))); PUTNEXT(Ipoutput, nb); } freeb(bp); @@ -448,14 +442,14 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp) Ilcb *ic = &s->ilctl; USED(ic); - DBG("%s rcv %d/%d snt %d/%d pkt(%s id %d ack %d %d->%d) ", + DBG("%11s rcv %d/%d snt %d/%d pkt(%s id %d ack %d %d->%d) ", ilstate[ic->state], ic->rstart, ic->recvd, ic->start, ic->next, iltype[h->iltype], nhgetl(h->ilid), nhgetl(h->ilack), nhgets(h->ilsrc), nhgets(h->ildst)); _ilprocess(s, h, bp); - DBG("%s rcv %d snt %d\n", ilstate[ic->state], ic->recvd, ic->next); + DBG("%11s rcv %d snt %d\n", ilstate[ic->state], ic->recvd, ic->next); } void @@ -578,10 +572,10 @@ ilsendctl(Ipconv *ipc, Ilhdr *inih, int type) if(ilcksum) hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, IL_HDRSIZE)); - DBG("\nctl(%s id %d ack %d %d->%d)\n", +/* DBG("\nctl(%s id %d ack %d %d->%d)\n", iltype[ih->iltype], nhgetl(ih->ilid), nhgetl(ih->ilack), nhgets(ih->ilsrc), nhgets(ih->ildst)); - +*/ PUTNEXT(Ipoutput, bp); } diff --git a/port/stnoether.c b/port/stnoether.c index 80b9872708a6fdbbe91eefee3997cb269b209309..247a361f6c1c7edc185012472c6421aee32de8c0 100644 --- a/port/stnoether.c +++ b/port/stnoether.c @@ -220,7 +220,7 @@ noetheriput(Queue *q, Block *bp) /* * if not a new call, then its misaddressed */ - if((nh->flag & NO_NEWCALL) == 0){ + if((nh->flag & NO_NEWCALL) == 0 || nh->mid != 1){ noetherbad(ifc, bp, circuit); return; } @@ -228,7 +228,6 @@ noetheriput(Queue *q, Block *bp) /* * Queue call in a circular queue and wakeup a listener. */ - DPRINT("call in\n"); lock(&ifc->lock); next = (ifc->wptr + 1) % Nnocalls; if(next == ifc->rptr){ @@ -246,6 +245,7 @@ noetheriput(Queue *q, Block *bp) ifc->wptr = next; unlock(&ifc->lock); wakeup(&ifc->listenr); + DPRINT("call from %s wptr %d\n", clp->raddr, ifc->wptr); } /* diff --git a/port/stream.c b/port/stream.c index ab0a5dc0c1feb7a8950eb72111c46eda0955ea0d..67a0ed707e18fc30beb567351d34fadd5ba8dca1 100644 --- a/port/stream.c +++ b/port/stream.c @@ -625,6 +625,7 @@ expandb(Block *bp, int len) { Block *nbp, *new; int i; + ulong delim = 0; new = allocb(len); if(new == 0){ @@ -636,7 +637,8 @@ expandb(Block *bp, int len) * copy bytes into new block */ for(nbp = bp; len>0 && nbp; nbp = nbp->next){ - i = BLEN(bp); + delim = nbp->flags & S_DELIM; + i = BLEN(nbp); if(i > len) { memmove(new->wptr, nbp->rptr, len); new->wptr += len; @@ -651,6 +653,7 @@ expandb(Block *bp, int len) memset(new->wptr, 0, len); new->wptr += len; } + new->flags |= delim; freeb(bp); return new;