From 3cf5031291eaa530d2cb74a29f8fbed084387f25 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 28 Mar 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-03-28 --- ip/ip.h | 1 + ip/ipaux.c | 2 +- ip/ipmux.c | 60 +++++++++++++++++++++++++++++++----------------------- port/qio.c | 30 ++++++++++++++++++--------- 4 files changed, 57 insertions(+), 36 deletions(-) diff --git a/ip/ip.h b/ip/ip.h index 950a2d30c95fc92862ac5259150971589422a72a..103c218fd6afd60e650c1a65e7550cc7f0321c47 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -411,6 +411,7 @@ struct Cmdbuf extern int myetheraddr(uchar*, char*); extern ulong parseip(uchar*, char*); extern ulong parseipmask(uchar*, char*); +extern char* v4parseip(uchar*, char*); extern void maskip(uchar *from, uchar *mask, uchar *to); extern int parsemac(uchar *to, char *from, int len); extern uchar* defmask(uchar*); diff --git a/ip/ipaux.c b/ip/ipaux.c index 7dd0f65fc8a4ee6c80a02f62b5fa35b6f5550847..ce9b66046138eaac60fd136caf9d2a68529671d6 100644 --- a/ip/ipaux.c +++ b/ip/ipaux.c @@ -210,7 +210,7 @@ common: #define CLASS(p) ((*(uchar*)(p))>>6) -static char* +extern char* v4parseip(uchar *to, char *from) { int i; diff --git a/ip/ipmux.c b/ip/ipmux.c index a44881cc076c5d2112fdd5ce0985f66a0481383e..b3b5d54555f64ae37263fc0d2ec24d883e6441bd 100644 --- a/ip/ipmux.c +++ b/ip/ipmux.c @@ -61,7 +61,7 @@ struct Ipmux Ipmux *no; uchar type; uchar len; /* length in bytes of item to compare */ - ushort off; /* offset of comparison */ + short off; /* offset of comparison */ int n; /* number of items val points to */ uchar *val; uchar *mask; @@ -78,6 +78,8 @@ struct Ipmuxrock Ipmux *chain; }; +static int ipmuxsprint(Ipmux*, int, char*, int); + static char* skipwhite(char *p) { @@ -111,25 +113,25 @@ parseop(char **pp) p = skipwhite(p); if(strncmp(p, "dst", 3) == 0){ type = Tdst; - off = ((ulong)(ipoff->dst)) - IPHDR; + off = (ulong)(ipoff->dst); len = IPv4addrlen; p += 3; } else if(strncmp(p, "src", 3) == 0){ type = Tsrc; - off = ((ulong)(ipoff->src)) - IPHDR; + off = (ulong)(ipoff->src); len = IPv4addrlen; p += 3; } else if(strncmp(p, "ifc", 3) == 0){ type = Tifc; - off = -IPv4addrlen - IPHDR; + off = -IPv4addrlen; len = IPv4addrlen; p += 3; } else if(strncmp(p, "proto", 5) == 0){ type = Tproto; - off = ((ulong)&(ipoff->proto)) - IPHDR; + off = (ulong)&(ipoff->proto); len = 1; p += 5; } @@ -158,7 +160,7 @@ parseop(char **pp) return nil; p++; len = end - off + 1; - off += ((ulong)(ipoff->data)) - IPHDR; + off += (ulong)(ipoff->data); } else return nil; @@ -232,7 +234,7 @@ parsemux(char *p) case Tdst: case Tifc: f->mask = smalloc(f->len); - parseipmask(f->mask, mask); + v4parseip(f->mask, mask); break; case Tdata: f->mask = smalloc(f->len); @@ -257,7 +259,7 @@ parsemux(char *p) case Tsrc: case Tdst: case Tifc: - parseip(v, vals[n]); + v4parseip(v, vals[n]); break; case Tproto: case Tdata: @@ -538,8 +540,10 @@ ipmuxconnect(Conv *c, char **argv, int argc) static int ipmuxstate(Conv *c, char *state, int n) { - USED(c); - return snprint(state, n, "%s", "Datagram"); + Ipmuxrock *r; + + r = (Ipmuxrock*)(c->ptcl); + return ipmuxsprint(r->chain, 0, state, n); } static void @@ -579,6 +583,7 @@ ipmuxclose(Conv *c) ipmuxremove(&(c->p->priv), r->chain); wunlock(f); ipmuxtreefree(r->chain); + r->chain = nil; unlock(c); } @@ -612,13 +617,12 @@ ipmuxiput(Proto *p, uchar *ia, Block *bp) goto nomatch; /* make interface address part of packet */ - h = bp->rp - IPHDR - IPv4addrlen; - if(h < bp->base){ - bp = padblock(bp, IPHDR + IPv4addrlen); - h = bp->rp; - bp->rp += IPHDR + IPv4addrlen; + if(bp->rp - bp->base < IPv4addrlen){ + bp = padblock(bp, IPv4addrlen); + bp->rp += IPv4addrlen; } - memmove(h, ia+IPv4off, IPv4addrlen); + h = bp->rp; + memmove(h-IPv4addrlen, ia+IPv4off, IPv4addrlen); len = BLEN(bp); /* run the v4 filter (needs optimizing) */ @@ -635,29 +639,29 @@ ipmuxiput(Proto *p, uchar *ia, Block *bp) m = mux->mask; hp = h + mux->off; for(ve = v + mux->len; v < ve; v++){ - if((*hp++ & *m++) != *v++) + if((*hp++ & *m++) != *v) break; } if(v == ve){ if(mux->conv != nil) c = mux->conv; mux = mux->yes; - break; + goto match; } } - if(v == e) - mux = mux->no; + mux = mux->no; +match:; } runlock(f); if(c != nil){ - bp->rp -= IPHDR; if(bp->next){ bp = concatblock(bp); if(bp == 0) panic("ilpullup"); } qpass(c->rq, bp); + return; } nomatch: @@ -675,20 +679,26 @@ static int ipmuxsprint(Ipmux *mux, int level, char *buf, int len) { int i, j, n; + uchar *v; n = 0; - if(mux == nil) - return n; for(i = 0; i < level; i++) n += snprint(buf+n, len-n, " "); - n += snprint(buf+n, len-n, "h[%d:%d] & ", mux->off, mux->off+mux->len-1); + if(mux == nil){ + n += snprint(buf+n, len-n, "\n"); + return n; + } + n += snprint(buf+n, len-n, "h[%d:%d]&", mux->off, mux->off+mux->len-1); for(i = 0; i < mux->len; i++) n += snprint(buf+n, len - n, "%2.2ux", mux->mask[i]); + n += snprint(buf+n, len-n, "="); + v = mux->val; for(j = 0; j < mux->n; j++){ for(i = 0; i < mux->len; i++) - n += snprint(buf+n, len - n, "%2.2ux", mux->mask[i]); + n += snprint(buf+n, len - n, "%2.2ux", *v++); n += snprint(buf+n, len-n, "|"); } + n += snprint(buf+n, len-n, "\n"); level++; n += ipmuxsprint(mux->no, level, buf+n, len-n); n += ipmuxsprint(mux->yes, level, buf+n, len-n); diff --git a/port/qio.c b/port/qio.c index 7d1ad976785792aabd0f51336b62c9fe5a9b26e2..96774f2d1c89bfe1199aa409e432936d1ad55176 100644 --- a/port/qio.c +++ b/port/qio.c @@ -766,12 +766,14 @@ qopen(int limit, int msg, void (*kick)(void*), void *arg) if(q == 0) return 0; + ilock(q); q->limit = q->inilim = limit; q->kick = kick; q->arg = arg; q->state = msg ? Qmsg : 0; q->state |= Qstarve; q->eof = 0; + iunlock(q); return q; } @@ -911,30 +913,36 @@ qbwrite(Queue *q, Block *b) dowakeup = 0; n = BLEN(b); + qlock(&q->wlock); if(waserror()){ qunlock(&q->wlock); nexterror(); } - qlock(&q->wlock); /* flow control */ - while(!qnotfull(q)){ + for(;;){ + ilock(q); + + if(q->state & Qclosed){ + iunlock(q); + freeb(b); + error(q->err); + } + + if(q->len < q->limit) + break; + if(q->noblock){ + iunlock(q); freeb(b); qunlock(&q->wlock); poperror(); return n; } - q->state |= Qflow; - sleep(&q->wr, qnotfull, q); - } - - ilock(q); - if(q->state & Qclosed){ + q->state |= Qflow; iunlock(q); - freeb(b); - error(q->err); + sleep(&q->wr, qnotfull, q); } if(q->bfirst) @@ -1120,10 +1128,12 @@ qhangup(Queue *q, char *msg) void qreopen(Queue *q) { + ilock(q); q->state &= ~Qclosed; q->state |= Qstarve; q->eof = 0; q->limit = q->inilim; + iunlock(q); } /*