[pptp-server] Possible patch/bugfix for dropped packets killing mppe

Eric H eric at we-24-30-125-179.we.mediaone.net
Wed May 17 13:30:10 CDT 2000


Whenever I had a packet drop, mppe would die. I wrote a quick fix for
it... If someone else can verify it works for them (and they were having
the same problem with mppe dropping when a packet drops), I'd greatly
appreciate it. This patch is from ppp-2.3.11, but I think it'll work on
older versions. It assumes you have already used the mppe_stateless and
the original ppp-2.3.10 patch. Run it from the ppp-2.3.x directory. It
modifies linux/ppp_mppe.c and pppd/ccp.c PLEASE: Don't blame me if this
screws something up! :) Like I said, I haven't fully tested it, BUT it did
work nicely from the machine I was getting dropped packets (It still
drops packets, but it doesn't kill off mppe.)
I tried to make it conform to:
http://www.ietf.org/internet-drafts/draft-ietf-pppext-mppe-04.txt
under sections
8.1 Stateless Synchronization
and 8.2 Statefull Synchronization

(please note the reply to field if you try to email
me: eharashe at mediaone.net)

Eric Harashevsky (eharashe at mediaone.net)
----------------------------------------------------------------
Health food makes me sick.
-------------- next part --------------
--- linux/ppp_mppe.c.orig	Tue May 16 18:21:23 2000
+++ linux/ppp_mppe.c	Wed May 17 11:17:06 2000
@@ -83,6 +83,7 @@
     int			keylen;
     int                 stateless;
     int                 decomp_error;
+    int                 mppe_flush;  /* To discard packets before a FLUSH */
     unsigned int	bits;
     int			unit;
     int			debug;
@@ -498,18 +500,33 @@
     }
 
     if (seq != state->ccount) {
-	if (state->debug) {
-	    printk(KERN_DEBUG "mppe_decompress%d: bad seq # %d, expected %d\n",
-		   state->unit, seq, state->ccount);
-	}
-
-        while(state->ccount != seq) {
-            mppe_update_count(state);
+      if (state->debug) {  
+	printk(KERN_DEBUG "mppe_decompress%d: bad seq # %d, expected %d\n",
+	       state->unit, seq, state->ccount);
+     }  
+
+      if (state->stateless) {
+	while(state->ccount != seq) { 
+	  mppe_update_count(state); 
+	} 
+      } else {
+	/* DO NOT resend resets! */
+	if (state->mppe_flush!=1) {
+	  if (state->debug)
+	    printk(KERN_DEBUG "mppe_decompress: Sending CCP_RESETREQ\n");
+	  state->mppe_flush=1; /* ignore packets till a flush bit */
+	  mppe_synchronize_key(state); /* needed ? */
+	  return DECOMP_ERROR; /* will cause a reset */
+	  /* This seems to turn off mppe briefly, but probably not too bad
+	   * (I noticed some pppd: rcvd Compressed data). It definitely
+	   * gets turned on again if it does go off...
+	   */
+	} else {
+	  if (state->debug)
+	    printk(KERN_DEBUG "mppe_decompress: Sent reset -- ignoring\n");
 	}
-
-        mppe_update_count(state);
-
-	return DECOMP_ERROR;
+      }
+      /* DO NOT return an error for stateless */
     }
 
     /*
@@ -525,12 +542,23 @@
         mppe_synchronize_key(state);
 	return DECOMP_ERROR;
     } else {
-	if(!state->stateless && (MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED))
+       if(!state->stateless) {
+	 if (MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED) {
+	    state->mppe_flush=0;
 	    mppe_synchronize_key(state);
+	 }
+       }
 	mppe_update_count(state);
 
-	/* decrypt - adjust for PPP_HDRLEN + MPPE_OVHD - mru should be OK */
-	RC4(&(state->RC4_recv_key),isize-6,ibuf+6,obuf);
+	if (state->mppe_flush!=1) {
+	  /* decrypt - adjust for PPP_HDRLEN + MPPE_OVHD - mru should be OK */
+	  RC4(&(state->RC4_recv_key),isize-6,ibuf+6,obuf);
+	} else {
+	   /* Need to ignore this packet BUT not return DECOMP_ERROR
+	    * since that will resend the resend...
+	    */
+	  
+	 }
 
 	(state->stats).unc_bytes += (isize-MPPE_OVHD);
 	(state->stats).unc_packets ++;
--- pppd/ccp.c.orig	Thu Aug 12 23:46:11 1999
+++ pppd/ccp.c	        Wed May 17 08:49:39 2000
@@ -1193,6 +1436,21 @@
 	    error("Lost compression sync: disabling compression");
 	    ccp_close(unit, "Lost compression sync");
 	} else {
+	    /* MPPE/MPPC ONLY requires CCP_RESETREQ 
+	     * when using statefull decryption. We do not
+	     * recieve a reset ACK, just a packet with FLUSHED set
+	     */
+	  if (ccp_gotoptions[f->unit].method == CI_MPPE) {
+	    if (ccp_gotoptions[f->unit].mppe_stateless)
+		return;
+	    ccp_localstate[f->unit] &= ~RREQ_REPEAT;
+	    ccp_localstate[f->unit] &= ~RACK_PENDING;
+	    fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
+	    /* DO NOT expect an ack... */
+	    ccp_localstate[f->unit] &= ~RREQ_REPEAT;
+	    ccp_localstate[f->unit] &= ~RACK_PENDING;
+	    return;
+	  }
 	    /*
 	     * Send a reset-request to reset the peer's compressor.
 	     * We don't do that if we are still waiting for an


More information about the pptp-server mailing list