Changes to the NR-Sack code so that:

1) All bit disappears
2) The two sets of gaps (nr and non-nr) are
   disjointed, you don't have gaps struck in
   both places.

This adjusts us to coorespond to the new draft. Still
to-do, cleanup the code so that there are only one set
of sack routines (original NR-Sack done by E cloned all
sack code).
This commit is contained in:
rrs 2009-06-17 12:34:56 +00:00
parent 9e1fc95c2f
commit 8a5e849118
4 changed files with 145 additions and 237 deletions

View File

@ -415,9 +415,6 @@ struct sctp_error_unrecognized_chunk {
/* ECN Nonce: SACK Chunk Specific Flags */
#define SCTP_SACK_NONCE_SUM 0x01
/* EY nr_sack all bit - All bit is the 2nd LSB of nr_sack chunk flags*/
/* if All bit is set in an nr-sack chunk, then all nr gap acks gap acks*/
#define SCTP_NR_SACK_ALL_BIT 0x02
/* CMT DAC algorithm SACK flag */
#define SCTP_SACK_CMT_DAC 0x80

View File

@ -45,6 +45,24 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_uio.h>
#include <netinet/sctp_timer.h>
#define SCTP_CALC_TSN_TO_GAP(gap, tsn, mapping_tsn) do { \
if ((compare_with_wrap(tsn, mapping_tsn, MAX_TSN)) || \
(tsn == mapping_tsn)) { \
gap = tsn - mapping_tsn; \
} else { \
gap = (MAX_TSN - mapping_tsn) + tsn + 1; \
} \
} while(0)
#define SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc) do { \
if (asoc->mapping_array_base_tsn == asoc->nr_mapping_array_base_tsn) { \
SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, nr_gap); \
} else {\
int lgap; \
SCTP_CALC_TSN_TO_GAP(lgap, tsn, asoc->mapping_array_base_tsn); \
SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, lgap); \
} \
} while(0)
/*
* NOTES: On the outbound side of things I need to check the sack timer to
@ -423,12 +441,7 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
nr_tsn = chk->rec.data.TSN_seq;
if ((compare_with_wrap(nr_tsn, asoc->nr_mapping_array_base_tsn, MAX_TSN)) ||
(nr_tsn == asoc->nr_mapping_array_base_tsn)) {
nr_gap = nr_tsn - asoc->nr_mapping_array_base_tsn;
} else {
nr_gap = (MAX_TSN - asoc->nr_mapping_array_base_tsn) + nr_tsn + 1;
}
SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
if ((nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3)) ||
(nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
/*
@ -445,6 +458,7 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
} else {
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
asoc->highest_tsn_inside_nr_map = nr_tsn;
}
@ -510,14 +524,10 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
* NR
*/
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
if (nr_tsn >= asoc->nr_mapping_array_base_tsn) {
nr_gap = nr_tsn - asoc->nr_mapping_array_base_tsn;
} else {
nr_gap = (MAX_TSN - asoc->nr_mapping_array_base_tsn) + nr_tsn + 1;
}
SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
(nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
printf("Impossible NR gap calculation?\n");
/*
* EY The
* 1st
@ -552,6 +562,7 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
} else {
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
if (compare_with_wrap(nr_tsn,
asoc->highest_tsn_inside_nr_map,
MAX_TSN))
@ -682,14 +693,10 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
* chk->rec.data.TSN_seq
*/
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
if (nr_tsn >= asoc->nr_mapping_array_base_tsn) {
nr_gap = nr_tsn - asoc->nr_mapping_array_base_tsn;
} else {
nr_gap = (MAX_TSN - asoc->nr_mapping_array_base_tsn) + nr_tsn + 1;
}
SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
(nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
printf("Impossible nr_tsn set 2?\n");
/*
* EY The 1st should never happen, as in
* process_a_data_chunk method this check
@ -703,6 +710,7 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
} else {
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
asoc->highest_tsn_inside_nr_map = nr_tsn;
}
@ -739,14 +747,10 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
* chk->rec.data.TSN_seq
*/
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
if (nr_tsn >= asoc->nr_mapping_array_base_tsn) {
nr_gap = nr_tsn - asoc->nr_mapping_array_base_tsn;
} else {
nr_gap = (MAX_TSN - asoc->nr_mapping_array_base_tsn) + nr_tsn + 1;
}
SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
(nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
printf("Impossible nr TSN set 3?\n");
/*
* EY The 1st should never
* happen, as in
@ -763,6 +767,7 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
*/
} else {
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map,
MAX_TSN))
@ -1613,11 +1618,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
return (0);
}
/* Calculate the number of TSN's between the base and this TSN */
if (tsn >= asoc->mapping_array_base_tsn) {
gap = tsn - asoc->mapping_array_base_tsn;
} else {
gap = (MAX_TSN - asoc->mapping_array_base_tsn) + tsn + 1;
}
SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
if (gap >= (SCTP_MAPPING_ARRAY << 3)) {
/* Can't hold the bit in the mapping at max array, toss it */
return (0);
@ -1752,6 +1753,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
SCTP_REVERSE_OUT_TSN_PRES(gap, tsn, asoc);
}
if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) {
/* we have a new high score */
@ -1948,6 +1950,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
/* EY - not %100 sure about the lock thing */
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
asoc->highest_tsn_inside_nr_map = tsn;
}
@ -2025,6 +2028,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
/* EY - not %100 sure about the lock thing */
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
asoc->highest_tsn_inside_nr_map = tsn;
}
@ -2291,6 +2295,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
}
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
asoc->highest_tsn_inside_nr_map = tsn;
}
@ -2400,6 +2405,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->peer_supports_nr_sack &&
(SCTP_BASE_SYSCTL(sctp_do_drain) == 0)) {
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
asoc->highest_tsn_inside_nr_map = tsn;
}
@ -5725,11 +5731,7 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
*/
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
if (nr_tsn >= asoc->nr_mapping_array_base_tsn) {
nr_gap = nr_tsn - asoc->nr_mapping_array_base_tsn;
} else {
nr_gap = (MAX_TSN - asoc->nr_mapping_array_base_tsn) + nr_tsn + 1;
}
SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
(nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
/*
@ -5739,12 +5741,12 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
} else {
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
if (compare_with_wrap(nr_tsn,
asoc->highest_tsn_inside_nr_map,
MAX_TSN))
asoc->highest_tsn_inside_nr_map = nr_tsn;
}
if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, nr_gap))
/*
* printf("In
@ -5829,12 +5831,7 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
* chk->rec.data.TSN_seq
*/
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
if (nr_tsn >= asoc->nr_mapping_array_base_tsn) {
nr_gap = nr_tsn - asoc->nr_mapping_array_base_tsn;
} else {
nr_gap = (MAX_TSN - asoc->nr_mapping_array_base_tsn) + nr_tsn + 1;
}
SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
(nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
/*
@ -5844,12 +5841,11 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
} else {
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map,
MAX_TSN))
asoc->highest_tsn_inside_nr_map = nr_tsn;
}
if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, nr_gap))
/*
* printf("In
@ -6062,15 +6058,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
* now we know the new TSN is more advanced, let's find the actual
* gap
*/
if ((compare_with_wrap(new_cum_tsn, asoc->mapping_array_base_tsn,
MAX_TSN)) ||
(new_cum_tsn == asoc->mapping_array_base_tsn)) {
gap = new_cum_tsn - asoc->mapping_array_base_tsn;
} else {
/* try to prevent underflow here */
gap = new_cum_tsn + (MAX_TSN - asoc->mapping_array_base_tsn) + 1;
}
SCTP_CALC_TSN_TO_GAP(gap, new_cum_tsn, asoc->mapping_array_base_tsn);
if (gap >= m_size) {
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
sctp_log_map(0, 0, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
@ -6131,14 +6119,11 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
} else {
SCTP_TCB_LOCK_ASSERT(stcb);
for (i = 0; i <= gap; i++) {
SCTP_SET_TSN_PRESENT(asoc->mapping_array, i);
/*
* EY if drain is off then every gap-ack is an
* nr-gap-ack
*/
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack
&& SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, i);
} else {
SCTP_SET_TSN_PRESENT(asoc->mapping_array, i);
}
}
/*
@ -6847,7 +6832,7 @@ sctp_handle_nr_sack_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb,
struct sctp_gap_ack_block *frag, block;
struct sctp_nr_gap_ack_block *nr_frag, nr_block;
struct sctp_tmit_chunk *tp1;
uint32_t i, j, all_bit;
uint32_t i, j;
int wake_him = 0;
uint32_t theTSN;
int num_frs = 0;
@ -6858,8 +6843,6 @@ sctp_handle_nr_sack_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb,
uint32_t last_frag_high;
uint32_t last_nr_frag_high;
all_bit = ch->ch.chunk_flags & SCTP_NR_SACK_ALL_BIT;
/*
* @@@ JRI : TODO: This flag is not used anywhere .. remove?
*/
@ -6963,12 +6946,12 @@ sctp_handle_nr_sack_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb,
*/
if (tp1->sent < SCTP_DATAGRAM_RESEND) {
/*-
* If it is less than RESEND, it is
* now no-longer in flight.
* Higher values may already be set
* via previous Gap Ack Blocks...
* i.e. ACKED or RESEND.
*/
* If it is less than RESEND, it is
* now no-longer in flight.
* Higher values may already be set
* via previous Gap Ack Blocks...
* i.e. ACKED or RESEND.
*/
if (compare_with_wrap(tp1->rec.data.TSN_seq,
*biggest_newly_acked_tsn, MAX_TSN)) {
*biggest_newly_acked_tsn = tp1->rec.data.TSN_seq;
@ -7123,39 +7106,6 @@ sctp_handle_nr_sack_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb,
tp1->whoTo->cwnd -= tp1->book_size;
tp1->rec.data.chunk_was_revoked = 0;
}
/*
* EY - if all bit is set
* then this TSN is
* nr_marked
*/
if (all_bit) {
if (tp1->sent != SCTP_FORWARD_TSN_SKIP)
tp1->sent = SCTP_DATAGRAM_NR_MARKED;
/*
* TAILQ_REMOVE(&asoc
* ->sent_queue,
* tp1, sctp_next);
*/
if (tp1->data) {
/*
* sa_ignore
* NO_NULL_CH
* K
*/
sctp_free_bufspace(stcb, asoc, tp1, 1);
sctp_m_freem(tp1->data);
}
tp1->data = NULL;
/*
* asoc->sent_queue_c
* nt--;
*/
/*
* sctp_free_a_chunk(
* stcb, tp1);
*/
wake_him++;
}
}
break;
} /* if (tp1->TSN_seq == theTSN) */
@ -7180,120 +7130,105 @@ sctp_handle_nr_sack_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb,
*biggest_newly_acked_tsn,
last_tsn, SCTP_FR_LOG_BIGGEST_TSNS);
}
/*
* EY - if all bit is not set then there should be other loops to
* identify nr TSNs
*/
if (!all_bit) {
nr_frag = (struct sctp_nr_gap_ack_block *)sctp_m_getptr(m, *offset,
sizeof(struct sctp_nr_gap_ack_block), (uint8_t *) & nr_block);
*offset += sizeof(nr_block);
if (nr_frag == NULL) {
return;
}
tp1 = NULL;
last_nr_frag_high = 0;
for (i = 0; i < num_nr_seg; i++) {
nr_frag_strt = ntohs(nr_frag->start);
nr_frag_end = ntohs(nr_frag->end);
/* some sanity checks on the nr fargment offsets */
if (nr_frag_strt > nr_frag_end) {
/* this one is malformed, skip */
nr_frag++;
continue;
}
/* mark acked dgs and find out the highestTSN being acked */
if (tp1 == NULL) {
tp1 = TAILQ_FIRST(&asoc->sent_queue);
/* save the locations of the last frags */
last_nr_frag_high = nr_frag_end + last_tsn;
} else {
/*
* now lets see if we need to reset the queue due to
* a out-of-order SACK fragment
*/
if (compare_with_wrap(nr_frag_strt + last_tsn,
last_nr_frag_high, MAX_TSN)) {
/*
* if the new frag starts after the last TSN
* frag covered, we are ok and this one is
* beyond the last one
*/
;
} else {
/*
* ok, they have reset us, so we need to
* reset the queue this will cause extra
* hunting but hey, they chose the
* performance hit when they failed to order
* there gaps..
*/
tp1 = TAILQ_FIRST(&asoc->sent_queue);
}
last_nr_frag_high = nr_frag_end + last_tsn;
}
for (j = nr_frag_strt + last_tsn; (compare_with_wrap((nr_frag_end + last_tsn), j, MAX_TSN)); j++) {
while (tp1) {
if (tp1->rec.data.TSN_seq == j) {
if (tp1->sent != SCTP_DATAGRAM_UNSENT) {
if (tp1->sent != SCTP_FORWARD_TSN_SKIP)
tp1->sent = SCTP_DATAGRAM_NR_MARKED;
/*
* TAILQ_REMOVE(&asoc->sent_q
* ueue, tp1, sctp_next);
*/
if (tp1->data) {
/*
* sa_ignore
* NO_NULL_CHK
*/
sctp_free_bufspace(stcb, asoc, tp1, 1);
sctp_m_freem(tp1->data);
}
tp1->data = NULL;
/* asoc->sent_queue_cnt--; */
/*
* sctp_free_a_chunk(stcb,
* tp1);
*/
wake_him++;
}
break;
} /* if (tp1->TSN_seq == j) */
if (compare_with_wrap(tp1->rec.data.TSN_seq, j,
MAX_TSN))
break;
tp1 = TAILQ_NEXT(tp1, sctp_next);
} /* end while (tp1) */
} /* end for (j = nrFragStart */
nr_frag = (struct sctp_nr_gap_ack_block *)sctp_m_getptr(m, *offset,
sizeof(struct sctp_nr_gap_ack_block), (uint8_t *) & nr_block);
*offset += sizeof(nr_block);
if (nr_frag == NULL) {
return;
break;
}
tp1 = NULL;
last_nr_frag_high = 0;
for (i = 0; i < num_nr_seg; i++) {
nr_frag_strt = ntohs(nr_frag->start);
nr_frag_end = ntohs(nr_frag->end);
/* some sanity checks on the nr fargment offsets */
if (nr_frag_strt > nr_frag_end) {
/* this one is malformed, skip */
nr_frag++;
continue;
}
/*
* mark acked dgs and find out the highestTSN being
* acked
*/
if (tp1 == NULL) {
tp1 = TAILQ_FIRST(&asoc->sent_queue);
/* save the locations of the last frags */
last_nr_frag_high = nr_frag_end + last_tsn;
} else {
/*
* now lets see if we need to reset the
* queue due to a out-of-order SACK fragment
*/
if (compare_with_wrap(nr_frag_strt + last_tsn,
last_nr_frag_high, MAX_TSN)) {
/*
* if the new frag starts after the
* last TSN frag covered, we are ok
* and this one is beyond the last
* one
*/
;
} else {
/*
* ok, they have reset us, so we
* need to reset the queue this will
* cause extra hunting but hey, they
* chose the performance hit when
* they failed to order there gaps..
*/
tp1 = TAILQ_FIRST(&asoc->sent_queue);
}
last_nr_frag_high = nr_frag_end + last_tsn;
}
for (j = nr_frag_strt + last_tsn; (compare_with_wrap((nr_frag_end + last_tsn), j, MAX_TSN)); j++) {
while (tp1) {
if (tp1->rec.data.TSN_seq == j) {
if (tp1->sent != SCTP_DATAGRAM_UNSENT) {
if (tp1->sent != SCTP_FORWARD_TSN_SKIP)
tp1->sent = SCTP_DATAGRAM_NR_MARKED;
/*
* TAILQ_REMOVE(&asoc
* ->sent_queue,
* tp1, sctp_next);
*/
if (tp1->data) {
/*
* sa_ignore
* NO_NULL_CH
* K
*/
sctp_free_bufspace(stcb, asoc, tp1, 1);
sctp_m_freem(tp1->data);
}
tp1->data = NULL;
/*
* asoc->sent_queue_c
* nt--;
*/
/*
* sctp_free_a_chunk(
* stcb, tp1);
*/
wake_him++;
}
break;
} /* if (tp1->TSN_seq == j) */
if (compare_with_wrap(tp1->rec.data.TSN_seq, j,
MAX_TSN))
break;
tp1 = TAILQ_NEXT(tp1, sctp_next);
} /* end while (tp1) */
} /* end for (j = nrFragStart */
nr_frag = (struct sctp_nr_gap_ack_block *)sctp_m_getptr(m, *offset,
sizeof(struct sctp_nr_gap_ack_block), (uint8_t *) & nr_block);
*offset += sizeof(nr_block);
if (nr_frag == NULL) {
break;
}
} /* end of if(!all_bit) */
}
/*
* EY- wake up the socket if things have been removed from the sent
* queue
@ -7405,7 +7340,7 @@ sctp_handle_nr_sack(struct mbuf *m, int offset,
int win_probe_recovery = 0;
int win_probe_recovered = 0;
struct sctp_nets *net = NULL;
int nonce_sum_flag, ecn_seg_sums = 0, all_bit;
int nonce_sum_flag, ecn_seg_sums = 0;
int done_once;
uint8_t reneged_all = 0;
uint8_t cmt_dac_flag;
@ -7448,11 +7383,8 @@ sctp_handle_nr_sack(struct mbuf *m, int offset,
stcb->asoc.cumack_log_at = 0;
}
#endif
all_bit = ch->ch.chunk_flags & SCTP_NR_SACK_ALL_BIT;
num_seg = ntohs(nr_sack->num_gap_ack_blks);
num_nr_seg = ntohs(nr_sack->num_nr_gap_ack_blks);
if (all_bit)
num_seg = num_nr_seg;
a_rwnd = rwnd;
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_SACK_ARRIVALS_ENABLE) {
@ -7485,14 +7417,8 @@ sctp_handle_nr_sack(struct mbuf *m, int offset,
int off_to_dup, iii;
uint32_t *dupdata, dblock;
/* EY! gotta be careful here */
if (all_bit) {
off_to_dup = (num_nr_seg * sizeof(struct sctp_nr_gap_ack_block)) +
sizeof(struct sctp_nr_sack_chunk);
} else {
off_to_dup = (num_seg * sizeof(struct sctp_gap_ack_block)) +
(num_nr_seg * sizeof(struct sctp_nr_gap_ack_block)) + sizeof(struct sctp_nr_sack_chunk);
}
off_to_dup = (num_seg * sizeof(struct sctp_gap_ack_block)) +
(num_nr_seg * sizeof(struct sctp_nr_gap_ack_block)) + sizeof(struct sctp_nr_sack_chunk);
if ((off_to_dup + (num_dup * sizeof(uint32_t))) <= nr_sack_length) {
dupdata = (uint32_t *) sctp_m_getptr(m, off_to_dup,
sizeof(uint32_t), (uint8_t *) & dblock);

View File

@ -4656,7 +4656,7 @@ __attribute__((noinline))
int abort_now = 0;
uint32_t a_rwnd, cum_ack;
uint16_t num_seg, num_nr_seg;
int nonce_sum_flag, all_bit;
int nonce_sum_flag;
if ((stcb == NULL) || (chk_length < sizeof(struct sctp_nr_sack_chunk))) {
SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on nr_sack chunk, too small\n");
@ -4685,17 +4685,9 @@ __attribute__((noinline))
}
nr_sack = (struct sctp_nr_sack_chunk *)ch;
nonce_sum_flag = ch->chunk_flags & SCTP_SACK_NONCE_SUM;
all_bit = ch->chunk_flags & SCTP_NR_SACK_ALL_BIT;
cum_ack = ntohl(nr_sack->nr_sack.cum_tsn_ack);
num_seg = ntohs(nr_sack->nr_sack.num_gap_ack_blks);
/*
* EY -if All bit is set, then there are as
* many gaps as nr_gaps
*/
if (all_bit) {
num_seg = ntohs(nr_sack->nr_sack.num_nr_gap_ack_blks);
}
num_nr_seg = ntohs(nr_sack->nr_sack.num_nr_gap_ack_blks);
a_rwnd = (uint32_t) ntohl(nr_sack->nr_sack.a_rwnd);
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK process cum_ack:%x num_seg:%d a_rwnd:%d\n",

View File

@ -10375,13 +10375,6 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
nr_sack->ch.chunk_flags |= (asoc->cmt_dac_pkts_rcvd << 6);
asoc->cmt_dac_pkts_rcvd = 0;
}
/*
* EY - this is a never reneging receiver, that makes all gaps are
* nr-gaps, set the All bit
*/
if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
nr_sack->ch.chunk_flags |= SCTP_NR_SACK_ALL_BIT;
}
#ifdef SCTP_ASOCLOG_OF_TSNS
stcb->asoc.cumack_logsnt[stcb->asoc.cumack_log_atsnt] = asoc->cumulative_tsn;
stcb->asoc.cumack_log_atsnt++;