Author: rrs
Date: Mon Jun  7 18:29:10 2010
New Revision: 208897
URL: http://svn.freebsd.org/changeset/base/208897

Log:
  This fixes a BUG in the handling of the cum-ack calculation.
  We were only paying attention to the nr-mapping-array. Which
  seems to make sense on the surface, by definition things
  up to the cum-ack should be deliverable thus in the nr-mapping-array.
  However (there is always a gotcha) thats not true when it
  comes to large messages. The stack may hold the message
  while re-assembling it not not deliver it based on several
  thresholds. If that happens (which it would for smaller
  large messages) then the cum-ack is figured wrong. We
  now properly use both arrays in the cum-ack calculation.
  
  MFC after:    1 week.

Modified:
  head/sys/netinet/sctp_indata.c

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c      Mon Jun  7 17:41:34 2010        
(r208896)
+++ head/sys/netinet/sctp_indata.c      Mon Jun  7 18:29:10 2010        
(r208897)
@@ -2245,15 +2245,19 @@ sctp_slide_mapping_arrays(struct sctp_tc
        /*
         * Now we also need to check the mapping array in a couple of ways.
         * 1) Did we move the cum-ack point?
+        * 
+        * When you first glance at this you might think that all entries that
+        * make up the postion of the cum-ack would be in the nr-mapping
+        * array only.. i.e. things up to the cum-ack are always
+        * deliverable. Thats true with one exception, when its a fragmented
+        * message we may not deliver the data until some threshold (or all
+        * of it) is in place. So we must OR the nr_mapping_array and
+        * mapping_array to get a true picture of the cum-ack.
         */
        struct sctp_association *asoc;
        int at;
+       uint8_t val;
        int slide_from, slide_end, lgap, distance;
-
-       /* EY nr_mapping array variables */
-       /* int nr_at; */
-       /* int nr_last_all_ones = 0; */
-       /* int nr_slide_from, nr_slide_end, nr_lgap, nr_distance; */
        uint32_t old_cumack, old_base, old_highest, highest_tsn;
 
        asoc = &stcb->asoc;
@@ -2268,11 +2272,12 @@ sctp_slide_mapping_arrays(struct sctp_tc
         */
        at = 0;
        for (slide_from = 0; slide_from < stcb->asoc.mapping_array_size; 
slide_from++) {
-               if (asoc->nr_mapping_array[slide_from] == 0xff) {
+               val = asoc->nr_mapping_array[slide_from] | 
asoc->mapping_array[slide_from];
+               if (val == 0xff) {
                        at += 8;
                } else {
                        /* there is a 0 bit */
-                       at += 
sctp_map_lookup_tab[asoc->nr_mapping_array[slide_from]];
+                       at += sctp_map_lookup_tab[val];
                        break;
                }
        }
_______________________________________________
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