~kris/9p

9hist

791cd62a463108a5a94e0e5871c884b40d301873 — David du Colombier 23 years ago 2acb671
Plan 9 from Bell Labs 2002-11-10
4 files changed, 51 insertions(+), 9 deletions(-)

M ip/devip.c
M ip/ip.h
M ip/ipifc.c
M ip/pktmedium.c
M ip/devip.c => ip/devip.c +25 -1
@@ 32,6 32,7 @@ enum
	Qlocal,
	Qremote,
	Qstatus,
	Qsnoop,

	Logtype=	5,
	Masktype=	(1<<Logtype)-1,


@@ 84,7 85,7 @@ ip3gen(Chan *c, int i, Dir *dp)
		devdir(c, q, "err", qlen(cv->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)

M ip/ip.h => ip/ip.h +2 -0
@@ 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;

M ip/ipifc.c => ip/ipifc.c +18 -7
@@ 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;

M ip/pktmedium.c => ip/pktmedium.c +6 -1
@@ 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