This fixes PR-SCTP issues:
- Slide the map at the proper place. - Mark the bits in the nr_array ONLY if there is no marking. - When generating a FWD-TSN we allow us to skip past ACKED chunks too. MFC after: 1 weeks
This commit is contained in:
parent
6a440fc3e0
commit
7898f4085c
@ -3694,6 +3694,7 @@ sctp_try_advance_peer_ack_point(struct sctp_tcb *stcb,
|
||||
tp1 = TAILQ_FIRST(&asoc->sent_queue);
|
||||
while (tp1) {
|
||||
if (tp1->sent != SCTP_FORWARD_TSN_SKIP &&
|
||||
tp1->sent != SCTP_DATAGRAM_ACKED &&
|
||||
tp1->sent != SCTP_DATAGRAM_RESEND) {
|
||||
/* no chance to advance, out of here */
|
||||
break;
|
||||
@ -5540,8 +5541,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
|
||||
* report where we are.
|
||||
*/
|
||||
struct sctp_association *asoc;
|
||||
uint32_t new_cum_tsn, tsn, gap;
|
||||
unsigned int i, fwd_sz, cumack_set_flag, m_size, fnd = 0;
|
||||
uint32_t new_cum_tsn, gap;
|
||||
unsigned int i, fwd_sz, cumack_set_flag, m_size;
|
||||
uint32_t str_seq;
|
||||
struct sctp_stream_in *strm;
|
||||
struct sctp_tmit_chunk *chk, *at;
|
||||
@ -5565,15 +5566,6 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
|
||||
/* Already got there ... */
|
||||
return;
|
||||
}
|
||||
if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_map,
|
||||
MAX_TSN)) {
|
||||
asoc->highest_tsn_inside_map = new_cum_tsn;
|
||||
|
||||
}
|
||||
if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_nr_map,
|
||||
MAX_TSN)) {
|
||||
asoc->highest_tsn_inside_nr_map = new_cum_tsn;
|
||||
}
|
||||
/*
|
||||
* now we know the new TSN is more advanced, let's find the actual
|
||||
* gap
|
||||
@ -5628,34 +5620,14 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
|
||||
} else {
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
for (i = 0; i <= gap; i++) {
|
||||
SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, i);
|
||||
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, i);
|
||||
/* FIX ME add something to set up highest TSN in map */
|
||||
}
|
||||
if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
|
||||
asoc->highest_tsn_inside_nr_map = new_cum_tsn;
|
||||
}
|
||||
if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_map, MAX_TSN) ||
|
||||
new_cum_tsn == asoc->highest_tsn_inside_map) {
|
||||
/* We must back down to see what the new highest is */
|
||||
for (tsn = new_cum_tsn; (compare_with_wrap(tsn, asoc->mapping_array_base_tsn, MAX_TSN) ||
|
||||
(tsn == asoc->mapping_array_base_tsn)); tsn--) {
|
||||
SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
|
||||
if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
|
||||
asoc->highest_tsn_inside_map = tsn;
|
||||
fnd = 1;
|
||||
break;
|
||||
if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, i) &&
|
||||
!SCTP_IS_TSN_PRESENT(asoc->nr_mapping_array, i)) {
|
||||
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, i);
|
||||
if (compare_with_wrap(asoc->mapping_array_base_tsn + i, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
|
||||
asoc->highest_tsn_inside_nr_map = asoc->mapping_array_base_tsn + i;
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Now after marking all, slide thing forward but no sack
|
||||
* please.
|
||||
*/
|
||||
sctp_slide_mapping_arrays(stcb);
|
||||
}
|
||||
/*************************************************************/
|
||||
/* 2. Clear up re-assembly queue */
|
||||
@ -5826,6 +5798,11 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
|
||||
}
|
||||
SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
|
||||
}
|
||||
/*
|
||||
* Now slide thing forward.
|
||||
*/
|
||||
sctp_slide_mapping_arrays(stcb);
|
||||
|
||||
if (TAILQ_FIRST(&asoc->reasmqueue)) {
|
||||
/* now lets kick out and check for more fragmented delivery */
|
||||
/* sa_ignore NO_NULL_CHK */
|
||||
|
Loading…
Reference in New Issue
Block a user