From 35899f69de02fbe474f0ab4157df250e6fb69439 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 25 Aug 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-08-25 --- port/devmnt.c | 4 +-- port/devssl.c | 72 ++++++++++++++++++++++++++++++-------------------- port/portfns.h | 2 +- port/qio.c | 27 +++++++++++++++---- 4 files changed, 69 insertions(+), 36 deletions(-) diff --git a/port/devmnt.c b/port/devmnt.c index 29dd0b36a07f14bfa5f8d57a3f3e9b729ad0e162..cd9a38a5743a3ea51ae8448a210dc1518d395a1f 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -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) */ diff --git a/port/devssl.c b/port/devssl.c index aa301f0cc841f0cb624ef6b93704676988eeef13..5070250ae5a781625192184fa25a9473a965cb89 100644 --- a/port/devssl.c +++ b/port/devssl.c @@ -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 */ diff --git a/port/portfns.h b/port/portfns.h index 9297ecaa1caf2f011586b4e37cdd6e2454fe8fd2..36ab2804ccf0e922ec459b766353eee2fd568a0f 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -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*); diff --git a/port/qio.c b/port/qio.c index 0e5b7e2a746147d8c6742d560f960bd3c77464c6..bc4d2fec477a2f6ce37107bbe6563547932988e9 100644 --- a/port/qio.c +++ b/port/qio.c @@ -149,6 +149,22 @@ blocklen(Block *bp) return len; } +/* + * 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); } /*