From owner-svn-src-all@FreeBSD.ORG Wed Jun 17 12:34:57 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5732C1065695; Wed, 17 Jun 2009 12:34:57 +0000 (UTC) (envelope-from rrs@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 44D168FC1A; Wed, 17 Jun 2009 12:34:57 +0000 (UTC) (envelope-from rrs@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n5HCYvJQ075593; Wed, 17 Jun 2009 12:34:57 GMT (envelope-from rrs@svn.freebsd.org) Received: (from rrs@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n5HCYv4b075588; Wed, 17 Jun 2009 12:34:57 GMT (envelope-from rrs@svn.freebsd.org) Message-Id: <200906171234.n5HCYv4b075588@svn.freebsd.org> From: Randall Stewart Date: Wed, 17 Jun 2009 12:34:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r194355 - head/sys/netinet X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Jun 2009 12:34:57 -0000 Author: rrs Date: Wed Jun 17 12:34:56 2009 New Revision: 194355 URL: http://svn.freebsd.org/changeset/base/194355 Log: 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). Modified: head/sys/netinet/sctp.h head/sys/netinet/sctp_indata.c head/sys/netinet/sctp_input.c head/sys/netinet/sctp_output.c Modified: head/sys/netinet/sctp.h ============================================================================== --- head/sys/netinet/sctp.h Wed Jun 17 12:27:00 2009 (r194354) +++ head/sys/netinet/sctp.h Wed Jun 17 12:34:56 2009 (r194355) @@ -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 Modified: head/sys/netinet/sctp_indata.c ============================================================================== --- head/sys/netinet/sctp_indata.c Wed Jun 17 12:27:00 2009 (r194354) +++ head/sys/netinet/sctp_indata.c Wed Jun 17 12:34:56 2009 (r194355) @@ -45,6 +45,24 @@ __FBSDID("$FreeBSD$"); #include #include +#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 @@ abandon: 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 @@ abandon: } 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 @@ abandon: * 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 @@ abandon: } 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 @@ protocol_error: * 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 @@ protocol_error: } 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 @@ protocol_error: * 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 @@ protocol_error: */ } 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_tc 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_tc 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_tc /* 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 @@ failed_express_del: /* 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 @@ failed_pdapi_express_del: } 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 @@ finish_express_del: 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 sc */ 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 sc } 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 sc * 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 sc } 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 * 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 } 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 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 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 */ 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 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 *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); - 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; - if (nr_frag == NULL) { - return; - } - tp1 = NULL; - last_nr_frag_high = 0; + for (i = 0; i < num_nr_seg; i++) { - for (i = 0; i < num_nr_seg; i++) { + nr_frag_strt = ntohs(nr_frag->start); + nr_frag_end = ntohs(nr_frag->end); - 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); - /* some sanity checks on the nr fargment offsets */ - if (nr_frag_strt > nr_frag_end) { - /* this one is malformed, skip */ - nr_frag++; - continue; - } + /* save the locations of the last frags */ + last_nr_frag_high = nr_frag_end + last_tsn; + } else { /* - * mark acked dgs and find out the highestTSN being - * acked + * now lets see if we need to reset the queue due to + * a out-of-order SACK fragment */ - 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; + 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 { /* - * now lets see if we need to reset the - * queue due to a out-of-order SACK fragment + * 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.. */ - 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; + 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--; - */ + 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) { /* - * sctp_free_a_chunk( - * stcb, tp1); + * sa_ignore + * NO_NULL_CHK */ - wake_him++; + sctp_free_bufspace(stcb, asoc, tp1, 1); + sctp_m_freem(tp1->data); } - 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) */ + 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 */ + } /* 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) */ + 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; + } } + /* * 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 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 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 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); Modified: head/sys/netinet/sctp_input.c ============================================================================== --- head/sys/netinet/sctp_input.c Wed Jun 17 12:27:00 2009 (r194354) +++ head/sys/netinet/sctp_input.c Wed Jun 17 12:34:56 2009 (r194355) @@ -4656,7 +4656,7 @@ process_control_chunks: 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 @@ process_control_chunks: } 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", Modified: head/sys/netinet/sctp_output.c ============================================================================== --- head/sys/netinet/sctp_output.c Wed Jun 17 12:27:00 2009 (r194354) +++ head/sys/netinet/sctp_output.c Wed Jun 17 12:34:56 2009 (r194355) @@ -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++;