Author: rrs
Date: Wed May 12 13:45:46 2010
New Revision: 207963
URL: http://svn.freebsd.org/changeset/base/207963

Log:
  This fixes PR-SCTP issues:
   - Slide the map at the proper place.
   - Mark the bits in the nr_array ONLY if there
     is no marking.
   - When generating a FWD-TSN we allow us to skip past
     ACKED chunks too.
  
  MFC after:    1 weeks

Modified:
  head/sys/netinet/sctp_indata.c

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c      Wed May 12 13:20:05 2010        
(r207962)
+++ head/sys/netinet/sctp_indata.c      Wed May 12 13:45:46 2010        
(r207963)
@@ -3694,6 +3694,7 @@ sctp_try_advance_peer_ack_point(struct s
        tp1 = TAILQ_FIRST(&asoc->sent_queue);
        while (tp1) {
                if (tp1->sent != SCTP_FORWARD_TSN_SKIP &&
+                   tp1->sent != SCTP_DATAGRAM_ACKED &&
                    tp1->sent != SCTP_DATAGRAM_RESEND) {
                        /* no chance to advance, out of here */
                        break;
@@ -5540,8 +5541,8 @@ sctp_handle_forward_tsn(struct sctp_tcb 
         * report where we are.
         */
        struct sctp_association *asoc;
-       uint32_t new_cum_tsn, tsn, gap;
-       unsigned int i, fwd_sz, cumack_set_flag, m_size, fnd = 0;
+       uint32_t new_cum_tsn, gap;
+       unsigned int i, fwd_sz, cumack_set_flag, m_size;
        uint32_t str_seq;
        struct sctp_stream_in *strm;
        struct sctp_tmit_chunk *chk, *at;
@@ -5565,15 +5566,6 @@ sctp_handle_forward_tsn(struct sctp_tcb 
                /* Already got there ... */
                return;
        }
-       if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_map,
-           MAX_TSN)) {
-               asoc->highest_tsn_inside_map = new_cum_tsn;
-
-       }
-       if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_nr_map,
-           MAX_TSN)) {
-               asoc->highest_tsn_inside_nr_map = new_cum_tsn;
-       }
        /*
         * now we know the new TSN is more advanced, let's find the actual
         * gap
@@ -5628,34 +5620,14 @@ sctp_handle_forward_tsn(struct sctp_tcb 
        } else {
                SCTP_TCB_LOCK_ASSERT(stcb);
                for (i = 0; i <= gap; i++) {
-                       SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, i);
-                       SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, i);
-                       /* FIX ME add something to set up highest TSN in map */
-               }
-               if (compare_with_wrap(new_cum_tsn, 
asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
-                       asoc->highest_tsn_inside_nr_map = new_cum_tsn;
-               }
-               if (compare_with_wrap(new_cum_tsn, 
asoc->highest_tsn_inside_map, MAX_TSN) ||
-                   new_cum_tsn == asoc->highest_tsn_inside_map) {
-                       /* We must back down to see what the new highest is */
-                       for (tsn = new_cum_tsn; (compare_with_wrap(tsn, 
asoc->mapping_array_base_tsn, MAX_TSN) ||
-                           (tsn == asoc->mapping_array_base_tsn)); tsn--) {
-                               SCTP_CALC_TSN_TO_GAP(gap, tsn, 
asoc->mapping_array_base_tsn);
-                               if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, 
gap)) {
-                                       asoc->highest_tsn_inside_map = tsn;
-                                       fnd = 1;
-                                       break;
+                       if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, i) &&
+                           !SCTP_IS_TSN_PRESENT(asoc->nr_mapping_array, i)) {
+                               SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, i);
+                               if 
(compare_with_wrap(asoc->mapping_array_base_tsn + i, 
asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
+                                       asoc->highest_tsn_inside_nr_map = 
asoc->mapping_array_base_tsn + i;
                                }
                        }
-                       if (!fnd) {
-                               asoc->highest_tsn_inside_map = 
asoc->mapping_array_base_tsn - 1;
-                       }
                }
-               /*
-                * Now after marking all, slide thing forward but no sack
-                * please.
-                */
-               sctp_slide_mapping_arrays(stcb);
        }
        /*************************************************************/
        /* 2. Clear up re-assembly queue                             */
@@ -5826,6 +5798,11 @@ sctp_handle_forward_tsn(struct sctp_tcb 
                }
                SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
        }
+       /*
+        * Now slide thing forward.
+        */
+       sctp_slide_mapping_arrays(stcb);
+
        if (TAILQ_FIRST(&asoc->reasmqueue)) {
                /* now lets kick out and check for more fragmented delivery */
                /* sa_ignore NO_NULL_CHK */
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to