From 8df99f1ca907699bc9dde35b90f191e20d619468 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 24 Oct 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-10-24 --- port/devenv.c | 3 + port/devip.c | 154 +++++++++++++++++++++++++------------------------ port/ipdat.h | 3 + port/proc.c | 8 +-- port/segment.c | 15 ++--- port/stil.c | 30 ++++++++-- 6 files changed, 122 insertions(+), 91 deletions(-) diff --git a/port/devenv.c b/port/devenv.c index 9d215c8f14b72d1385f455b9a77fb5e23846d247..d9322d89911dd77f873d9d1bedb11b33bb523517 100644 --- a/port/devenv.c +++ b/port/devenv.c @@ -391,6 +391,8 @@ evfree(Envval *ev) if(ev->prev) ev->prev->next = ev->next; + else + panic("evfree"); if(ev->next) ev->next->prev = ev->prev; n = (ev->len + ALIGN - 1) & ~(ALIGN - 1); @@ -399,6 +401,7 @@ evfree(Envval *ev) if(n > EVFREE) n = EVFREE; ev->next = envalloc.free[n]; + ev->prev = 0; envalloc.free[n] = ev; } diff --git a/port/devip.c b/port/devip.c index 1918b6c0f8ac117914fe03becf43f3bc2300287b..9aa9b7e19a2cd79a730c799b4d15ce3ba39323f8 100644 --- a/port/devip.c +++ b/port/devip.c @@ -181,7 +181,7 @@ ipopen(Chan *c, int omode) error(Eprotonosup); if(cp->backlog == 0) - cp->backlog = 1; + cp->backlog = 3; streamopen(c, &ipinfo); if(c->stream->devq->next->info != cp->stproto) @@ -226,7 +226,7 @@ ipclonecon(Chan *c) base = ipconv[c->dev]; etab = &base[conf.ip]; for(new = base; new < etab; new++) { - new = ipincoming(c->dev); + new = ipincoming(base); if(new == 0) error(Enodev); @@ -243,11 +243,10 @@ ipclonecon(Chan *c) } Ipconv * -ipincoming(int dev) +ipincoming(Ipconv *base) { - Ipconv *base, *new, *etab; + Ipconv *new, *etab; - base = ipconv[dev]; etab = &base[conf.ip]; for(new = base; new < etab; new++) { if(new->ref == 0 && canqlock(new)) { @@ -335,86 +334,93 @@ long ipwrite(Chan *c, char *a, long n, ulong offset) { int m, backlog, type; - char *field[5], buf[256]; - Ipconv *cp; + char *field[5], *ctlarg[5], buf[256]; Port port, base; + Ipconv *cp; type = STREAMTYPE(c->qid.path); if (type == Sdataqid) return streamwrite(c, a, n, 0); - if (type == Sctlqid) { - cp = &ipconv[c->dev][STREAMID(c->qid.path)]; - - strncpy(buf, a, sizeof buf); - m = getfields(buf, field, 5, ' '); - - if(strcmp(field[0], "connect") == 0) { - if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || - (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) - error(Edevbusy); - - if(m != 2) - error(Ebadarg); - - switch(getfields(field[1], field, 5, '!')) { - default: - error(Ebadarg); - case 2: - base = PORTALLOC; - break; - case 3: - if(strcmp(field[2], "r") != 0) - error(Eperm); - base = PRIVPORTALLOC; - break; - } - cp->dst = ipparse(field[0]); - cp->pdst = atoi(field[1]); + if (type != Sctlqid) + error(Eperm); - /* If we have no local port assign one */ - qlock(&ipalloc); - if(cp->psrc == 0) - cp->psrc = nextport(ipconv[c->dev], base); - qunlock(&ipalloc); + cp = &ipconv[c->dev][STREAMID(c->qid.path)]; + m = n; + if(m > sizeof(buf)-1) + m = sizeof(buf)-1; + strncpy(buf, a, m); + buf[m] = '\0'; + + m = getfields(buf, field, 5, ' '); + if(m < 1) + errors("bad ip control"); + + if(strcmp(field[0], "connect") == 0) { + if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || + (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) + error(Edevbusy); + + if(m != 2) + error(Ebadarg); + + switch(m = getfields(field[1], ctlarg, 5, '!')) { + default: + error(Ebadarg); + case 2: + base = PORTALLOC; + break; + case 3: + if(strcmp(ctlarg[2], "r") != 0) + error(Eperm); + base = PRIVPORTALLOC; + break; } - 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); - - if(m != 2) - error(Ebadarg); - port = atoi(field[1]); - - qlock(&ipalloc); - if(portused(ipconv[c->dev], port)) { - qunlock(&ipalloc); - error(Einuse); - } - cp->psrc = port; - cp->ptype = *field[0]; - qunlock(&ipalloc); - } - else if(strcmp(field[0], "backlog") == 0) { - if(m != 2) - error(Ebadarg); - backlog = atoi(field[1]); - if(backlog == 0) - error(Ebadarg); - if(backlog > 5) - backlog = 5; - cp->backlog = backlog; - } - else - return streamwrite(c, a, n, 0); + cp->dst = ipparse(ctlarg[0]); + cp->pdst = atoi(ctlarg[1]); + + /* If we have no local port assign one */ + qlock(&ipalloc); + if(cp->psrc == 0) + cp->psrc = nextport(ipconv[c->dev], base); + qunlock(&ipalloc); - return n; } + 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); - error(Eperm); + if(m != 2) + error(Ebadarg); + + port = atoi(field[1]); + + qlock(&ipalloc); + if(portused(ipconv[c->dev], port)) { + qunlock(&ipalloc); + error(Einuse); + } + cp->psrc = port; + cp->ptype = *field[0]; + qunlock(&ipalloc); + } + else if(strcmp(field[0], "backlog") == 0) { + if(m != 2) + error(Ebadarg); + backlog = atoi(field[1]); + if(backlog == 0) + error(Ebadarg); + if(backlog > 5) + backlog = 5; + cp->backlog = backlog; + } + else + return streamwrite(c, a, n, 0); + + return n; } @@ -690,7 +696,7 @@ iplisten(Chan *c, Ipconv *s, Ipconv *base) pushq(c->stream, new->stproto); new->ref--; qunlock(&s->listenq); - +print("ip listener!\n"); return; } } diff --git a/port/ipdat.h b/port/ipdat.h index 8b9195e80e1c5a781d8a14ddc49655ea18bbc8b6..a6b3919739535a1b4a0554b0e978d5d0725d83b9 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -46,6 +46,7 @@ struct Udphdr uchar d[6]; /* Ethernet destination */ uchar s[6]; /* Ethernet source */ uchar type[2]; /* Ethernet packet type */ + uchar vihl; /* Version and header length */ uchar tos; /* Type of service */ uchar length[2]; /* packet length */ @@ -72,6 +73,7 @@ struct Ilhdr uchar d[6]; /* Ethernet destination */ uchar s[6]; /* Ethernet source */ uchar type[2]; /* Ethernet packet type */ + uchar vihl; /* Version and header length */ uchar tos; /* Type of service */ uchar length[2]; /* packet length */ @@ -265,6 +267,7 @@ struct Ipconv Ipaddr dst; /* Destination from connect */ Port psrc; /* Source port */ Port pdst; /* Destination port */ + char ptype; /* Port type */ Ipifc *ipinterface; /* Ip protocol interface */ Queue *readq; /* Pointer to upstream read q */ diff --git a/port/proc.c b/port/proc.c index 2948abd63b9e996c69a779eef5e49311a69612d4..502d82ad29dec5180d9ce90cfafa82f09f7c6d8c 100644 --- a/port/proc.c +++ b/port/proc.c @@ -521,6 +521,10 @@ pexit(char *exitstr, int freemem) if(c->fgrp) closefgrp(c->fgrp); + closepgrp(c->pgrp); + close(u->dot); + if(c->egrp) + closeegrp(c->egrp); if(c->kp == 0) { wq = newwaitq(); @@ -566,10 +570,6 @@ pexit(char *exitstr, int freemem) *s = 0; putseg(os); } - closepgrp(c->pgrp); - if(c->egrp) - closeegrp(c->egrp); - close(u->dot); lock(&c->exl); /* Prevent my children from leaving waits */ c->pid = 0; diff --git a/port/segment.c b/port/segment.c index 7ab3e89708ef2894df66271cafb7a1fb0876420b..7e4bcb609ae0ec2a23316c3e1de4a09277a6f9f5 100644 --- a/port/segment.c +++ b/port/segment.c @@ -265,21 +265,22 @@ imagereclaim(void) if(!canqlock(&ireclaim)) /* Somebody is already cleaning the page cache */ return; - lock(&palloc); - for(p = palloc.head; p; p = p->next) { - if(p->image == 0) - continue; + for(;;) { + lock(&palloc); + for(p = palloc.head; p; p = p->next) + if(p->image && p->ref == 0 && p->image != &swapimage) + break; unlock(&palloc); + if(p == 0) + break; + lockpage(p); if(p->ref == 0 && p->image != &swapimage) uncachepage(p); unlockpage(p); - lock(&palloc); } - unlock(&palloc); - qunlock(&ireclaim); } diff --git a/port/stil.c b/port/stil.c index 4976d5a7fbf611c23dcd212eac3f51c003292d32..6691c7156d8a3a6bdafd4d8cf520d9b38238a875 100644 --- a/port/stil.c +++ b/port/stil.c @@ -187,8 +187,9 @@ ilrcvmsg(Ipconv *ipc, Block *bp) int plen; Ipconv *s, *etab, *new; short sp, dp; + Ipaddr dst; - ih = (Ilhdr *)bp; + ih = (Ilhdr *)bp->rptr; plen = blen(bp); if(plen < IL_EHSIZE+IL_HDRSIZE) @@ -201,17 +202,26 @@ ilrcvmsg(Ipconv *ipc, Block *bp) sp = nhgets(ih->ildst); 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) { + if(s->psrc == sp && s->pdst == dp && s->dst == dst) { ilprocess(s, ih, bp); return; } } + if(s->curlog > s->backlog) { +print("Backlog\n"); + goto reset; + } + for(s = ipc; s < etab; s++) { - if(s->ilctl.state == Illistening && s->psrc == 0) { + if(s->ilctl.state == Illistening && s->pdst == 0) { /* Do the listener stuff */ new = ipincoming(ipc); if(new == 0) @@ -222,6 +232,7 @@ ilrcvmsg(Ipconv *ipc, Block *bp) new->newcon = 1; new->ipinterface = s->ipinterface; s->ipinterface->ref++; + s->curlog++; new->psrc = sp; new->pdst = dp; new->dst = nhgetl(ih->src); @@ -240,6 +251,8 @@ drop: void ilprocess(Ipconv *s, Ilhdr *h, Block *bp) { + Block *nb; + switch(s->ilctl.state) { case Ilclosed: case Ilclosing: @@ -265,10 +278,14 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp) case Ildata: ilackto(&s->ilctl, nhgetl(h->ilack)); bp->rptr += IL_EHSIZE+IL_HDRSIZE; +/* Check and trim to length */ PUTNEXT(s->readq, bp); break; case Ilreset: s->ilctl.state = Ilclosed; + nb = allocb(0); + nb->type = M_HANGUP; + PUTNEXT(s->readq, nb); freeb(bp); } } @@ -287,17 +304,18 @@ ilsendctl(Ipconv *ipc, Ilhdr *inih, int type, int ack) ic = &ipc->ilctl; /* Ip fields */ - hnputl(ih->src, Myip); - hnputl(ih->dst, ipc->dst); ih->proto = IP_ILPROTO; + hnputl(ih->src, Myip); hnputs(ih->illen, IL_HDRSIZE); if(inih) { + hnputl(ih->dst, nhgetl(inih->src)); hnputs(ih->ilsrc, nhgets(inih->ildst)); hnputs(ih->ildst, nhgets(inih->ilsrc)); hnputl(ih->ilid, nhgetl(inih->ilack)); hnputl(ih->ilack, nhgetl(inih->ilid)); } else { + hnputl(ih->dst, ipc->dst); hnputs(ih->ilsrc, ipc->psrc); hnputs(ih->ildst, ipc->pdst); hnputl(ih->ilid, ic->sent); @@ -311,7 +329,7 @@ ilsendctl(Ipconv *ipc, Ilhdr *inih, int type, int ack) if(ilcksum) hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, IL_HDRSIZE)); - if(!ack) { + if(!ack && ipc) { ic->sent++; /* Maybe needs locking */ ilackq(&ipc->ilctl, bp); }