From 90b0301e162f4cb43e9e0f11319500e0ebaf361b Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 30 Oct 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-10-30 --- port/devarp.c | 10 +++--- port/devenv.c | 11 +++++++ port/devip.c | 10 ++---- port/qlock.c | 2 +- port/stil.c | 84 +++++++++++++++++++++++++++--------------------- port/tcpinput.c | 80 ++++++++------------------------------------- port/tcpoutput.c | 51 ++++++----------------------- ss/main.c | 2 +- 8 files changed, 92 insertions(+), 158 deletions(-) diff --git a/port/devarp.c b/port/devarp.c index b984303b490b4a98421df07fb853b0910fbd1a04..4face11c5e7b97669f7595297c97c4a38cc77bfc 100644 --- a/port/devarp.c +++ b/port/devarp.c @@ -282,7 +282,6 @@ arpoput(Queue *q, Block *bp) if(bp->type != M_DATA) { if(Servq == 0 && streamparse("arpd", bp)) { -print("setting arp channel\n"); Servq = RD(q); freeb(bp); } @@ -298,17 +297,20 @@ print("setting arp channel\n"); } eh = (Etherhdr *)bp->rptr; + if(nhgets(eh->type) != ET_IP) { + PUTNEXT(q, bp); + return; + } + iproute(eh->dst, ip); /* Send downstream to the ethernet */ if(arplookup(ip, eh->d)) { -print("arp hit %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); PUTNEXT(q, bp); return; } -print("arp miss %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); - /* Return the packet to the arp server for address resolution */ + /* Push the packet up to the arp server for address resolution */ memmove(eh->d, ip, sizeof(ip)); PUTNEXT(Servq, bp); } diff --git a/port/devenv.c b/port/devenv.c index d9322d89911dd77f873d9d1bedb11b33bb523517..afdbf8f94c97231b56d4dfdc7283c83ad1b5a2da 100644 --- a/port/devenv.c +++ b/port/devenv.c @@ -433,6 +433,17 @@ envdump(void) for(i = 0; i < EVHASH; i++){ j = 0; for(ev = evhash[i].next; ev; ev = ev->next){ + uchar *t, *s; + int h, n; + + s = (uchar*)ev->val; + n = ev->len; + h = 0; + for(t = s; t - s < n; t++) + h = (h << 1) ^ *t; + h &= EVHASH - 1; + if(h != i) + print("hash conflict: %d %d\n", i, h); if(j++ == 1000){ print("hash bucket %d circular\n", i); break; diff --git a/port/devip.c b/port/devip.c index e93b5c897b90d665eb195ed9c5d0a99cc8771c26..9b13560d11d7f356409c37add85cc9d46fb63d18 100644 --- a/port/devip.c +++ b/port/devip.c @@ -15,8 +15,7 @@ enum Nipsubdir = 4, /* Number of subdirectory entries per connection */ }; -int udpsum = 1; - +int udpsum = 1; Queue *Ipoutput; /* Control message stream for tcp/il */ Ipifc *ipifc; /* IP protocol interfaces for stip */ Ipconv *ipconv[Nrprotocol]; /* Connections for each protocol */ @@ -389,8 +388,7 @@ ipwrite(Chan *c, char *a, long n, ulong offset) qunlock(&ipalloc); } - else if(strcmp(field[0], "announce") == 0 || - strcmp(field[0], "reserve") == 0) { + else if(strcmp(field[0], "announce") == 0 || strcmp(field[0], "reserve") == 0) { if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) error(Edevbusy); @@ -682,11 +680,10 @@ iplisten(Chan *c, Ipconv *s, Ipconv *base) qunlock(&s->listenq); nexterror(); } -print("listener on %lux R 0x%lux\n", s, &s->listenr); + for(;;) { sleep(&s->listenr, iphavecon, s); poperror(); -print("listen awoke\n"); new = base; for(etab = &base[conf.ip]; new < etab; new++) { if(new->newcon) { @@ -704,7 +701,6 @@ print("listen awoke\n"); pushq(c->stream, new->stproto); new->ref--; qunlock(&s->listenq); -print("ip listener!\n"); return; } } diff --git a/port/qlock.c b/port/qlock.c index a94feeedc75e16d3bc618226747ee05864a2a451..2bb950492ae3021671dd499a641449158ae0c8b7 100644 --- a/port/qlock.c +++ b/port/qlock.c @@ -33,7 +33,7 @@ int canqlock(QLock *q) { lock(&q->use); - if(q->locked) { + if(q->locked){ unlock(&q->use); return 0; } diff --git a/port/stil.c b/port/stil.c index 5f47e933ab86ef86f5437138dc2020c8188d7ef4..059e43348642fb6e3d8e4083e6de78abedd36f10 100644 --- a/port/stil.c +++ b/port/stil.c @@ -28,10 +28,8 @@ ilopen(Queue *q, Stream *s) Ipconv *ipc; static int ilkproc; - /* Start il service processes */ if(!Ipoutput) { Ipoutput = WR(q); - /* This never goes away - we use this queue to send acks/rejects */ s->opens++; s->inuse++; } @@ -57,6 +55,13 @@ ilopen(Queue *q, Stream *s) void ilclose(Queue *q) { + Ipconv *s; + + s = (Ipconv *)(q->ptr); + qlock(s); + s->ref--; + qunlock(s); + s->readq = 0; } void @@ -74,7 +79,6 @@ iloput(Queue *q, Block *bp) switch(ipc->ilctl.state) { case Ilclosed: - case Ilsyncee: case Illistening: case Ilclosing: error(Ehungup); @@ -123,7 +127,6 @@ iloput(Queue *q, Block *bp) hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, dlen+IL_HDRSIZE)); ilackq(ic, bp); - PUTNEXT(q, bp); } @@ -135,14 +138,11 @@ ilackq(Ilcb *ic, Block *bp) /* Enqueue a copy on the unacked queue in case this one gets lost */ np = copyb(bp, blen(bp)); - if(ic->unacked) { + if(ic->unacked) ic->unackedtail->next = np; - ic->unackedtail = np; - } - else { + else ic->unacked = np; - ic->unackedtail = np; - } + ic->unackedtail = np; np->next = 0; } @@ -158,6 +158,7 @@ ilackto(Ilcb *ic, ulong ackto) break; bp = ic->unacked; ic->unacked = bp->next; + bp->next = 0; freeb(bp); } } @@ -172,7 +173,7 @@ void ilrcvmsg(Ipconv *ipc, Block *bp) { Ilhdr *ih; - int plen; + int plen, illen; Ipconv *s, *etab, *new; short sp, dp; Ipaddr dst; @@ -183,7 +184,11 @@ ilrcvmsg(Ipconv *ipc, Block *bp) if(plen < IL_EHSIZE+IL_HDRSIZE) goto drop; - if(ilcksum && ptcl_csum(bp, IL_EHSIZE, plen) != 0) { + illen = nhgets(ih->illen); + if(illen+IL_EHSIZE > plen) + goto drop; + + if(ilcksum && ptcl_csum(bp, IL_EHSIZE, illen) != 0) { print("il: cksum error\n"); goto drop; } @@ -192,28 +197,26 @@ ilrcvmsg(Ipconv *ipc, Block *bp) dp = nhgets(ih->ilsrc); dst = nhgetl(ih->src); -print("got packet from %d.%d.%d.%d %d %d\n", fmtaddr(dst), sp, dp); - etab = &ipc[conf.ip]; for(s = ipc; s < etab; s++) { if(s->psrc == sp && s->pdst == dp && s->dst == dst) { ilprocess(s, ih, bp); return; } - } + if(ih->iltype != Ilsync) + goto drop; + if(s->curlog > s->backlog) goto reset; + /* Look for a listener */ for(s = ipc; s < etab; s++) { if(s->ilctl.state == Illistening && s->pdst == 0 && s->dst == 0) { - /* Do the listener stuff */ new = ipincoming(ipc); if(new == 0) goto reset; - if(ih->iltype != Ilsync) - goto reset; new->newcon = 1; new->ipinterface = s->ipinterface; @@ -243,7 +246,8 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp) Block *nb; Ilcb *ic; Ilhdr *oh; - ulong id, ack, oid; + ulong id, ack, oid, dlen; + int sendack = 0; id = nhgetl(h->ilid); ack = nhgetl(h->ilack); @@ -264,8 +268,8 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp) break; case Ilsyncer: if(h->iltype == Ilsync && ic->start == ack) { - ic->recvd = id; - ilsendctl(s, 0, Ilack, 0); + ic->recvd = id+1; + sendack = 1; ic->state = Ilestablished; } break; @@ -288,6 +292,7 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp) freeb(bp); break; case Ildataquery: + sendack = 1; case Ildata: ilackto(&s->ilctl, ack); switch(s->ilctl.state) { @@ -301,7 +306,8 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp) iloutoforder(s, h, bp); else { s->ilctl.recvd++; - bp->rptr += IL_EHSIZE+IL_HDRSIZE; + dlen = nhgets(h->illen)-IL_HDRSIZE; + bp = btrim(bp, IL_EHSIZE+IL_HDRSIZE, dlen); PUTNEXT(s->readq, bp); } } @@ -319,7 +325,7 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp) } /* Process out of order packets */ - if(ic->state == Ilestablished) { + if(ic->state == Ilestablished && s->readq) { while(ic->outoforder) { bp = ic->outoforder; oh = (Ilhdr*)bp->rptr; @@ -335,11 +341,18 @@ print("recvd = %d outoforder = %d\n", ic->recvd, oid); print("outoforder %d\n", oid); ic->recvd++; ic->outoforder = bp->next; - bp->rptr += IL_EHSIZE+IL_HDRSIZE; + bp->next = 0; + dlen = nhgets(oh->illen)-IL_HDRSIZE; + bp = btrim(bp, IL_EHSIZE+IL_HDRSIZE, dlen); PUTNEXT(s->readq, bp); } } } + + if(sendack) + ilsendctl(s, 0, Ilack, 1); + + print("revd = %d sent = %d\n", ic->recvd, ic->sent); } @@ -352,23 +365,22 @@ iloutoforder(Ipconv *s, Ilhdr *h, Block *bp) uchar *lid; ic = &s->ilctl; - if(ic->outoforder == 0) { ic->outoforder = bp; bp->next = 0; - return; } - - id = nhgetl(h->id); - l = &ic->outoforder; - for(f = *l; f; f = f->next) { - lid = ((Ilhdr*)(bp->rptr))->ilid; - if(id < nhgetl(lid)) - break; - l = &f->next; + else { + id = nhgetl(h->id); + l = &ic->outoforder; + for(f = *l; f; f = f->next) { + lid = ((Ilhdr*)(bp->rptr))->ilid; + if(id > nhgetl(lid)) + break; + l = &f->next; + } + bp->next = *l; + *l = bp; } - bp->next = *l; - *l = bp; } void diff --git a/port/tcpinput.c b/port/tcpinput.c index 99143d0a132215eaea5647ce81e3b2f04585628c..b2ecf9a63d47c1ae1964cfa5f2a0bc7db74b4a04 100644 --- a/port/tcpinput.c +++ b/port/tcpinput.c @@ -39,7 +39,6 @@ tcp_input(Ipconv *ipc, Block *bp) Tcphdr *h; Tcp seg; int hdrlen; - Block *oobbp; Ipaddr source, dest; char tos; ushort length; @@ -293,22 +292,9 @@ tcp_input(Ipconv *ipc, Block *bp) } if ((seg.flags&URG) && seg.up) { - DPRINT("tcpin: oob: up = %u seq = %u rcv.up = %u\n", - seg.up, seg.seq, tcb->rcv.up); if (seq_gt(seg.up + seg.seq, tcb->rcv.up)) { tcb->rcv.up = seg.up + seg.seq; - tcb->oobflags &= ~(TCPOOB_HAVEDATA|TCPOOB_HADDATA); - extract_oob(&bp, &oobbp, &seg); - if (oobbp) { - DPRINT("tcpin: oob delivered\n"); - appendb(&tcb->rcvoobq, oobbp); - tcb->rcvoobcnt += blen(oobbp); - tcb->oobmark = tcb->rcvcnt; - tcb->oobflags |= TCPOOB_HAVEDATA; -#ifdef NOTIFY - urg_signal(s); -#endif - } + copyupb(&bp, 0, seg.up); } } else if (seq_gt(tcb->rcv.nxt, tcb->rcv.up)) @@ -386,7 +372,7 @@ tcp_input(Ipconv *ipc, Block *bp) goto gotone; } break; -gotone:; + gotone:; } output: tcp_output(s); @@ -490,9 +476,10 @@ void update(Ipconv *s, Tcp *seg) { ushort acked; - ushort oobacked; ushort expand; Tcpctl *tcb = &s->tcpctl; + int rtt; + int abserr; if(seq_gt(seg->ack, tcb->snd.nxt)) { tcb->flags |= FORCE; @@ -512,7 +499,6 @@ update(Ipconv *s, Tcp *seg) return; acked = seg->ack - tcb->snd.una; - if(tcb->cwind < tcb->snd.wnd) { if(tcb->cwind < tcb->ssthresh) expand = MIN(acked,tcb->mss); @@ -521,25 +507,19 @@ update(Ipconv *s, Tcp *seg) if(tcb->cwind + expand < tcb->cwind) expand = 65535 - tcb->cwind; - if(tcb->cwind + expand > tcb->snd.wnd) expand = tcb->snd.wnd - tcb->cwind; - if(expand != 0) tcb->cwind += expand; - } /* Round trip time estimation */ if(run_timer(&tcb->rtt_timer) && seq_ge(seg->ack, tcb->rttseq)) { stop_timer(&tcb->rtt_timer); if(!(tcb->flags & RETRAN)) { - int rtt; /* measured round trip time */ - int abserr; /* abs(rtt - srtt) */ rtt = tcb->rtt_timer.start - tcb->rtt_timer.count; rtt *= MSPTICK; - if(rtt > tcb->srtt && (tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED)) tcb->srtt = rtt; @@ -556,28 +536,16 @@ update(Ipconv *s, Tcp *seg) } /* If we're waiting for an ack of our SYN, note it and adjust count */ - if(!(tcb->flags & SYNACK)){ + if((tcb->flags & SYNACK) == 0){ tcb->flags |= SYNACK; acked--; tcb->sndcnt--; } - /* Acking some oob data if relevant */ - if(tcb->sndoobq && seq_ge(tcb->snd.up,tcb->snd.una) && - seq_gt(seg->ack, tcb->snd.up)) { - oobacked = seg->ack - tcb->snd.up; - acked -= oobacked; - copyupb(&tcb->sndoobq, 0, oobacked); - tcb->sndoobcnt -= oobacked; - DPRINT("update: oobacked = %d\n", oobacked); - } - copyupb(&tcb->sndq, 0, acked); - /* This will include the FIN if there is one */ tcb->sndcnt -= acked; tcb->snd.una = seg->ack; - /* If ack includes some out-of-band data then update urgent pointer */ if (seq_gt(seg->ack, tcb->snd.up)) tcb->snd.up = seg->ack; @@ -588,9 +556,6 @@ update(Ipconv *s, Tcp *seg) if(tcb->snd.una != tcb->snd.nxt) start_timer(&tcb->timer); - /* If retransmissions have been occurring, make sure the - * send pointer doesn't repeat ancient history - */ if(seq_lt(tcb->snd.ptr, tcb->snd.una)) tcb->snd.ptr = tcb->snd.una; @@ -605,8 +570,7 @@ update(Ipconv *s, Tcp *seg) int in_window(Tcpctl *tcb, int seq) { - return seq_within(seq, tcb->rcv.nxt, - (int)(tcb->rcv.nxt+tcb->rcv.wnd-1)); + return seq_within(seq, tcb->rcv.nxt, (int)(tcb->rcv.nxt+tcb->rcv.wnd-1)); } void @@ -629,7 +593,6 @@ proc_syn(Ipconv *s, char tos, Tcp *seg) tcb->mss = seg->mss; tcb->max_snd = seg->wnd; - if((mtu = s->ipinterface->maxmtu) != 0) { mtu -= TCP_HDRSIZE + TCP_EHSIZE + TCP_PHDRSIZE; tcb->cwind = tcb->mss = MIN(mtu, tcb->mss); @@ -677,8 +640,7 @@ add_reseq(Tcpctl *tcb, char tos, Tcp *seg, Block *bp, ushort length) } else { for(;;){ - if(rp1->next == 0 || - seq_lt(seg->seq, rp1->next->seg.seq)) { + if(rp1->next == 0 || seq_lt(seg->seq, rp1->next->seg.seq)) { rp->next = rp1->next; rp1->next = rp; break; @@ -688,7 +650,6 @@ add_reseq(Tcpctl *tcb, char tos, Tcp *seg, Block *bp, ushort length) } } - void get_reseq(Tcpctl *tcb, char *tos, Tcp *seg, Block **bp, ushort *length) { @@ -729,7 +690,8 @@ trim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length) if(tcb->rcv.wnd == 0) { if(seg->seq == tcb->rcv.nxt && len == 0) return 0; - } else { + } + else { /* Some part of the segment must be in the window */ if(in_window(tcb,seg->seq)) { accept++; @@ -771,7 +733,7 @@ trim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length) } } excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd); - if(excess > 0){ + if(excess > 0) { tcb->rerecv += excess; *length -= excess; nbp = copyb(*bp, *length); @@ -782,19 +744,6 @@ trim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length) return 0; } -void -extract_oob(Block **bp, Block **oobbp, Tcp *seg) - -{ - DPRINT("extract_oob: size = %u\n", seg->up); - - if (*oobbp = allocb(seg->up)) - (*oobbp)->wptr = (*oobbp)->wptr + - copyupb(bp, (*oobbp)->rptr, seg->up); - else - copyupb(bp, 0, seg->up); -} - int copyupb(Block **bph, uchar *data, int count) { @@ -821,7 +770,6 @@ copyupb(Block **bph, uchar *data, int count) freeb(bp); } } - return bytes; } @@ -949,7 +897,6 @@ close_self(Ipconv *s, int reason) tcb->reseq = 0; s->err = reason; - setstate(s, CLOSED); } @@ -968,7 +915,8 @@ seq_within(int x, int low, int high) if(low <= high){ if(low <= x && x <= high) return 1; - } else { + } + else { if(low >= x && x >= high) return 1; } @@ -1007,7 +955,6 @@ setstate(Ipconv *s, char newstate) oldstate = tcb->state; tcb->state = newstate; - state_upcall(s, oldstate, newstate); } @@ -1107,7 +1054,7 @@ ntohtcp(Tcp *tcph, Block **bpp) for(optr = h->tcpopt, i = TCP_HDRSIZE; i < hdrlen;) { switch(*optr++){ case EOL_KIND: - goto eol; + return hdrlen; case NOOP_KIND: i++; break; @@ -1119,6 +1066,5 @@ ntohtcp(Tcp *tcph, Block **bpp) break; } } -eol: return hdrlen; } diff --git a/port/tcpoutput.c b/port/tcpoutput.c index ae1e58da3cafd461af95338a8412d39f73218879..2069e8abbcb7f4678018f0f101c4ecab250fb419 100644 --- a/port/tcpoutput.c +++ b/port/tcpoutput.c @@ -8,19 +8,16 @@ #include "ipdat.h" extern int tcpdbg; +#define DPRINT if(tcpdbg) print extern ushort tcp_mss; int tcptimertype = 0; - -#define DPRINT if(tcpdbg) print - void tcp_output(Ipconv *s) { Block *hbp,*dbp, *sndq; - ushort ssize, dsize, usable, sent, oobsent; + ushort ssize, dsize, usable, sent; int qlen; - char doing_oob; Tcphdr ph; Tcp seg; Tcpctl *tcb; @@ -32,29 +29,11 @@ tcp_output(Ipconv *s) case CLOSED: return; } + for(;;){ - if (tcb->sndoobq) { - /* We have pending out-of-band data - use it */ - qlen = tcb->sndoobcnt; - oobsent = tcb->snd.ptr - tcb->snd.up; - if (oobsent >= qlen) { - oobsent = qlen; - goto normal; - } - sndq = tcb->sndoobq; - sent = oobsent; - doing_oob = 1; - DPRINT("tcp_out: oob: qlen = %lux sent = %lux\n", - qlen, sent); - } else { - oobsent = 0; - normal: - qlen = tcb->sndcnt; - sent = tcb->snd.ptr - tcb->snd.una - oobsent; - sndq = tcb->sndq; - doing_oob = 0; - DPRINT("tcp_out: norm: qlen = %lux sent = %lux\n", qlen, sent); - } + qlen = tcb->sndcnt; + sent = tcb->snd.ptr - tcb->snd.una; + sndq = tcb->sndq; /* Don't send anything else until our SYN has been acked */ if(sent != 0 && !(tcb->flags & SYNACK)) @@ -78,16 +57,10 @@ tcp_output(Ipconv *s) ssize = MIN(qlen - sent, usable); ssize = MIN(ssize, tcb->mss); dsize = ssize; - - if (!doing_oob) - seg.up = 0; - else { - seg.up = ssize; - DPRINT("tcp_out: oob seg.up = %d\n", seg.up); - } + seg.up = 0; DPRINT("tcp_out: ssize = %lux\n", ssize); - if(ssize == 0 && !(tcb->flags & FORCE)) + if(ssize == 0 && (tcb->flags & FORCE) == 0) break; /* Stop ack timer if one will be piggy backed on data */ @@ -110,7 +83,6 @@ tcp_output(Ipconv *s) if(tcb->snd.ptr == tcb->iss){ seg.flags |= SYN; dsize--; - /* Also send MSS */ seg.mss = tcp_mss; } break; @@ -119,11 +91,6 @@ tcp_output(Ipconv *s) seg.ack = tcb->last_ack = tcb->rcv.nxt; seg.wnd = tcb->rcv.wnd; - if (doing_oob) { - DPRINT("tcp_out: Setting URG (up = %u)\n", seg.up); - seg.flags |= URG; - } - /* Now try to extract some data from the send queue. * Since SYN and FIN occupy sequence space and are reflected * in sndcnt but don't actually sit in the send queue, @@ -259,7 +226,7 @@ void tcp_acktimer(Ipconv *s) { Tcpctl *tcb = &s->tcpctl; - +print("Acktimer!\n"); qlock(tcb); tcb->flags |= FORCE; tcprcvwin(s); diff --git a/ss/main.c b/ss/main.c index 05de641e77167633e3c0eaf6f8e383915e3cd163..1c50676b0762fb9c580c6ed234c8f494b61d7730 100644 --- a/ss/main.c +++ b/ss/main.c @@ -266,7 +266,7 @@ lancesetup(Lance *lp) lp->ea[i] = *cp++; kunmap(k); - lp->lognrrb = 5; + lp->lognrrb = 7; lp->logntrb = 5; lp->nrrb = 1<lognrrb; lp->ntrb = 1<logntrb;