Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 May 2010 13:45:46 +0000 (UTC)
From:      Randall Stewart <rrs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r207963 - head/sys/netinet
Message-ID:  <201005121345.o4CDjkcI024359@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201005121345.o4CDjkcI024359>