ppp-2.3.x ships with a bad compression number for deflate. It uses number

24 (which is magnalink!) rather than the correct (according to the rfc) 26.

Initial attempt at a compatability kludge that will negotiate for either
but will prefer to use the correct deflate compression type.
This commit is contained in:
Peter Wemm
1998-03-22 06:57:20 +00:00
parent 880dcadfce
commit a65dba1221
3 changed files with 186 additions and 4 deletions
+162 -1
View File
@@ -26,7 +26,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id$";
static char rcsid[] = "$Id: ccp.c,v 1.7 1997/08/19 17:52:33 peter Exp $";
#endif
#include <string.h>
@@ -116,8 +116,14 @@ static fsm_callbacks ccp_callbacks = {
/*
* Do we want / did we get any compression?
*/
#ifdef CI_BADDEFLATE
#define ANY_COMPRESS(opt) ((opt).deflate || (opt).baddeflate \
|| (opt).bsd_compress \
|| (opt).predictor_1 || (opt).predictor_2)
#else
#define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \
|| (opt).predictor_1 || (opt).predictor_2)
#endif
/*
* Local state (mainly for handling reset-reqs and reset-acks).
@@ -154,6 +160,13 @@ ccp_init(unit)
ccp_allowoptions[0].deflate = 1;
ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE;
#ifdef CI_BADDEFLATE
ccp_wantoptions[0].baddeflate = 1;
ccp_wantoptions[0].baddeflate_size = DEFLATE_MAX_SIZE;
ccp_allowoptions[0].baddeflate = 1;
ccp_allowoptions[0].baddeflate_size = DEFLATE_MAX_SIZE;
#endif
ccp_wantoptions[0].bsd_compress = 1;
ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS;
ccp_allowoptions[0].bsd_compress = 1;
@@ -322,6 +335,16 @@ ccp_resetci(f)
if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
go->deflate = 0;
}
#ifdef CI_BADDEFLATE
if (go->baddeflate) {
opt_buf[0] = CI_BADDEFLATE;
opt_buf[1] = CILEN_DEFLATE;
opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE);
opt_buf[3] = DEFLATE_CHK_SEQUENCE;
if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
go->baddeflate = 0;
}
#endif
if (go->predictor_1) {
opt_buf[0] = CI_PREDICTOR_1;
opt_buf[1] = CILEN_PREDICTOR_1;
@@ -347,6 +370,9 @@ ccp_cilen(f)
return (go->bsd_compress? CILEN_BSD_COMPRESS: 0)
+ (go->deflate? CILEN_DEFLATE: 0)
#ifdef CI_BADDEFLATE
+ (go->baddeflate? CILEN_DEFLATE: 0)
#endif
+ (go->predictor_1? CILEN_PREDICTOR_1: 0)
+ (go->predictor_2? CILEN_PREDICTOR_2: 0);
}
@@ -388,6 +414,31 @@ ccp_addci(f, p, lenp)
p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
}
}
#ifdef CI_BADDEFLATE
if (go->baddeflate) {
p[0] = CI_BADDEFLATE;
p[1] = CILEN_DEFLATE;
p[2] = DEFLATE_MAKE_OPT(go->baddeflate_size);
p[3] = DEFLATE_CHK_SEQUENCE;
if (p != p0) {
p += CILEN_DEFLATE; /* not the first option */
} else {
for (;;) {
res = ccp_test(f->unit, p, CILEN_DEFLATE, 0);
if (res > 0) {
p += CILEN_DEFLATE;
break;
}
if (res < 0 || go->baddeflate_size <= DEFLATE_MIN_SIZE) {
go->baddeflate = 0;
break;
}
--go->baddeflate_size;
p[2] = DEFLATE_MAKE_OPT(go->baddeflate_size);
}
}
}
#endif
if (go->bsd_compress) {
p[0] = CI_BSD_COMPRESS;
p[1] = CILEN_BSD_COMPRESS;
@@ -460,6 +511,20 @@ ccp_ackci(f, p, len)
if (len == 0)
return 1;
}
#ifdef CI_BADDEFLATE
if (go->baddeflate) {
if (len < CILEN_DEFLATE
|| p[0] != CI_BADDEFLATE || p[1] != CILEN_DEFLATE
|| p[2] != DEFLATE_MAKE_OPT(go->baddeflate_size)
|| p[3] != DEFLATE_CHK_SEQUENCE)
return 0;
p += CILEN_DEFLATE;
len -= CILEN_DEFLATE;
/* XXX Cope with first/fast ack */
if (p == p0 && len == 0)
return 1;
}
#endif
if (go->bsd_compress) {
if (len < CILEN_BSD_COMPRESS
|| p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS
@@ -531,6 +596,25 @@ ccp_nakci(f, p, len)
len -= CILEN_DEFLATE;
}
#ifdef CI_BADDEFLATE
if (go->baddeflate && len >= CILEN_DEFLATE
&& p[0] == CI_BADDEFLATE && p[1] == CILEN_DEFLATE) {
no.baddeflate = 1;
/*
* Peer wants us to use a different code size or something.
* Stop asking for Deflate if we don't understand his suggestion.
*/
if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
|| DEFLATE_SIZE(p[2]) < DEFLATE_MIN_SIZE
|| p[3] != DEFLATE_CHK_SEQUENCE)
try.baddeflate = 0;
else if (DEFLATE_SIZE(p[2]) < go->baddeflate_size)
try.baddeflate_size = DEFLATE_SIZE(p[2]);
p += CILEN_DEFLATE;
len -= CILEN_DEFLATE;
}
#endif
if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
&& p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
no.bsd_compress = 1;
@@ -590,6 +674,17 @@ ccp_rejci(f, p, len)
p += CILEN_DEFLATE;
len -= CILEN_DEFLATE;
}
#ifdef CI_BADDEFLATE
if (go->baddeflate && len >= CILEN_DEFLATE
&& p[0] == CI_BADDEFLATE && p[1] == CILEN_DEFLATE) {
if (p[2] != DEFLATE_MAKE_OPT(go->baddeflate_size)
|| p[3] != DEFLATE_CHK_SEQUENCE)
return 0; /* Rej is bad */
try.baddeflate = 0;
p += CILEN_DEFLATE;
len -= CILEN_DEFLATE;
}
#endif
if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
&& p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
@@ -700,6 +795,51 @@ ccp_reqci(f, p, lenp, dont_nak)
}
break;
#ifdef CI_BADDEFLATE
case CI_BADDEFLATE:
if (!ao->baddeflate || clen != CILEN_DEFLATE) {
newret = CONFREJ;
break;
}
ho->baddeflate = 1;
ho->baddeflate_size = nb = DEFLATE_SIZE(p[2]);
if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
|| p[3] != DEFLATE_CHK_SEQUENCE
|| nb > ao->baddeflate_size || nb < DEFLATE_MIN_SIZE) {
newret = CONFNAK;
if (!dont_nak) {
p[2] = DEFLATE_MAKE_OPT(ao->baddeflate_size);
p[3] = DEFLATE_CHK_SEQUENCE;
/* fall through to test this #bits below */
} else
break;
}
/*
* Check whether we can do Deflate with the window
* size they want. If the window is too big, reduce
* it until the kernel can cope and nak with that.
* We only check this for the first option.
*/
if (p == p0) {
for (;;) {
res = ccp_test(f->unit, p, CILEN_DEFLATE, 1);
if (res > 0)
break; /* it's OK now */
if (res < 0 || nb == DEFLATE_MIN_SIZE || dont_nak) {
newret = CONFREJ;
p[2] = DEFLATE_MAKE_OPT(ho->baddeflate_size);
break;
}
newret = CONFNAK;
--nb;
p[2] = DEFLATE_MAKE_OPT(nb);
}
}
break;
#endif
case CI_BSD_COMPRESS:
if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) {
newret = CONFREJ;
@@ -817,6 +957,15 @@ method_name(opt, opt2)
else
sprintf(result, "Deflate (%d)", opt->deflate_size);
break;
#ifdef CI_BADDEFLATE
case CI_BADDEFLATE:
if (opt2 != NULL && opt2->baddeflate_size != opt->baddeflate_size)
sprintf(result, "Bad-Deflate (%d/%d)", opt->baddeflate_size,
opt2->baddeflate_size);
else
sprintf(result, "Bad-Deflate (%d)", opt->baddeflate_size);
break;
#endif
case CI_BSD_COMPRESS:
if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)
sprintf(result, "BSD-Compress (%d/%d)", opt->bsd_bits,
@@ -941,6 +1090,18 @@ ccp_printpkt(p, plen, printer, arg)
p += CILEN_DEFLATE;
}
break;
#ifdef CI_BADDEFLATE
case CI_BADDEFLATE:
if (optlen >= CILEN_DEFLATE) {
printer(arg, "baddeflate %d", DEFLATE_SIZE(p[2]));
if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL)
printer(arg, " method %d", DEFLATE_METHOD(p[2]));
if (p[3] != DEFLATE_CHK_SEQUENCE)
printer(arg, " check %d", p[3]);
p += CILEN_DEFLATE;
}
break;
#endif
case CI_BSD_COMPRESS:
if (optlen >= CILEN_BSD_COMPRESS) {
printer(arg, "bsd v%d %d", BSD_VERSION(p[2]),
+4 -2
View File
@@ -24,16 +24,18 @@
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
* OR MODIFICATIONS.
*
* $Id$
* $Id: ccp.h,v 1.5 1997/08/19 17:52:33 peter Exp $
*/
typedef struct ccp_options {
u_int bsd_compress: 1; /* do BSD Compress? */
u_int deflate: 1; /* do Deflate? */
u_int deflate: 1; /* do Deflate? (RFC code) */
u_int baddeflate: 1; /* do Deflate? (Magnalink!) */
u_int predictor_1: 1; /* do Predictor-1? */
u_int predictor_2: 1; /* do Predictor-2? */
u_short bsd_bits; /* # bits/code for BSD Compress */
u_short deflate_size; /* lg(window size) for Deflate */
u_short baddeflate_size; /* lg(window size) for Deflate */
short method; /* code for chosen compression method */
} ccp_options;
+20 -1
View File
@@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: options.c,v 1.16 1997/10/10 09:28:37 peter Exp $";
static char rcsid[] = "$Id: options.c,v 1.17 1998/03/22 05:33:03 peter Exp $";
#endif
#include <ctype.h>
@@ -216,6 +216,7 @@ static int setbsdcomp __P((char **));
static int setnobsdcomp __P((char **));
static int setdeflate __P((char **));
static int setnodeflate __P((char **));
static int setnobaddeflate __P((char **));
static int setdemand __P((char **));
static int setpred1comp __P((char **));
static int setnopred1comp __P((char **));
@@ -370,6 +371,8 @@ static struct cmd {
{"deflate", 1, setdeflate}, /* request Deflate compression */
{"nodeflate", 0, setnodeflate}, /* don't allow Deflate compression */
{"-deflate", 0, setnodeflate}, /* don't allow Deflate compression */
{"nobaddeflate", 0, setnobaddeflate}, /* don't allow (wrong) Deflate */
{"-baddeflate", 0, setnobaddeflate}, /* don't allow (wrong) Deflate */
{"predictor1", 0, setpred1comp}, /* request Predictor-1 */
{"nopredictor1", 0, setnopred1comp},/* don't allow Predictor-1 */
{"-predictor1", 0, setnopred1comp}, /* don't allow Predictor-1 */
@@ -2220,6 +2223,13 @@ setdeflate(argv)
ccp_allowoptions[0].deflate_size = abits;
} else
ccp_allowoptions[0].deflate = 0;
/* XXX copy over settings for switch compatability */
ccp_wantoptions[0].baddeflate = ccp_wantoptions[0].deflate;
ccp_wantoptions[0].baddeflate_size = ccp_wantoptions[0].deflate_size;
ccp_allowoptions[0].baddeflate = ccp_allowoptions[0].deflate;
ccp_allowoptions[0].baddeflate_size = ccp_allowoptions[0].deflate_size;
return 1;
}
@@ -2232,6 +2242,15 @@ setnodeflate(argv)
return 1;
}
static int
setnobaddeflate(argv)
char **argv;
{
ccp_wantoptions[0].baddeflate = 0;
ccp_allowoptions[0].baddeflate = 0;
return 1;
}
static int
setpred1comp(argv)
char **argv;