Author: rrs
Date: Sat Apr 17 04:15:46 2010
New Revision: 206742
URL: http://svn.freebsd.org/changeset/base/206742

Log:
  MFC of 206137
  
  This is Part III of the great IETF hack-a-thon to fix
  the NR-Sack code. (the last one on the cpu options
  was a lull.. i.e MFC 205629).. still 2 more to go.

Modified:
  stable/8/sys/netinet/sctp_asconf.c
  stable/8/sys/netinet/sctp_constants.h
  stable/8/sys/netinet/sctp_indata.c
  stable/8/sys/netinet/sctp_indata.h
  stable/8/sys/netinet/sctp_input.c
  stable/8/sys/netinet/sctp_output.c
  stable/8/sys/netinet/sctp_output.h
  stable/8/sys/netinet/sctp_pcb.c
  stable/8/sys/netinet/sctp_pcb.h
  stable/8/sys/netinet/sctp_structs.h
  stable/8/sys/netinet/sctp_usrreq.c
  stable/8/sys/netinet/sctp_var.h
  stable/8/sys/netinet/sctputil.c
  stable/8/sys/netinet/sctputil.h
  stable/8/sys/netinet6/sctp6_usrreq.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/netinet/sctp_asconf.c
==============================================================================
--- stable/8/sys/netinet/sctp_asconf.c  Sat Apr 17 04:13:52 2010        
(r206741)
+++ stable/8/sys/netinet/sctp_asconf.c  Sat Apr 17 04:15:46 2010        
(r206742)
@@ -556,9 +556,9 @@ sctp_process_asconf_set_primary(struct m
                 * PRIMARY with DELETE IP ADDRESS of the previous primary
                 * destination, unacknowledged DATA are retransmitted
                 * immediately to the new primary destination for seamless
-                * handover.  If the destination is UNCONFIRMED and marked
-                * to REQ_PRIM, The retransmission occur when reception of
-                * the HEARTBEAT-ACK.  (See sctp_handle_heartbeat_ack in
+                * handover. If the destination is UNCONFIRMED and marked to
+                * REQ_PRIM, The retransmission occur when reception of the
+                * HEARTBEAT-ACK.  (See sctp_handle_heartbeat_ack in
                 * sctp_input.c) Also, when change of the primary
                 * destination, it is better that all subsequent new DATA
                 * containing already queued DATA are transmitted to the new
@@ -1166,7 +1166,7 @@ sctp_path_check_and_react(struct sctp_tc
 
        /*
         * If number of local valid addresses is 1, the valid address is
-        * probably newly added address.  Several valid addresses in this
+        * probably newly added address. Several valid addresses in this
         * association.  A source address may not be changed.  Additionally,
         * they can be configured on a same interface as "alias" addresses.
         * (by micchie)
@@ -1210,7 +1210,7 @@ sctp_path_check_and_react(struct sctp_tc
                /*
                 * Check if the nexthop is corresponding to the new address.
                 * If the new address is corresponding to the current
-                * nexthop, the path will be changed.  If the new address is
+                * nexthop, the path will be changed. If the new address is
                 * NOT corresponding to the current nexthop, the path will
                 * not be changed.
                 */

Modified: stable/8/sys/netinet/sctp_constants.h
==============================================================================
--- stable/8/sys/netinet/sctp_constants.h       Sat Apr 17 04:13:52 2010        
(r206741)
+++ stable/8/sys/netinet/sctp_constants.h       Sat Apr 17 04:15:46 2010        
(r206742)
@@ -544,13 +544,7 @@ __FBSDID("$FreeBSD$");
 #define SCTP_INITIAL_MAPPING_ARRAY  16
 /* how much we grow the mapping array each call */
 #define SCTP_MAPPING_ARRAY_INCR     32
-/* EY 05/13/08 - nr_sack version of the previous 3 constants */
-/* Maximum the nr mapping array will  grow to (TSN mapping array) */
-#define SCTP_NR_MAPPING_ARRAY  512
-/* size of the inital malloc on the nr mapping array */
-#define SCTP_INITIAL_NR_MAPPING_ARRAY  16
-/* how much we grow the nr mapping array each call */
-#define SCTP_NR_MAPPING_ARRAY_INCR     32
+
 /*
  * Here we define the timer types used by the implementation as arguments in
  * the set/get timer type calls.
@@ -933,6 +927,13 @@ __FBSDID("$FreeBSD$");
 #define SCTP_IS_TSN_PRESENT(arry, gap) ((arry[(gap >> 3)] >> (gap & 0x07)) & 
0x01)
 #define SCTP_SET_TSN_PRESENT(arry, gap) (arry[(gap >> 3)] |= (0x01 << ((gap & 
0x07))))
 #define SCTP_UNSET_TSN_PRESENT(arry, gap) (arry[(gap >> 3)] &= ((~(0x01 << 
((gap & 0x07)))) & 0xff))
+#define SCTP_CALC_TSN_TO_GAP(gap, tsn, mapping_tsn) do { \
+                       if (tsn >= mapping_tsn) { \
+                                               gap = tsn - mapping_tsn; \
+                                       } else { \
+                                               gap = (MAX_TSN - mapping_tsn) + 
tsn + 1; \
+                                       } \
+                  } while(0)
 
 
 #define SCTP_RETRAN_DONE -1

Modified: stable/8/sys/netinet/sctp_indata.c
==============================================================================
--- stable/8/sys/netinet/sctp_indata.c  Sat Apr 17 04:13:52 2010        
(r206741)
+++ stable/8/sys/netinet/sctp_indata.c  Sat Apr 17 04:15:46 2010        
(r206742)
@@ -45,13 +45,6 @@ __FBSDID("$FreeBSD$");
 #include <netinet/sctp_uio.h>
 #include <netinet/sctp_timer.h>
 
-#define SCTP_CALC_TSN_TO_GAP(gap, tsn, mapping_tsn) do { \
-                       if (tsn >= mapping_tsn) { \
-                                               gap = tsn - mapping_tsn; \
-                                       } else { \
-                                               gap = (MAX_TSN - mapping_tsn) + 
tsn + 1; \
-                                       } \
-                  } while(0)
 
 /*
  * NOTES: On the outbound side of things I need to check the sack timer to
@@ -303,13 +296,13 @@ sctp_mark_non_revokable(struct sctp_asso
                return;
        }
        SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
-#ifdef INVARIANTS
        if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
                printf("gap:%x tsn:%x\n", gap, tsn);
                sctp_print_mapping_array(asoc);
+#ifdef INVARIANTS
                panic("Things are really messed up now!!");
-       }
 #endif
+       }
        SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
        SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
        if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
@@ -317,7 +310,8 @@ sctp_mark_non_revokable(struct sctp_asso
        }
        if (tsn == asoc->highest_tsn_inside_map) {
                /* We must back down to see what the new highest is */
-               for (i = tsn - 1; compare_with_wrap(i, 
asoc->mapping_array_base_tsn, MAX_TSN); i--) {
+               for (i = tsn - 1; (compare_with_wrap(i, 
asoc->mapping_array_base_tsn, MAX_TSN) ||
+                   (i == asoc->mapping_array_base_tsn)); i--) {
                        SCTP_CALC_TSN_TO_GAP(gap, i, 
asoc->mapping_array_base_tsn);
                        if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
                                asoc->highest_tsn_inside_map = i;
@@ -411,6 +405,7 @@ abandon:
                                end = 1;
                        else
                                end = 0;
+                       sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
                        sctp_add_to_readq(stcb->sctp_ep,
                            stcb, control, &stcb->sctp_socket->so_rcv, end,
                            SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
@@ -420,6 +415,7 @@ abandon:
                                end = 1;
                        else
                                end = 0;
+                       sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
                        if (sctp_append_to_readq(stcb->sctp_ep, stcb,
                            stcb->asoc.control_pdapi,
                            chk->data, end, chk->rec.data.TSN_seq,
@@ -454,7 +450,6 @@ abandon:
                }
                /* pull it we did it */
                TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next);
-               sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
                if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
                        asoc->fragmented_delivery_inprogress = 0;
                        if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == 
0) {
@@ -501,11 +496,11 @@ abandon:
                                                asoc->size_on_all_streams -= 
ctl->length;
                                                
sctp_ucount_decr(asoc->cnt_on_all_streams);
                                                strm->last_sequence_delivered++;
+                                               sctp_mark_non_revokable(asoc, 
ctl->sinfo_tsn);
                                                
sctp_add_to_readq(stcb->sctp_ep, stcb,
                                                    ctl,
                                                    &stcb->sctp_socket->so_rcv, 
1,
                                                    SCTP_READ_LOCK_NOT_HELD, 
SCTP_SO_NOT_LOCKED);
-                                               sctp_mark_non_revokable(asoc, 
ctl->sinfo_tsn);
                                                ctl = ctlat;
                                        } else {
                                                break;
@@ -616,11 +611,11 @@ protocol_error:
                sctp_ucount_decr(asoc->cnt_on_all_streams);
                strm->last_sequence_delivered++;
 
+               sctp_mark_non_revokable(asoc, control->sinfo_tsn);
                sctp_add_to_readq(stcb->sctp_ep, stcb,
                    control,
                    &stcb->sctp_socket->so_rcv, 1,
                    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
-               sctp_mark_non_revokable(asoc, control->sinfo_tsn);
                control = TAILQ_FIRST(&strm->inqueue);
                while (control != NULL) {
                        /* all delivered */
@@ -641,13 +636,12 @@ protocol_error:
                                        sctp_log_strm_del(control, NULL,
                                            SCTP_STR_LOG_FROM_IMMED_DEL);
                                }
-                               /* EY will be used to calculate nr-gap */
+                               sctp_mark_non_revokable(asoc, 
control->sinfo_tsn);
                                sctp_add_to_readq(stcb->sctp_ep, stcb,
                                    control,
                                    &stcb->sctp_socket->so_rcv, 1,
                                    SCTP_READ_LOCK_NOT_HELD,
                                    SCTP_SO_NOT_LOCKED);
-                               sctp_mark_non_revokable(asoc, 
control->sinfo_tsn);
                                control = at;
                                continue;
                        }
@@ -965,8 +959,7 @@ sctp_queue_data_for_reasm(struct sctp_tc
                                        *abort_flag = 1;
                                } else if ((asoc->fragment_flags & 
SCTP_DATA_UNORDERED) !=
                                            SCTP_DATA_UNORDERED &&
-                                           chk->rec.data.stream_seq !=
-                                   asoc->ssn_of_pdapi) {
+                                   chk->rec.data.stream_seq != 
asoc->ssn_of_pdapi) {
                                        /* Got to be the right STR Seq */
                                        SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil 
plot, it IS not same stream seq %d vs %d\n",
                                            chk->rec.data.stream_seq,
@@ -1623,7 +1616,6 @@ sctp_process_a_data_chunk(struct sctp_tc
                }
                SCTP_STAT_INCR(sctps_badsid);
                SCTP_TCB_LOCK_ASSERT(stcb);
-
                SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
                if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, 
MAX_TSN)) {
                        asoc->highest_tsn_inside_nr_map = tsn;
@@ -1787,6 +1779,7 @@ sctp_process_a_data_chunk(struct sctp_tc
                            SCTP_STR_LOG_FROM_EXPRS_DEL);
                }
                control = NULL;
+
                SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
                if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, 
MAX_TSN)) {
                        asoc->highest_tsn_inside_nr_map = tsn;
@@ -1853,10 +1846,6 @@ failed_express_del:
                                        need_reasm_check = 1;
                                }
                        }
-                       SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
-                       if (compare_with_wrap(tsn, 
asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
-                               asoc->highest_tsn_inside_nr_map = tsn;
-                       }
                        control = NULL;
                        goto finish_express_del;
                }
@@ -2059,10 +2048,10 @@ failed_pdapi_express_del:
                /* ok, if we reach here we have passed the sanity checks */
                if (chunk_flags & SCTP_DATA_UNORDERED) {
                        /* queue directly into socket buffer */
+                       sctp_mark_non_revokable(asoc, control->sinfo_tsn);
                        sctp_add_to_readq(stcb->sctp_ep, stcb,
                            control,
                            &stcb->sctp_socket->so_rcv, 1, 
SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
-
                } else {
                        /*
                         * Special check for when streams are resetting. We
@@ -2134,10 +2123,6 @@ failed_pdapi_express_del:
                }
        }
 finish_express_del:
-       if (tsn == (asoc->cumulative_tsn + 1)) {
-               /* Update cum-ack */
-               asoc->cumulative_tsn = tsn;
-       }
        if (last_chunk) {
                *m = NULL;
        }
@@ -2215,43 +2200,43 @@ finish_express_del:
 }
 
 int8_t sctp_map_lookup_tab[256] = {
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 3,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 4,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 3,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 5,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 3,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 4,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 3,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 6,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 3,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 4,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 3,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 5,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 3,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 4,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 3,
-       -1, 0, -1, 1, -1, 0, -1, 2,
-       -1, 0, -1, 1, -1, 0, -1, 7,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 4,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 5,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 4,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 6,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 4,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 5,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 4,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 7,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 4,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 5,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 4,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 6,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 4,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 5,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 4,
+       0, 1, 0, 2, 0, 1, 0, 3,
+       0, 1, 0, 2, 0, 1, 0, 8
 };
 
 
 void
-sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int 
*abort_flag)
+sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
 {
        /*
         * Now we also need to check the mapping array in a couple of ways.
@@ -2259,7 +2244,6 @@ sctp_sack_check(struct sctp_tcb *stcb, i
         */
        struct sctp_association *asoc;
        int at;
-       int last_all_ones = 0;
        int slide_from, slide_end, lgap, distance;
 
        /* EY nr_mapping array variables */
@@ -2279,19 +2263,16 @@ sctp_sack_check(struct sctp_tcb *stcb, i
         * offset of the current cum-ack as the starting point.
         */
        at = 0;
-       for (slide_from = 0; slide_from < stcb->asoc.nr_mapping_array_size; 
slide_from++) {
+       for (slide_from = 0; slide_from < stcb->asoc.mapping_array_size; 
slide_from++) {
                if (asoc->nr_mapping_array[slide_from] == 0xff) {
                        at += 8;
-                       last_all_ones = 1;
                } else {
                        /* there is a 0 bit */
                        at += 
sctp_map_lookup_tab[asoc->nr_mapping_array[slide_from]];
-                       last_all_ones = 0;
                        break;
                }
        }
-       asoc->cumulative_tsn = asoc->nr_mapping_array_base_tsn + (at - 
last_all_ones);
-       at++;
+       asoc->cumulative_tsn = asoc->mapping_array_base_tsn + (at - 1);
 
        if (compare_with_wrap(asoc->cumulative_tsn, 
asoc->highest_tsn_inside_map, MAX_TSN) &&
            compare_with_wrap(asoc->cumulative_tsn, 
asoc->highest_tsn_inside_nr_map, MAX_TSN)
@@ -2320,18 +2301,22 @@ sctp_sack_check(struct sctp_tcb *stcb, i
        if ((asoc->cumulative_tsn == highest_tsn) && (at >= 8)) {
                /* The complete array was completed by a single FR */
                /* highest becomes the cum-ack */
-               int clr;
+               int clr, i;
 
                /* clear the array */
-               clr = (at >> 3) + 1;
+               clr = ((at + 7) >> 3);
                if (clr > asoc->mapping_array_size) {
                        clr = asoc->mapping_array_size;
                }
                memset(asoc->mapping_array, 0, clr);
                memset(asoc->nr_mapping_array, 0, clr);
-
+               for (i = 0; i < asoc->mapping_array_size; i++) {
+                       if ((asoc->mapping_array[i]) || 
(asoc->nr_mapping_array[i])) {
+                               printf("Error Mapping array's not clean at 
clear\n");
+                               sctp_print_mapping_array(asoc);
+                       }
+               }
                asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1;
-               asoc->nr_mapping_array_base_tsn = asoc->cumulative_tsn + 1;
                asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map 
= asoc->cumulative_tsn;
        } else if (at >= 8) {
                /* we can slide the mapping array down */
@@ -2393,12 +2378,11 @@ sctp_sack_check(struct sctp_tcb *stcb, i
                                    asoc->nr_mapping_array[slide_from + ii];
 
                        }
-                       for (ii = distance; ii <= slide_end; ii++) {
+                       for (ii = distance; ii <= asoc->mapping_array_size; 
ii++) {
                                asoc->mapping_array[ii] = 0;
                                asoc->nr_mapping_array[ii] = 0;
                        }
                        asoc->mapping_array_base_tsn += (slide_from << 3);
-                       asoc->nr_mapping_array_base_tsn += (slide_from << 3);
                        if (SCTP_BASE_SYSCTL(sctp_logging_level) & 
SCTP_MAP_LOGGING_ENABLE) {
                                sctp_log_map(asoc->mapping_array_base_tsn,
                                    asoc->cumulative_tsn, 
asoc->highest_tsn_inside_map,
@@ -2406,95 +2390,95 @@ sctp_sack_check(struct sctp_tcb *stcb, i
                        }
                }
        }
+}
+
+
+void
+sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap, int *abort_flag)
+{
+       struct sctp_association *asoc;
+       uint32_t highest_tsn;
+
+       asoc = &stcb->asoc;
+       if (compare_with_wrap(asoc->highest_tsn_inside_nr_map,
+           asoc->highest_tsn_inside_map,
+           MAX_TSN)) {
+               highest_tsn = asoc->highest_tsn_inside_nr_map;
+       } else {
+               highest_tsn = asoc->highest_tsn_inside_map;
+       }
+
        /*
         * Now we need to see if we need to queue a sack or just start the
         * timer (if allowed).
         */
-       if (ok_to_sack) {
-               if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) {
-                       /*
-                        * Ok special case, in SHUTDOWN-SENT case. here we
-                        * maker sure SACK timer is off and instead send a
-                        * SHUTDOWN and a SACK
-                        */
-                       if 
(SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
-                               sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
-                                   stcb->sctp_ep, stcb, NULL, 
SCTP_FROM_SCTP_INDATA + SCTP_LOC_18);
-                       }
-                       sctp_send_shutdown(stcb, 
stcb->asoc.primary_destination);
-                       /*
-                        * EY if nr_sacks used then send an nr-sack , a sack
-                        * otherwise
-                        */
-                       if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && 
stcb->asoc.peer_supports_nr_sack)
-                               sctp_send_nr_sack(stcb);
-                       else
-                               sctp_send_sack(stcb);
-               } else {
-                       int is_a_gap;
+       if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) {
+               /*
+                * Ok special case, in SHUTDOWN-SENT case. here we maker
+                * sure SACK timer is off and instead send a SHUTDOWN and a
+                * SACK
+                */
+               if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
+                       sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
+                           stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_INDATA + 
SCTP_LOC_18);
+               }
+               sctp_send_shutdown(stcb, stcb->asoc.primary_destination);
+               sctp_send_sack(stcb);
+       } else {
+               int is_a_gap;
 
-                       /* is there a gap now ? */
-                       is_a_gap = compare_with_wrap(highest_tsn, 
stcb->asoc.cumulative_tsn, MAX_TSN);
+               /* is there a gap now ? */
+               is_a_gap = compare_with_wrap(highest_tsn, 
stcb->asoc.cumulative_tsn, MAX_TSN);
 
-                       /*
-                        * CMT DAC algorithm: increase number of packets
-                        * received since last ack
-                        */
-                       stcb->asoc.cmt_dac_pkts_rcvd++;
+               /*
+                * CMT DAC algorithm: increase number of packets received
+                * since last ack
+                */
+               stcb->asoc.cmt_dac_pkts_rcvd++;
 
-                       if ((stcb->asoc.send_sack == 1) ||      /* We need to 
send a
-                                                                * SACK */
-                           ((was_a_gap) && (is_a_gap == 0)) || /* was a gap, 
but no
-                                                                * longer is 
one */
-                           (stcb->asoc.numduptsns) ||  /* we have dup's */
-                           (is_a_gap) ||       /* is still a gap */
-                           (stcb->asoc.delayed_ack == 0) ||    /* Delayed sack 
disabled */
-                           (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq) 
/* hit limit of pkts */
-                           ) {
+               if ((stcb->asoc.send_sack == 1) ||      /* We need to send a
+                                                        * SACK */
+                   ((was_a_gap) && (is_a_gap == 0)) || /* was a gap, but no
+                                                        * longer is one */
+                   (stcb->asoc.numduptsns) ||  /* we have dup's */
+                   (is_a_gap) ||       /* is still a gap */
+                   (stcb->asoc.delayed_ack == 0) ||    /* Delayed sack 
disabled */
+                   (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq) /* hit 
limit of pkts */
+                   ) {
 
-                               if ((SCTP_BASE_SYSCTL(sctp_cmt_on_off)) &&
-                                   (SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) &&
-                                   (stcb->asoc.send_sack == 0) &&
-                                   (stcb->asoc.numduptsns == 0) &&
-                                   (stcb->asoc.delayed_ack) &&
-                                   
(!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer))) {
+                       if ((SCTP_BASE_SYSCTL(sctp_cmt_on_off)) &&
+                           (SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) &&
+                           (stcb->asoc.send_sack == 0) &&
+                           (stcb->asoc.numduptsns == 0) &&
+                           (stcb->asoc.delayed_ack) &&
+                           
(!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer))) {
 
-                                       /*
-                                        * CMT DAC algorithm: With CMT,
-                                        * delay acks even in the face of
-                                        * 
-                                        * reordering. Therefore, if acks that
-                                        * do not have to be sent because of
-                                        * the above reasons, will be
-                                        * delayed. That is, acks that would
-                                        * have been sent due to gap reports
-                                        * will be delayed with DAC. Start
-                                        * the delayed ack timer.
-                                        */
-                                       sctp_timer_start(SCTP_TIMER_TYPE_RECV,
-                                           stcb->sctp_ep, stcb, NULL);
-                               } else {
-                                       /*
-                                        * Ok we must build a SACK since the
-                                        * timer is pending, we got our
-                                        * first packet OR there are gaps or
-                                        * duplicates.
-                                        */
-                                       
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
-                                       /*
-                                        * EY if nr_sacks used then send an
-                                        * nr-sack , a sack otherwise
-                                        */
-                                       if 
(SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
-                                               sctp_send_nr_sack(stcb);
-                                       else
-                                               sctp_send_sack(stcb);
-                               }
+                               /*
+                                * CMT DAC algorithm: With CMT, delay acks
+                                * even in the face of
+                                * 
+                                * reordering. Therefore, if acks that do not
+                                * have to be sent because of the above
+                                * reasons, will be delayed. That is, acks
+                                * that would have been sent due to gap
+                                * reports will be delayed with DAC. Start
+                                * the delayed ack timer.
+                                */
+                               sctp_timer_start(SCTP_TIMER_TYPE_RECV,
+                                   stcb->sctp_ep, stcb, NULL);
                        } else {
-                               if 
(!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
-                                       sctp_timer_start(SCTP_TIMER_TYPE_RECV,
-                                           stcb->sctp_ep, stcb, NULL);
-                               }
+                               /*
+                                * Ok we must build a SACK since the timer
+                                * is pending, we got our first packet OR
+                                * there are gaps or duplicates.
+                                */
+                               
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
+                               sctp_send_sack(stcb);
+                       }
+               } else {
+                       if 
(!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
+                               sctp_timer_start(SCTP_TIMER_TYPE_RECV,
+                                   stcb->sctp_ep, stcb, NULL);
                        }
                }
        }
@@ -2834,14 +2818,7 @@ sctp_process_data(struct mbuf **mm, int 
                        if 
(SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
                                
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
                        }
-                       /*
-                        * EY if nr_sacks used then send an nr-sack , a sack
-                        * otherwise
-                        */
-                       if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && 
stcb->asoc.peer_supports_nr_sack)
-                               sctp_send_nr_sack(stcb);
-                       else
-                               sctp_send_sack(stcb);
+                       sctp_send_sack(stcb);
                } else {
                        if 
(!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
                                sctp_timer_start(SCTP_TIMER_TYPE_RECV,
@@ -2849,7 +2826,7 @@ sctp_process_data(struct mbuf **mm, int 
                        }
                }
        } else {
-               sctp_sack_check(stcb, 1, was_a_gap, &abort_flag);
+               sctp_sack_check(stcb, was_a_gap, &abort_flag);
        }
        if (abort_flag)
                return (2);
@@ -2867,7 +2844,7 @@ sctp_process_segment_range(struct sctp_t
 {
        struct sctp_tmit_chunk *tp1;
        unsigned int theTSN;
-       int j, wake_him = 0;
+       int j, wake_him = 0, circled = 0;
 
        /* Recover the tp1 we last saw */
        tp1 = *p_tp1;
@@ -3045,12 +3022,6 @@ sctp_process_segment_range(struct sctp_t
                                        }
                                        /* NR Sack code here */
                                        if (nr_sacking) {
-                                               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
@@ -3058,13 +3029,8 @@ sctp_process_segment_range(struct sctp_t
                                                         */
                                                        
sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
                                                        sctp_m_freem(tp1->data);
+                                                       tp1->data = NULL;
                                                }
-                                               tp1->data = NULL;
-                                               /* asoc->sent_queue_cnt--; */
-                                               /*
-                                                * sctp_free_a_chunk(stcb,
-                                                * tp1);
-                                                */
                                                wake_him++;
                                        }
                                }
@@ -3075,11 +3041,16 @@ sctp_process_segment_range(struct sctp_t
                                break;
 
                        tp1 = TAILQ_NEXT(tp1, sctp_next);
+                       if ((tp1 == NULL) && (circled == 0)) {
+                               circled++;
+                               tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue);
+                       }
                }               /* end while (tp1) */
-               /* In case the fragments were not in order we must reset */
                if (tp1 == NULL) {
+                       circled = 0;
                        tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue);
                }
+               /* In case the fragments were not in order we must reset */
        }                       /* end for (j = fragStart */
        *p_tp1 = tp1;
        return (wake_him);      /* Return value only used for nr-sack */
@@ -3158,6 +3129,9 @@ sctp_handle_segments(struct mbuf *m, int
                } else {
                        non_revocable = 1;
                }
+               if (i == num_seg) {
+                       tp1 = NULL;
+               }
                if (sctp_process_segment_range(stcb, &tp1, last_tsn, frag_strt, 
frag_end,
                    non_revocable, &num_frs, biggest_newly_acked_tsn,
                    this_sack_lowest_newack, ecn_seg_sums)) {
@@ -3961,6 +3935,7 @@ sctp_express_handle_sack(struct sctp_tcb
 #ifdef INVARIANTS
                        panic("Impossible sack 1");
 #else
+
                        *abort_now = 1;
                        /* XXX */
                        oper = sctp_get_mbuf_for_msg((sizeof(struct 
sctp_paramhdr) + sizeof(uint32_t)),
@@ -4439,50 +4414,6 @@ again:
        }
 }
 
-/* EY- nr_sack */
-/* Identifies the non-renegable tsns that are revoked*/
-static void
-sctp_check_for_nr_revoked(struct sctp_tcb *stcb,
-    struct sctp_association *asoc, uint32_t cumack,
-    uint32_t biggest_tsn_acked)
-{
-       struct sctp_tmit_chunk *tp1;
-
-       for (tp1 = TAILQ_FIRST(&asoc->sent_queue); tp1; tp1 = TAILQ_NEXT(tp1, 
sctp_next)) {
-               if (compare_with_wrap(tp1->rec.data.TSN_seq, cumack,
-                   MAX_TSN)) {
-                       /*
-                        * ok this guy is either ACK or MARKED. If it is
-                        * ACKED it has been previously acked but not this
-                        * time i.e. revoked.  If it is MARKED it was ACK'ed
-                        * again.
-                        */
-                       if (compare_with_wrap(tp1->rec.data.TSN_seq, 
biggest_tsn_acked,
-                           MAX_TSN))
-                               break;
-
-
-                       if (tp1->sent == SCTP_DATAGRAM_NR_ACKED) {
-                               /*
-                                * EY! a non-renegable TSN is revoked, need
-                                * to abort the association
-                                */
-                               /*
-                                * EY TODO: put in the code to abort the
-                                * assoc.
-                                */
-                               return;
-                       } else if (tp1->sent == SCTP_DATAGRAM_NR_MARKED) {
-                               /* it has been re-acked in this SACK */
-                               tp1->sent = SCTP_DATAGRAM_NR_ACKED;
-                       }
-               }
-               if (tp1->sent == SCTP_DATAGRAM_UNSENT)
-                       break;
-       }
-       return;
-}
-
 void
 sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
     struct sctp_tcb *stcb, struct sctp_nets *net_from,
@@ -4588,22 +4519,23 @@ sctp_handle_sack(struct mbuf *m, int off
                            sctpchunk_listhead);
                        send_s = tp1->rec.data.TSN_seq + 1;
                } else {
+                       tp1 = NULL;
                        send_s = asoc->sending_seq;
                }
                if (cum_ack == send_s ||
                    compare_with_wrap(cum_ack, send_s, MAX_TSN)) {
-#ifndef INVARIANTS
                        struct mbuf *oper;
 
-#endif
-#ifdef INVARIANTS
-       hopeless_peer:
-                       panic("Impossible sack 1");
-#else
                        /*
                         * no way, we have not even sent this TSN out yet.
                         * Peer is hopelessly messed up with us.
                         */
+                       printf("NEW cum_ack:%x send_s:%x is smaller or equal\n",
+                           cum_ack, send_s);
+                       if (tp1) {
+                               printf("Got send_s from tsn:%x + 1 of tp1:%p\n",
+                                   tp1->rec.data.TSN_seq, tp1);
+                       }
        hopeless_peer:
                        *abort_now = 1;
                        /* XXX */
@@ -4624,7 +4556,6 @@ sctp_handle_sack(struct mbuf *m, int off
                        stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA 
+ SCTP_LOC_25;
                        sctp_abort_an_association(stcb->sctp_ep, stcb, 
SCTP_PEER_FAULTY, oper, SCTP_SO_NOT_LOCKED);
                        return;
-#endif
                }
        }
        /**********************/
@@ -4844,6 +4775,10 @@ sctp_handle_sack(struct mbuf *m, int off
                                 * peer is either confused or we are under
                                 * attack. We must abort.
                                 */
+                               printf("Hopeless peer! biggest_tsn_acked:%x 
largest seq:%x\n",
+                                   biggest_tsn_acked,
+                                   send_s);
+
                                goto hopeless_peer;
                        }
                }
@@ -4991,15 +4926,9 @@ done_with_it:
                                 */
                                if ((tp1->sent == SCTP_DATAGRAM_NR_ACKED) ||
                                    (tp1->sent == SCTP_DATAGRAM_NR_MARKED)) {
-                                       /*
-                                        * EY! - TODO: Something previously
-                                        * nr_gapped is reneged, abort the
-                                        * association
-                                        */
-                                       return;
+                                       continue;
                                }
-                               if ((tp1->sent > SCTP_DATAGRAM_RESEND) &&
-                                   (tp1->sent < SCTP_FORWARD_TSN_SKIP)) {
+                               if (tp1->sent == SCTP_DATAGRAM_ACKED) {
                                        tp1->sent = SCTP_DATAGRAM_SENT;
                                        if 
(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
                                                
sctp_misc_ints(SCTP_FLIGHT_LOG_UP_REVOKE,
@@ -5028,15 +4957,11 @@ done_with_it:
                }
                asoc->saw_sack_with_frags = 0;
        }
-       if (num_seg)
+       if (num_seg || num_nr_seg)
                asoc->saw_sack_with_frags = 1;
        else
                asoc->saw_sack_with_frags = 0;
 
-       /* EY! - not sure about if there should be an IF */
-       if (num_nr_seg > 0)
-               sctp_check_for_nr_revoked(stcb, asoc, cum_ack, 
biggest_tsn_acked);
-
        /* JRS - Use the congestion control given in the CC module */
        asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, accum_moved, 
reneged_all, will_exit_fast_recovery);
 
@@ -5457,11 +5382,10 @@ sctp_kick_prsctp_reorder_queue(struct sc
                        sctp_ucount_decr(asoc->cnt_on_all_streams);
                        /* deliver it to at least the delivery-q */
                        if (stcb->sctp_socket) {
-                               /* EY need the tsn info for calculating nr */
+                               sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
                                sctp_add_to_readq(stcb->sctp_ep, stcb,
                                    ctl,
                                    &stcb->sctp_socket->so_rcv, 1, 
SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
-                               sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
                        }
                } else {
                        /* no more delivery now. */
@@ -5486,10 +5410,10 @@ sctp_kick_prsctp_reorder_queue(struct sc
                        /* deliver it to at least the delivery-q */
                        strmin->last_sequence_delivered = ctl->sinfo_ssn;
                        if (stcb->sctp_socket) {
+                               sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
                                sctp_add_to_readq(stcb->sctp_ep, stcb,
                                    ctl,
                                    &stcb->sctp_socket->so_rcv, 1, 
SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
-                               sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
 
                        }
                        tt = strmin->last_sequence_delivered + 1;
@@ -5593,7 +5517,8 @@ sctp_flush_reassm_for_str_seq(struct sct
 
 void
 sctp_handle_forward_tsn(struct sctp_tcb *stcb,
-    struct sctp_forward_tsn_chunk *fwd, int *abort_flag, struct mbuf *m, int 
offset)
+    struct sctp_forward_tsn_chunk *fwd,
+    int *abort_flag, struct mbuf *m, int offset)
 {
        /*
         * ISSUES that MUST be fixed for ECN! When we are the sender of the
@@ -5619,8 +5544,8 @@ sctp_handle_forward_tsn(struct sctp_tcb 
         * report where we are.
         */
        struct sctp_association *asoc;
-       uint32_t new_cum_tsn, gap;
-       unsigned int i, fwd_sz, cumack_set_flag, m_size;
+       uint32_t new_cum_tsn, tsn, gap;
+       unsigned int i, fwd_sz, cumack_set_flag, m_size, fnd = 0;
        uint32_t str_seq;
        struct sctp_stream_in *strm;
        struct sctp_tmit_chunk *chk, *at;
@@ -5657,7 +5582,7 @@ sctp_handle_forward_tsn(struct sctp_tcb 
         * now we know the new TSN is more advanced, let's find the actual
         * gap
         */
-       SCTP_CALC_TSN_TO_GAP(gap, new_cum_tsn, asoc->nr_mapping_array_base_tsn);
+       SCTP_CALC_TSN_TO_GAP(gap, new_cum_tsn, asoc->mapping_array_base_tsn);
        asoc->cumulative_tsn = new_cum_tsn;
        if (gap >= m_size) {
                if ((long)gap > sctp_sbspace(&stcb->asoc, 
&stcb->sctp_socket->so_rcv)) {
@@ -5697,8 +5622,7 @@ sctp_handle_forward_tsn(struct sctp_tcb 
                asoc->mapping_array_base_tsn = new_cum_tsn + 1;
                asoc->highest_tsn_inside_map = new_cum_tsn;
 
-               memset(stcb->asoc.nr_mapping_array, 0, 
stcb->asoc.nr_mapping_array_size);
-               asoc->nr_mapping_array_base_tsn = new_cum_tsn + 1;
+               memset(stcb->asoc.nr_mapping_array, 0, 
stcb->asoc.mapping_array_size);
                asoc->highest_tsn_inside_nr_map = new_cum_tsn;
 
                if (SCTP_BASE_SYSCTL(sctp_logging_level) & 
SCTP_MAP_LOGGING_ENABLE) {
@@ -5710,14 +5634,32 @@ sctp_handle_forward_tsn(struct sctp_tcb 
                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 (!fnd) {
+                               asoc->highest_tsn_inside_map = 
asoc->mapping_array_base_tsn - 1;
+                       }
                }
                /*
                 * Now after marking all, slide thing forward but no sack
                 * please.
                 */
-               sctp_sack_check(stcb, 0, 0, abort_flag);
-               if (*abort_flag)
-                       return;
+               sctp_slide_mapping_arrays(stcb);
        }
        /*************************************************************/
        /* 2. Clear up re-assembly queue                             */

Modified: stable/8/sys/netinet/sctp_indata.h
==============================================================================
--- stable/8/sys/netinet/sctp_indata.h  Sat Apr 17 04:13:52 2010        
(r206741)
+++ stable/8/sys/netinet/sctp_indata.h  Sat Apr 17 04:15:46 2010        
(r206742)
@@ -121,7 +121,9 @@ sctp_process_data(struct mbuf **, int, i
     struct sctp_inpcb *, struct sctp_tcb *,
     struct sctp_nets *, uint32_t *);
 
-void sctp_sack_check(struct sctp_tcb *, int, int, int *);
+void sctp_slide_mapping_arrays(struct sctp_tcb *stcb);
+
+void sctp_sack_check(struct sctp_tcb *, int, int *);
 
 #endif
 #endif

Modified: stable/8/sys/netinet/sctp_input.c
==============================================================================
--- stable/8/sys/netinet/sctp_input.c   Sat Apr 17 04:13:52 2010        
(r206741)
+++ stable/8/sys/netinet/sctp_input.c   Sat Apr 17 04:15:46 2010        
(r206742)
@@ -343,11 +343,6 @@ sctp_process_init(struct sctp_init_chunk
        asoc->str_reset_seq_in = asoc->asconf_seq_in + 1;
 
        asoc->mapping_array_base_tsn = ntohl(init->initial_tsn);
-       /*
-        * EY 05/13/08 - nr_sack: initialize nr_mapping array's base tsn
-        * like above
-        */
-       asoc->nr_mapping_array_base_tsn = ntohl(init->initial_tsn);
        asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->asconf_seq_in;
        asoc->last_echo_tsn = asoc->asconf_seq_in;
        asoc->advanced_peer_ack_point = asoc->last_acked_seq;
@@ -1862,7 +1857,7 @@ sctp_process_cookie_existing(struct mbuf
                }
                if (asoc->nr_mapping_array) {
                        memset(asoc->nr_mapping_array, 0,
-                           asoc->nr_mapping_array_size);
+                           asoc->mapping_array_size);
                }
                SCTP_TCB_UNLOCK(stcb);
                SCTP_INP_INFO_WLOCK();
@@ -2027,7 +2022,7 @@ sctp_process_cookie_new(struct mbuf *m, 
         * socket is unbound and we must do an implicit bind. Since we are
         * getting a cookie, we cannot be unbound.
         */
-       stcb = sctp_aloc_assoc(inp, init_src, 0, &error,
+       stcb = sctp_aloc_assoc(inp, init_src, &error,
            ntohl(initack_cp->init.initiate_tag), vrf_id,
            (struct thread *)NULL
            );
@@ -3236,13 +3231,10 @@ process_chunk_drop(struct sctp_tcb *stcb
                }
                break;
        case SCTP_SELECTIVE_ACK:
+       case SCTP_NR_SELECTIVE_ACK:
                /* resend the sack */
                sctp_send_sack(stcb);
                break;
-               /* EY for nr_sacks */
-       case SCTP_NR_SELECTIVE_ACK:
-               sctp_send_nr_sack(stcb);        /* EY resend the nr-sack */
-               break;
        case SCTP_HEARTBEAT_REQUEST:
                /* resend a demand HB */
                if ((stcb->asoc.overall_error_count + 3) < 
stcb->asoc.max_send_times) {
@@ -3514,8 +3506,7 @@ sctp_handle_stream_reset_response(struct
                                        memset(stcb->asoc.mapping_array, 0, 
stcb->asoc.mapping_array_size);
 
                                        stcb->asoc.highest_tsn_inside_nr_map = 
stcb->asoc.highest_tsn_inside_map;
-                                       stcb->asoc.nr_mapping_array_base_tsn = 
stcb->asoc.mapping_array_base_tsn;
-                                       memset(stcb->asoc.nr_mapping_array, 0, 
stcb->asoc.nr_mapping_array_size);
+                                       memset(stcb->asoc.nr_mapping_array, 0, 
stcb->asoc.mapping_array_size);
 
                                        stcb->asoc.sending_seq = 
ntohl(resp->receivers_next_tsn);
                                        stcb->asoc.last_acked_seq = 
stcb->asoc.cumulative_tsn;
@@ -3624,8 +3615,7 @@ sctp_handle_str_reset_request_tsn(struct
                stcb->asoc.mapping_array_base_tsn = 
stcb->asoc.highest_tsn_inside_map + 1;
                memset(stcb->asoc.mapping_array, 0, 
stcb->asoc.mapping_array_size);
                stcb->asoc.highest_tsn_inside_nr_map = 
stcb->asoc.highest_tsn_inside_map;
-               stcb->asoc.nr_mapping_array_base_tsn = 
stcb->asoc.highest_tsn_inside_map + 1;
-               memset(stcb->asoc.nr_mapping_array, 0, 
stcb->asoc.nr_mapping_array_size);
+               memset(stcb->asoc.nr_mapping_array, 0, 
stcb->asoc.mapping_array_size);
                atomic_add_int(&stcb->asoc.sending_seq, 1);
                /* save off historical data for retrans */
                stcb->asoc.last_sending_seq[1] = stcb->asoc.last_sending_seq[0];
@@ -5636,7 +5626,7 @@ sctp_common_input_processing(struct mbuf
                        was_a_gap = 1;
                }
                stcb->asoc.send_sack = 1;
-               sctp_sack_check(stcb, 1, was_a_gap, &abort_flag);
+               sctp_sack_check(stcb, was_a_gap, &abort_flag);
                if (abort_flag) {
                        /* Again, we aborted so NO UNLOCK needed */
                        goto out_now;

Modified: stable/8/sys/netinet/sctp_output.c
==============================================================================
--- stable/8/sys/netinet/sctp_output.c  Sat Apr 17 04:13:52 2010        
(r206741)
+++ stable/8/sys/netinet/sctp_output.c  Sat Apr 17 04:15:46 2010        
(r206742)
@@ -9003,6 +9003,11 @@ sctp_chunk_retransmission(struct sctp_in
                        /* No, not sent to this net or not ready for rtx */
                        continue;
                }
+               if (chk->data == NULL) {
+                       printf("TSN:%x chk->snd_count:%d chk->sent:%d can't 
retran - no data\n",
+                           chk->rec.data.TSN_seq, chk->snd_count, chk->sent);
+                       continue;
+               }
                if ((SCTP_BASE_SYSCTL(sctp_max_retran_chunk)) &&
                    (chk->snd_count >= 
SCTP_BASE_SYSCTL(sctp_max_retran_chunk))) {
                        /* Gak, we have exceeded max unlucky retran, abort! */
@@ -9426,14 +9431,7 @@ sctp_chunk_output(struct sctp_inpcb *inp
         * running, if so piggy-back the sack.
         */
        if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
-               /*
-                * EY if nr_sacks used then send an nr-sack , a sack
-                * otherwise
-                */
-               if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && 
asoc->peer_supports_nr_sack)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to