~kris/9p

9hist

def0bd0615970f31d47041dd2b05ca9dfd4fd7e3 — David du Colombier 25 years ago a232380
Plan 9 from Bell Labs 2001-02-14
7 files changed, 267 insertions(+), 51 deletions(-)

M boot/boot.h
M boot/bootip.c
A boot/fcall.c
M port/chan.c
M port/devsdp.c
M port/thwack.h
M port/unthwack.c
M boot/boot.h => boot/boot.h +1 -0
@@ 15,6 15,7 @@ extern int	cpuflag;
extern char	cputype[];
extern int	fflag;
extern int	kflag;
extern int pushfcall(int);
extern Method	method[];
extern void	(*pword)(int, Method*);
extern char	sys[];

M boot/bootip.c => boot/bootip.c +18 -17
@@ 97,54 97,55 @@ configip(void)
}

void
configtcp(Method*)
configil(Method*)
{
	sleep(100);
	print("t");
	sleep(100);
	configip();
	sleep(100);
	print(".");
	sleep(100);
}

int
authtcp(void)
authil(void)
{
	return -1;
	char buf[2*NAMELEN];

	sprint(buf, "il!%I!566", auip);
	return dial(buf, 0, 0, 0);
}

int
connecttcp(void)
connectil(void)
{
	char buf[2*NAMELEN];

	sprint(buf, "tcp!%I!564", fsip);
	sprint(buf, "il!%I!17008", fsip);
	return dial(buf, 0, 0, 0);
}

void
configil(Method*)
configtcp(Method*)
{
	configip();
}

int
authil(void)
authtcp(void)
{
	char buf[2*NAMELEN];

	sprint(buf, "il!%I!566", auip);
	sprint(buf, "tcp!%I!567", auip);
	return dial(buf, 0, 0, 0);
}

int
connectil(void)
connecttcp(void)
{
	char buf[2*NAMELEN];
	int fd;

	sprint(buf, "il!%I!17008", fsip);
	return dial(buf, 0, 0, 0);
	sprint(buf, "tcp!%I!564", fsip);
	fd = dial(buf, 0, 0, 0);
	if(fd < 0)
		return -1;
	return pushfcall(fd);
}

static int

A boot/fcall.c => boot/fcall.c +171 -0
@@ 0,0 1,171 @@
#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include <ip.h>

#include "boot.h"

/*
 * reassemble 9P messages for stream based protocols
 * interposed between devmnt and the network by srv for tcp connections
 * fcall expects devmnt on fd0, network fd1
 */
static uchar msglen[256] =
{
	[Tnop]		3,
	[Rnop]		3,
	[Tsession]	3+CHALLEN,
	[Rsession]	3+NAMELEN+DOMLEN+CHALLEN,
	[Terror]	0,
	[Rerror]	67,
	[Tflush]	5,
	[Rflush]	3,
	[Tattach]	5+2*NAMELEN+TICKETLEN+AUTHENTLEN,
	[Rattach]	13+AUTHENTLEN,
	[Tclone]	7,
	[Rclone]	5,
	[Twalk]		33,
	[Rwalk]		13,
	[Topen]		6,
	[Ropen]		13,
	[Tcreate]	38,
	[Rcreate]	13,
	[Tread]		15,
	[Rread]		8,
	[Twrite]	16,
	[Rwrite]	7,
	[Tclunk]	5,
	[Rclunk]	5,
	[Tremove]	5,
	[Rremove]	5,
	[Tstat]		5,
	[Rstat]		121,
	[Twstat]	121,
	[Rwstat]	5,
	[Tclwalk]	35,
	[Rclwalk]	13,
};

enum
{
	Twritehdr	= 16,	/* Min bytes for Twrite */
	Rreadhdr	= 8,	/* Min bytes for Rread */
	Twritecnt	= 13,	/* Offset in byte stream of write count */
	Rreadcnt	= 5,	/* Offset for Readcnt */
};

void
echo(int f, int t)
{
	int n;
	char buf[MAXRPC];

	for(;;) {
		n = read9p(f, buf, MAXRPC);
		if(n <= 0)
			break;
		if(write(t, buf, n) < n)
			break;
	}
}

int
mntrpclen(uchar *d, int n)
{
	uchar t;
	int len, off;

	if(n < 1)
		return 0;

	t = d[0];
	switch(t) {			/* This is the type */
	default:
		len = msglen[t];
		if(len == 0)		/* Illegal type so consume */
			return n;
		if(n < len)
			return 0;
		return len;
	case Twrite:			/* Fmt: TGGFFOOOOOOOOCC */
		len = Twritehdr;	/* T = type, G = tag, F = fid */
		off = Twritecnt;	/* O = offset, C = count */
		break;
	case Rread:			/* Fmt: TGGFFCC */
		len = Rreadhdr;
		off = Rreadcnt;
		break;
	}
	if(n < off+2)
		return 0;

	len += d[off]|(d[off+1]<<8);
	if(n < len)
		return 0;

	return len;
}

int
pushfcall(int fd)
{
	int r, n, l, pfd[2];
	uchar *p, buf[MAXRPC];

	if(pipe(pfd) < 0){
		fprint(2, "pipe: %r\n");
		exits("pipe");
	}

	/* Downstream is just a copy process */
	switch(rfork(RFPROC|RFFDG|RFMEM)){
	case 0:
		close(pfd[1]);
		echo(pfd[0], fd);
		fprint(2, "echo finished\n");
		exits("echo done");
	case -1:
		fprint(2, "fcall fork failed: %r\n");
		exits("fork");
	}

	switch(rfork(RFPROC|RFFDG|RFMEM)){
	default:
		close(pfd[0]);
		return pfd[1];
	case 0:
		close(pfd[1]);
		break;
	case -1:
		fprint(2, "fcall fork failed: %r\n");
		exits("fork");
	}

	/* Dispatch only full RPC's to the mount driver */
	l = MAXRPC;
	p = buf;
	for(;;) {
		n = read(fd, p, l);
		if(n < 0)
			break;
		p += n;
		l -= n;

		for(;;) {
			r = mntrpclen(buf, p - buf);
			if(r == 0)
				break;

			if(write(pfd[0], buf, r) < 0)
				break;

			n = (p - buf) - r;
			memmove(buf, buf+r, n);
			p = buf+n;
			l = MAXRPC - n;
		}
	}
	abort();
	return 0;
}

M port/chan.c => port/chan.c +0 -1
@@ 361,7 361,6 @@ cunmount(Chan *mnt, Chan *mounted)
			mountfree(f);
			if(m->mount == nil) {
				*l = m->hash;
				wunlock(&pg->ns);
				cclose(m->from);
				wunlock(&m->lock);
				putmhead(m);

M port/devsdp.c => port/devsdp.c +8 -8
@@ 99,8 99,6 @@ struct OneWay
	int		(*auth)(OneWay*, uchar *buf, int len);

	void	*compstate;
	ulong	compseq;
	ulong	compwindow;
	int		(*comp)(Conv*, int subtype, ulong seq, Block **);
};



@@ 1310,8 1308,6 @@ print("pad too big\n");
			c->lstats.inBadComp++;
			return nil;
		}
		c->in.compseq = c->in.seq;
		c->in.compwindow = c->in.window;
		c->lstats.inDataBytes += BLEN(b);
		if(control)
			break;


@@ 2238,13 2234,17 @@ thwackcomp(Conv *c, int, ulong seq, Block **bp)
{
	Block *b, *bb;
	int nn;
	ulong ackseq;
	uchar mask;

	// add ack info
	b = padblock(*bp, 4);
	b->rp[0] = (c->in.compwindow>>1) & 0xff;
	b->rp[1] = c->in.compseq>>16;
	b->rp[2] = c->in.compseq>>8;
	b->rp[3] = c->in.compseq;

	ackseq = unthwackstate(c->in.compstate, &mask);
	b->rp[0] = mask;
	b->rp[1] = ackseq>>16;
	b->rp[2] = ackseq>>8;
	b->rp[3] = ackseq;

	bb = allocb(BLEN(b));
	nn = thwack(c->out.compstate, bb->wp, b->rp, BLEN(b), seq, c->lstats.outCompStats);

M port/thwack.h => port/thwack.h +1 -0
@@ 65,3 65,4 @@ void	unthwackinit(Unthwack*);
int	thwack(Thwack*, uchar *dst, uchar *src, int nsrc, ulong seq, ulong stats[ThwStats]);
void	thwackack(Thwack*, ulong seq, ulong mask);
int	unthwack(Unthwack*, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq);
ulong	unthwackstate(Unthwack *ut, uchar *mask);

M port/unthwack.c => port/unthwack.c +68 -25
@@ 59,39 59,86 @@ unthwackinit(Unthwack *ut)
		ut->blocks[i].data = ut->data[i];
}

int
unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
ulong
unthwackstate(Unthwack *ut, uchar *mask)
{
	UnthwBlock blocks[CompBlocks], *b, *eblocks;
	uchar *s, *d, *dmax, *smax, lit;
	ulong cmask, cseq, bseq, utbits, lithist;
	int i, off, len, bits, slot, tslot, use, code, utnbits, overbits;
	ulong bseq, seq;
	int slot, m;

	if(nsrc < 4 || nsrc > ThwMaxBlock)
		return -1;
	seq = ~0UL;
	m = 0;
	slot = ut->slot;
	for(;;){
		slot--;
		if(slot < 0)
			slot += DWinBlocks;
		if(slot == ut->slot)
			break;
		if(ut->blocks[slot].maxoff == 0)
			continue;
		bseq = ut->blocks[slot].seq;
		if(seq == ~0UL)
			seq = bseq;
		else if(seq - bseq > MaxSeqMask)
			break;
		else
			m |= 1 << (seq - bseq - 1);
	}
	*mask = m;
	return seq;
}

/*
 * insert this block in it's correct sequence number order.
 * replace the oldest block, which is always pointed to by ut->slot.
 * the encoder doesn't use a history at wraparound,
 * so don't worry about that case.
 */
static int
unthwackinsert(Unthwack *ut, int len, ulong seq)
{
	uchar *d;
	int slot, tslot;

	/*
	 * insert this block in it's correct sequence number order.
	 * replace the oldest block, which is always pointed to by ut->slot.
	 * the encoder doesn't use a history at wraparound,
	 * so don't worry about that case.
	 */
	tslot = ut->slot;
	for(;;){
		slot = tslot - 1;
		if(slot < 0)
			slot += DWinBlocks;
		if(ut->blocks[slot].seq <= seq)
		if(ut->blocks[slot].seq <= seq || ut->blocks[slot].maxoff == 0)
			break;
		d = ut->blocks[tslot].data;
		ut->blocks[tslot] = ut->blocks[slot];
		ut->blocks[slot].data = d;
		tslot = slot;
	}
	b = blocks;
	ut->blocks[tslot].seq = seq;
	ut->blocks[tslot].maxoff = 0;
	*b = ut->blocks[tslot];
	ut->blocks[tslot].maxoff = len;

	ut->slot++;
	if(ut->slot >= DWinBlocks)
		ut->slot = 0;

	ut->blocks[ut->slot].seq = ~0UL;
	ut->blocks[ut->slot].maxoff = 0;

	return tslot;
}

int
unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
{
	UnthwBlock blocks[CompBlocks], *b, *eblocks;
	uchar *s, *d, *dmax, *smax, lit;
	ulong cmask, cseq, bseq, utbits;
	int i, off, len, bits, slot, use, code, utnbits, overbits, lithist;

	if(nsrc < 4 || nsrc > ThwMaxBlock)
		return -1;

	slot = ut->slot;
	b = blocks;
	*b = ut->blocks[slot];
	d = b->data;
	dmax = d + ndst;



@@ 101,7 148,6 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
	cseq = seq - src[0];
	cmask = src[1];
	b++;
	slot = tslot;
	while(cseq != seq && b < blocks + CompBlocks){
		slot--;
		if(slot < 0)


@@ 125,8 171,8 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
	}
	eblocks = b;
	if(cseq != seq){
		print("blocks not in decompression window: cseq=%ld seq=%ld cmask=%lx nb=%ld\n", cseq, seq, cmask, eblocks - blocks);
		return -1;
		print("blocks dropped: seq=%ld cseq=%ld %d cmask=%#lx %#x\n", seq, cseq, src[0], cmask, src[1]);
		return -2;
	}

	smax = src + nsrc;


@@ 244,11 290,8 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)

	len = d - blocks->data;
	memmove(dst, blocks->data, len);
	ut->blocks[tslot].maxoff = len;

	ut->slot++;
	if(ut->slot >= DWinBlocks)
		ut->slot = 0;
	unthwackinsert(ut, len, seq);

	return len;
}