From owner-svn-src-all@FreeBSD.ORG Mon Jun 7 18:29:10 2010 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 9CA131065678; Mon, 7 Jun 2010 18:29:10 +0000 (UTC) (envelope-from rrs@FreeBSD.org) Received: from svn.freebsd.org (unknown [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8AC4F8FC1D; Mon, 7 Jun 2010 18:29:10 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o57ITAoe057575; Mon, 7 Jun 2010 18:29:10 GMT (envelope-from rrs@svn.freebsd.org) Received: (from rrs@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o57ITAG5057544; Mon, 7 Jun 2010 18:29:10 GMT (envelope-from rrs@svn.freebsd.org) Message-Id: <201006071829.o57ITAG5057544@svn.freebsd.org> From: Randall Stewart Date: Mon, 7 Jun 2010 18:29:10 +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: r208897 - 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: Mon, 07 Jun 2010 18:29:10 -0000 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; } }