* Fix an accounting bug regarding SACK/NR-SACK chunks.
* Fix the generation of the SACK/NR-SACK gap lists. MFC after: 3 days.
This commit is contained in:
parent
b790ac8809
commit
699437a2ba
@ -9927,7 +9927,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
|
||||
caddr_t limit;
|
||||
uint32_t *dup;
|
||||
int limit_reached = 0;
|
||||
unsigned int i, sel_start, siz, j, starting_index;
|
||||
unsigned int i, sel_start, siz, j;
|
||||
unsigned int num_gap_blocks = 0, num_nr_gap_blocks = 0, space;
|
||||
int num_dups = 0;
|
||||
int space_req;
|
||||
@ -9954,7 +9954,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
|
||||
if (chk->rec.chunk_id.id == type) {
|
||||
/* Hmm, found a sack already on queue, remove it */
|
||||
TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
|
||||
asoc->ctrl_queue_cnt++;
|
||||
asoc->ctrl_queue_cnt--;
|
||||
a_chk = chk;
|
||||
if (a_chk->data) {
|
||||
sctp_m_freem(a_chk->data);
|
||||
@ -9993,15 +9993,13 @@ sctp_send_sack(struct sctp_tcb *stcb)
|
||||
a_chk->whoTo = NULL;
|
||||
|
||||
if ((asoc->numduptsns) ||
|
||||
(asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)
|
||||
) {
|
||||
(asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)) {
|
||||
/*-
|
||||
* Ok, we have some duplicates or the destination for the
|
||||
* sack is unreachable, lets see if we can select an
|
||||
* alternate than asoc->last_data_chunk_from
|
||||
*/
|
||||
if ((!(asoc->last_data_chunk_from->dest_state &
|
||||
SCTP_ADDR_NOT_REACHABLE)) &&
|
||||
if ((!(asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)) &&
|
||||
(asoc->used_alt_onsack > asoc->numnets)) {
|
||||
/* We used an alt last time, don't this time */
|
||||
a_chk->whoTo = NULL;
|
||||
@ -10120,53 +10118,25 @@ sctp_send_sack(struct sctp_tcb *stcb)
|
||||
}
|
||||
}
|
||||
|
||||
if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
|
||||
offset = 1;
|
||||
/*-
|
||||
* The base TSN is intialized to be the first TSN the peer
|
||||
* will send us. If the cum-ack is behind this then when they
|
||||
* send us the next in sequence it will mark the base_tsn bit.
|
||||
* Thus we need to use the very first selector and the offset
|
||||
* is 1. Our table is built for this case.
|
||||
*/
|
||||
starting_index = 0;
|
||||
if (((type == SCTP_SELECTIVE_ACK) &&
|
||||
(((asoc->mapping_array[0] | asoc->nr_mapping_array[0]) & 0x01) == 0x00)) ||
|
||||
((type == SCTP_NR_SELECTIVE_ACK) &&
|
||||
((asoc->mapping_array[0] & 0x01) == 0x00))) {
|
||||
sel_start = 0;
|
||||
} else {
|
||||
/*-
|
||||
* we skip the first selector when the cum-ack is at or above the
|
||||
* mapping array base. This is because the bits at the base or above
|
||||
* are turned on and our first selector in the table assumes they are
|
||||
* off. We thus will use the second selector (first is 0). We use
|
||||
* the reverse of our macro to fix the offset, in bits, that our
|
||||
* table is at. Note that this method assumes that the cum-tsn is
|
||||
* within the first bit, i.e. its value is 0-7 which means the
|
||||
* result to our offset will be either a 0 - -7. If the cumack
|
||||
* is NOT in the first byte (0) (which it should be since we did
|
||||
* a mapping array slide above) then we need to calculate the starting
|
||||
* index i.e. which byte of the mapping array we should start at. We
|
||||
* do this by dividing by 8 and pushing the remainder (mod) into offset.
|
||||
* then we multiply the offset to be negative, since we need a negative
|
||||
* offset into the selector table.
|
||||
*/
|
||||
SCTP_CALC_TSN_TO_GAP(offset, asoc->cumulative_tsn, asoc->mapping_array_base_tsn);
|
||||
if (offset > 7) {
|
||||
starting_index = offset / 8;
|
||||
offset = offset % 8;
|
||||
printf("Strange starting index is %d offset:%d (not 0/x)\n",
|
||||
starting_index, offset);
|
||||
} else {
|
||||
starting_index = 0;
|
||||
}
|
||||
/* We need a negative offset in our table */
|
||||
offset *= -1;
|
||||
sel_start = 1;
|
||||
}
|
||||
if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
|
||||
offset = 1;
|
||||
} else {
|
||||
offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
|
||||
}
|
||||
if (((type == SCTP_SELECTIVE_ACK) &&
|
||||
compare_with_wrap(highest_tsn, asoc->cumulative_tsn, MAX_TSN)) ||
|
||||
((type == SCTP_NR_SELECTIVE_ACK) &&
|
||||
compare_with_wrap(asoc->highest_tsn_inside_map, asoc->cumulative_tsn, MAX_TSN))) {
|
||||
/* we have a gap .. maybe */
|
||||
for (i = starting_index; i < siz; i++) {
|
||||
for (i = 0; i < siz; i++) {
|
||||
if (type == SCTP_SELECTIVE_ACK) {
|
||||
selector = &sack_array[asoc->mapping_array[i] | asoc->nr_mapping_array[i]];
|
||||
} else {
|
||||
@ -10224,26 +10194,22 @@ sctp_send_sack(struct sctp_tcb *stcb)
|
||||
|
||||
mergeable = 0;
|
||||
|
||||
if (asoc->highest_tsn_inside_nr_map > asoc->mapping_array_base_tsn)
|
||||
if (asoc->highest_tsn_inside_nr_map > asoc->mapping_array_base_tsn) {
|
||||
siz = (((asoc->highest_tsn_inside_nr_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
|
||||
else
|
||||
} else {
|
||||
siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_nr_map + 7) / 8;
|
||||
}
|
||||
|
||||
if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
|
||||
offset = 1;
|
||||
/*-
|
||||
* cum-ack behind the mapping array, so we start and use all
|
||||
* entries.
|
||||
*/
|
||||
if ((asoc->nr_mapping_array[0] & 0x01) == 0x00) {
|
||||
sel_start = 0;
|
||||
} else {
|
||||
offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
|
||||
/*-
|
||||
* we skip the first one when the cum-ack is at or above the
|
||||
* mapping array base. Note this only works if
|
||||
*/
|
||||
sel_start = 1;
|
||||
}
|
||||
if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
|
||||
offset = 1;
|
||||
} else {
|
||||
offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
|
||||
}
|
||||
if (compare_with_wrap(asoc->highest_tsn_inside_nr_map, asoc->cumulative_tsn, MAX_TSN)) {
|
||||
/* we have a gap .. maybe */
|
||||
for (i = 0; i < siz; i++) {
|
||||
|
Loading…
Reference in New Issue
Block a user