From ab1ac347a37a51424d62cef8fcd2b418dadce593 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 9 Feb 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-02-09 --- ip/devip.c | 50 +++++++----- ip/udp.c | 223 ++++++++++++++++++++++++++--------------------------- 2 files changed, 141 insertions(+), 132 deletions(-) diff --git a/ip/devip.c b/ip/devip.c index c0c73884f530837ac8ec06753e7317431093538d..c7c1068022bd71d8039b533931bc542b2af299bb 100644 --- a/ip/devip.c +++ b/ip/devip.c @@ -731,11 +731,7 @@ setlport(Conv* c) /* * set a local address and port from a string of the form - * address!port - * if address is missing and not announcing, pick one - * if address is missing and announcing, leave address as zero (i.e. matches anything) - * if port is 0, pick a free one - * if port is '*', leave port as zero (i.e. matches anything) + * [address!]port[!r] */ static char* setladdrport(Conv* c, char* str, int announcing) @@ -751,25 +747,41 @@ setladdrport(Conv* c, char* str, int announcing) * meaningless on local ports. */ p = strchr(str, '!'); - if(p == nil || strcmp(p, "!r") == 0) { - p = str; - memset(c->laddr, 0, sizeof(c->laddr)); - if(!announcing) - setladdr(c); - } else { + if(p != nil){ *p++ = 0; - parseip(c->laddr, str); + if(strcmp(p, "r") == 0) + p = nil; } c->lport = 0; - if(*p != '*'){ - lport = atoi(p); - if(lport > 0) - rv = setluniqueport(c, lport); - else + if(announcing){ + if(p == nil){ + ipmove(c->laddr, IPnoaddr); + lport = atoi(str); + } else { + if(strcmp(str, "*") == 0) + ipmove(c->laddr, IPnoaddr); + else + parseip(c->laddr, str); + lport = atoi(p); + } + rv = setluniqueport(c, lport); + } else { + if(p == nil){ + setladdr(c); + lport = atoi(str); + } else { + if(strcmp(str, "*") == 0) + setladdr(c); + else + parseip(c->laddr, str); + lport = atoi(p); + } + if(lport <= 0) setlport(c); - } else - rv = setluniqueport(c, 0); + else + rv = setluniqueport(c, lport); + } return rv; } diff --git a/ip/udp.c b/ip/udp.c index 45b5b02894a31f813c6957c8510d519dbffd280b..b0b791e3df0290feccea87c3539e9648293ff214 100644 --- a/ip/udp.c +++ b/ip/udp.c @@ -45,35 +45,25 @@ struct Udphdr uchar udpcksum[2]; /* Checksum */ }; -enum +/* MIB II counters */ +typedef struct Udpstats Udpstats; +struct Udpstats { - /* MIB II counters */ - InDatagrams, - NoPorts, - InErrors, - OutDatagrams, - - /* non-MIB counters */ - CsumErrs, - LenErrs, - - Nstats, + ulong udpInDatagrams; + ulong udpNoPorts; + ulong udpInErrors; + ulong udpOutDatagrams; }; -static char *statnames[] = { -[InDatagrams] "InDatagrams", -[NoPorts] "NoPorts", -[InErrors] "InErrors", -[OutDatagrams] "OutDatagrams", -[CsumErrs] "CsumErrs", -[LenErrs] "LenErrs", -}; - - typedef struct Udppriv Udppriv; struct Udppriv { - ulong stats[Nstats]; + /* MIB counters */ + Udpstats ustats; + + /* non-MIB stats */ + ulong csumerr; /* checksum errors */ + ulong lenerr; /* short packet */ }; /* @@ -120,8 +110,8 @@ udpannounce(Conv *c, char** argv, int argc) static void udpcreate(Conv *c) { - c->rq = qopen(256*1024, 1, 0, 0); - c->wq = qopen(128*1024, 0, 0, 0); + c->rq = qopen(64*1024, 1, 0, 0); + c->wq = qopen(64*1024, 0, 0, 0); } static void @@ -140,6 +130,8 @@ udpclose(Conv *c) ucb = (Udpcb*)c->ptcl; ucb->headers = 0; + + qunlock(c); } void @@ -234,16 +226,26 @@ udpkick(Conv *c, int) hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_HDRSIZE)); - upriv->stats[OutDatagrams]++; + upriv->ustats.udpOutDatagrams++; ipoput(f, bp, 0, c->ttl, c->tos); } +Conv* +udpincoming(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport) +{ + Conv *new; + + new = Fsnewcall(c, raddr, rport, laddr, lport); + if(new == nil) + return nil; +} + void udpiput(Proto *udp, uchar *ia, Block *bp) { int len, olen, ottl; Udphdr *uh; - Conv *c, **p, *spec, *gen; + Conv *c, **p, *gen; Udpcb *ucb; uchar raddr[IPaddrlen], laddr[IPaddrlen]; ushort rport, lport; @@ -253,7 +255,7 @@ udpiput(Proto *udp, uchar *ia, Block *bp) upriv = udp->priv; f = udp->f; - upriv->stats[InDatagrams]++; + upriv->ustats.udpInDatagrams++; uh = (Udphdr*)(bp->rp); @@ -271,8 +273,7 @@ udpiput(Proto *udp, uchar *ia, Block *bp) if(nhgets(uh->udpcksum)) { if(ptclcsum(bp, UDP_IPHDR, len+UDP_PHDRSIZE)) { - upriv->stats[InErrors]++; - upriv->stats[CsumErrs]++; + upriv->ustats.udpInErrors++; netlog(f, Logudp, "udp: checksum error %I\n", raddr); DPRINT("udp: checksum error %I\n", raddr); freeblist(bp); @@ -282,64 +283,84 @@ udpiput(Proto *udp, uchar *ia, Block *bp) qlock(udp); - /* - * Look for a conversation structure for this packet - */ - spec = gen = c = nil; - for(p = udp->conv; *p; p++) { + gen = nil; + + /* look for an announced port with headers (most likely) */ + for(p = udp->conv; *p; p++){ c = *p; - if(c->inuse == 0) + ucb = (Udpcb*)c->ptcl; + if(c->inuse == 0 || c->state != Announced || ucb->headers == 0) continue; - if(c->lport == lport){ - ucb = (Udpcb*)c->ptcl; - - switch(c->state){ - case Announced: - /* headers + Announced is special behaviour */ - if(ucb->headers) - goto found; - spec = c; - break; - - case Connected: - /* exact match */ - if(c->rport == rport) - if(ipcmp(c->raddr, raddr) == 0 || ipisbm(c->raddr)) - goto found; - } - - } else if(c->lport == 0) { - /* generic listen for all udp ports */ - if(c->state == Announced) - gen = c; - } + + if(c->lport != lport) + continue; + + if(ipcmp(c->laddr, laddr) == 0) + goto found; + + if(ipcmp(c->laddr, IPnoaddr) == 0 || ipcmp(c->laddr, v4prefix) == 0) + gen = c; } -found: - if(*p == nil){ - if(spec != nil) - gen = spec; - if(gen != nil){ - if(ipforme(f, laddr) != Runi) - v4tov6(laddr, ia); - c = Fsnewcall(gen, raddr, rport, laddr, lport); - if(c == nil){ - freeblist(bp); - return; - } - c->state = Connected; - } else { - upriv->stats[NoPorts]++; - 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); + if(gen != nil){ + c = gen; + goto found; + } + + /* look for a connected port */ + for(p = udp->conv; *p; p++){ + c = *p; + if(c->inuse == 0 || c->state != Connected) + continue; + if(c->lport == lport + && c->rport == rport + && (ipcmp(c->laddr, laddr) == 0) + && ipcmp(c->raddr, raddr) == 0 || ipisbm(c->raddr)) + goto found; + } + + /* finally, look for a listener */ + for(p = udp->conv; *p; p++){ + c = *p; + ucb = (Udpcb*)c->ptcl; + if(c->inuse == 0 || c->state != Announced || ucb->headers != 0) + continue; + + if(c->lport != lport) + continue; + + if(ipcmp(c->laddr, laddr) == 0) + break; + + if(ipcmp(c->laddr, IPnoaddr) == 0) + gen = c; + } + c = *p; + if(c == nil) + c = gen; + if(c != nil){ + if(ipforme(f, laddr) != Runi) + v4tov6(laddr, ia); + c = Fsnewcall(gen, raddr, rport, laddr, lport); + if(c == nil){ freeblist(bp); return; } + c->state = Connected; + goto found; } + /* no converstation found */ + 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; + +found: ucb = (Udpcb*)c->ptcl; qlock(c); qunlock(udp); @@ -353,8 +374,7 @@ found: qunlock(c); netlog(f, Logudp, "udp: len err %I.%d -> %I.%d\n", raddr, rport, laddr, lport); - upriv->stats[LenErrs]++; - upriv->stats[InErrors]++; + upriv->lenerr++; return; } @@ -402,22 +422,6 @@ found: } -/* - * close any incoming calls waiting on this conversation - * called with c locked - */ -void -udpcloseincalls(Conv *c) -{ - Conv *nc; - - for(nc = c->incall; nc; nc = c->incall){ - c->incall = nc->next; - closeconv(nc); - } -} - -/* called with c locked */ char* udpctl(Conv *c, char **f, int n) { @@ -427,13 +431,9 @@ udpctl(Conv *c, char **f, int n) if(n == 1){ if(strcmp(f[0], "headers4") == 0){ ucb->headers = 4; - /* close any calls that got in twixt announce and headers */ - udpcloseincalls(c); return nil; } else if(strcmp(f[0], "headers") == 0){ ucb->headers = 6; - /* close any calls that got in twixt announce and headers */ - udpcloseincalls(c); return nil; } } @@ -479,16 +479,14 @@ udpadvise(Proto *udp, Block *bp, char *msg) int udpstats(Proto *udp, char *buf, int len) { - Udppriv *priv; - char *p, *e; - int i; - - priv = udp->priv; - p = buf; - e = p+len; - for(i = 0; i < Nstats; i++) - p = seprint(p, e, "%s: %lud\n", statnames[i], priv->stats[i]); - return p - buf; + Udppriv *upriv; + + upriv = udp->priv; + return snprint(buf, len, "%lud %lud %lud %lud", + upriv->ustats.udpInDatagrams, + upriv->ustats.udpNoPorts, + upriv->ustats.udpInErrors, + upriv->ustats.udpOutDatagrams); } void @@ -509,7 +507,6 @@ udpinit(Fs *fs) udp->rcv = udpiput; udp->advise = udpadvise; udp->stats = udpstats; - udp->gc = nil; udp->ipproto = IP_UDPPROTO; udp->nc = Nchans; udp->ptclsize = sizeof(Udpcb);