From e041b930696c9816ee023d7e577381b61284ee6a Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 7 Oct 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-10-07 --- ip/ip.c | 4 +- pc/devusb.c | 252 +++++++++++++++++++----------------------- port/devtls.c | 297 ++++++++++++++++++++++++++------------------------ 3 files changed, 265 insertions(+), 288 deletions(-) diff --git a/ip/ip.c b/ip/ip.c index 559d0cd6a7619f00f014570998276084b7a2b6d7..23f58d7ed79c07d722228a0de79ccb1136d7a7f1 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -150,7 +150,7 @@ ipoput(Fs *f, Block *bp, int gating, int ttl, int tos) { Ipifc *ifc; uchar *gate; - ushort fragoff; + ulong fragoff; Block *xp, *nb; Iphdr *eh, *feh; int lid, len, seglen, chunk, dlen, blklen, offset, medialen; @@ -269,7 +269,7 @@ ipoput(Fs *f, Block *bp, int gating, int ttl, int tos) xp->rp += offset; if(gating) - fragoff = nhgets(eh->frag); + fragoff = nhgets(eh->frag)<<3; else fragoff = 0; dlen += fragoff; diff --git a/pc/devusb.c b/pc/devusb.c index c6a0d2dd39b93c5888e39963bf72d506cd82993b..8ccf1426d7e33be4d8fa64f88d05480744f4c57d 100644 --- a/pc/devusb.c +++ b/pc/devusb.c @@ -146,7 +146,6 @@ enum { /* TD.flags (software) */ CancelTD= 1<<0, - IsoLock= 1<<1, IsoClean= 1<<2, }; @@ -212,25 +211,27 @@ struct Endpt { volatile byte iso; byte debug; byte active; /* listed for examination by interrupts */ + int setin; + /* ISO related: */ byte * tdalloc; byte * bpalloc; int hz; - int remain; + int remain; /* for packet size calculations */ int samplesz; int sched; /* schedule index; -1 if undefined or aperiodic */ - int setin; int pollms; /* polling interval in msec */ - int psize; /* size of this packet */ - int curbytes; /* # of bytes in that block */ + int psize; /* (remaining) size of this packet */ + int off; /* offset into packet */ + int isolock; /* reader/writer interlock with interrupt */ + TD* td0; /* first td in array */ + TD* etd; /* pointer into circular list of TDs for isochronous ept */ + TD* xtd; /* next td to be cleaned */ + /* end ISO stuff */ QH* epq; /* queue of TDs for this endpoint */ - TD* td0; /* pointer to list of TDs for isochronous ept */ - volatile TD* etd; /* reader/writer pointer into list of TDs for isochronous ept */ - volatile TD* xtd; /* next td to be cleaned */ QLock rlock; Rendez rr; Queue* rq; QLock wlock; - int isolock; Rendez wr; Queue* wq; @@ -803,7 +804,7 @@ schedendpt(Endpt *e) if (e->isopen){ return -1; } - e->curbytes = 0; + e->off = 0; e->sched = usbsched(ub, e->pollms, e->maxpkt); if(e->sched < 0){ qunlock(&usbstate); @@ -818,9 +819,8 @@ schedendpt(Endpt *e) bp = (byte *)(((ulong)e->bpalloc + 0xf) & ~0xf); frnum = (IN(Frnum) + 1) & 0x3ff; frnum = (frnum & ~(e->pollms - 1)) + e->sched; - e->isolock = 1; - e->xtd = &e->td0[frnum]; /* Next td to finish */ - e->etd = nil; /* Writer is idle */ + e->xtd = &e->td0[(frnum+8)&0x3ff]; /* Next td to finish */ + e->etd = nil; e->remain = 0; td = e->td0; for(i = e->sched; i < NFRAME; i += e->pollms){ @@ -851,7 +851,6 @@ schedendpt(Endpt *e) td->link = ub->frames[ix]; ub->frames[ix] = PADDR(td); } - e->isolock = 0; return 0; } @@ -1067,41 +1066,50 @@ static void cleaniso(Endpt *e, int frnum) { TD *td; - int tok, id, size; + int id, n; - if (e->xtd->status & Active){ - td = e->td0 + ((frnum -1)&0x3ff); - if (td->status & Active) - return; - iprint("%ld active -> %ld", e->xtd - e->td0, td - e->td0); - e->xtd = td; - } - tok = (e->mode == OREAD)?TokIN:TokOUT; + td = e->xtd; + if (td->status & Active) + return; id = (e->x<<7)|(e->dev->x&0x7F); - for(td = e->xtd; (td->status & Active) == 0; td = td->next){ - if (td->flags & IsoLock) - iprint("usbinterrupt: locked?\n"); - if (e->isolock == 0 && td == e->etd){ - /* if isolock is set, don't touch e->etd */ - if (e->xtd == e->etd) - wakeup(&e->wr); /* writer had to wait */ - else - e->etd = nil; /* writer was overtaken */ - } + do{ if (td->status & AnyError) iprint("usbisoerror 0x%lux\n", td->status); - size = (e->hz + e->remain)*e->pollms/1000; - e->remain = (e->hz + e->remain)*e->pollms%1000; - size *= e->samplesz; - if ((td->flags & IsoClean) == 0){ + if (e->mode == OREAD){ + td->dev = ((e->maxpkt -1)<<21) | ((id&0x7FF)<<8) | TokIN; + }else{ + n = (e->hz + e->remain)*e->pollms/1000; + e->remain = (e->hz + e->remain)*e->pollms%1000; + n *= e->samplesz; + td->dev = ((n -1)<<21) | ((id&0x7FF)<<8) | TokOUT; + } + td = td->next; + if (e->xtd == td){ + iprint("@"); + break; + } + } while ((td->status & Active) == 0); + e->xtd = td; + if (e->isolock){ + wakeup(&e->wr); + return; + } + for (n = 2; n < 6; n++){ + td = e->td0 + ((frnum + n)&0x3ff); + if (td->status & Active) + continue; + + if (td == e->etd) { + memset((byte*)td->bp+e->off, 0, e->maxpkt-e->off); + if (e->off == 0) + td->flags |= IsoClean; + e->etd = nil; + }else if ((td->flags & IsoClean) == 0){ memset((byte*)td->bp, 0, e->maxpkt); td->flags |= IsoClean; } - td->dev = ((size-1)<<21) | ((id&0x7FF)<<8) | tok; td->status = ErrLimit3 | Active | IsoSelect | IOC; } - e->xtd = td; - if (e->etd) wakeup(&e->wr); } static void @@ -1597,33 +1605,12 @@ eptinput(void *arg) } static int -isorready(void *arg) +isoready(void *arg) { - int frnum; - Ctlr *ub; Endpt *e; e = arg; - e->isolock = 1; - ub = &ubus; - frnum = IN(Frnum) & 0x3ff; - if (e->etd == nil){ - /* reader was idle, find a place to start */ - e->etd = e->td0 + (frnum & 0x3ff); - } - if (e->etd->status & Active){ - /* not yet ready */ - e->isolock = 0; - return 0; - } - /* leave locked if succesful */ - e->psize = (e->etd->status + 1) & 0x7FF; - e->curbytes = 0; - e->nbytes += e->psize; - e->nblocks++; - if (e->psize > e->maxpkt) - panic("packet size > maximum"); - return 1; + return e->etd == nil || (e->etd->status & Active) == 0; } static long @@ -1631,8 +1618,9 @@ readusb(Endpt *e, void *a, long n) { Block *b; uchar *p, *q; - long l, i, id; + int l, i, frnum; TD *td; + Ctlr *ub; XPRINT("qlock(%p)\n", &e->rlock); qlock(&e->rlock); @@ -1644,43 +1632,47 @@ readusb(Endpt *e, void *a, long n) } p = a; if (e->iso){ + if(waserror()){ + e->isolock = 0; + nexterror(); + } + e->isolock = 1; do { - if (e->psize == 0){ - while(isorready(e) == 0){ - XPRINT("readusb: sleep %lux\n", &e->wr); - sleep(&e->wr, isorready, e); - XPRINT("readusb: awake\n"); - } + while (isoready(e) == 0){ + XPRINT("readusb: sleep %lux\n", &e->wr); + sleep(&e->wr, isoready, e); + XPRINT("readusb: awake\n"); } - td = e->etd; - e->isolock = 0; - - if (e->psize > 0){ - q = (byte*)td->bp + e->curbytes; + if ((td = e->etd) == nil){ + ub = &ubus; + frnum = (IN(Frnum) + 8) & 0x3ff; + e->etd = e->td0 +frnum; + }else{ + q = (uchar*)td->bp + e->off; if((i = n) >= e->psize) i = e->psize; memmove(p, q, i); p += i; n -= i; - e->curbytes += i; + e->off += i; e->psize -= i; - if (e->psize > 0){ - /* Read done, return */ + if (e->psize){ if (n != 0) panic("usb iso: can't happen"); break; } + td->status = ErrLimit3 | Active | IsoSelect | IOC; + e->etd = td->next; } - e->isolock = 1; - /* Finished a packet */ - id = (e->x<<7)|(e->dev->x&0x7F); - td->dev = ((e->maxpkt-1)<<21) | ((id&0x7FF)<<8) | TokIN; - td->status = ErrLimit3 | Active | IsoSelect | IOC; - if (e->xtd == td) - e->xtd = td->next; - /* Get next buffer, wait for it to become ready */ - e->etd = td->next; - } while (n > 0); + e->off = 0; + e->psize = (e->etd->status + 1) & 0x7ff; + if (e->psize > e->maxpkt) + panic("packet size > maximum"); + e->nbytes += e->psize; + e->nblocks++; + } while(n > 0); + e->isolock = 0; + poperror(); }else{ do { if(e->eof) { @@ -1801,40 +1793,14 @@ qisempty(void *arg) return ((QH*)arg)->entries & Terminate; } -static int -isowready(void *arg) -{ - int frnum; - Ctlr *ub; - Endpt *e; - - e = arg; - e->isolock = 1; - ub = &ubus; - frnum = IN(Frnum) & 0x3ff; - if (e->etd == nil){ - /* writer was idle, find a place to start */ - e->etd = e->td0 + ((frnum + 4) & 0x3ff); - e->curbytes = 0; - e->psize = ((e->etd->dev >> 21) & 0x7ff) + 1; - if (e->psize > e->maxpkt) - panic("packet size > maximum"); - } - if (e->etd != e->xtd && e->etd->next != e->xtd){ - /* leave locked if succesful */ - return 1; - } - e->isolock = 0; - return 0; -} - static long writeusb(Endpt *e, void *a, long n, int tok) { - int i; + int i, frnum; Block *b; uchar *p, *q; QH *qh; + Ctlr *ub; TD *td; p = a; @@ -1848,41 +1814,45 @@ writeusb(Endpt *e, void *a, long n, int tok) if (e->iso){ if(waserror()){ e->isolock = 0; - if (td = e->etd) - td->flags &= ~IsoLock; nexterror(); } + e->isolock = 1; do { - while (isowready(e) == 0){ - XPRINT("writeusb: sleep %lux\n", &e->wr); - sleep(&e->wr, isowready, e); - XPRINT("writeusb: awake\n"); + while (isoready(e) == 0){ + iprint("i"); + sleep(&e->wr, isoready, e); } - td = e->etd; - e->isolock = 0; - td->flags |= IsoLock; - td->flags &= ~IsoClean; - q = (uchar*)td->bp + e->curbytes; - if((i = n) >= e->psize - e->curbytes) - i = e->psize - e->curbytes; - memmove(q, p, i); - p += i; - n -= i; - e->curbytes += i; - td->flags &= ~IsoLock; - if (e->curbytes < e->psize){ - if (n != 0) - panic("usb iso: can't happen"); - break; + if ((td = e->etd) == nil){ + iprint("0"); + ub = &ubus; + frnum = (IN(Frnum) + 8) & 0x3ff; + e->etd = e->td0 +frnum; + }else{ + td->flags &= ~IsoClean; + q = (uchar*)td->bp + e->off; + if((i = n) >= e->psize) + i = e->psize; + memmove(q, p, i); + p += i; + n -= i; + e->off += i; + e->psize -= i; + if (e->psize){ + if (n != 0) + panic("usb iso: can't happen"); + break; + } + td->status = ErrLimit3 | Active | IsoSelect | IOC; + e->etd = td->next; } - e->etd = td->next; - e->curbytes = 0; - e->psize = ((e->etd->dev >> 21) & 0x7ff) + 1; + e->off = 0; + e->psize = ((e->etd->dev >> 21) + 1) & 0x7ff; if (e->psize > e->maxpkt) panic("packet size > maximum"); e->nbytes += e->psize; e->nblocks++; } while(n > 0); + e->isolock = 0; poperror(); }else{ do { diff --git a/port/devtls.c b/port/devtls.c index d48e371c879efd581d0cec4bb36fb7e6b259b885..cb84b2832d061133e32f0288cf130b23b01a2ffa 100644 --- a/port/devtls.c +++ b/port/devtls.c @@ -11,21 +11,21 @@ #include typedef struct OneWay OneWay; -typedef struct Secret Secret; +typedef struct Secret Secret; typedef struct TlsRec TlsRec; typedef struct TlsErrs TlsErrs; enum { Statlen= 1024, /* max. length of status or stats message */ /* buffer limits */ - MaxRecLen = 1<<14, /* max payload length of a record layer message */ + MaxRecLen = 1<<14, /* max payload length of a record layer message */ MaxCipherRecLen = MaxRecLen + 2048, - RecHdrLen = 5, - MaxMacLen = SHA1dlen, + RecHdrLen = 5, + MaxMacLen = SHA1dlen, /* protocol versions we can accept */ - TLSVersion = 0x0301, - SSL3Version = 0x0300, + TLSVersion = 0x0301, + SSL3Version = 0x0300, ProtocolVersion = 0x0301, /* maximum version we speak */ MinProtoVersion = 0x0300, /* limits on version we accept */ MaxProtoVersion = 0x03ff, @@ -46,30 +46,30 @@ enum { RApplication, /* alerts */ - ECloseNotify = 0, - EUnexpectedMessage = 10, - EBadRecordMac = 20, - EDecryptionFailed = 21, - ERecordOverflow = 22, - EDecompressionFailure = 30, - EHandshakeFailure = 40, - ENoCertificate = 41, - EBadCertificate = 42, - EUnsupportedCertificate = 43, - ECertificateRevoked = 44, - ECertificateExpired = 45, - ECertificateUnknown = 46, - EIllegalParameter = 47, - EUnknownCa = 48, - EAccessDenied = 49, - EDecodeError = 50, - EDecryptError = 51, - EExportRestriction = 60, - EProtocolVersion = 70, - EInsufficientSecurity = 71, - EInternalError = 80, - EUserCanceled = 90, - ENoRenegotiation = 100, + ECloseNotify = 0, + EUnexpectedMessage = 10, + EBadRecordMac = 20, + EDecryptionFailed = 21, + ERecordOverflow = 22, + EDecompressionFailure = 30, + EHandshakeFailure = 40, + ENoCertificate = 41, + EBadCertificate = 42, + EUnsupportedCertificate = 43, + ECertificateRevoked = 44, + ECertificateExpired = 45, + ECertificateUnknown = 46, + EIllegalParameter = 47, + EUnknownCa = 48, + EAccessDenied = 49, + EDecodeError = 50, + EDecryptError = 51, + EExportRestriction = 60, + EProtocolVersion = 70, + EInsufficientSecurity = 71, + EInternalError = 80, + EUserCanceled = 90, + ENoRenegotiation = 100, EMAX = 256 }; @@ -85,7 +85,7 @@ struct Secret int block; /* encryption block len, 0 if none */ int maclen; void *enckey; - uchar mackey[MaxMacLen]; + uchar mackey[MaxMacLen]; }; struct OneWay @@ -99,16 +99,16 @@ struct OneWay struct TlsRec { - Chan *c; /* io channel */ - int ref; /* serialized by tdlock for atomic destroy */ - int version; /* version of the protocol we are speaking */ - char verset; /* version has been set */ - char opened; /* opened command every issued? */ - char err[ERRLEN]; /* error message to return to handshake requests */ - vlong handin; /* bytes communicated by the record layer */ - vlong handout; - vlong datain; - vlong dataout; + Chan *c; /* io channel */ + int ref; /* serialized by tdlock for atomic destroy */ + int version; /* version of the protocol we are speaking */ + char verset; /* version has been set */ + char opened; /* opened command every issued? */ + char err[ERRMAX]; /* error message to return to handshake requests */ + vlong handin; /* bytes communicated by the record layer */ + vlong handout; + vlong datain; + vlong dataout; Lock statelk; int state; @@ -122,7 +122,7 @@ struct TlsRec Block *unprocessed; /* data read from c but not parsed into records */ /* handshake queue */ - Lock hqlock; /* protects hqref, alloc & free of handq, hprocessed */ + Lock hqlock; /* protects hqref, alloc & free of handq, hprocessed */ int hqref; Queue *handq; /* queue of handshake messages */ Block *hprocessed; /* remainder of last block read from handq */ @@ -132,7 +132,7 @@ struct TlsRec OneWay out; /* protections */ - char user[NAMELEN]; + char *user; int perm; }; @@ -145,54 +145,30 @@ struct TlsErrs{ }; static TlsErrs tlserrs[] = { - {ECloseNotify, ECloseNotify, ECloseNotify, - 0, "close notify"}, - {EUnexpectedMessage, EUnexpectedMessage, EUnexpectedMessage, - 1, "unexpected message"}, - {EBadRecordMac, EBadRecordMac, EBadRecordMac, - 1, "bad record mac"}, - {EDecryptionFailed, EIllegalParameter, EDecryptionFailed, - 1, "decryption failed"}, - {ERecordOverflow, EIllegalParameter, ERecordOverflow, - 1, "record too long"}, - {EDecompressionFailure, EDecompressionFailure, EDecompressionFailure, - 1, "decompression failed"}, - {EHandshakeFailure, EHandshakeFailure, EHandshakeFailure, - 1, "could not negotiate acceptable security paramters"}, - {ENoCertificate, ENoCertificate, ECertificateUnknown, - 1, "no appropriate certificate available"}, - {EBadCertificate, EBadCertificate, EBadCertificate, - 1, "corrupted or invalid certificate"}, - {EUnsupportedCertificate, EUnsupportedCertificate, EUnsupportedCertificate, - 1, "unsupported certificate type"}, - {ECertificateRevoked, ECertificateRevoked, ECertificateRevoked, - 1, "revoked certificate"}, - {ECertificateExpired, ECertificateExpired, ECertificateExpired, - 1, "expired certificate"}, - {ECertificateUnknown, ECertificateUnknown, ECertificateUnknown, - 1, "unacceptable certificate"}, - {EIllegalParameter, EIllegalParameter, EIllegalParameter, - 1, "illegal parameter"}, - {EUnknownCa, EHandshakeFailure, EUnknownCa, - 1, "unknown certificate authority"}, - {EAccessDenied, EHandshakeFailure, EAccessDenied, - 1, "access denied"}, - {EDecodeError, EIllegalParameter, EDecodeError, - 1, "error decoding message"}, - {EDecryptError, EIllegalParameter, EDecryptError, - 1, "error decrypting message"}, - {EExportRestriction, EHandshakeFailure, EExportRestriction, - 1, "export restriction violated"}, - {EProtocolVersion, EIllegalParameter, EProtocolVersion, - 1, "protocol version not supported"}, - {EInsufficientSecurity, EHandshakeFailure, EInsufficientSecurity, - 1, "stronger security routines required"}, - {EInternalError, EHandshakeFailure, EInternalError, - 1, "internal error"}, - {EUserCanceled, ECloseNotify, EUserCanceled, - 0, "handshake canceled by user"}, - {ENoRenegotiation, EUnexpectedMessage, ENoRenegotiation, - 0, "no renegotiation"}, + {ECloseNotify, ECloseNotify, ECloseNotify, 0, "close notify"}, + {EUnexpectedMessage, EUnexpectedMessage, EUnexpectedMessage, 1, "unexpected message"}, + {EBadRecordMac, EBadRecordMac, EBadRecordMac, 1, "bad record mac"}, + {EDecryptionFailed, EIllegalParameter, EDecryptionFailed, 1, "decryption failed"}, + {ERecordOverflow, EIllegalParameter, ERecordOverflow, 1, "record too long"}, + {EDecompressionFailure, EDecompressionFailure, EDecompressionFailure, 1, "decompression failed"}, + {EHandshakeFailure, EHandshakeFailure, EHandshakeFailure, 1, "could not negotiate acceptable security paramters"}, + {ENoCertificate, ENoCertificate, ECertificateUnknown, 1, "no appropriate certificate available"}, + {EBadCertificate, EBadCertificate, EBadCertificate, 1, "corrupted or invalid certificate"}, + {EUnsupportedCertificate, EUnsupportedCertificate, EUnsupportedCertificate, 1, "unsupported certificate type"}, + {ECertificateRevoked, ECertificateRevoked, ECertificateRevoked, 1, "revoked certificate"}, + {ECertificateExpired, ECertificateExpired, ECertificateExpired, 1, "expired certificate"}, + {ECertificateUnknown, ECertificateUnknown, ECertificateUnknown, 1, "unacceptable certificate"}, + {EIllegalParameter, EIllegalParameter, EIllegalParameter, 1, "illegal parameter"}, + {EUnknownCa, EHandshakeFailure, EUnknownCa, 1, "unknown certificate authority"}, + {EAccessDenied, EHandshakeFailure, EAccessDenied, 1, "access denied"}, + {EDecodeError, EIllegalParameter, EDecodeError, 1, "error decoding message"}, + {EDecryptError, EIllegalParameter, EDecryptError, 1, "error decrypting message"}, + {EExportRestriction, EHandshakeFailure, EExportRestriction, 1, "export restriction violated"}, + {EProtocolVersion, EIllegalParameter, EProtocolVersion, 1, "protocol version not supported"}, + {EInsufficientSecurity, EHandshakeFailure, EInsufficientSecurity, 1, "stronger security routines required"}, + {EInternalError, EHandshakeFailure, EInternalError, 1, "internal error"}, + {EUserCanceled, ECloseNotify, EUserCanceled, 0, "handshake canceled by user"}, + {ENoRenegotiation, EUnexpectedMessage, ENoRenegotiation, 0, "no renegotiation"}, }; enum @@ -205,6 +181,7 @@ static Lock tdlock; static int tdhiwat; static int maxtlsdevs = 128; static TlsRec **tlsdevs; +static char **trnames; static char *encalgs; static char *hashalgs; @@ -262,46 +239,49 @@ static char *tlsstate(int s); #pragma varargck argpos rcvError 3 static char *tlsnames[] = { -[Qclonus] "clone", +[Qclonus] "clone", [Qencalgs] "encalgs", [Qhashalgs] "hashalgs", [Qdata] "data", [Qctl] "ctl", [Qhand] "hand", -[Qstatus] "status", -[Qstats] "stats", +[Qstatus] "status", +[Qstats] "stats", }; static int convdir[] = { Qctl, Qdata, Qhand, Qstatus, Qstats }; static int -tlsgen(Chan *c, Dirtab *d, int nd, int s, Dir *dp) +tlsgen(Chan *c, char*, Dirtab *, int, int s, Dir *dp) { Qid q; TlsRec *tr; - char name[16], *nm; + char *name, *nm; int perm, t; - USED(nd); - USED(d); q.vers = 0; + q.type = QTFILE; + t = TYPE(c->qid); switch(t) { case Qtopdir: if(s == DEVDOTDOT){ - q.path = QID(0, Qtopdir)|CHDIR; - devdir(c, q, "#D", 0, eve, CHDIR|0555, dp); + q.path = QID(0, Qtopdir); + q.type = QTDIR; + devdir(c, q, "#a", 0, eve, 0555, dp); return 1; } if(s > 0) return -1; - q.path = QID(0, Qprotodir)|CHDIR; - devdir(c, q, "tls", 0, eve, CHDIR|0555, dp); + q.path = QID(0, Qprotodir); + q.type = QTDIR; + devdir(c, q, "tls", 0, eve, 0555, dp); return 1; case Qprotodir: if(s == DEVDOTDOT){ - q.path = QID(0, Qtopdir)|CHDIR; - devdir(c, q, ".", 0, eve, CHDIR|0555, dp); + q.path = QID(0, Qtopdir); + q.type = QTDIR; + devdir(c, q, ".", 0, eve, 0555, dp); return 1; } if(s < 3){ @@ -327,21 +307,26 @@ tlsgen(Chan *c, Dirtab *d, int nd, int s, Dir *dp) s -= 3; if(s >= tdhiwat) return -1; - sprint(name, "%d", s); - q.path = QID(s, Qconvdir)|CHDIR; + q.path = QID(s, Qconvdir); + q.type = QTDIR; lock(&tdlock); tr = tlsdevs[s]; if(tr != nil) nm = tr->user; else nm = eve; - devdir(c, q, name, 0, nm, CHDIR|0555, dp); + if ((name = trnames[s]) == nil) { + name = trnames[s] = smalloc(16); + sprint(name, "%d", s); + } + devdir(c, q, name, 0, nm, 0555, dp); unlock(&tdlock); return 1; case Qconvdir: if(s == DEVDOTDOT){ - q.path = QID(0, Qprotodir)|CHDIR; - devdir(c, q, "tls", 0, eve, CHDIR|0555, dp); + q.path = QID(0, Qprotodir); + q.type = QTDIR; + devdir(c, q, "tls", 0, eve, 0555, dp); return 1; } if(s < 0 || s >= nelem(convdir)) @@ -395,21 +380,22 @@ tlsattach(char *spec) Chan *c; c = devattach('a', spec); - c->qid.path = QID(0, Qtopdir)|CHDIR; + c->qid.path = QID(0, Qtopdir); + c->qid.type = QTDIR; c->qid.vers = 0; return c; } -static int -tlswalk(Chan *c, char *name) +static Walkqid* +tlswalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, 0, 0, tlsgen); + return devwalk(c, nc, name, nname, nil, 0, tlsgen); } -static void -tlsstat(Chan *c, char *db) +static int +tlsstat(Chan *c, uchar *db, int n) { - devstat(c, db, 0, 0, tlsgen); + return devstat(c, db, n, nil, 0, tlsgen); } static Chan* @@ -498,18 +484,18 @@ tlsopen(Chan *c, int omode) return c; } -static void -tlswstat(Chan *c, char *dp) +static int +tlswstat(Chan *c, uchar *dp, int n) { - Dir d; + Dir *d; TlsRec *tr; - - convM2D(dp, &d); + int rv; if(waserror()){ unlock(&tdlock); nexterror(); } + lock(&tdlock); tr = tlsdevs[CONV(c->qid)]; if(tr == nil) @@ -517,9 +503,17 @@ tlswstat(Chan *c, char *dp) if(strcmp(tr->user, up->user) != 0) error(Eperm); - memmove(tr->user, d.uid, NAMELEN); - tr->perm = d.mode; + d = smalloc(n + sizeof *d); + rv = convM2D(dp, n, &d[0], (char*) &d[1]); + if (rv > 0) { + kstrdup(&tr->user, d->uid); + tr->perm = d->mode; + } + free(d); + poperror(); unlock(&tdlock); + + return rv; } static void @@ -582,6 +576,7 @@ tlsclose(Chan *c) freeSec(tr->in.new); freeSec(tr->out.sec); freeSec(tr->out.new); + free(tr->user); free(tr); break; } @@ -731,7 +726,7 @@ tlsrecread(TlsRec *tr) nconsumed = 0; if(waserror()){ - if(strcmp(up->error, Eintr) == 0 && !waserror()){ + if(strcmp(up->errstr, Eintr) == 0 && !waserror()){ regurgitate(tr, header, nconsumed); poperror(); }else @@ -909,7 +904,7 @@ rcvAlert(TlsRec *tr, int err) static void rcvError(TlsRec *tr, int err, char *fmt, ...) { - char msg[ERRLEN]; + char msg[ERRMAX]; va_list arg; va_start(arg, fmt); @@ -986,10 +981,12 @@ checkstate(TlsRec *tr, int ishand, int ok) static Block* tlsbread(Chan *c, long n, ulong offset) { - TlsRec *volatile tr; + int ty; Block *b; + TlsRec *volatile tr; - switch(TYPE(c->qid)) { + ty = TYPE(c->qid); + switch(ty) { default: return devbread(c, n, offset); case Qhand: @@ -1006,7 +1003,7 @@ tlsbread(Chan *c, long n, ulong offset) nexterror(); } qlock(&tr->in.io); - if(TYPE(c->qid) == Qdata){ + if(ty == Qdata){ checkstate(tr, 0, SOpen); while(tr->processed == nil) tlsrecread(tr); @@ -1038,10 +1035,9 @@ tlsbread(Chan *c, long n, ulong offset) if(tr->hprocessed == nil){ b = qbread(tr->handq, MaxRecLen + 1); if(*b->rp++ == RAlert){ - strncpy(up->error, (char*)b->rp, ERRLEN - 1); - up->error[ERRLEN - 1] = '\0'; + strecpy(up->errstr, up->errstr+ERRMAX, (char*)b->rp); freeb(b); - error(up->error); + nexterror(); } tr->hprocessed = b; } @@ -1060,16 +1056,17 @@ tlsread(Chan *c, void *a, long n, vlong off) Block *volatile b; Block *nb; uchar *va; - int i; + int i, ty; char *buf, *s, *e; ulong offset = off; TlsRec * tr; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) return devdirread(c, a, n, 0, 0, tlsgen); tr = tlsdevs[CONV(c->qid)]; - switch(TYPE(c->qid)) { + ty = TYPE(c->qid); + switch(ty) { default: error(Ebadusefd); case Qstatus: @@ -1106,7 +1103,7 @@ tlsread(Chan *c, void *a, long n, vlong off) return n; case Qctl: buf = smalloc(Statlen); - snprint(buf, Statlen, "%lud", CONV(c->qid)); + snprint(buf, Statlen, "%llud", CONV(c->qid)); n = readstr(offset, a, n, buf); free(buf); return n; @@ -1235,7 +1232,7 @@ tlsrecwrite(TlsRec *tr, int type, Block *b) * if not, we're out of sync with the receiver and will not recover. */ if(waserror()){ - if(strcmp(up->error, "interrupted") != 0) + if(strcmp(up->errstr, "interrupted") != 0) tlsError(tr, "channel error"); nexterror(); } @@ -1249,8 +1246,9 @@ tlsrecwrite(TlsRec *tr, int type, Block *b) static long tlsbwrite(Chan *c, Block *b, ulong offset) { - TlsRec *tr; + int ty; ulong n; + TlsRec *tr; n = BLEN(b); @@ -1258,7 +1256,8 @@ tlsbwrite(Chan *c, Block *b, ulong offset) if(tr == nil) panic("tlsbread"); - switch(TYPE(c->qid)) { + ty = TYPE(c->qid); + switch(ty) { default: return devbwrite(c, b, offset); case Qhand: @@ -1398,7 +1397,7 @@ tlswrite(Chan *c, void *a, long n, vlong off) Secret *volatile tos, *volatile toc; Block *volatile b; Cmdbuf *volatile cb; - int m; + int m, ty; char *p, *e; uchar *volatile x; ulong offset = off; @@ -1407,7 +1406,8 @@ tlswrite(Chan *c, void *a, long n, vlong off) if(tr == nil) panic("tlswrite"); - switch(TYPE(c->qid)){ + ty = TYPE(c->qid); + switch(ty){ case Qdata: case Qhand: p = a; @@ -1572,7 +1572,7 @@ tlswrite(Chan *c, void *a, long n, vlong off) if(cb->nf != 1) error("usage: opened"); if(tr->in.sec == nil || tr->out.sec == nil) - error("cipher must be configure before enabling data messages"); + error("cipher must be configured before enabling data messages"); lock(&tr->statelk); if(tr->state != SHandshake && tr->state != SOpen){ unlock(&tr->statelk); @@ -1622,6 +1622,8 @@ tlsinit(void) if((tlsdevs = smalloc(sizeof(TlsRec*) * maxtlsdevs)) == 0) panic("tlsinit"); + if((trnames = smalloc((sizeof *trnames) * maxtlsdevs)) == 0) + panic("tlsinit"); n = 1; for(e = encrypttab; e->name != nil; e++) @@ -1659,7 +1661,6 @@ Dev tlsdevtab = { devreset, tlsinit, tlsattach, - devclone, tlswalk, tlsstat, tlsopen, @@ -1732,8 +1733,8 @@ tlsError(TlsRec *tr, char *msg) s = tr->state; tr->state = SError; if(s != SError){ - strncpy(tr->err, msg, ERRLEN - 1); - tr->err[ERRLEN - 1] = '\0'; + strncpy(tr->err, msg, ERRMAX - 1); + tr->err[ERRMAX - 1] = '\0'; } unlock(&tr->statelk); if(s != SError) @@ -1773,6 +1774,7 @@ static TlsRec* newtls(Chan *ch) { TlsRec **pp, **ep, **np; + char **nmp; int t, newmax; if(waserror()) { @@ -1798,6 +1800,11 @@ newtls(Chan *ch) tlsdevs = np; pp = &tlsdevs[maxtlsdevs]; memset(pp, 0, sizeof(TlsRec*)*(newmax - maxtlsdevs)); + + nmp = smalloc(sizeof *nmp * newmax); + memmove(nmp, trnames, sizeof *nmp * maxtlsdevs); + trnames = nmp; + maxtlsdevs = newmax; } *pp = mktlsrec(); @@ -1823,7 +1830,7 @@ mktlsrec(void) error(Enomem); tr->state = SClosed; tr->ref = 1; - strncpy(tr->user, up->user, sizeof(tr->user)); + kstrdup(&tr->user, up->user); tr->perm = 0660; return tr; }