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:
+162
-1
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user