From 6a2dd849e5264e702568476422236a91c4fd9afc Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 20 Feb 2003 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2003-02-20 --- ip/gre.c | 8 +++----- ip/icmp.c | 8 +++----- ip/icmp6.c | 8 +++----- ip/il.c | 6 ++---- ip/ip.c | 15 ++++++--------- ip/ip.h | 4 ++-- ip/ipv6.c | 9 +++++---- ip/tcp.c | 25 ++++++++++++------------- ip/udp.c | 8 +++----- port/portfns.h | 1 + port/qio.c | 29 ++++++++++++++++++++++++++--- 11 files changed, 66 insertions(+), 55 deletions(-) diff --git a/ip/gre.c b/ip/gre.c index 2c98cc1cebfaf346cb03a3d96c1c6bd866b87ec5..641d351bd7a709faff9240b2514a700352eb99e1 100644 --- a/ip/gre.c +++ b/ip/gre.c @@ -47,7 +47,7 @@ struct GREpriv ulong lenerr; /* short packet */ }; -static void grekick(void *x); +static void grekick(void *x, Block *bp); static char* greconnect(Conv *c, char **argv, int argc) @@ -90,7 +90,7 @@ static void grecreate(Conv *c) { c->rq = qopen(64*1024, Qmsg, 0, c); - c->wq = qopen(64*1024, Qkick, grekick, c); + c->wq = qbypass(grekick, c); } static int @@ -121,14 +121,12 @@ greclose(Conv *c) int drop; static void -grekick(void *x) +grekick(void *x, Block *bp) { Conv *c = x; GREhdr *ghp; - Block *bp; uchar laddr[IPaddrlen], raddr[IPaddrlen]; - bp = qget(c->wq); if(bp == nil) return; diff --git a/ip/icmp.c b/ip/icmp.c index 302669c7661babba8aa5066b8642d10c5d021bdb..7b3dc0adf28be0500169b7ae5d8e05df0263d15f 100644 --- a/ip/icmp.c +++ b/ip/icmp.c @@ -104,13 +104,13 @@ struct Icmppriv ulong out[Maxtype+1]; }; -static void icmpkick(void *x); +static void icmpkick(void *x, Block*); static void icmpcreate(Conv *c) { c->rq = qopen(64*1024, Qmsg, 0, c); - c->wq = qopen(64*1024, Qkick, icmpkick, c); + c->wq = qbypass(icmpkick, c); } extern char* @@ -157,14 +157,12 @@ icmpclose(Conv *c) } static void -icmpkick(void *x) +icmpkick(void *x, Block *bp) { Conv *c = x; Icmp *p; - Block *bp; Icmppriv *ipriv; - bp = qget(c->wq); if(bp == nil) return; diff --git a/ip/icmp6.c b/ip/icmp6.c index c102b35707888ce38296be3a0db7be371f893aae..c0e0e90ce96bc38d81a4206bdabba3dc57907ca3 100644 --- a/ip/icmp6.c +++ b/ip/icmp6.c @@ -172,13 +172,13 @@ enum { mtuopt = 5, }; -static void icmpkick6(void *x); +static void icmpkick6(void *x, Block *bp); static void icmpcreate6(Conv *c) { c->rq = qopen(64*1024, Qmsg, 0, c); - c->wq = qopen(64*1024, Qkick, icmpkick6, c); + c->wq = qbypass(icmpkick6, c); } static void @@ -228,16 +228,14 @@ icmpadvise6(Proto *icmp, Block *bp, char *msg) } static void -icmpkick6(void *x) +icmpkick6(void *x, Block *bp) { Conv *c = x; IPICMP *p; - Block *bp; uchar laddr[IPaddrlen], raddr[IPaddrlen]; Icmppriv6 *ipriv = c->p->priv; Icmpcb6 *icb = (Icmpcb6*)c->ptcl; - bp = qget(c->wq); if(bp == nil) return; diff --git a/ip/il.c b/ip/il.c index 6f618f413f5a292b8885b8151d1bffb9d48d96f3..b3bc8a1f3c24fa2dbcc98e7081a62847a35e9e94 100644 --- a/ip/il.c +++ b/ip/il.c @@ -335,14 +335,13 @@ ilclose(Conv *c) } void -ilkick(void *x) +ilkick(void *x, Block *bp) { Conv *c = x; Ilhdr *ih; Ilcb *ic; int dlen; ulong id, ack; - Block *bp; Fs *f; Ilpriv *priv; @@ -350,7 +349,6 @@ ilkick(void *x) priv = c->p->priv; ic = (Ilcb*)c->ptcl; - bp = qget(c->wq); if(bp == nil) return; @@ -418,7 +416,7 @@ static void ilcreate(Conv *c) { c->rq = qopen(64*1024, 0, 0, c); - c->wq = qopen(64*1024, Qkick, ilkick, c); + c->wq = qbypass(ilkick, c); } int diff --git a/ip/ip.c b/ip/ip.c index 5dd8b768986bcd46f8253ff793bd8a624bd08fc1..0917c2994256e7c2031236b19142a5c28d3231d5 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -220,7 +220,7 @@ iprouting(Fs *f, int on) f->ip->stats[Forwarding] = 1; } -void +int ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos) { Ipifc *ifc; @@ -231,7 +231,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos) int lid, len, seglen, chunk, dlen, blklen, offset, medialen; Route *r, *sr; IP *ip; - Proto *pr; + int rv = 0; ip = f->ip; @@ -263,11 +263,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos) if(r == nil){ ip->stats[OutNoRoutes]++; netlog(f, Logip, "no interface %V\n", eh->dst); - if(!gating){ - freeblist(bp); -print("ipoput4: no route\n"); - error("no route"); - } + rv = -1; goto free; } @@ -315,7 +311,7 @@ print("ipoput4: no route\n"); ifc->m->bwrite(ifc, bp, V4, gate); runlock(ifc); poperror(); - return; + return 0; } if((eh->frag[0] & (IP_DF>>8)) && !gating) print("%V: DF set\n", eh->dst); @@ -404,7 +400,8 @@ raise: runlock(ifc); poperror(); free: - freeblist(bp); + freeblist(bp); + return rv; } void diff --git a/ip/ip.h b/ip/ip.h index ff73780c6b71114d63752d6ec7e9496b11f4b5b7..62a46dbaccd23c67db53ec75339253bfbffe3437 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -620,8 +620,8 @@ extern void icmpttlexceeded(Fs*, uchar*, Block*); extern ushort ipcsum(uchar*); extern void ipiput4(Fs*, Ipifc*, Block*); extern void ipiput6(Fs*, Ipifc*, Block*); -extern void ipoput4(Fs*, Block*, int, int, int); -extern void ipoput6(Fs*, Block*, int, int, int); +extern int ipoput4(Fs*, Block*, int, int, int); +extern int ipoput6(Fs*, Block*, int, int, int); extern int ipstats(Fs*, char*, int); extern ushort ptclbsum(uchar*, int); extern ushort ptclcsum(Block*, int, int); diff --git a/ip/ipv6.c b/ip/ipv6.c index 30f384eb6bea608f5474410faff14f97d2b92ceb..ff48390119288f0d21dbd5e6fd80133334427d2c 100644 --- a/ip/ipv6.c +++ b/ip/ipv6.c @@ -131,7 +131,7 @@ struct IP int iprouting; /* true if we route like a gateway */ }; -void +int ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos) { int tentative; @@ -143,7 +143,7 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos) Fraghdr6 fraghdr; Block *xp, *nb; IP *ip; - + int rv = 0; ip = f->ip; @@ -184,6 +184,7 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos) // print("no route for %I, src %I free\n", eh->dst, eh->src); ip->stats[OutNoRoutes]++; netlog(f, Logip, "no interface %I\n", eh->dst); + rv = -1; goto free; } @@ -228,7 +229,7 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos) ifc->m->bwrite(ifc, bp, V6, gate); runlock(ifc); poperror(); - return; + return 0; } if(gating) @@ -328,7 +329,7 @@ raise: poperror(); free: freeblist(bp); - + return rv; } void diff --git a/ip/tcp.c b/ip/tcp.c index d7578b56b173847ee5e9d3db6e84af95d7c89483..c25c3a46cad179abe15c21913ccf0d8a94411b7f 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -2411,11 +2411,6 @@ tcpoutput(Conv *s) tpriv = s->p->priv; version = s->ipversion; - if(waserror()){ - localclose(s, up->errstr); - return; - } - for(msgs = 0; msgs < 100; msgs++) { tcb = (Tcpctl*)s->ptcl; @@ -2423,7 +2418,7 @@ tcpoutput(Conv *s) case Listen: case Closed: case Finwait2: - goto out; + return; } /* force an ack when a window has opened up */ @@ -2550,7 +2545,7 @@ tcpoutput(Conv *s) hbp = htontcp4(&seg, bp, &tcb->protohdr.tcp4hdr, tcb); if(hbp == nil) { freeblist(bp); - goto out; + return; } break; case V6: @@ -2558,7 +2553,7 @@ tcpoutput(Conv *s) hbp = htontcp6(&seg, bp, &tcb->protohdr.tcp6hdr, tcb); if(hbp == nil) { freeblist(bp); - goto out; + return; } break; default: @@ -2590,10 +2585,16 @@ tcpoutput(Conv *s) switch(version){ case V4: - ipoput4(f, hbp, 0, s->ttl, s->tos); + if(ipoput4(f, hbp, 0, s->ttl, s->tos) < 0){ + /* a negative return means no route */ + localclose(s, "no route"); + } break; case V6: - ipoput6(f, hbp, 0, s->ttl, s->tos); + if(ipoput6(f, hbp, 0, s->ttl, s->tos) < 0){ + /* a negative return means no route */ + localclose(s, "no route"); + } break; default: panic("tcpoutput2: version %d", version); @@ -2604,8 +2605,6 @@ tcpoutput(Conv *s) qlock(s); } } -out: - poperror(); } /* @@ -2745,7 +2744,7 @@ tcprxmit(Conv *s) tcb->snd.ptr = tcb->snd.una; /* - * We should be halving the slow start thershhold (down to one + * We should be halving the slow start threshhold (down to one * mss) but leaving it at mss seems to work well enough */ tcb->ssthresh = tcb->mss; diff --git a/ip/udp.c b/ip/udp.c index fc09f3ded438eb7c05766563a16bbe8596af4b08..85ca87b425debf573d5198d5a203c24045ec8ec1 100644 --- a/ip/udp.c +++ b/ip/udp.c @@ -93,7 +93,7 @@ struct Udppriv }; void (*etherprofiler)(char *name, int qlen); -void udpkick(void *x); +void udpkick(void *x, Block *bp); /* * protocol specific part of Conv @@ -148,7 +148,7 @@ static void udpcreate(Conv *c) { c->rq = qopen(128*1024, Qmsg, 0, 0); - c->wq = qopen(128*1024, Qkick, udpkick, c); + c->wq = qbypass(udpkick, c); } static void @@ -176,14 +176,13 @@ udpclose(Conv *c) } void -udpkick(void *x) +udpkick(void *x, Block *bp) { Conv *c = x; Udp4hdr *uh4; Udp6hdr *uh6; ushort rport; uchar laddr[IPaddrlen], raddr[IPaddrlen]; - Block *bp; Udpcb *ucb; int dlen, ptcllen; Udppriv *upriv; @@ -194,7 +193,6 @@ udpkick(void *x) f = c->p->f; netlog(c->p->f, Logudp, "udp: kick\n"); - bp = qget(c->wq); if(bp == nil) return; diff --git a/port/portfns.h b/port/portfns.h index 1bfccea1208cf938ee0edcd5d07732bda50ce8a1..e141c8aa0ddbce1ce9915121529afd35eaeee4be 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -241,6 +241,7 @@ ulong pwait(Waitmsg*); void qaddlist(Queue*, Block*); Block* qbread(Queue*, int); long qbwrite(Queue*, Block*); +Queue* qbypass(void (*)(void*, Block*), void*); int qcanread(Queue*); void qclose(Queue*); int qconsume(Queue*, void*, int); diff --git a/port/qio.c b/port/qio.c index 9cc79bd9f5a12b47c1d488f6fdd741b7a627017e..69234d6d5449db88ca3d86b1e662151ef656b574 100644 --- a/port/qio.c +++ b/port/qio.c @@ -38,6 +38,7 @@ struct Queue int eof; /* number of eofs read by user */ void (*kick)(void*); /* restart output */ + void (*bypass)(void*, Block*); /* bypass queue altogether */ void* arg; /* argument to kick */ QLock rlock; /* mutex for reading processes */ @@ -795,7 +796,6 @@ qopen(int limit, int msg, void (*kick)(void*), void *arg) if(q == 0) return 0; - ilock(q); q->limit = q->inilim = limit; q->kick = kick; q->arg = arg; @@ -804,7 +804,24 @@ qopen(int limit, int msg, void (*kick)(void*), void *arg) q->state |= Qstarve; q->eof = 0; q->noblock = 0; - iunlock(q); + + return q; +} + +/* open a queue to be bypassed */ +Queue* +qbypass(void (*bypass)(void*, Block*), void *arg) +{ + Queue *q; + + q = malloc(sizeof(Queue)); + if(q == 0) + return 0; + + q->limit = 0; + q->arg = arg; + q->bypass = bypass; + q->state = 0; return q; } @@ -1143,8 +1160,14 @@ qbwrite(Queue *q, Block *b) int n, dowakeup; Proc *p; - dowakeup = 0; n = BLEN(b); + + if(q->bypass){ + (*q->bypass)(q->arg, b); + return n; + } + + dowakeup = 0; qlock(&q->wlock); if(waserror()){ if(b != nil)