From b8ca6787ed20244faf0187a79db892ec2a2c1e19 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 1 Sep 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-09-01 --- ip/devip.c | 42 ++++++++++-- mpc/main.c | 21 +++--- port/devbridge.c | 12 +++- port/devsdp.c | 171 +++++++++++++++++++++++++++++++++-------------- 4 files changed, 177 insertions(+), 69 deletions(-) diff --git a/ip/devip.c b/ip/devip.c index e061ee4c92cdb07823302ae2eed990e5a67d9ed0..ff772ac3d940d2790864d3e495c02a3b26043a02 100644 --- a/ip/devip.c +++ b/ip/devip.c @@ -609,9 +609,21 @@ ipread(Chan *ch, void *a, long n, vlong off) } static Block* -ipbread(Chan* c, long n, ulong offset) +ipbread(Chan* ch, long n, ulong offset) { - return devbread(c, n, offset); + Conv *c; + Proto *x; + Fs *f; + + switch(TYPE(ch->qid)){ + case Qdata: + f = ipfs[ch->dev]; + x = f->p[PROTO(ch->qid)]; + c = x->conv[CONV(ch->qid)]; + return qbread(c->rq, n); + default: + return devbread(ch, n, offset); + } } /* @@ -964,9 +976,31 @@ ipwrite(Chan* ch, void *v, long n, vlong) } static long -ipbwrite(Chan* c, Block* bp, ulong offset) +ipbwrite(Chan* ch, Block* bp, ulong offset) { - return devbwrite(c, bp, offset); + Conv *c; + Proto *x; + Fs *f; + int n; + + switch(TYPE(ch->qid)){ + case Qdata: + f = ipfs[ch->dev]; + x = f->p[PROTO(ch->qid)]; + c = x->conv[CONV(ch->qid)]; + + if(c->wq == nil) + error(Eperm); + + if(bp->next) + bp = concatblock(bp); + n = BLEN(bp); + qbwrite(c->wq, bp); + x->kick(c, n); + return n; + default: + return devbwrite(ch, bp, offset); + } } Dev ipdevtab = { diff --git a/mpc/main.c b/mpc/main.c index 29a644ceec967ab59ed8d45074e664270a733a2d..8d55bcf762031f8f73d6dac9addbc830b87c70e0 100644 --- a/mpc/main.c +++ b/mpc/main.c @@ -235,21 +235,16 @@ procsave(Proc *p) } // print without using interrupts -int -iprint(char *fmt, ...) +void +serialputs(char *s, int n) { - char buf[PRINTSIZE]; - int n; - va_list arg; - - va_start(arg, fmt); - n = doprint(buf, buf+sizeof(buf), fmt, arg) - buf; - va_end(arg); - - putstrn(buf, n); - uartwait(); + putstrn(s, n); +} - return n; +void +rdb(void) +{ + panic("rdb"); } void diff --git a/port/devbridge.c b/port/devbridge.c index ba71ee8c5816c2e50e87dff29f20f05819e08c7a..37303bcb44f4b3ebf9973c4e63dcb132520434a9 100644 --- a/port/devbridge.c +++ b/port/devbridge.c @@ -94,8 +94,9 @@ struct Bridge int nport; Port *port[Maxport]; Centry cache[CacheSize]; - int hit; - int miss; + ulong hit; + ulong miss; + ulong copy; int tcpmss; // modify tcpmss value Log; @@ -350,6 +351,11 @@ bridgeread(Chan *c, void *a, long n, vlong off) case Qcache: n = readstr(off, a, n, c->aux); return n; + case Qstats: + snprint(buf, sizeof(buf), "hit=%uld miss=%uld copy=%uld\n", + b->hit, b->miss, b->copy); + n = readstr(off, a, n, buf); + return n; } } @@ -832,7 +838,7 @@ ethermultiwrite(Bridge *b, Block *bp, Port *port) // delay one so that the last write does not copy if(c != nil) { - // can not use write since it changes scr addr + b->copy++; bp2 = copyblock(bp, blocklen(bp)); devtab[c->type]->bwrite(c, bp2, 0); } diff --git a/port/devsdp.c b/port/devsdp.c index 72b62d2a76caeba3c3b470e6235a80264b26d5f1..c551b9f19291dcbc4ca3d40abb1ce1fae2c14dad 100644 --- a/port/devsdp.c +++ b/port/devsdp.c @@ -9,7 +9,8 @@ #include typedef struct Sdp Sdp; -typedef struct Port Port; +typedef struct Conv Conv; +typedef struct OneWay OneWay; enum { @@ -20,53 +21,74 @@ enum Qstats, Qlog, - Qportdir, /* directory for a protocol */ + Qconvdir, /* directory per conversation */ Qctl, Qdata, /* reliable control channel */ Qpacket, /* unreliable packet channel */ - Qerr, - Qlisten, - Qlocal, - Qremote, Qstatus, MaxQ, - Maxport= 256, // power of 2 + Maxconv= 256, // power of 2 Nfs= 4, // number of file systems }; #define TYPE(x) ((x).path & 0xff) -#define PORT(x) (((x).path >> 8)&(Maxport-1)) +#define CONV(x) (((x).path >> 8)&(Maxconv-1)) #define QID(x, y) (((x)<<8) | (y)) -struct Port { +struct OneWay +{ + ulong seqwrap; // number of wraps of the sequence number + ulong seq; + ulong window; // for replay attacks + + char *calg; + void *cstate; // state cipher + int civlen; // in bytes + int (*cipher)(OneWay*, uchar *buf, int len); + + char *aalg; + void *astate; // auth state + int alen; // auth data length in bytes + int (*auth)(OneWay*, uchar *buf, int len, uchar *hash); +}; + +struct Conv { + QLock; + int id; Sdp *sdp; - int ref; - int closed; + + Chan chan; // packet channel + + char user[NAMELEN]; /* protections */ + int perm; + int inuse; + int length; + int state; + + OneWay in; + OneWay out; }; struct Sdp { QLock; Log; - int nport; - Port *port[Maxport]; + int nconv; + Conv *conv[Maxconv]; }; static Dirtab sdpdirtab[]={ - "ctl", {Qctl}, 0, 0666, "stats", {Qstats}, 0, 0444, "log", {Qlog}, 0, 0666, + "clone", {Qclone}, 0, 0666, }; -static Dirtab portdirtab[]={ +static Dirtab convdirtab[]={ "ctl", {Qctl}, 0, 0666, "data", {Qdata}, 0, 0666, "packet", {Qpacket}, 0, 0666, - "listen", {Qlisten}, 0, 0666, - "local", {Qlocal}, 0, 0444, - "remote", {Qlocal}, 0, 0444, "status", {Qstatus}, 0, 0444, }; @@ -94,6 +116,7 @@ static Dirtab *dirtab[MaxQ]; static Sdp sdptab[Nfs]; static int sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp); +static Conv *sdpclone(Sdp *sdp); static void sdpinit(void) @@ -107,8 +130,8 @@ sdpinit(void) dirtab[TYPE(dt->qid)] = dt; } - for(i=0; iqid)] = dt; } } @@ -123,7 +146,7 @@ sdpattach(char* spec) if(dev<0 || dev >= Nfs) error("bad specification"); - c = devattach('B', spec); + c = devattach('T', spec); c->qid = (Qid){QID(0, Qtopdir)|CHDIR, 0}; c->dev = dev; @@ -139,7 +162,7 @@ sdpwalk(Chan *c, char *name) case Qsdpdir: c->qid = (Qid){CHDIR|Qtopdir, 0}; break; - case Qportdir: + case Qconvdir: c->qid = (Qid){CHDIR|Qsdpdir, 0}; break; default: @@ -158,25 +181,25 @@ sdpstat(Chan* c, char* db) } static Chan* -sdpopen(Chan* c, int omode) +sdpopen(Chan* ch, int omode) { int perm; Sdp *sdp; + Conv *c; omode &= 3; perm = m2p[omode]; USED(perm); - sdp = sdptab + c->dev; + sdp = sdptab + ch->dev; - switch(TYPE(c->qid)) { + switch(TYPE(ch->qid)) { default: break; case Qtopdir: case Qsdpdir: - case Qportdir: + case Qconvdir: case Qstatus: - case Qlocal: case Qstats: if(omode != OREAD) error(Eperm); @@ -184,11 +207,17 @@ sdpopen(Chan* c, int omode) case Qlog: logopen(sdp); break; + case Qclone: + c = sdpclone(sdp); + if(c == nil) + error(Enodev); + ch->qid.path = QID(c->id, Qctl); + break; } - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; + ch->mode = openmode(omode); + ch->flag |= COPEN; + ch->offset = 0; + return ch; } static void @@ -205,46 +234,48 @@ sdpclose(Chan* c) } static long -sdpread(Chan *c, void *a, long n, vlong off) +sdpread(Chan *ch, void *a, long n, vlong off) { char buf[256]; - Sdp *sdp = sdptab + c->dev; - Port *port; + Sdp *sdp = sdptab + ch->dev; + Conv *c; USED(off); - switch(TYPE(c->qid)) { + switch(TYPE(ch->qid)) { default: error(Eperm); case Qtopdir: case Qsdpdir: - case Qportdir: - return devdirread(c, a, n, 0, 0, sdpgen); + case Qconvdir: + return devdirread(ch, a, n, 0, 0, sdpgen); case Qlog: return logread(sdp, a, off, n); case Qstatus: qlock(sdp); - port = sdp->port[PORT(c->qid)]; - if(port == 0) + c = sdp->conv[CONV(ch->qid)]; + if(c == 0) strcpy(buf, "unbound\n"); else { } n = readstr(off, a, n, buf); qunlock(sdp); return n; + case Qctl: + sprint(buf, "%lud", CONV(ch->qid)); + return readstr(off, a, n, buf); } - } static long -sdpwrite(Chan *c, void *a, long n, vlong off) +sdpwrite(Chan *ch, void *a, long n, vlong off) { - Sdp *sdp = sdptab + c->dev; + Sdp *sdp = sdptab + ch->dev; Cmdbuf *cb; char *arg0; char *p; USED(off); - switch(TYPE(c->qid)) { + switch(TYPE(ch->qid)) { default: error(Eperm); case Qctl: @@ -258,6 +289,7 @@ sdpwrite(Chan *c, void *a, long n, vlong off) if(cb->nf == 0) error("short write"); arg0 = cb->f[0]; +print("cmd = %s\n", arg0); if(strcmp(arg0, "xxx") == 0) { print("xxx\n"); } else @@ -309,22 +341,63 @@ sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp) return 1; } s -= nelem(sdpdirtab); - if(s >= sdp->nport) + if(s >= sdp->nconv) return -1; - qid = (Qid){QID(s,Qportdir)|CHDIR, 0}; + qid = (Qid){QID(s,Qconvdir)|CHDIR, 0}; snprint(buf, sizeof(buf), "%d", s); devdir(c, qid, buf, 0, eve, 0555, dp); return 1; - case Qportdir: - if(s>=nelem(portdirtab)) + case Qconvdir: + if(s>=nelem(convdirtab)) return -1; - dt = portdirtab+s; - qid = (Qid){QID(PORT(c->qid),TYPE(dt->qid)),0}; + dt = convdirtab+s; + qid = (Qid){QID(CONV(c->qid),TYPE(dt->qid)),0}; devdir(c, qid, dt->name, dt->length, eve, dt->perm, dp); return 1; } } +static Conv* +sdpclone(Sdp *sdp) +{ + Conv *c, **pp, **ep; + + c = nil; + ep = sdp->conv + nelem(sdp->conv); + for(pp = sdp->conv; pp < ep; pp++) { + c = *pp; + if(c == nil){ + c = malloc(sizeof(Conv)); + if(c == nil) + error(Enomem); + qlock(c); + c->sdp = sdp; + c->id = pp - sdp->conv; + *pp = c; + sdp->nconv++; + break; + } + if(canqlock(c)){ + if(c->inuse == 0) + break; + + qunlock(c); + } + } + + if(pp >= ep) { + return nil; + } + + c->inuse = 1; + strncpy(c->user, up->user, sizeof(c->user)); + c->perm = 0660; + c->state = 0; + + qunlock(c); + return c; +} + Dev sdpdevtab = { 'T',