From: Phil Mayers <p.mayers@imperial.ac.uk>
To: linux-ppp@vger.kernel.org
Subject: mppe_decompress pessimism / CCP collapse
Date: Tue, 07 Feb 2006 19:55:13 +0000 [thread overview]
Message-ID: <43E8FB21.90505@imperial.ac.uk> (raw)
All,
I'm surprised not to find another report on this. I'm using ppp as part
of a PPTP (Poptop) VPN. We're seeing problems with various crappy
clients getting their realworld MTU, MRU and tunnel MTU wrong.
Whilst investigating this, I found that ANY use of the "mru" option on
an MPPE connection creates a "hole" at the top of the IP MTU which if
any packets are sent with, locks the connection up.
This works:
lock
#uncomment when testing:
debug
# /testing
name pptpd
asyncmap 0
-chap
-mschap
+mschap-v2
require-mppe
lcp-echo-failure 30
lcp-echo-interval 5
ipcp-accept-local
ipcp-accept-remote
using channel 19
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <auth chap MS-v2> <magic
0x4a337f21> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x0 <mru 1400> <magic 0x13cc7131> <pcomp> <accomp>
<callback CBCP>]
sent [LCP ConfRej id=0x0 <callback CBCP>]
rcvd [LCP ConfReq id=0x1 <mru 1400> <magic 0x13cc7131> <pcomp> <accomp>]
sent [LCP ConfAck id=0x1 <mru 1400> <magic 0x13cc7131> <pcomp> <accomp>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <auth chap MS-v2> <magic
0x4a337f21> <pcomp> <accomp>]
rcvd [LCP ConfAck id=0x1 <asyncmap 0x0> <auth chap MS-v2> <magic
0x4a337f21> <pcomp> <accomp>]
sent [LCP EchoReq id=0x0 magic=0x4a337f21]
sent [CHAP Challenge id=0xf5 <CHAL>, name = "pptpd"]
rcvd [LCP code=0xc id=0x2 13 cc 71 31 4d 53 52 41 53 56 35 2e 31 30]
sent [LCP CodeRej id=0x2 0c 02 00 12 13 cc 71 31 4d 53 52 41 53 56 35 2e
31 30]
rcvd [LCP code=0xc id=0x3 13 cc 71 31 4d 53 52 41 53 2d 30 2d 58 50 2d
53 50 32 2d 56 4d 57 41 52 45]
sent [LCP CodeRej id=0x3 0c 03 00 1d 13 cc 71 31 4d 53 52 41 53 2d 30 2d
58 50 2d 53 50 32 2d 56 4d 57 41 52 45]
rcvd [LCP EchoRep id=0x0 magic=0x13cc7131]
rcvd [CHAP Response id=0xf5 <RESP>, name = "user"]
sent [CHAP Success id=0xf5 "S=BYTES"]
sent [CCP ConfReq id=0x1 <mppe +H -M +S +L -D -C>]
rcvd [CCP ConfReq id=0x4 <mppe +H +M +S +L -D +C>]
sent [CCP ConfNak id=0x4 <mppe +H -M +S -L -D -C>]
rcvd [IPCP ConfReq id=0x5 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-wins
0.0.0.0> <ms-dns3 0.0.0.0> <ms-wins 0.0.0.0>]
sent [IPCP TermAck id=0x5]
rcvd [CCP ConfNak id=0x1 <mppe +H -M +S -L -D -C>]
sent [CCP ConfReq id=0x2 <mppe +H -M +S -L -D -C>]
rcvd [CCP ConfReq id=0x6 <mppe +H -M +S -L -D -C>]
sent [CCP ConfAck id=0x6 <mppe +H -M +S -L -D -C>]
rcvd [CCP ConfAck id=0x2 <mppe +H -M +S -L -D -C>]
sent [IPCP ConfReq id=0x1 <compress VJ 0f 01> <addr ADDR>]
rcvd [IPCP ConfRej id=0x1 <compress VJ 0f 01>]
sent [IPCP ConfReq id=0x2 <addr ADDR>]
rcvd [IPCP ConfAck id=0x2 <addr ADDR>]
rcvd [IPCP ConfReq id=0x7 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-wins
0.0.0.0> <ms-dns3 0.0.0.0> <ms-wins 0.0.0.0>]
sent [IPCP ConfNak id=0x7 <addr ADDR> <ms-dns1 DNS1> <ms-wins WINS1>
<ms-dns3 DNS2> <ms-wins WINS2>]
rcvd [IPCP ConfReq id=0x8 <addr ADDR> <ms-dns1 DNS1> <ms-wins WINS1>
<ms-dns3 DNS2> <ms-wins WINS2>]
sent [IPCP ConfAck id=0x8 <addr ADDR> <ms-dns1 DNS1> <ms-wins WINS1>
<ms-dns3 DNS2> <ms-wins WINS2>]
Script /etc/ppp/ip-up started (pid 30930)
Script /etc/ppp/ip-up finished (pid 30930), status = 0x0
I can then send packets with 1400 byte payloads and everything works,
even though pppd has set the MTU to 1396
rcvd [LCP TermReq id=0x9 13 cc 71 31 00 3c cd 74 00 00 00 00]
Script /etc/ppp/ip-down started (pid 30938)
sent [LCP TermAck id=0x9]
Script /etc/ppp/ip-down finished (pid 30938), status = 0x0
However, if I add:
mru 1400
...to the options.pptpd (doesn't matter what value I use, it happens
with all of them), I get:
using channel 20
sent [LCP ConfReq id=0x1 <mru 1400> <asyncmap 0x0> <auth chap MS-v2>
<magic 0xb85c8941> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x0 <mru 1400> <magic 0x6cbd0cba> <pcomp> <accomp>
<callback CBCP>]
sent [LCP ConfRej id=0x0 <callback CBCP>]
rcvd [LCP ConfAck id=0x1 <mru 1400> <asyncmap 0x0> <auth chap MS-v2>
<magic 0xb85c8941> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <mru 1400> <magic 0x6cbd0cba> <pcomp> <accomp>]
sent [LCP ConfAck id=0x1 <mru 1400> <magic 0x6cbd0cba> <pcomp> <accomp>]
sent [LCP EchoReq id=0x0 magic=0xb85c8941]
sent [CHAP Challenge id=0xd1 <CHAL>, name = "pptpd"]
rcvd [LCP code=0xc id=0x2 6c bd 0c ba 4d 53 52 41 53 56 35 2e 31 30]
sent [LCP CodeRej id=0x2 0c 02 00 12 6c bd 0c ba 4d 53 52 41 53 56 35 2e
31 30]
rcvd [LCP code=0xc id=0x3 6c bd 0c ba 4d 53 52 41 53 2d 30 2d 58 50 2d
53 50 32 2d 56 4d 57 41 52 45]
sent [LCP CodeRej id=0x3 0c 03 00 1d 6c bd 0c ba 4d 53 52 41 53 2d 30 2d
58 50 2d 53 50 32 2d 56 4d 57 41 52 45]
rcvd [LCP EchoRep id=0x0 magic=0x6cbd0cba]
rcvd [CHAP Response id=0xd1 <RESP>, name = "user"]
sent [CHAP Success id=0xd1 "S=BYTES"]
sent [CCP ConfReq id=0x1 <mppe +H -M +S +L -D -C>]
rcvd [CCP ConfReq id=0x4 <mppe +H +M +S +L -D +C>]
sent [CCP ConfNak id=0x4 <mppe +H -M +S -L -D -C>]
rcvd [IPCP ConfReq id=0x5 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-wins
0.0.0.0> <ms-dns3 0.0.0.0> <ms-wins 0.0.0.0>]
sent [IPCP TermAck id=0x5]
rcvd [CCP ConfNak id=0x1 <mppe +H -M +S -L -D -C>]
sent [CCP ConfReq id=0x2 <mppe +H -M +S -L -D -C>]
rcvd [CCP ConfReq id=0x6 <mppe +H -M +S -L -D -C>]
sent [CCP ConfAck id=0x6 <mppe +H -M +S -L -D -C>]
rcvd [CCP ConfAck id=0x2 <mppe +H -M +S -L -D -C>]
sent [IPCP ConfReq id=0x1 <compress VJ 0f 01> <addr ADDR>]
rcvd [IPCP ConfRej id=0x1 <compress VJ 0f 01>]
sent [IPCP ConfReq id=0x2 <addr ADDR>]
rcvd [IPCP ConfAck id=0x2 <addr ADDR>]
rcvd [IPCP ConfReq id=0x7 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-wins
0.0.0.0> <ms-dns3 0.0.0.0> <ms-wins 0.0.0.0>]
sent [IPCP ConfNak id=0x7 <addr ADDR> <ms-dns1 DNS1> <ms-wins WINS1>
<ms-dns3 DNS2> <ms-wins WINS2>]
rcvd [IPCP ConfReq id=0x8 <addr ADDR> <ms-dns1 DNS1> <ms-wins WINS2>
<ms-dns3 DNS2> <ms-wins WINS2>]
sent [IPCP ConfAck id=0x8 <addr ADDR> <ms-dns1 DNS1> <ms-wins WINS1>
<ms-dns3 DNS2> <ms-wins WINS2>]
Script /etc/ppp/ip-up started (pid 31165)
Script /etc/ppp/ip-up finished (pid 31165), status = 0x0
Then, when I send a packet of 1400 bytes I get this:
rcvd [Compressed data] 90 13 53 11 6b f8 d5 3d ...
sent [CCP ResetReq id=0x3]
decompress[0]: osize too small! (have: 1404 need: 1405)
...and the connection collapses:
rcvd [Compressed data] 90 14 f6 94 c2 07 e5 db ...
sent [CCP ResetReq id=0x3]
rcvd [Compressed data] 90 15 7c 2d 5d 98 46 23 ...
sent [CCP ResetReq id=0x3]
rcvd [Compressed data] 90 16 67 90 1a 78 d7 1a ...
rcvd [Compressed data] 90 17 65 60 78 20 2c c3 ...
sent [CCP ResetReq id=0x3]
rcvd [LCP TermReq id=0x9
"l\37777777675\014\37777777672\000<\37777777715t\000\000\000\000"]
Script /etc/ppp/ip-down started (pid 31178)
sent [LCP TermAck id=0x9]
Script /etc/ppp/ip-down finished (pid 31178), status = 0x0
I think the problem may be pessimistic code in ppp_mppe.c or I guess
possibly a bug in windows' PPP stack.
Specifically, ppp_generic.c has ppp_decompress_frame, which does:
len = ppp->rcomp->decompress(OTHERARGS, ppp->mru + PPP_HDRLEN);
...and ppp_mppe.c has:
/*
* Make sure we have enough room to decrypt the packet.
* Note that for our test we only subtract 1 byte whereas in
* mppe_compress() we added 2 bytes (+MPPE_OVHD);
* this is to account for possible PFC.
*/
if (osize < isize - MPPE_OVHD - 1) {
printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
"(have: %d need: %d)\n", state->unit,
osize, isize - MPPE_OVHD - 1);
return DECOMP_ERROR;
}
osize = isize - MPPE_OVHD - 2; /* assume no PFC */
I think this "-1" is wrong. Surely it should be a -2, then further down
when it says:
/*
* Do PFC decompression.
* This would be nicer if we were given the actual sk_buff
* instead of a char *.
*/
if ((obuf[0] & 0x01) != 0) {
obuf[1] = obuf[0];
obuf[0] = 0;
obuf++;
osize++;
}
...only THEN once you KNOW you've got a compressed packet add the extra
byte and raise an error if you don't have enough space.
Would this be correct and feasible? If so I'll have a go at a patch, but
it's possible my limited understanding of PPP or MPPE means this would
not help. I don't really understand the user-space code, but as far as I
can tell, it pushes the MRU into the kernel via the ioctl() and that
number ends up as the osize parameter.
So, if you *don't* specify mru, the user-space code pushes DEFMRU, 1500
in and everything is fine. But if you *do* want to decrease the MRU, the
value you specify gets pushed into the kernel *and* sent via LCP, and
the far end obeys it.
Hope I'm being clear - let me know if not.
reply other threads:[~2006-02-07 19:55 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=43E8FB21.90505@imperial.ac.uk \
--to=p.mayers@imperial.ac.uk \
--cc=linux-ppp@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).