📄 rfc1977.txt
字号:
if (i != db->seqno++) { freemsg(cmsg); if (db->debug) printf("bsd_decomp%d: bad sequence number 0x%x" " instead of 0x%x\n", db->unit, i, db->seqno-1); return 0; }Schryver Informational [Page 19]RFC 1977 PPP BSD Compress August 1996 /* Guess how much memory we will need. Assume this packet was * compressed by at least 1.5X regardless of the recent ratio. */ if (db->ratio > (RATIO_SCALE*3)/2) explen = (msgdsize(cmsg)*db->ratio)/RATIO_SCALE; else explen = (msgdsize(cmsg)*3)/2; if (explen > db->mru) explen = db->mru; dmsg = dmsg1 = allocb(explen+PPP_BUF_HEAD_INFO, BPRI_HI); if (!dmsg1) { freemsg(cmsg); return 0; } wptr = dmsg1->b_wptr; ((struct ppp_buf*)wptr)->type = BEEP_FRAME; /* the protocol field must be compressed */ ((struct ppp_buf*)wptr)->proto = 0; wptr += PPP_BUF_HEAD_PROTO+1; rptr9 = cmsg->b_wptr; db->bytes_out += rptr9-rptr; wptr0 = wptr; explen = dmsg1->b_datap->db_lim - wptr; oldcode = CLEAR; for (;;) { if (rptr >= rptr9) { bp = cmsg; cmsg = cmsg->b_cont; freeb(bp); if (!cmsg) /* quit at end of message */ break; rptr = cmsg->b_rptr; rptr9 = cmsg->b_wptr; db->bytes_out += rptr9-rptr; continue; /* handle 0-length buffers */ } /* Accumulate bytes until we have a complete code. * Then get the next code, relying on the 32-bit, * unsigned accum to mask the result. */ bitno -= 8; accum |= *rptr++ << bitno; if (tgtbitno < bitno)Schryver Informational [Page 20]RFC 1977 PPP BSD Compress August 1996 continue; incode = accum >> tgtbitno; accum <<= n_bits; bitno += n_bits; if (incode == CLEAR) { /* The dictionary must only be cleared at * the end of a packet. But there could be an * empty message block at the end. */ if (rptr != rptr9 || cmsg->b_cont != 0) { cmsg->b_rptr = rptr; i = msgdsize(cmsg); if (i != 0) { freemsg(dmsg); freemsg(cmsg); if (db->debug) printf("bsd_decomp%d: " "bad CLEAR\n", db->unit); return 0; } } pf_bsd_clear(db); freemsg(cmsg); wptr0 = wptr; break; } /* Special case for KwKwK string. */ if (incode > max_ent) { if (incode > max_ent+2 || incode > db->maxmaxcode || oldcode == CLEAR) { freemsg(dmsg); freemsg(cmsg); if (db->debug) printf("bsd_decomp%d: bad code %x\n", db->unit, incode); return 0; } i = db->lens[oldcode]; /* do not write past end of buf */ explen -= i+1; if (explen < 0) { db->undershoot -= explen; db->in_count += wptr-wptr0;Schryver Informational [Page 21]RFC 1977 PPP BSD Compress August 1996 dmsg1->b_wptr = wptr; CK_WPTR(dmsg1); explen = MAX(64,i+1); bp = allocb(explen, BPRI_HI); if (!bp) { freemsg(cmsg); freemsg(dmsg); return 0; } dmsg1->b_cont = bp; dmsg1 = bp; wptr0 = wptr = dmsg1->b_wptr; explen=dmsg1->b_datap->db_lim-wptr-(i+1); } p = (wptr += i); *wptr++ = finchar; finchar = oldcode; } else { i = db->lens[finchar = incode]; explen -= i; if (explen < 0) { db->undershoot -= explen; db->in_count += wptr-wptr0; dmsg1->b_wptr = wptr; CK_WPTR(dmsg1); explen = MAX(64,i); bp = allocb(explen, BPRI_HI); if (!bp) { freemsg(dmsg); freemsg(cmsg); return 0; } dmsg1->b_cont = bp; dmsg1 = bp; wptr0 = wptr = dmsg1->b_wptr; explen = dmsg1->b_datap->db_lim-wptr-i; } p = (wptr += i); } /* decode code and install in decompressed buffer */ while (finchar > LAST) { dictp = &db->dict[db->dict[finchar].cptr]; *--p = dictp->f.hs.suffix; finchar = dictp->f.hs.prefix; } *--p = finchar;Schryver Informational [Page 22]RFC 1977 PPP BSD Compress August 1996 /* If not first code in a packet, and * if not out of code space, then allocate a new code. * * Keep the hash table correct so it can be used * with uncompressed packets. */ if (oldcode != CLEAR && max_ent < db->maxmaxcode) { struct bsd_dict *dictp2; __uint32_t fcode; int hval, disp; fcode = BSD_KEY(oldcode,finchar); hval = BSD_HASH(oldcode,finchar,db->hshift); dictp = &db->dict[hval]; /* look for a free hash table entry */ if (dictp->codem1 < max_ent) { disp = (hval == 0) ? 1 : hval; do { hval += disp; if (hval >= db->hsize) hval -= db->hsize; dictp = &db->dict[hval]; } while (dictp->codem1 < max_ent); } /* Invalidate previous hash table entry * assigned this code, and then take it over */ dictp2 = &db->dict[max_ent+1]; if (db->dict[dictp2->cptr].codem1 == max_ent) { db->dict[dictp2->cptr].codem1=BADCODEM1; } dictp2->cptr = hval; dictp->codem1 = max_ent; dictp->f.fcode = fcode; db->max_ent = ++max_ent; db->lens[max_ent] = db->lens[oldcode]+1; /* Expand code size if needed. */ if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) { db->n_bits = ++n_bits; tgtbitno = 32-n_bits; } }Schryver Informational [Page 23]RFC 1977 PPP BSD Compress August 1996 oldcode = incode; } db->in_count += wptr-wptr0; dmsg1->b_wptr = wptr; CK_WPTR(dmsg1); db->overshoot += explen; /* Keep the checkpoint right so that incompressible packets * clear the dictionary at the right times. */ if (pf_bsd_check(db) && db->debug) { printf("bsd_decomp%d: peer should have " "cleared dictionary\n", db->unit); } return dmsg;}Security Considerations Security issues are not discussed in this memo.References [1] Simpson, W., "The Point-to-Point Protocol (PPP)", STD 51, RFC 1661, July 1994. [2] Rand, D., "The PPP Compression Control Protocol (CCP)", RFC 1962, June 1996. [3] Simpson, W., "PPP LCP Extensions", RFC 1570, January 1994. [4] Simpson, W., "PPP in HDLC-like Framing", STD 51, RFC 1662, July 1994.Acknowledgments William Simpson provided and supported the very valuable idea of not using any additional header bytes for incompressible packets.Schryver Informational [Page 24]RFC 1977 PPP BSD Compress August 1996Chair's Address The working group can be contacted via the current chair: Karl Fox Ascend Communications 3518 Riverside Drive, Suite 101 Columbus, Ohio 43221 EMail: karl@ascend.comAuthor's Address Questions about this memo can also be directed to: Vernon Schryver 2482 Lee Hill Drive Boulder, Colorado 80302 EMail: vjs@rhyolite.comSchryver Informational [Page 25]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -