Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Mar 2010 01:36:50 +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: r205502 - head/sys/netinet
Message-ID:  <201003230136.o2N1aoO1004865@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rrs
Date: Tue Mar 23 01:36:50 2010
New Revision: 205502
URL: http://svn.freebsd.org/changeset/base/205502

Log:
  Fixes a bug where SACKs in the face of
  mapping_array expansion would break. Basically
  once we expanded the array we no longer had both
  mapping arrays in sync which the sack processing code depends on.
  This would mean we were randomly referring to memory that was probably
  not there. This mostly just gave us bad sack results going back to the peer.
  If INVARIENTS was on of course we would hit the panic routine in the sack_check
  call.
  
  We also add a print routine for the place where one would panic in
  invarients so one can see what the main mapping array holds.
  
  Reviewed by: tuexen@freebsd.org
  MFC after:	2 weeks

Modified:
  head/sys/netinet/sctp_indata.c
  head/sys/netinet/sctputil.c
  head/sys/netinet/sctputil.h

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c	Tue Mar 23 01:35:46 2010	(r205501)
+++ head/sys/netinet/sctp_indata.c	Tue Mar 23 01:36:50 2010	(r205502)
@@ -2540,15 +2540,7 @@ sctp_sack_check(struct sctp_tcb *stcb, i
 	/* 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;
-	unsigned char aux_array[64];
-
-	/*
-	 * EY! Don't think this is required but I am immitating the code for
-	 * map just to make sure
-	 */
-	unsigned char nr_aux_array[64];
 
 	asoc = &stcb->asoc;
 	at = 0;
@@ -2556,33 +2548,6 @@ sctp_sack_check(struct sctp_tcb *stcb, i
 	old_cumack = asoc->cumulative_tsn;
 	old_base = asoc->mapping_array_base_tsn;
 	old_highest = asoc->highest_tsn_inside_map;
-	if (asoc->mapping_array_size < 64)
-		memcpy(aux_array, asoc->mapping_array,
-		    asoc->mapping_array_size);
-	else
-		memcpy(aux_array, asoc->mapping_array, 64);
-	/* EY do the same for nr_mapping_array */
-	if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
-		if (asoc->nr_mapping_array_size != asoc->mapping_array_size) {
-			/*
-			 * printf("\nEY-IN sack_check method: \nEY-" "The
-			 * size of map and nr_map are inconsitent")
-			 */ ;
-		}
-		if (asoc->nr_mapping_array_base_tsn != asoc->mapping_array_base_tsn) {
-			/*
-			 * printf("\nEY-IN sack_check method VERY CRUCIAL
-			 * error: \nEY-" "The base tsns of map and nr_map
-			 * are inconsitent")
-			 */ ;
-		}
-		/* EY! just immitating the above code */
-		if (asoc->nr_mapping_array_size < 64)
-			memcpy(nr_aux_array, asoc->nr_mapping_array,
-			    asoc->nr_mapping_array_size);
-		else
-			memcpy(aux_array, asoc->nr_mapping_array, 64);
-	}
 	/*
 	 * We could probably improve this a small bit by calculating the
 	 * offset of the current cum-ack as the starting point.
@@ -2618,6 +2583,7 @@ sctp_sack_check(struct sctp_tcb *stcb, i
 #else
 		SCTP_PRINTF("huh, cumack 0x%x greater than high-tsn 0x%x in map - should panic?\n",
 		    asoc->cumulative_tsn, asoc->highest_tsn_inside_map);
+		sctp_print_mapping_array(asoc);
 		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
 			sctp_log_map(0, 6, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
 		}

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c	Tue Mar 23 01:35:46 2010	(r205501)
+++ head/sys/netinet/sctputil.c	Tue Mar 23 01:36:50 2010	(r205502)
@@ -1180,6 +1180,25 @@ sctp_init_asoc(struct sctp_inpcb *m, str
 	return (0);
 }
 
+void
+sctp_print_mapping_array(struct sctp_association *asoc)
+{
+	int i;
+
+	printf("Mapping size:%d baseTSN:%8.8x cumAck:%8.8x highestTSN:%8.8x\n",
+	    asoc->mapping_array_size,
+	    asoc->mapping_array_base_tsn,
+	    asoc->cumulative_tsn,
+	    asoc->highest_tsn_inside_map
+	    );
+	for (i = 0; i < asoc->mapping_array_size; i++) {
+		printf("%8.8x ", asoc->mapping_array[i]);
+		if (((i + 1) % 8) == 0)
+			printf("\n");
+	}
+	printf("\n");
+}
+
 int
 sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
 {
@@ -1187,7 +1206,9 @@ sctp_expand_mapping_array(struct sctp_as
 	uint8_t *new_array;
 	uint32_t new_size;
 
+
 	new_size = asoc->mapping_array_size + ((needed + 7) / 8 + SCTP_MAPPING_ARRAY_INCR);
+
 	SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
 	if (new_array == NULL) {
 		/* can't get more, forget it */
@@ -1200,21 +1221,19 @@ sctp_expand_mapping_array(struct sctp_as
 	SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
 	asoc->mapping_array = new_array;
 	asoc->mapping_array_size = new_size;
-	if (asoc->peer_supports_nr_sack) {
-		new_size = asoc->nr_mapping_array_size + ((needed + 7) / 8 + SCTP_NR_MAPPING_ARRAY_INCR);
-		SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
-		if (new_array == NULL) {
-			/* can't get more, forget it */
-			SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
-			    new_size);
-			return (-1);
-		}
-		memset(new_array, 0, new_size);
-		memcpy(new_array, asoc->nr_mapping_array, asoc->nr_mapping_array_size);
-		SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
-		asoc->nr_mapping_array = new_array;
-		asoc->nr_mapping_array_size = new_size;
+	new_size = asoc->nr_mapping_array_size + ((needed + 7) / 8 + SCTP_NR_MAPPING_ARRAY_INCR);
+	SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
+	if (new_array == NULL) {
+		/* can't get more, forget it */
+		SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
+		    new_size);
+		return (-1);
 	}
+	memset(new_array, 0, new_size);
+	memcpy(new_array, asoc->nr_mapping_array, asoc->nr_mapping_array_size);
+	SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
+	asoc->nr_mapping_array = new_array;
+	asoc->nr_mapping_array_size = new_size;
 	return (0);
 }
 

Modified: head/sys/netinet/sctputil.h
==============================================================================
--- head/sys/netinet/sctputil.h	Tue Mar 23 01:35:46 2010	(r205501)
+++ head/sys/netinet/sctputil.h	Tue Mar 23 01:36:50 2010	(r205502)
@@ -376,7 +376,7 @@ int sctp_fill_stat_log(void *, size_t *)
 void sctp_log_fr(uint32_t, uint32_t, uint32_t, int);
 void sctp_log_sack(uint32_t, uint32_t, uint32_t, uint16_t, uint16_t, int);
 void sctp_log_map(uint32_t, uint32_t, uint32_t, int);
-
+void sctp_print_mapping_array(struct sctp_association *asoc);
 void sctp_clr_stat_log(void);
 
 



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