MPPP: Discard fragments even when reassembling failed
[l2tpns.git] / ppp.c
diff --git a/ppp.c b/ppp.c
index 3f5a9a5..ee299cb 100644 (file)
--- a/ppp.c
+++ b/ppp.c
@@ -1946,7 +1946,7 @@ void processmpin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
 
                // return if a lost fragment is found
                if (!(this_fragmentation->fragment[begin_index].length))
 
                // return if a lost fragment is found
                if (!(this_fragmentation->fragment[begin_index].length))
-                       return; // assembling frame failed
+                       goto discard_lost_frames; // assembling frame failed
                // get the end of his frame
                while (this_fragmentation->fragment[end_index].length)
                {
                // get the end of his frame
                while (this_fragmentation->fragment[end_index].length)
                {
@@ -1957,7 +1957,7 @@ void processmpin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
 
                // return if a lost fragment is found
                if (!(this_fragmentation->fragment[end_index].length))
 
                // return if a lost fragment is found
                if (!(this_fragmentation->fragment[end_index].length))
-                       return; // assembling frame failed
+                       goto discard_lost_frames; // assembling frame failed
 
                // assemble the packet
                //assemble frame, process it, reset fragmentation
 
                // assemble the packet
                //assemble frame, process it, reset fragmentation
@@ -2007,47 +2007,49 @@ discard_lost_frames:
        // if we have something to discard
        if (M_index != this_fragmentation->start_index)
        {
        // if we have something to discard
        if (M_index != this_fragmentation->start_index)
        {
-               uint8_t end_found = 0;
                // look for end of previous frame
                // start at M-1, going backward
                // look for end of previous frame
                // start at M-1, going backward
-               for (end_index = (M_index + (MAXFRAGNUM-1)) & MAXFRAGNUM_MASK;
-                    end_index != this_fragmentation->start_index;
-                    end_index = (end_index + (MAXFRAGNUM-1)) & MAXFRAGNUM_MASK)
+               uint16_t index = M_index;
+               uint8_t end_or_hole_found = 0;
+
+               while (index != this_fragmentation->start_index)
                {
                {
-                       fragmentt *this_frag = &this_fragmentation->frag[end_index];
-                       fragmentt *front_frag = &this_fragmentation->frag[(end_index+1)&MAXFRAGNUM_MASK];
-                       // before a MP_BEGIN, we must be a MP_END
-                       if (front_frag->length && (front_frag->flags & MP_BEGIN))
+                       fragmentt *this_frag;
+
+                       if (!end_or_hole_found)
                        {
                        {
-                               end_found = 1;
-                               break;
+                               fragmentt *front_frag = &this_fragmentation->frag[index];
+
+                               // before a MP_BEGIN, there must be a MP_END
+                               if (front_frag->length && (front_frag->flags & MP_BEGIN))
+                               {
+                                       end_or_hole_found = 1;
+                                       end_index = index;
+                               }
                        }
                        }
-                       // we are a MP_END
-                       if (this_frag->length && (this_frag->flags & MP_END))
+
+                       index = (index + (MAXFRAGNUM-1)) & MAXFRAGNUM_MASK;
+                       this_frag = &this_fragmentation->frag[index];
+
+                       if (!end_or_hole_found)
                        {
                        {
-                               end_found = 1;
-                               break;
+                               // we are a hole or a MP_END
+                               if (!this_frag->length || (this_frag->flags & MP_END))
+                               {
+                                       end_or_hole_found = 1;
+                                       end_index = index;
+                               }
                        }
                        }
-               }
-               // ok, we may not count it for found if end_index == this_fragmentation->start_index
-               // but it complicates things too much and it will be discarded on next round anyway
 
 
-               //clear length and flags of the discarded fragments
-               if (end_found)
-               {
-                       begin_index = this_fragmentation->start_index;
-                       while (begin_index != end_index)
+                       if (end_or_hole_found)
                        {
                        {
-                               this_fragmentation->fragment[begin_index].flags = 0;
-                               this_fragmentation->fragment[begin_index].length = 0;
-                               begin_index = (begin_index + 1) & MAXFRAGNUM_MASK;
+                               this_frag->flags = 0;
+                               this_frag->length = 0;
                        }
                        }
-                       this_fragmentation->fragment[begin_index].flags = 0;
-                       this_fragmentation->fragment[begin_index].length = 0;
-
-                       this_fragmentation->start_index = (end_index + 1) & MAXFRAGNUM_MASK;
-                       this_fragmentation->start_seq = (this_fragmentation->fragment[end_index].seq + 1) & (this_bundle->max_seq-1);
                }
                }
+
+               this_fragmentation->start_index = (end_index + 1) & MAXFRAGNUM_MASK;
+               this_fragmentation->start_seq = (this_fragmentation->fragment[end_index].seq + 1) & (this_bundle->max_seq-1);
        }
 
        LOG(4, s, t, "MPPP after assembling: M index is =%d, start index is = %d, start seq=%d\n",M_index, this_fragmentation->start_index, this_fragmentation->start_seq);     
        }
 
        LOG(4, s, t, "MPPP after assembling: M index is =%d, start index is = %d, start seq=%d\n",M_index, this_fragmentation->start_index, this_fragmentation->start_seq);