~kris/9p

9hist

b8ca6787ed20244faf0187a79db892ec2a2c1e19 — David du Colombier 27 years ago 6130ddb
Plan 9 from Bell Labs 1999-09-01
4 files changed, 177 insertions(+), 69 deletions(-)

M ip/devip.c
M mpc/main.c
M port/devbridge.c
M port/devsdp.c
M ip/devip.c => ip/devip.c +38 -4
@@ 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 = {

M mpc/main.c => mpc/main.c +8 -13
@@ 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

M port/devbridge.c => port/devbridge.c +9 -3
@@ 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);
		}

M port/devsdp.c => port/devsdp.c +122 -49
@@ 9,7 9,8 @@
#include	<libcrypt.h>

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; i<nelem(portdirtab); i++) {
		dt = portdirtab + i;
	for(i=0; i<nelem(convdirtab); i++) {
		dt = convdirtab + i;
		dirtab[TYPE(dt->qid)] = 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',