From f82c55e630f2f8f6212e77643f4b7f2669a00387 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 9 Sep 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-09-09 --- ip/ip.h | 1 + ip/ipifc.c | 12 ++-- ip/udp.c | 41 +++++++----- pc/devlml.c | 2 +- pc/devlml.h | 2 +- pc/vgamach64xx.c | 1 + port/devsdp.c | 160 +++++++++++++++++++++++++++-------------------- 7 files changed, 128 insertions(+), 91 deletions(-) diff --git a/ip/ip.h b/ip/ip.h index 4a693d0c34fb4ee256ae265cb5a6999216c334b5..f5eb7d01726c06c9e7d91c8c6d253ae209fefb89 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -333,6 +333,7 @@ enum Runi= (1<<3), /* a unicast self address */ Rbcast= (1<<4), /* a broadcast self address */ Rmulti= (1<<5), /* a multicast self address */ + Rproxy= (1<<6), /* this route should be proxied */ }; struct Routewalk diff --git a/ip/ipifc.c b/ip/ipifc.c index 54778e0dd2b5302e2eaba2f79475d1f6b5ccc69a..ced0d0b1c2f6891c3a316e654371fb04eaabc347 100644 --- a/ip/ipifc.c +++ b/ip/ipifc.c @@ -345,10 +345,15 @@ ipifcadd(Ipifc *ifc, char **argv, int argc) f = ifc->conv->p->f; + type = Rifc; memset(ip, 0, IPaddrlen); memset(mask, 0, IPaddrlen); memset(rem, 0, IPaddrlen); switch(argc){ + case 6: + if(strcmp(argv[5], "proxy") == 0) + type |= Rproxy; + /* fall through */ case 5: mtu = strtoul(argv[4], 0, 0); if(mtu >= ifc->m->minmtu && mtu <= ifc->m->maxmtu) @@ -396,7 +401,6 @@ ipifcadd(Ipifc *ifc, char **argv, int argc) *l = lifc; /* add a route for the local network */ - type = Rifc; if(ipcmp(mask, IPallbits) == 0){ /* point to point networks are a hack */ if(ipcmp(ip, rem) == 0) @@ -410,7 +414,7 @@ ipifcadd(Ipifc *ifc, char **argv, int argc) addselfcache(f, ifc, lifc, ip, Runi); - if(type & Rptpt){ + if((type & (Rptpt|Rproxy)) == (Rptpt|Rproxy)){ ipifcregisterproxy(f, ifc, rem); goto out; } @@ -1088,9 +1092,7 @@ ipproxyifc(Fs *f, Ipifc *ifc, uchar *ip) r = v6lookup(f, ip); if(r == nil) return 0; - if((r->type & Rifc) == 0) - return 0; - if((r->type & Rptpt) == 0) + if((r->type & (Rifc|Rptpt|Rproxy)) != (Rifc|Rptpt|Rproxy)) return 0; /* see if this is on the right interface */ diff --git a/ip/udp.c b/ip/udp.c index 92a8ad2c4a2d70a7ae8dd606c1b73e3e77c3dfd4..754ad9e97427aea39d48460ce725ac38451c23b0 100644 --- a/ip/udp.c +++ b/ip/udp.c @@ -234,7 +234,7 @@ udpiput(Proto *udp, uchar *ia, Block *bp) { int len, olen, ottl; Udphdr *uh; - Conv *c, **p; + Conv *c, **p, *gc; Udpcb *ucb; uchar raddr[IPaddrlen], laddr[IPaddrlen]; ushort rport, lport; @@ -272,8 +272,12 @@ udpiput(Proto *udp, uchar *ia, Block *bp) qlock(udp); - /* Look for a conversation structure for this port */ - c = nil; + /* + * Look for a conversation structure for this port. One + * with headers off wins over one with headers on, i.e., + * specific wins over generic. + */ + gc = c = nil; for(p = udp->conv; *p; p++) { c = *p; if(c->inuse == 0) @@ -282,8 +286,10 @@ udpiput(Proto *udp, uchar *ia, Block *bp) ucb = (Udpcb*)c->ptcl; /* with headers turned on, descriminate only on local port */ - if(ucb->headers) - break; + if(ucb->headers && gc == nil){ + gc = c; + continue; + } /* otherwise discriminate on lport, rport, and raddr */ if(c->rport == 0 || c->rport == rport) @@ -292,17 +298,20 @@ udpiput(Proto *udp, uchar *ia, Block *bp) break; } } - - if(*p == nil) { - upriv->ustats.udpNoPorts++; - qunlock(udp); - netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport, - laddr, lport); - uh->Unused = ottl; - hnputs(uh->udpplen, olen); - icmpnoconv(f, bp); - freeblist(bp); - return; + if(*p == nil){ + if(gc != nil) + c = gc; + else { + upriv->ustats.udpNoPorts++; + qunlock(udp); + netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport, + laddr, lport); + uh->Unused = ottl; + hnputs(uh->udpplen, olen); + icmpnoconv(f, bp); + freeblist(bp); + return; + } } ucb = (Udpcb*)c->ptcl; diff --git a/pc/devlml.c b/pc/devlml.c index feceda52f986d2be3b2fdadfa498d68e3130e811..604f184336c4106c70d4c7bd22a5047b177d66bb 100644 --- a/pc/devlml.c +++ b/pc/devlml.c @@ -351,7 +351,7 @@ lmlintr(Ureg *, void *) { } thetime = todget(nil); jpgheader[fno].sec = (ulong)(thetime / 1000000000LL); - jpgheader[fno].usec = (ulong)(thetime % 1000000000LL) / 1000; + jpgheader[fno].nsec = (ulong)(thetime % 1000000000LL); jpgheader[fno].frameSize = (codeData->statCom[fno] & 0x00ffffff) >> 1; jpgheader[fno].frameSeqNo = codeData->statCom[fno] >> 24; diff --git a/pc/devlml.h b/pc/devlml.h index 195393639a548dc53f1f5dfda72410bcfaef6513..4a11df979afdf337336ad34dda3bd180fb75b998 100644 --- a/pc/devlml.h +++ b/pc/devlml.h @@ -71,7 +71,7 @@ struct FrameHeader { // Don't modify this struct, used by h/w char nm[4]; ushort frameNo; ulong sec; - ulong usec; + ulong nsec; ulong frameSize; ulong frameSeqNo; }; diff --git a/pc/vgamach64xx.c b/pc/vgamach64xx.c index 30fc6a633c1a7d8255fd43df4e9a92d6198975eb..ea5d2cc5c322866296b7063f78010db7a91c1642 100644 --- a/pc/vgamach64xx.c +++ b/pc/vgamach64xx.c @@ -25,6 +25,7 @@ static ushort mach64xxdid[] = { ('G'<<8)|'Q', ('G'<<8)|'T', ('G'<<8)|'U', + ('G'<<8)|'Z', ('V'<<8)|'T', ('V'<<8)|'U', 0, diff --git a/port/devsdp.c b/port/devsdp.c index 8f698d009c09ff01c9219157e20b51a89dc54ea1..8799c9f196a18911e45bda34606b0d268f96a449 100644 --- a/port/devsdp.c +++ b/port/devsdp.c @@ -36,7 +36,8 @@ enum Maxconv= 256, // power of 2 Nfs= 4, // number of file systems - Maxretries= 4, + MaxRetries= 8, + KeepAlive = 60, // keep alive in seconds KeyLength= 32, }; @@ -70,7 +71,8 @@ struct OneWay // conv states enum { CInit, - COpening, + CDial, + CAccept, COpen, CClosing, CClosed, @@ -127,11 +129,11 @@ enum { }; enum { - ConOpen, + ConOpenRequest, ConOpenAck, - ConOpenNack, ConClose, ConCloseAck, + ConReset, }; struct ConnectPkt @@ -181,7 +183,8 @@ static Dirtab *dirtab[MaxQ]; static Sdp sdptab[Nfs]; static char *convstatename[] = { [CInit] "Init", - [COpening] "Opening", + [CDial] "Dial", + [CAccept] "Accept", [COpen] "Open", [CClosing] "Closing", [CClosed] "Closed", @@ -325,7 +328,6 @@ sdpopen(Chan* ch, int omode) if(strcmp(up->user, c->owner) != 0 || (perm & c->perm) != perm) error(Eperm); c->ref++; -print(c->ref = %d\n", c->ref); if(TYPE(ch->qid) == Qdata) c->dataopen++; qunlock(c); @@ -373,6 +375,7 @@ print("close c->ref = %d\n", c->ref); default: convsetstate(c, CClosed); break; + case CAccept: case COpen: convsetstate(c, CClosing); break; @@ -391,7 +394,6 @@ sdpread(Chan *ch, void *a, long n, vlong off) { char buf[256]; Sdp *sdp = sdptab + ch->dev; - char *s; Conv *c; Block *b; @@ -408,23 +410,7 @@ sdpread(Chan *ch, void *a, long n, vlong off) case Qstatus: c = sdp->conv[CONV(ch->qid)]; qlock(c); - switch(c->state) { - default: - panic("unknown state"); - case CClosed: - s = "closed"; - break; - case COpening: - s = "opening"; - break; - case COpen: - s = "open"; - break; - case CClosing: - s = "closing"; - break; - } - n = readstr(off, a, n, s); + n = readstr(off, a, n, convstatename[c->state]); qunlock(c); return n; case Qctl: @@ -498,11 +484,11 @@ print("cmd = %s\n", arg0); if(cb->nf != 2) error("usage: accect id"); c->dialid = atoi(cb->f[1]); - convsetstate(c, COpen); + convsetstate(c, CAccept); } else if(strcmp(arg0, "dial") == 0) { if(cb->nf != 1) error("usage: dial"); - convsetstate(c, COpening); + convsetstate(c, CDial); } else if(strcmp(arg0, "drop") == 0) { if(cb->nf != 2) error("usage: drop permil"); @@ -619,17 +605,26 @@ sdpclone(Sdp *sdp) return c; } +// assume c is locked +static void +convretryinit(Conv *c) +{ + c->retries = 0; + // +2 to avoid rounding effects. + c->timeout = TK2SEC(m->ticks) + 2; +}; + // assume c is locked static int convretry(Conv *c) { c->retries++; - if(c->retries > Maxretries) { + if(c->retries > MaxRetries) { print("convretry: giving up\n"); convsetstate(c, CClosed); return 0; } - c->timeout = TK2SEC(m->ticks) + (1<retries); + c->timeout = TK2SEC(m->ticks) + (c->retries+1); return 1; } @@ -643,17 +638,20 @@ convtimer(Conv *c, ulong sec) qunlock(c); nexterror(); } +print("convtimer: %s\n", convstatename[c->state]); switch(c->state) { - case COpening: -print("COpening timeout\n"); + case CDial: + if(convretry(c)) + convoput2(c, ConOpenRequest, c->dialid, 0); + break; + case CAccept: if(convretry(c)) - convoput2(c, ConOpen, c->dialid, 0); + convoput2(c, ConOpenAck, c->dialid, c->acceptid); break; case COpen: - // check for control packet + // check for control packet and keepalive break; case CClosing: -print("CClosing timeout\n"); if(convretry(c)) convoput2(c, ConClose, c->dialid, c->acceptid); break; @@ -716,31 +714,30 @@ print("convsetstate %s -> %s\n", convstatename[c->state], convstatename[state]); switch(state) { default: panic("setstate: bad state: %d", state); - case COpening: - if(c->state != CInit) - error("convsetstate: illegal transition"); + case CDial: + assert(c->state == CInit); c->dialid = (rand()<<16) + rand(); - c->timeout = TK2SEC(m->ticks) + 2; - c->retries = 0; - convoput2(c, ConOpen, c->dialid, 0); + convretryinit(c); + convoput2(c, ConOpenRequest, c->dialid, 0); + break; + case CAccept: + assert(c->state == CInit); + c->acceptid = (rand()<<16) + rand(); + convretryinit(c); + convoput2(c, ConOpenAck, c->dialid, c->acceptid); break; case COpen: - switch(c->state) { - default: - error("convsetstate: illegal transition"); - case CInit: - c->acceptid = (rand()<<16) + rand(); + assert(c->state == CDial || c->state == CAccept); + if(c->state == CDial) { + convretryinit(c); convoput2(c, ConOpenAck, c->dialid, c->acceptid); - break; - case COpening: - break; } // setup initial key and auth method break; case CClosing: + assert(c->state == COpen); + convretryinit(c); convoput2(c, ConClose, c->dialid, c->acceptid); - c->timeout = TK2SEC(m->ticks) + 2; - c->retries = 0; break; case CClosed: if(c->readproc) @@ -900,32 +897,59 @@ conviput2(Conv *c, Block *b) print("conviput2: %d %uld %uld\n", con->op, dialid, acceptid); switch(con->op) { - case ConOpen: - if(c->state != COpen || dialid != c->dialid || acceptid != c->acceptid) - convoput2(c, ConOpenNack, dialid, acceptid); - else - convoput2(c, ConOpenAck, dialid, acceptid); - break; - case ConOpenAck: - if(c->state != COpening || dialid != c->dialid) + case ConOpenRequest: + switch(c->state) { + default: + convoput2(c, ConReset, dialid, acceptid); + break; + case CInit: + c->dialid = dialid; + convsetstate(c, CAccept); break; - c->acceptid = acceptid; - convsetstate(c, COpen); + case CAccept: + case COpen: + if(dialid != c->dialid || acceptid != c->acceptid) + convoput2(c, ConReset, dialid, acceptid); + break; + } break; - case ConOpenNack: - if(c->state != COpening || dialid != c->dialid) + case ConOpenAck: + switch(c->state) { + case CDial: + if(dialid != c->dialid) { + convoput2(c, ConReset, dialid, acceptid); + break; + } + c->acceptid = acceptid; + convsetstate(c, COpen); break; - convsetstate(c, CClosed); + case CAccept: + if(dialid != c->dialid || acceptid != c->acceptid) { + convoput2(c, ConReset, dialid, acceptid); + break; + } + convsetstate(c, COpen); + } break; case ConClose: - if(dialid != c->dialid || acceptid != c->acceptid) + convoput2(c, ConCloseAck, dialid, acceptid); + // fall though + case ConReset: + switch(c->state) { + case CDial: + if(dialid == c->dialid) + convsetstate(c, CClosed); break; - convsetstate(c, CClosed); - break; - case ConCloseAck: - if(c->state != CClosing || dialid != c->dialid || acceptid != c->acceptid) + case CAccept: + case COpen: + case CClosing: + if(dialid == c->dialid && acceptid == c->acceptid) + convsetstate(c, CClosed); break; - convsetstate(c, CClosed); + } + case ConCloseAck: + if(c->state == CClosing && dialid == c->dialid && acceptid == c->acceptid) + convsetstate(c, CClosed); break; } }