mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-23 11:18:54 +00:00
This fixes a BUG in the handling of the cum-ack calculation.
We were only paying attention to the nr-mapping-array. Which seems to make sense on the surface, by definition things up to the cum-ack should be deliverable thus in the nr-mapping-array. However (there is always a gotcha) thats not true when it comes to large messages. The stack may hold the message while re-assembling it not not deliver it based on several thresholds. If that happens (which it would for smaller large messages) then the cum-ack is figured wrong. We now properly use both arrays in the cum-ack calculation. MFC after: 1 week.
This commit is contained in:
parent
9d8284a1aa
commit
66bd30bd4f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=208897
@ -2245,15 +2245,19 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
|
||||
/*
|
||||
* Now we also need to check the mapping array in a couple of ways.
|
||||
* 1) Did we move the cum-ack point?
|
||||
*
|
||||
* When you first glance at this you might think that all entries that
|
||||
* make up the postion of the cum-ack would be in the nr-mapping
|
||||
* array only.. i.e. things up to the cum-ack are always
|
||||
* deliverable. Thats true with one exception, when its a fragmented
|
||||
* message we may not deliver the data until some threshold (or all
|
||||
* of it) is in place. So we must OR the nr_mapping_array and
|
||||
* mapping_array to get a true picture of the cum-ack.
|
||||
*/
|
||||
struct sctp_association *asoc;
|
||||
int at;
|
||||
uint8_t val;
|
||||
int slide_from, slide_end, lgap, distance;
|
||||
|
||||
/* EY nr_mapping array variables */
|
||||
/* int nr_at; */
|
||||
/* int nr_last_all_ones = 0; */
|
||||
/* int nr_slide_from, nr_slide_end, nr_lgap, nr_distance; */
|
||||
uint32_t old_cumack, old_base, old_highest, highest_tsn;
|
||||
|
||||
asoc = &stcb->asoc;
|
||||
@ -2268,11 +2272,12 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
|
||||
*/
|
||||
at = 0;
|
||||
for (slide_from = 0; slide_from < stcb->asoc.mapping_array_size; slide_from++) {
|
||||
if (asoc->nr_mapping_array[slide_from] == 0xff) {
|
||||
val = asoc->nr_mapping_array[slide_from] | asoc->mapping_array[slide_from];
|
||||
if (val == 0xff) {
|
||||
at += 8;
|
||||
} else {
|
||||
/* there is a 0 bit */
|
||||
at += sctp_map_lookup_tab[asoc->nr_mapping_array[slide_from]];
|
||||
at += sctp_map_lookup_tab[val];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user