From 0e12f635bfb37a4c9f65b33839f13d4e9d8fa22e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 14 Sep 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-09-14 --- boot/key.c | 4 ++-- ip/tcp.c | 38 ++++++++++++++++++++++++++++++-------- port/devssl.c | 6 ++---- port/qio.c | 48 +++++++++++++++++++++++++++++++++--------------- 4 files changed, 67 insertions(+), 29 deletions(-) diff --git a/boot/key.c b/boot/key.c index 7fd6f24c20d5f719e387444d8538dbfb34764d1e..cb96ceda14918812d2c5057f9208efef36f79115 100644 --- a/boot/key.c +++ b/boot/key.c @@ -207,12 +207,12 @@ finddosfile(int fd, char *file) sectsize = GETSHORT(b->sectsize); if(sectsize != 512) return -1; - rootoff = (1 + b->nfats*GETSHORT(b->fatsize)) * sectsize; + rootoff = (GETSHORT(b->nresrv) + b->nfats*GETSHORT(b->fatsize)) * sectsize; if(seek(fd, rootoff, 0) < 0) return -1; nroot = GETSHORT(b->rootsize); rootsects = (nroot*sizeof(Dosdir)+sectsize-1)/sectsize; - if(rootsects <= 0 || rootsects > 20) + if(rootsects <= 0 || rootsects > 64) return -1; /* diff --git a/ip/tcp.c b/ip/tcp.c index 62c2f4bcdb96dac806d8db5ea7f32d917151d6e0..cc66b90455756ae300ab92c180295889a160ed99 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -189,6 +189,7 @@ struct Tcpctl int kacounter; /* count down for keep alive */ uint sndsyntime; /* time syn sent */ ulong time; /* time Finwait2 or Syn_received was sent */ + int nochecksum; /* non-zero means don't send checksums */ Tcphdr protohdr; /* prototype header */ }; @@ -751,7 +752,7 @@ tcpflag(ushort flag) } Block * -htontcp(Tcp *tcph, Block *data, Tcphdr *ph) +htontcp(Tcp *tcph, Block *data, Tcphdr *ph, Tcpctl *tcb) { int dlen; Tcphdr *h; @@ -793,8 +794,12 @@ htontcp(Tcp *tcph, Block *data, Tcphdr *ph) h->tcpopt[1] = MSS_LENGTH; hnputs(h->tcpmss, tcph->mss); } - csum = ptclcsum(data, TCP_IPLEN, hdrlen+dlen+TCP_PHDRSIZE); - hnputs(h->tcpcksum, csum); + if(tcb != nil && tcb->nochecksum){ + h->tcpcksum[0] = h->tcpcksum[1] = 0; + } else { + csum = ptclcsum(data, TCP_IPLEN, hdrlen+dlen+TCP_PHDRSIZE); + hnputs(h->tcpcksum, csum); + } /* netlog(f, Logtcpmsg, "%d > %d s %l8.8ux a %8.8lux %s w %.4ux l %d\n", tcph->source, tcph->dest, @@ -931,7 +936,7 @@ sndrst(Proto *tcp, uchar *source, uchar *dest, ushort length, Tcp *seg) seg->wnd = 0; seg->urg = 0; seg->mss = 0; - hbp = htontcp(seg, nil, &ph); + hbp = htontcp(seg, nil, &ph, nil); if(hbp == nil) return; @@ -964,7 +969,7 @@ tcphangup(Conv *s) seg.mss = 0; tcb->last_ack = tcb->rcv.nxt; hnputs(ph.tcplen, TCP_HDRSIZE); - hbp = htontcp(&seg, nil, &tcb->protohdr); + hbp = htontcp(&seg, nil, &tcb->protohdr, tcb); ipoput(s->p->f, hbp, 0, s->ttl, s->tos); } localclose(s, nil); @@ -1231,7 +1236,8 @@ tcpiput(Proto *tcp, uchar*, Block *bp) h->Unused = 0; hnputs(h->tcplen, length-TCP_PKT); - if(ptclcsum(bp, TCP_IPLEN, length-TCP_IPLEN)) { + if((h->tcpcksum[0] || h->tcpcksum[0]) && + ptclcsum(bp, TCP_IPLEN, length-TCP_IPLEN)) { tpriv->stats[CsumErrs]++; tpriv->stats[InErrs]++; netlog(f, Logtcp, "bad tcp proto cksum\n"); @@ -1800,7 +1806,7 @@ tcpoutput(Conv *s) tcb->snd.nxt = tcb->snd.ptr; /* Build header, link data and compute cksum */ - hbp = htontcp(&seg, bp, &tcb->protohdr); + hbp = htontcp(&seg, bp, &tcb->protohdr, tcb); if(hbp == nil) { freeblist(bp); return; @@ -1875,7 +1881,7 @@ tcpsendka(Conv *s) } /* Build header, link data and compute cksum */ - hbp = htontcp(&seg, dbp, &tcb->protohdr); + hbp = htontcp(&seg, dbp, &tcb->protohdr, tcb); if(hbp == nil) { freeblist(dbp); return; @@ -1941,6 +1947,20 @@ tcpstartka(Conv *s, char **f, int n) return nil; } +/* + * turn checksums on/off + */ +char* +tcpsetchecksum(Conv *s, char **f, int) +{ + Tcpctl *tcb; + + tcb = (Tcpctl*)s->ptcl; + tcb->nochecksum = !atoi(f[1]); + + return nil; +} + void tcprxmit(Conv *s) { @@ -2230,6 +2250,8 @@ tcpctl(Conv* c, char** f, int n) return tcphangup(c); if(n >= 1 && strcmp(f[0], "keepalive") == 0) return tcpstartka(c, f, n); + if(n >= 1 && strcmp(f[0], "checksum") == 0) + return tcpsetchecksum(c, f, n); return "unknown control request"; } diff --git a/port/devssl.c b/port/devssl.c index b86283c0b4b220ed18d6212977dca83d11b64d18..05ee8bf982b1e3a512a3f330f146a3581ea81266 100644 --- a/port/devssl.c +++ b/port/devssl.c @@ -443,13 +443,13 @@ regurgitate(Dstate *s, uchar *p, int n) b = s->unprocessed; if(s->unprocessed == nil || b->rp - b->base < n) { b = allocb(n); - memmove(p, b->wp, n); + memmove(b->wp, p, n); b->wp += n; b->next = s->unprocessed; s->unprocessed = b; } else { b->rp -= n; - memmove(p, b->rp, n); + memmove(b->rp, p, n); } } @@ -701,8 +701,6 @@ sslbwrite(Chan *c, Block *b, ulong offset) qunlock(&s.s->out.q); if(bb.b != nil) freeb(bb.b); - if(nb != nil) - freeb(nb); nexterror(); } qlock(&s.s->out.q); diff --git a/port/qio.c b/port/qio.c index c2139341eff6c9a0f8ae570221ed444ee4385d96..c953e180ae0a08f1fc97e808978bb6e61f416ac6 100644 --- a/port/qio.c +++ b/port/qio.c @@ -902,18 +902,16 @@ qbwrite(Queue *q, Block *b) nexterror(); } - /* flow control */ - for(;;){ - ilock(q); - - if(q->state & Qclosed){ - iunlock(q); - error(q->err); - } + ilock(q); - if(q->len < q->limit) - break; + /* give up if the queue is closed */ + if(q->state & Qclosed){ + iunlock(q); + error(q->err); + } + /* if nonblocking, don't queue over the limit */ + if(q->len >= q->limit){ if(q->noblock){ iunlock(q); freeb(b); @@ -921,12 +919,9 @@ qbwrite(Queue *q, Block *b) poperror(); return n; } - - q->state |= Qflow; - iunlock(q); - sleep(&q->wr, qnotfull, q); } + /* queue the block */ if(q->bfirst) q->blast->next = b; else @@ -938,11 +933,11 @@ qbwrite(Queue *q, Block *b) QDEBUG checkb(b, "qbwrite"); b = nil; + /* make sure other end gets awakened */ if(q->state & Qstarve){ q->state &= ~Qstarve; dowakeup = 1; } - iunlock(q); if(dowakeup){ @@ -951,6 +946,29 @@ qbwrite(Queue *q, Block *b) wakeup(&q->rr); } + /* + * flow control, wait for queue to get below the limit + * before allowing the process to continue and queue + * more. We do this here so that postnote can only + * interrupt us after the data has been quued. This + * means that things like 9p flushes and ssl messages + * will not be disrupted by software interrupts. + * + * Note - this is moderately dangerous since a process + * that keeps getting interrupted and rewriting will + * queue infinite crud. + */ + for(;;){ + if(q->noblock || qnotfull(q)) + break; + + ilock(q); + q->state |= Qflow; + iunlock(q); + sleep(&q->wr, qnotfull, q); + } + USED(b); + qunlock(&q->wlock); poperror(); return n;