diff 278caaf11931ec0c71fc13fd4c4794fae325c404 uncommitted --- a/sys/src/cmd/ip/ppp/block.c +++ b/sys/src/cmd/ip/ppp/block.c @@ -7,93 +7,18 @@ enum { PAD = 128, - NLIST = (1<<5), - BPOW = 10, }; -typedef struct Barena Barena; -struct Barena -{ - QLock; - Block* list[NLIST]; -}; -static Barena area; - -#define ADEBUG if(0) - - -/* - * allocation tracing - */ -enum -{ - Npc= 64, -}; -typedef struct Arefent Arefent; -struct Arefent -{ - uint pc; - uint n; -}; -typedef struct Aref Aref; -struct Aref -{ - Arefent tab[Npc]; - QLock; -}; -Aref arefblock; - -static ulong callerpc(void*); -static void aref(Aref*, ulong); -static void aunref(Aref*, ulong); - Block* allocb(int len) { - int sz; - Block *bp, **l; - + Block *bp; len += PAD; - sz = (len>>BPOW)&(NLIST-1); - - qlock(&area); - l = &area.list[sz]; - for(bp = *l; bp; bp = bp->flist) { - if(bp->bsz >= len) { - *l = bp->flist; - qunlock(&area); - - bp->next = nil; - bp->list = nil; - bp->flist = nil; - bp->base = (uchar*)bp+sizeof(Block); - bp->rptr = bp->base+PAD; - bp->wptr = bp->rptr; - bp->lim = bp->base+bp->bsz; - bp->flow = nil; - bp->flags= 0; - ADEBUG { - bp->pc = callerpc(&len); - aref(&arefblock, bp->pc); - } - return bp; - } - l = &bp->flist; - } - - qunlock(&area); - - bp = mallocz(sizeof(Block)+len, 1); - - bp->bsz = len; + bp = mallocz(sizeof(Block)+len, 0); bp->base = (uchar*)bp+sizeof(Block); bp->rptr = bp->base+PAD; bp->wptr = bp->rptr; bp->lim = bp->base+len; - ADEBUG { - bp->pc = callerpc(&len); - aref(&arefblock, bp->pc); - } return bp; } @@ -100,267 +25,5 @@ void freeb(Block *bp) { - int sz; - Block **l, *next; - - qlock(&area); - while(bp) { - sz = (bp->bsz>>BPOW)&(NLIST-1); - - l = &area.list[sz]; - bp->flist = *l; - *l = bp; - - next = bp->next; - - /* to catch use after free */ - bp->rptr = (uchar*)0xdeadbabe; - bp->wptr = (uchar*)0xdeadbabe; - bp->next = (Block*)0xdeadbabe; - bp->list = (Block*)0xdeadbabe; - - ADEBUG aunref(&arefblock, bp->pc); - - bp = next; - } - qunlock(&area); -} - -/* - * concatenate a list of blocks into a single one and make sure - * the result is at least min uchars - */ -Block* -concat(Block *bp) -{ - int len; - Block *nb, *f; - - nb = allocb(blen(bp)); - for(f = bp; f; f = f->next) { - len = BLEN(f); - memmove(nb->wptr, f->rptr, len); - nb->wptr += len; - } - freeb(bp); - return nb; -} - -int -blen(Block *bp) -{ - int len; - - len = 0; - while(bp) { - len += BLEN(bp); - bp = bp->next; - } - return len; -} - -Block * -pullup(Block *bp, int n) -{ - int i; - Block *nbp; - - /* - * this should almost always be true, the rest it - * just for to avoid every caller checking. - */ - if(BLEN(bp) >= n) - return bp; - - /* - * if not enough room in the first block, - * add another to the front of the list. - */ - if(bp->lim - bp->rptr < n){ - nbp = allocb(n); - nbp->next = bp; - bp = nbp; - } - - /* - * copy uchars from the trailing blocks into the first - */ - n -= BLEN(bp); - while(nbp = bp->next){ - i = BLEN(nbp); - if(i >= n) { - memmove(bp->wptr, nbp->rptr, n); - bp->wptr += n; - nbp->rptr += n; - return bp; - } - else { - memmove(bp->wptr, nbp->rptr, i); - bp->wptr += i; - bp->next = nbp->next; - nbp->next = nil; - freeb(nbp); - n -= i; - } - } - freeb(bp); - return nil; -} - -/* - * Pad a block to the front with n uchars. This is used to add protocol - * headers to the front of blocks. - */ -Block* -padb(Block *bp, int n) -{ - Block *nbp; - - if(bp->rptr-bp->base >= n) { - bp->rptr -= n; - return bp; - } - else { - /* fprint(2, "padb: required %d PAD %d\n", n, PAD) = malloc(sizeof(*required %d PAD %d\n", n, PAD))); */ - nbp = allocb(n); - nbp->wptr = nbp->lim; - nbp->rptr = nbp->wptr - n; - nbp->next = bp; - return nbp; - } -} - -Block * -btrim(Block *bp, int offset, int len) -{ - ulong l; - Block *nb, *startb; - - if(blen(bp) < offset+len) { - freeb(bp); - return nil; - } - - while((l = BLEN(bp)) < offset) { - offset -= l; - nb = bp->next; - bp->next = nil; - freeb(bp); - bp = nb; - } - - startb = bp; - bp->rptr += offset; - - while((l = BLEN(bp)) < len) { - len -= l; - bp = bp->next; - } - - bp->wptr -= (BLEN(bp) - len); - bp->flags |= S_DELIM; - - if(bp->next) { - freeb(bp->next); - bp->next = nil; - } - - return startb; -} - -Block* -copyb(Block *bp, int count) -{ - int l; - Block *nb, *head, **p; - - p = &head; - head = nil; - while(bp != nil && count != 0) { - l = BLEN(bp); - if(count < l) - l = count; - nb = allocb(l); - memmove(nb->wptr, bp->rptr, l); - nb->wptr += l; - count -= l; - nb->flags = bp->flags; - *p = nb; - p = &nb->next; - bp = bp->next; - } - if(count) { - nb = allocb(count); - memset(nb->wptr, 0, count); - nb->wptr += count; - nb->flags |= S_DELIM; - *p = nb; - } - if(blen(head) == 0) - fprint(2, "copyb: zero length\n"); - - return head; -} - -int -pullb(Block **bph, int count) -{ - Block *bp; - int n, uchars; - - uchars = 0; - if(bph == nil) - return 0; - - while(*bph != nil && count != 0) { - bp = *bph; - n = BLEN(bp); - if(count < n) - n = count; - uchars += n; - count -= n; - bp->rptr += n; - if(BLEN(bp) == 0) { - *bph = bp->next; - bp->next = nil; - freeb(bp); - } - } - return uchars; -} - -/* - * handy routines for keeping track of allocations - */ -static ulong -callerpc(void *a) -{ - return ((ulong*)a)[-1]; -} -static void -aref(Aref *ap, ulong pc) -{ - Arefent *a, *e; - - e = &ap->tab[Npc-1]; - qlock(ap); - for(a = ap->tab; a < e; a++) - if(a->pc == pc || a->pc == 0) - break; - a->pc = pc; - a->n++; - qunlock(ap); -} -static void -aunref(Aref *ap, ulong pc) -{ - Arefent *a, *e; - - e = &ap->tab[Npc-1]; - qlock(ap); - for(a = ap->tab; a < e; a++) - if(a->pc == pc || a->pc == 0) - break; - a->n--; - qunlock(ap); + free(bp); } --- a/sys/src/cmd/ip/ppp/compress.c +++ b/sys/src/cmd/ip/ppp/compress.c @@ -439,12 +439,8 @@ * We assume the packet we were handed has enough space to prepend * up to 128 uchars of header. */ - b->rptr = cp; - if(b->rptr - b->base < len){ - b = padb(b, len); - b = pullup(b, blen(b)); - } else - b->rptr -= len; + b->rptr = cp - len; + assert(b->rptr >= b->base); hnputs(ip->length, BLEN(b)); memmove(b->rptr, ip, len); --- a/sys/src/cmd/ip/ppp/ipaux.c +++ b/sys/src/cmd/ip/ppp/ipaux.c @@ -4,126 +4,19 @@ #include #include "ppp.h" -static ushort endian = 1; -static uchar* aendian = (uchar*)&endian; -#define LITTLE *aendian - ushort -ptclbsum(uchar *addr, int len) -{ - ulong losum, hisum, mdsum, x; - ulong t1, t2; - - losum = 0; - hisum = 0; - mdsum = 0; - - x = 0; - if((uintptr)addr & 1) { - if(len) { - hisum += addr[0]; - len--; - addr++; - } - x = 1; - } - while(len >= 16) { - t1 = *(ushort*)(addr+0); - t2 = *(ushort*)(addr+2); mdsum += t1; - t1 = *(ushort*)(addr+4); mdsum += t2; - t2 = *(ushort*)(addr+6); mdsum += t1; - t1 = *(ushort*)(addr+8); mdsum += t2; - t2 = *(ushort*)(addr+10); mdsum += t1; - t1 = *(ushort*)(addr+12); mdsum += t2; - t2 = *(ushort*)(addr+14); mdsum += t1; - mdsum += t2; - len -= 16; - addr += 16; - } - while(len >= 2) { - mdsum += *(ushort*)addr; - len -= 2; - addr += 2; - } - if(x) { - if(len) - losum += addr[0]; - if(LITTLE) - losum += mdsum; - else - hisum += mdsum; - } else { - if(len) - hisum += addr[0]; - if(LITTLE) - hisum += mdsum; - else - losum += mdsum; - } - - losum += hisum >> 8; - losum += (hisum & 0xff) << 8; - while(hisum = losum>>16) - losum = hisum + (losum & 0xffff); - - return losum & 0xffff; -} - -ushort ptclcsum(Block *bp, int offset, int len) { uchar *addr; - ulong losum, hisum; - ushort csum; - int odd, blen, x; + int blen; - /* Correct to front of data area */ - while(bp != nil && offset && offset >= BLEN(bp)) { - offset -= BLEN(bp); - bp = bp->next; - } - if(bp == nil) + if(bp == nil || bp->rptr + offset >= bp->wptr) return 0; - addr = bp->rptr + offset; blen = BLEN(bp) - offset; - - if(bp->next == nil) { - if(blen < len) - len = blen; - return ~ptclbsum(addr, len) & 0xffff; - } - - losum = 0; - hisum = 0; - - odd = 0; - while(len) { - x = blen; - if(len < x) - x = len; - - csum = ptclbsum(addr, x); - if(odd) - hisum += csum; - else - losum += csum; - odd = (odd+x) & 1; - len -= x; - - bp = bp->next; - if(bp == nil) - break; - blen = BLEN(bp); - addr = bp->rptr; - } - - losum += hisum>>8; - losum += (hisum&0xff)<<8; - while((csum = losum>>16) != 0) - losum = csum + (losum & 0xffff); - - return ~losum & 0xffff; + if(blen < len) + len = blen; + return ~ptclbsum(addr, len) & 0xffff; } ushort --- a/sys/src/cmd/ip/ppp/ppp.c +++ b/sys/src/cmd/ip/ppp/ppp.c @@ -482,6 +482,7 @@ *to++ = c; fcs = (fcs >> 8) ^ fcstab[(fcs ^ c) & 0xff]; } + b->wptr = to - 2; /* copy down what's left in buffer */ p++; @@ -488,7 +489,6 @@ memmove(buf->rptr, p, buf->wptr - p); n = p - buf->rptr; buf->wptr -= n; - b->wptr = to - 2; /* return to caller if checksum matches */ if(fcs == PPP_goodfcs){ @@ -521,12 +521,10 @@ static int putframe(PPP *ppp, int proto, Block *b) { - Block *buf; uchar *to, *from; ushort fcs; ulong ctlmap; uchar c; - Block *bp; ppp->out.packets++; @@ -536,10 +534,7 @@ ctlmap = ppp->xctlmap; /* make sure we have head room */ - if(b->rptr - b->base < 4){ - b = padb(b, 4); - b->rptr += 4; - } + assert(b->rptr - b->base >= 4); netlog("ppp: putframe 0x%ux %zd\n", proto, BLEN(b)); @@ -554,37 +549,26 @@ } qlock(&ppp->outlock); - buf = ppp->outbuf; + if(ppp->framing == 0) + to = b->wptr; + else { + to = ppp->outbuf->rptr; - if(ppp->framing == 0) { - to = buf->rptr; - for(bp = b; bp; bp = bp->next){ - if(bp != b) - from = bp->rptr; - memmove(to, from, bp->wptr-from); - to += bp->wptr-from; - } - } else { /* escape and checksum the body */ fcs = PPP_initfcs; - to = buf->rptr; /* add frame marker */ *to++ = HDLC_frame; - for(bp = b; bp; bp = bp->next){ - if(bp != b) - from = bp->rptr; - for(; from < bp->wptr; from++){ - c = *from; - if(c == HDLC_frame || c == HDLC_esc - || (c < 0x20 && ((1<> 8) ^ fcstab[(fcs ^ c) & 0xff]; - } + for(; from < b->wptr; from++){ + c = *from; + if(c == HDLC_frame || c == HDLC_esc + || (c < 0x20 && ((1<> 8) ^ fcstab[(fcs ^ c) & 0xff]; } /* add on and escape the checksum */ @@ -606,16 +590,17 @@ /* add frame marker */ *to++ = HDLC_frame; - } - /* send */ - buf->wptr = to; - dmppkt("TX", buf->rptr, BLEN(buf)); - if(write(ppp->mediaout, buf->rptr, BLEN(buf)) < 0){ + from = ppp->outbuf->rptr; + } + + dmppkt("TX", from, to - from); + if(write(ppp->mediaout, from, to - from) < 0){ qunlock(&ppp->outlock); + return -1; } - ppp->out.uchars += BLEN(buf); + ppp->out.uchars += to - from; qunlock(&ppp->outlock); return 0; @@ -1892,7 +1877,7 @@ Iphdr *ip; Ip6hdr *ip6; - len = blen(b); + len = BLEN(b); ip = (Iphdr*)b->rptr; switch(ip->vihl & 0xF0){ default: @@ -1902,9 +1887,12 @@ case IP_VER4: if(len < IPV4HDR_LEN || (tot = nhgets(ip->length)) < IPV4HDR_LEN) goto Badhdr; - b = btrim(b, 0, tot); - if(b == nil) + + if(b->wptr < (uchar*)ip + tot){ + freeb(b); return len; + } + b->wptr = (uchar*)ip + tot; qlock(ppp); if(ppp->ipcp->state != Sopened) @@ -1924,9 +1912,12 @@ if(len < IPV6HDR_LEN) goto Badhdr; ip6 = (Ip6hdr*)ip; - b = btrim(b, 0, IPV6HDR_LEN + nhgets(ip6->ploadlen)); - if(b == nil) + tot = IPV6HDR_LEN + nhgets(ip6->ploadlen); + if(b->wptr < (uchar*)ip6 + tot){ + freeb(b); return len; + } + b->wptr = (uchar*)ip6 + tot; qlock(ppp); if(ppp->ipv6cp->state != Sopened) @@ -1941,7 +1932,7 @@ if(proto == Pcdata) { ppp->stat.comp++; ppp->stat.compin += len; - ppp->stat.compout += blen(b); + ppp->stat.compout += BLEN(b); } } @@ -2051,10 +2042,10 @@ } ppp->stat.iprecv++; if(debug > 1){ - netlog("ip write pkt %p %d\n", b->rptr, blen(b)); - hexdump(b->rptr, blen(b)); + netlog("ip write pkt %p %zd\n", b->rptr, BLEN(b)); + hexdump(b->rptr, BLEN(b)); } - if(write(ppp->ipfd, b->rptr, blen(b)) < 0) { + if(write(ppp->ipfd, b->rptr, BLEN(b)) < 0) { syslog(0, LOG, "error writing to pktifc"); freeb(b); break; --- a/sys/src/cmd/ip/ppp/ppp.h +++ b/sys/src/cmd/ip/ppp/ppp.h @@ -19,41 +19,15 @@ */ struct Block { - Block *next; - Block *flist; - Block *list; /* chain of block lists */ uchar *rptr; /* first unconsumed uchar */ uchar *wptr; /* first empty uchar */ uchar *lim; /* 1 past the end of the buffer */ uchar *base; /* start of the buffer */ - uchar flags; - void *flow; - ulong pc; - ulong bsz; }; #define BLEN(b) ((b)->wptr-(b)->rptr) -enum -{ - /* block flags */ - S_DELIM = (1<<0), - S_HANGUP = (1<<1), - S_RHANGUP = (1<<2), - - /* queue states */ - QHUNGUP = (1<<0), - QFLOW = (1<<1), /* queue is flow controlled */ -}; - Block* allocb(int); void freeb(Block*); -Block* concat(Block*); -int blen(Block*); -Block* pullup(Block*, int); -Block* padb(Block*, int); -Block* btrim(Block*, int, int); -Block* copyb(Block*, int); -int pullb(Block**, int); enum { HDLC_frame= 0x7e,