From 66db0535ca71850f6d0617d444042cf38f6f1d13 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 23 Oct 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-10-23 --- port/devbit.c | 2 +- port/devip.c | 52 +++++++++++++++++++++++++++++++------------------ port/ipdat.h | 8 +++----- port/stil.c | 28 +++++++++++++++++++------- port/stip.c | 1 - port/tcpinput.c | 23 +++++----------------- 6 files changed, 63 insertions(+), 51 deletions(-) diff --git a/port/devbit.c b/port/devbit.c index 1e4b77775f0b4f3160731446bf72929060df5d73..48f3d8e0ab50ef359ff4646254ab079a090344af 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -487,7 +487,7 @@ bitread(Chan *c, void *va, long n, ulong offset) ws = 1<<(3-gscreen.ldepth); /* pixels per byte */ l = (gscreen.r.max.x+ws-1)/ws - gscreen.r.min.x/ws; t = offset-5*12; - miny = t/l; + miny = t/l; /* unsigned computation */ maxy = (t+n)/l; if(miny >= gscreen.r.max.y) return 0; diff --git a/port/devip.c b/port/devip.c index 1ea2d848e4c65d7ed21253a4ef039981beb2c768..1918b6c0f8ac117914fe03becf43f3bc2300287b 100644 --- a/port/devip.c +++ b/port/devip.c @@ -225,6 +225,30 @@ ipclonecon(Chan *c) base = ipconv[c->dev]; etab = &base[conf.ip]; + for(new = base; new < etab; new++) { + new = ipincoming(c->dev); + if(new == 0) + error(Enodev); + + c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); + devwalk(c, "ctl", 0, 0, streamgen); + + streamopen(c, &ipinfo); + pushq(c->stream, new->stproto); + new->ref--; + return new; + } + + error(Enodev); +} + +Ipconv * +ipincoming(int dev) +{ + Ipconv *base, *new, *etab; + + base = ipconv[dev]; + etab = &base[conf.ip]; for(new = base; new < etab; new++) { if(new->ref == 0 && canqlock(new)) { if(new->ref || @@ -234,18 +258,11 @@ ipclonecon(Chan *c) continue; } new->ref++; - c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); - devwalk(c, "ctl", 0, 0, streamgen); qunlock(new); - - streamopen(c, &ipinfo); - pushq(c->stream, new->stproto); - new->ref--; return new; } } - - error(Enodev); + return 0; } void @@ -642,7 +659,7 @@ tcpstopen(Queue *q, Stream *s) } int -tcp_havecon(Ipconv *s) +iphavecon(Ipconv *s) { return s->curlog; } @@ -655,28 +672,25 @@ iplisten(Chan *c, Ipconv *s, Ipconv *base) qlock(&s->listenq); for(;;) { - sleep(&s->listenr, tcp_havecon, s); - - /* Search for the new connection, clone the control channel and - * return an open channel to the listener - */ - for(new = base, etab = &base[conf.ip]; new < etab; new++) { - if(new->psrc == s->psrc && new->pdst != 0 && - new->dst && (new->tcpctl.flags & CLONE) == 0) { - new->ref++; + sleep(&s->listenr, iphavecon, s); + new = base; + for(etab = &base[conf.ip]; new < etab; new++) { + if(new->newcon) { /* Remove the listen channel reference */ streamclose(c); s->curlog--; + /* Attach the control channel to the new connection */ + new->newcon = 0; c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); devwalk(c, "ctl", 0, 0, streamgen); streamopen(c, &ipinfo); pushq(c->stream, new->stproto); new->ref--; - qunlock(&s->listenq); + return; } } diff --git a/port/ipdat.h b/port/ipdat.h index a5afdd51411052df7b80b23388592390ee45aa98..8b9195e80e1c5a781d8a14ddc49655ea18bbc8b6 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -263,22 +263,19 @@ struct Ipconv int ref; Qinfo *stproto; /* Stream protocol for this device */ Ipaddr dst; /* Destination from connect */ - Port psrc; /* Source port */ Port pdst; /* Destination port */ - uchar ptype; /* Source port type */ Ipifc *ipinterface; /* Ip protocol interface */ Queue *readq; /* Pointer to upstream read q */ - QLock listenq; /* List of people waiting incoming cons */ Rendez listenr; /* Some where to sleep while waiting */ - Ipconv *listen; char err; /* Async protocol error */ int backlog; /* Maximum number of waiting connections */ int curlog; /* Number of waiting connections */ - int contype; + int newcon; /* Flags that this is the start of a connection */ + union { Tcpctl tcpctl; /* Tcp control block */ Ilcb ilctl; /* Il control block */ @@ -476,6 +473,7 @@ int seq_gt(int, int); void appendb(Block **, Block *); Ipconv *ip_conn(Ipconv *, Port, Port, Ipaddr dest, char proto); void ipmkdir(Qinfo *, Dirtab *, Ipconv *); +Ipconv *ipincoming(Ipconv*); int inb_window(Tcpctl *, int); Block *htontcp(Tcp *, Block *, Tcphdr *); void start_timer(Timer *); diff --git a/port/stil.c b/port/stil.c index 7962f033de43761b2277ac5550a8c9fdee2f3be1..4976d5a7fbf611c23dcd212eac3f51c003292d32 100644 --- a/port/stil.c +++ b/port/stil.c @@ -12,10 +12,9 @@ #include "ipdat.h" #define DPRINT if(pip)print -int ilcksum = 1; - -static int initseq = 25000; -char *ilstate[] = { "Closed", "Syncer", "Syncee", "Established", "Listening", "Closing" }; +int ilcksum = 1; +static int initseq = 25000; +char *ilstate[] = { "Closed", "Syncer", "Syncee", "Established", "Listening", "Closing" }; void ilrcvmsg(Ipconv*, Block*); void ilackproc(void*); @@ -186,7 +185,7 @@ ilrcvmsg(Ipconv *ipc, Block *bp) { Ilhdr *ih; int plen; - Ipconv *s, *etab; + Ipconv *s, *etab, *new; short sp, dp; ih = (Ilhdr *)bp; @@ -210,13 +209,29 @@ ilrcvmsg(Ipconv *ipc, Block *bp) } } + for(s = ipc; s < etab; s++) { if(s->ilctl.state == Illistening && s->psrc == 0) { /* Do the listener stuff */ - ilprocess(s, ih, bp); + new = ipincoming(ipc); + if(new == 0) + goto reset; + if(ih->type != Ilsync) + goto reset; + + new->newcon = 1; + new->ipinterface = s->ipinterface; + s->ipinterface->ref++; + new->psrc = sp; + new->pdst = dp; + new->dst = nhgetl(ih->src); + ilprocess(new, ih, bp); + + wakeup(&s->listenr); return; } } +reset: ilsendctl(0, ih, Ilreset, 0); drop: freeb(bp); @@ -333,5 +348,4 @@ ilstart(Ipconv *ipc, int type, int window) ilsendctl(ipc, 0, Ilsync, 1); break; } - } diff --git a/port/stip.c b/port/stip.c index 1b7dedab466ac7d8407756ec4094962306bf7c3a..db51a48fadd36bb27db86299fb7196d3f175d75d 100644 --- a/port/stip.c +++ b/port/stip.c @@ -555,7 +555,6 @@ ip_csum(uchar *addr) sum = (sum & 0xffff) + (sum >> 16); sum = (sum & 0xffff) + (sum >> 16); - return (sum^0xffff); } diff --git a/port/tcpinput.c b/port/tcpinput.c index c8bdc2ca49319c4103c2f1610f8144af817cee31..99143d0a132215eaea5647ce81e3b2f04585628c 100644 --- a/port/tcpinput.c +++ b/port/tcpinput.c @@ -34,7 +34,7 @@ tcpinit(void) void tcp_input(Ipconv *ipc, Block *bp) { - Ipconv *s, *new, *etab; + Ipconv *s, *new; Tcpctl *tcb; Tcphdr *h; Tcp seg; @@ -108,21 +108,8 @@ tcp_input(Ipconv *ipc, Block *bp) goto clear; } - /* Find a conversation to clone onto */ - etab = &ipc[conf.ip]; - for(new = ipc; new < etab; new++) { - if(new->ref == 0 && canqlock(new)) { - if(new->ref || new->tcpctl.state != CLOSED) { - qunlock(new); - continue; - } - new->ref++; - qunlock(new); - break; - } - } - - if(new == etab) + new = ipincoming(ipc); + if(new == 0) goto clear; s->curlog++; @@ -137,11 +124,11 @@ tcp_input(Ipconv *ipc, Block *bp) new->tcpctl.acktimer.arg = new; new->tcpctl.acktimer.state = TIMER_STOP; + new->newcon = 1; new->ipinterface = s->ipinterface; s->ipinterface->ref++; - - /* Wake the sleeping dodo */ wakeup(&s->listenr); + s = new; }