From 791cd62a463108a5a94e0e5871c884b40d301873 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 10 Nov 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-11-10 --- ip/devip.c | 26 +++++++++++++++++++++++++- ip/ip.h | 2 ++ ip/ipifc.c | 25 ++++++++++++++++++------- ip/pktmedium.c | 7 ++++++- 4 files changed, 51 insertions(+), 9 deletions(-) diff --git a/ip/devip.c b/ip/devip.c index 8dec7e2505afbdd2ed22ef8fdd9fb4d1e01e8b25..030ecbdaad3d8a1ac2279ceebf08a0a84a71ca36 100644 --- a/ip/devip.c +++ b/ip/devip.c @@ -32,6 +32,7 @@ enum Qlocal, Qremote, Qstatus, + Qsnoop, Logtype= 5, Masktype= (1<eq), cv->owner, cv->perm, dp); return 1; case Qlisten: - devdir(c, q, "listen", qlen(cv->eq), cv->owner, cv->perm, dp); + devdir(c, q, "listen", 0, cv->owner, cv->perm, dp); return 1; case Qlocal: p = "local"; @@ -92,6 +93,11 @@ ip3gen(Chan *c, int i, Dir *dp) case Qremote: p = "remote"; break; + case Qsnoop: + if(strcmp(cv->p->name, "ipifc") != 0) + return -1; + devdir(c, q, "snoop", qlen(cv->sq), cv->owner, 0400, dp); + return 1; case Qstatus: p = "status"; break; @@ -235,6 +241,7 @@ ipgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) case Qlocal: case Qremote: case Qstatus: + case Qsnoop: return ip3gen(c, TYPE(c->qid), dp); } return -1; @@ -391,6 +398,15 @@ ipopen(Chan* c, int omode) if(omode != OREAD) error(Eperm); break; + case Qsnoop: + if(omode != OREAD) + error(Eperm); + p = f->p[PROTO(c->qid)]; + cv = p->conv[CONV(c->qid)]; + if(strcmp(ATTACHER(c), cv->owner) != 0 && !iseve()) + error(Eperm); + incref(&cv->snoopers); + break; case Qclone: p = f->p[PROTO(c->qid)]; qlock(p); @@ -575,6 +591,11 @@ ipclose(Chan* c) case Qerr: if(c->flag & COPEN) closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]); + break; + case Qsnoop: + if(c->flag & COPEN) + decref(&f->p[PROTO(c->qid)]->conv[CONV(c->qid)]->snoopers); + break; } free(((IPaux*)c->aux)->owner); free(c->aux); @@ -663,6 +684,9 @@ ipread(Chan *ch, void *a, long n, vlong off) case Qerr: c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; return qread(c->eq, a, n); + case Qsnoop: + c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; + return qread(c->sq, a, n); case Qstats: x = f->p[PROTO(ch->qid)]; if(x->stats == nil) diff --git a/ip/ip.h b/ip/ip.h index 4c4c34f6ec7bf5cda57b059371322f785b1900b1..bf0f78afe09a81b14269627e766a609dd0182237 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -105,6 +105,8 @@ struct Conv Queue* rq; /* queued data waiting to be read */ Queue* wq; /* queued data waiting to be written */ Queue* eq; /* returned error packets */ + Queue* sq; /* snooping queue */ + Ref snoopers; /* number of processes with snoop open */ QLock car; Rendez cr; diff --git a/ip/ipifc.c b/ip/ipifc.c index 198a5d1d8372a72364ee949e3fab902b3e76b7f1..586b2aa771bb5320b91b325d1a1585987255d22b 100644 --- a/ip/ipifc.c +++ b/ip/ipifc.c @@ -128,18 +128,22 @@ ipifcbind(Conv *c, char **argv, int argc) nexterror(); } + /* do medium specific binding */ (*m->bind)(ifc, argc, argv); + + /* set the bound device name */ if(argc > 2) strncpy(ifc->dev, argv[2], sizeof(ifc->dev)); else sprint(ifc->dev, "%s%d", m->name, c->x); ifc->dev[sizeof(ifc->dev)-1] = 0; + + /* set up parameters */ ifc->m = m; ifc->minmtu = ifc->m->minmtu; ifc->maxmtu = ifc->m->maxmtu; if(ifc->m->unbindonclose == 0) ifc->conv->inuse++; - ifc->rp.mflag = 0; // default not managed ifc->rp.oflag = 0; ifc->rp.maxraint = 600000; // millisecs @@ -148,10 +152,16 @@ ipifcbind(Conv *c, char **argv, int argc) ifc->rp.reachtime = 0; ifc->rp.rxmitra = 0; ifc->rp.ttl = MAXTTL; - ifc->rp.routerlt = 3*(ifc->rp.maxraint); + ifc->rp.routerlt = 3*(ifc->rp.maxraint); + /* any ancillary structures (like routes) no longer pertain */ ifc->ifcid++; + /* reopen all the queues closed by a previous unbind */ + qreopen(c->rq); + qreopen(c->eq); + qreopen(c->sq); + wunlock(ifc); poperror(); @@ -188,9 +198,10 @@ ipifcunbind(Ipifc *ifc) ifc->arg = nil; ifc->reassemble = 0; - /* hangup queues to stop queuing of packets */ - qhangup(ifc->conv->rq, "unbind"); - qhangup(ifc->conv->wq, "unbind"); + /* close queues to stop queuing of packets */ + qclose(ifc->conv->rq); + qclose(ifc->conv->wq); + qclose(ifc->conv->sq); /* disassociate logical interfaces */ av[0] = "remove"; @@ -301,8 +312,7 @@ ipifckick(void *x) } /* - * we'll have to have a kick routine at - * some point to deal with these + * called when a new ipifc structure is created */ static void ipifccreate(Conv *c) @@ -310,6 +320,7 @@ ipifccreate(Conv *c) Ipifc *ifc; c->rq = qopen(QMAX, 0, 0, 0); + c->sq = qopen(2*QMAX, 0, 0, 0); c->wq = qopen(QMAX, Qkick, ipifckick, c); ifc = (Ipifc*)c->ptcl; ifc->conv = c; diff --git a/ip/pktmedium.c b/ip/pktmedium.c index 6f74f3f0310b4aacb2c79b83d5232e1127638f2e..9c136f6bc3b4004101d0ad5a548b279e89ee45cf 100644 --- a/ip/pktmedium.c +++ b/ip/pktmedium.c @@ -52,6 +52,8 @@ pktbwrite(Ipifc *ifc, Block *bp, int, uchar*) { /* enqueue onto the conversation's rq */ bp = concatblock(bp); + if(ifc->conv->snoopers.ref > 0) + qpass(ifc->conv->sq, copyblock(bp, BLEN(bp))); qpass(ifc->conv->rq, bp); } @@ -63,8 +65,11 @@ pktin(Fs *f, Ipifc *ifc, Block *bp) { if(ifc->lifc == nil) freeb(bp); - else + else { + if(ifc->conv->snoopers.ref > 0) + qpass(ifc->conv->sq, copyblock(bp, BLEN(bp))); ipiput4(f, ifc, bp); + } } void