~kris/9p

9hist

35899f69de02fbe474f0ab4157df250e6fb69439 — David du Colombier 25 years ago 0dd6406
Plan 9 from Bell Labs 2001-08-25
4 files changed, 69 insertions(+), 36 deletions(-)

M port/devmnt.c
M port/devssl.c
M port/portfns.h
M port/qio.c
M port/devmnt.c => port/devmnt.c +2 -2
@@ 837,7 837,7 @@ mntrpcread(Mnt *m, Mntrpc *r)
		b = devtab[m->c->type]->bread(m->c, 2*MAXRPC, 0);
		if(b == nil)
			return -1;
		qadd(m->q, b);
		qaddlist(m->q, b);
	}
	nb = pullupqueue(m->q, BIT32SZ+BIT8SZ+BIT16SZ);
	len = GBIT32(nb->rp);


@@ 847,7 847,7 @@ mntrpcread(Mnt *m, Mntrpc *r)
		b = devtab[m->c->type]->bread(m->c, 2*MAXRPC, 0);
		if(b == nil)
			return -1;
		qadd(m->q, b);
		qaddlist(m->q, b);
	}

	/* pullup the header (i.e. everything except data) */

M port/devssl.c => port/devssl.c +44 -28
@@ 415,7 415,7 @@ ensure(Dstate *s, Block **l, int n)
	while(sofar < n){
		bl = devtab[s->c->type]->bread(s->c, Maxdmsg, 0);
		if(bl == 0)
			error(Ehungup);
			nexterror();
		*l = bl;
		i = 0;
		for(b = bl; b; b = b->next){


@@ 457,7 457,6 @@ consume(Block **l, uchar *p, int n)

/*
 *  give back n bytes
 */
static void
regurgitate(Dstate *s, uchar *p, int n)
{


@@ 477,6 476,7 @@ regurgitate(Dstate *s, uchar *p, int n)
		memmove(b->rp, p, n);
	}
}
 */

/*
 *  remove at most n bytes from the queue, if discard is set


@@ 538,8 538,8 @@ sslbread(Chan *c, long n, ulong)
{
	volatile struct { Dstate *s; } s;
	Block *b;
	uchar consumed[3];
	int nconsumed;
	uchar consumed[3], *p;
	int toconsume;
	int len, pad;

	s.s = dstate[CONV(c->qid)];


@@ 548,44 548,58 @@ sslbread(Chan *c, long n, ulong)
	if(s.s->state == Sincomplete)
		error(Ebadusefd);

	nconsumed = 0;
	qlock(&s.s->in.q);
	if(waserror()){
		if(strcmp(up->error, Eintr) != 0)
			regurgitate(s.s, consumed, nconsumed);
		qunlock(&s.s->in.q);
		nexterror();
	}
	qlock(&s.s->in.q);

	if(s.s->processed == 0){
		/* read in the whole message */
		ensure(s.s, &s.s->unprocessed, 2);
		consume(&s.s->unprocessed, consumed, 2);
		nconsumed = 2;
		if(consumed[0] & 0x80){
			len = ((consumed[0] & 0x7f)<<8) | consumed[1];
		/*
		 * Read in the whole message.  Until we've got it all,
		 * it stays on s.s->unprocessed, so that if we get Eintr,
		 * we'll pick up where we left off.
		 */
		ensure(s.s, &s.s->unprocessed, 3);
		s.s->unprocessed = pullupblock(s.s->unprocessed, 2);
		p = s.s->unprocessed->rp;
		if(p[0] & 0x80){
			len = ((p[0] & 0x7f)<<8) | p[1];
			ensure(s.s, &s.s->unprocessed, len);
			pad = 0;
			toconsume = 2;
		} else {
			len = ((consumed[0] & 0x3f)<<8) | consumed[1];
			ensure(s.s, &s.s->unprocessed, len+1);
			consume(&s.s->unprocessed, &consumed[2], 1);
			pad = consumed[2];
			len = ((p[0] & 0x3f)<<8) | p[1];
			pad = p[2];
			if(pad > len){
				print("pad %d buf len %d\n", pad, len);
				error("bad pad in ssl message");
			}
			toconsume = 3;
		}
		USED(nconsumed);
		nconsumed = 0;

		/*  if an Eintr happens after this, we're screwed.  Make
		 *  sure nothing we call can sleep.  Luckily, allocb
		 *  won't sleep, it'll just error out.
		ensure(s.s, &s.s->unprocessed, toconsume+len+pad);

		/*
		 * Now we have a full SSL packet in the unprocessed list.
		 * Start processing.  We can't get Eintr's here.
		 * The only cause for errors from here until the end of the
		 * loop is allocation failures in the block manipulation.
		 * We'll worry about that when we come across it.
		 */

		if(waserror()){
			print("devssl: unhandled allocation failure\n");
			nexterror();
		}

		/* skip header */
		consume(&s.s->unprocessed, consumed, toconsume);

		/* grab the next message and decode/decrypt it */
		b = qtake(&s.s->unprocessed, len, 0);
		b = qtake(&s.s->unprocessed, len+pad, 0);

		if(blocklen(b) != len+pad)
			print("devssl: sslbread got wrong count %d != %d", blocklen(b), len);

		if(waserror()){
			qunlock(&s.s->in.ctlq);


@@ 596,12 610,14 @@ sslbread(Chan *c, long n, ulong)
		qlock(&s.s->in.ctlq);
		switch(s.s->state){
		case Sencrypting:
			if(b == nil)
				error("ssl message too short (encrypting)");
			b = decryptb(s.s, b);
			break;
		case Sdigesting:
			b = pullupblock(b, s.s->diglen);
			if(b == nil)
				error("ssl message too short");
				error("ssl message too short (digesting)");
			checkdigestb(s.s, b);
			b->rp += s.s->diglen;
			break;


@@ 609,7 625,7 @@ sslbread(Chan *c, long n, ulong)
			b = decryptb(s.s, b);
			b = pullupblock(b, s.s->diglen);
			if(b == nil)
				error("ssl message too short");
				error("ssl message too short (dig+enc)");
			checkdigestb(s.s, b);
			b->rp += s.s->diglen;
			len -= s.s->diglen;


@@ 625,7 641,7 @@ sslbread(Chan *c, long n, ulong)
		s.s->in.mid++;
		qunlock(&s.s->in.ctlq);
		poperror();
		USED(nconsumed);
		poperror();
	}

	/* return at most what was asked for */

M port/portfns.h => port/portfns.h +1 -1
@@ 229,7 229,7 @@ void		putstr(char*);
void		putstrn(char*, int);
void		putswap(Page*);
ulong		pwait(Waitmsg*);
void		qadd(Queue*, Block*);
void		qaddlist(Queue*, Block*);
Block*		qbread(Queue*, int);
long		qbwrite(Queue*, Block*);
int		qcanread(Queue*);

M port/qio.c => port/qio.c +22 -5
@@ 150,6 150,22 @@ blocklen(Block *bp)
}

/*
 * return count of space in blocks
 */
int
blockalloclen(Block *bp)
{
	int len;

	len = 0;
	while(bp) {
		len += BALLOC(bp);
		bp = bp->next;
	}
	return len;
}

/*
 *  copy the  string of blocks into
 *  a single block and free the string
 */


@@ 831,20 847,21 @@ qwait(Queue *q)
}

/*
 * add a block to a queue
 * add a block list to a queue
 */
void
qadd(Queue *q, Block *b)
qaddlist(Queue *q, Block *b)
{
	/* queue the block */
	if(q->bfirst)
		q->blast->next = b;
	else
		q->bfirst = b;
	q->len += blockalloclen(b);
	q->dlen += blocklen(b);
	while(b->next)
		b = b->next;
	q->blast = b;
	b->next = 0;
	q->len += BALLOC(b);
	q->dlen += BLEN(b);
}

/*