// 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);