From a54a4886e9dc530bb16e5eb0f6a8cfcb03824960 Mon Sep 17 00:00:00 2001 From: Benjamin Cama Date: Thu, 26 Jan 2012 00:19:59 +0100 Subject: [PATCH] MPPP: Fix M calculation --- ppp.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/ppp.c b/ppp.c index e21c103..4114bb4 100644 --- a/ppp.c +++ b/ppp.c @@ -1866,18 +1866,36 @@ void processmpin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) // update M sess_local[s].last_seq = seq_num; - if (seq_num < this_fragmentation->M) - this_fragmentation->M = seq_num; - else { - uint32_t i, min = sess_local[(this_bundle->members[0])].last_seq;; - for (i = 1; i < this_bundle->num_of_links; i++) + /* seq # can be spread over the wrapping limit, and we must + choose the "lowest" one, taking into account the wrapping: + + |-#-##--#----------------------M--###-#| + + but we must also care when the last highest seq # wraps, + so we keep two minimums: one for the higher limit, and + one for the lower one. + + In the nominal case, low_min = high_min. + */ + uint32_t i, low_min, high_min; + low_min = sess_local[(this_bundle->members[0])].last_seq;; + high_min = this_bundle->max_seq; // max_seq is impossible to reach + + for (i = 0; i < this_bundle->num_of_links; i++) { uint32_t s_seq = sess_local[(this_bundle->members[i])].last_seq; - if (s_seq < min) - min = s_seq; + if (s_seq < low_min) + low_min = s_seq; + if (s_seq >= this_fragmentation->M && s_seq < high_min) + high_min = s_seq; } - this_fragmentation->M = min; + + // if high_min was found, it's the "lowest" one + if (high_min < this_bundle->max_seq) + this_fragmentation->M = high_min; + else + this_fragmentation->M = low_min; } LOG(4, s, t, "MPPP: Setting M to %d\n", this_fragmentation->M); -- 2.20.1