Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Feb 2009 18:33:26 +0000 (UTC)
From:      Randall Stewart <rrs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r188530 - in stable/7/sys: . netinet
Message-ID:  <200902121833.n1CIXQ8o063979@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rrs
Date: Thu Feb 12 18:33:26 2009
New Revision: 188530
URL: http://svn.freebsd.org/changeset/base/188530

Log:
  MFC 184883 - a pack of bug fixes and misc adjustments:
  
  -Improvement: Add '\n' on debug output in sctp_lower_sosend().
  -Improvement: panic() on INVARIANTS kernels if memory allocation
   fails for a tagblock in sctp_add_vtag_to_timewait().
  -Bugfix: Protect code in sctp_is_in_timewait() by
   SCTP_INP_INFO_WLOCK/SCTP_INP_INFO_WUNLOCK.
  -Cleanup: Get rid of unused variable now in sctp_init_asoc().
  -Bugfix: Reuse the correct vtag in sctp_add_vtag_to_timewait().
  -Cleanup: Get rid of unused constant SCTP_TIME_WAIT_SHORT
   in sctp_constants.h.
  -Improvement: Use all hash buckets of the vtag hash table.
  -Cleanup: Get rid of then unused constant SCTP_STACK_VTAG_HASH_SIZE_A.
  -Bugfix: Handle SHUTDOWN;SACK packet correctly.
  -Bugfix: Last TSN in a gap ack block was not being "ack'd"
           in the internal scoreboard.
  Obtained from:  (with help from Michael Tuexen)

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/netinet/sctp_constants.h
  stable/7/sys/netinet/sctp_indata.c
  stable/7/sys/netinet/sctp_input.c
  stable/7/sys/netinet/sctp_pcb.c
  stable/7/sys/netinet/sctp_pcb.h
  stable/7/sys/netinet/sctputil.c

Modified: stable/7/sys/netinet/sctp_constants.h
==============================================================================
--- stable/7/sys/netinet/sctp_constants.h	Thu Feb 12 18:33:13 2009	(r188529)
+++ stable/7/sys/netinet/sctp_constants.h	Thu Feb 12 18:33:26 2009	(r188530)
@@ -1001,8 +1001,7 @@ __FBSDID("$FreeBSD$");
  * entries must be searched to see if the tag is in timed wait. If so we
  * reject it.
  */
-#define SCTP_STACK_VTAG_HASH_SIZE   31
-#define SCTP_STACK_VTAG_HASH_SIZE_A 32
+#define SCTP_STACK_VTAG_HASH_SIZE   32
 
 
 /*
@@ -1016,12 +1015,6 @@ __FBSDID("$FreeBSD$");
  */
 #define SCTP_TIME_WAIT 60
 
-/* This time wait is the same as the default cookie life
- * since we now enter a tag in every time we send a cookie.
- * We want this shorter to avoid vtag depletion.
- */
-#define SCTP_TIME_WAIT_SHORT 60
-
 /* The system retains a cache of free chunks such to
  * cut down on calls the memory allocation system. There
  * is a per association limit of free items and a overall

Modified: stable/7/sys/netinet/sctp_indata.c
==============================================================================
--- stable/7/sys/netinet/sctp_indata.c	Thu Feb 12 18:33:13 2009	(r188529)
+++ stable/7/sys/netinet/sctp_indata.c	Thu Feb 12 18:33:26 2009	(r188530)
@@ -2766,8 +2766,8 @@ sctp_handle_segments(struct mbuf *m, int
 	struct sctp_sack *sack;
 	struct sctp_gap_ack_block *frag, block;
 	struct sctp_tmit_chunk *tp1;
-	int i;
-	unsigned int j;
+	int i, j;
+	unsigned int theTSN;
 	int num_frs = 0;
 
 	uint16_t frag_strt, frag_end, primary_flag_set;
@@ -2835,7 +2835,8 @@ sctp_handle_segments(struct mbuf *m, int
 			}
 			last_frag_high = frag_end + last_tsn;
 		}
-		for (j = frag_strt + last_tsn; (compare_with_wrap((frag_end + last_tsn), j, MAX_TSN)); j++) {
+		for (j = frag_strt; j <= frag_end; j++) {
+			theTSN = j + last_tsn;
 			while (tp1) {
 				if (tp1->rec.data.doing_fast_retransmit)
 					num_frs++;
@@ -2858,7 +2859,7 @@ sctp_handle_segments(struct mbuf *m, int
 					tp1->whoTo->rtx_pseudo_cumack = tp1->rec.data.TSN_seq;
 					tp1->whoTo->find_rtx_pseudo_cumack = 0;
 				}
-				if (tp1->rec.data.TSN_seq == j) {
+				if (tp1->rec.data.TSN_seq == theTSN) {
 					if (tp1->sent != SCTP_DATAGRAM_UNSENT) {
 						/*
 						 * must be held until
@@ -3030,8 +3031,8 @@ sctp_handle_segments(struct mbuf *m, int
 						}
 					}
 					break;
-				}	/* if (tp1->TSN_seq == j) */
-				if (compare_with_wrap(tp1->rec.data.TSN_seq, j,
+				}	/* if (tp1->TSN_seq == theTSN) */
+				if (compare_with_wrap(tp1->rec.data.TSN_seq, theTSN,
 				    MAX_TSN))
 					break;
 

Modified: stable/7/sys/netinet/sctp_input.c
==============================================================================
--- stable/7/sys/netinet/sctp_input.c	Thu Feb 12 18:33:13 2009	(r188529)
+++ stable/7/sys/netinet/sctp_input.c	Thu Feb 12 18:33:26 2009	(r188530)
@@ -4280,7 +4280,6 @@ process_control_chunks:
 
 				if ((stcb == NULL) || (chk_length < sizeof(struct sctp_sack_chunk))) {
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on sack chunk, too small\n");
-			ignore_sack:
 					*offset = length;
 					if (locked_tcb) {
 						SCTP_TCB_UNLOCK(locked_tcb);
@@ -4293,7 +4292,7 @@ process_control_chunks:
 					 * attention to a sack sent in to us since
 					 * we don't care anymore.
 					 */
-					goto ignore_sack;
+					break;
 				}
 				sack = (struct sctp_sack_chunk *)ch;
 				nonce_sum_flag = ch->chunk_flags & SCTP_SACK_NONCE_SUM;

Modified: stable/7/sys/netinet/sctp_pcb.c
==============================================================================
--- stable/7/sys/netinet/sctp_pcb.c	Thu Feb 12 18:33:13 2009	(r188529)
+++ stable/7/sys/netinet/sctp_pcb.c	Thu Feb 12 18:33:26 2009	(r188530)
@@ -4191,6 +4191,7 @@ sctp_is_in_timewait(uint32_t tag)
 	int found = 0;
 	int i;
 
+	SCTP_INP_INFO_WLOCK();
 	chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
 	if (!SCTP_LIST_EMPTY(chain)) {
 		LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
@@ -4204,6 +4205,7 @@ sctp_is_in_timewait(uint32_t tag)
 				break;
 		}
 	}
+	SCTP_INP_INFO_WUNLOCK();
 	return (found);
 }
 
@@ -4236,8 +4238,8 @@ sctp_add_vtag_to_timewait(uint32_t tag, 
 					twait_block->vtag_block[i].v_tag = 0;
 					if (set == 0) {
 						/* Reuse it for my new tag */
-						twait_block->vtag_block[0].tv_sec_at_expire = now.tv_sec + time;
-						twait_block->vtag_block[0].v_tag = tag;
+						twait_block->vtag_block[i].tv_sec_at_expire = now.tv_sec + time;
+						twait_block->vtag_block[i].v_tag = tag;
 						set = 1;
 					}
 				}
@@ -4256,6 +4258,9 @@ sctp_add_vtag_to_timewait(uint32_t tag, 
 		SCTP_MALLOC(twait_block, struct sctp_tagblock *,
 		    sizeof(struct sctp_tagblock), SCTP_M_TIMW);
 		if (twait_block == NULL) {
+#ifdef INVARIANTS
+			panic("Can not alloc tagblock");
+#endif
 			return;
 		}
 		memset(twait_block, 0, sizeof(struct sctp_tagblock));
@@ -5392,7 +5397,7 @@ sctp_pcb_init()
 	SCTP_OS_TIMER_INIT(&SCTP_BASE_INFO(addr_wq_timer.timer));
 
 	/* Init the TIMEWAIT list */
-	for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE_A; i++) {
+	for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
 		LIST_INIT(&SCTP_BASE_INFO(vtag_timewait[i]));
 	}
 
@@ -5462,7 +5467,7 @@ sctp_pcb_finish(void)
 	 * free the TIMEWAIT list elements malloc'd in the function
 	 * sctp_add_vtag_to_timewait()...
 	 */
-	for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE_A; i++) {
+	for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
 		chain = &SCTP_BASE_INFO(vtag_timewait)[i];
 		if (!SCTP_LIST_EMPTY(chain)) {
 			prev_twait_block = NULL;

Modified: stable/7/sys/netinet/sctp_pcb.h
==============================================================================
--- stable/7/sys/netinet/sctp_pcb.h	Thu Feb 12 18:33:13 2009	(r188529)
+++ stable/7/sys/netinet/sctp_pcb.h	Thu Feb 12 18:33:26 2009	(r188530)
@@ -228,7 +228,7 @@ struct sctp_epinfo {
 	uint32_t ipi_free_strmoq;
 
 
-	struct sctpvtaghead vtag_timewait[SCTP_STACK_VTAG_HASH_SIZE_A];
+	struct sctpvtaghead vtag_timewait[SCTP_STACK_VTAG_HASH_SIZE];
 
 	/* address work queue handling */
 #if defined(SCTP_USE_THREAD_BASED_ITERATOR)

Modified: stable/7/sys/netinet/sctputil.c
==============================================================================
--- stable/7/sys/netinet/sctputil.c	Thu Feb 12 18:33:13 2009	(r188529)
+++ stable/7/sys/netinet/sctputil.c	Thu Feb 12 18:33:26 2009	(r188530)
@@ -910,9 +910,6 @@ sctp_init_asoc(struct sctp_inpcb *m, str
 #endif
 	asoc->sb_send_resv = 0;
 	if (override_tag) {
-		struct timeval now;
-
-		(void)SCTP_GETTIME_TIMEVAL(&now);
 		if (sctp_is_in_timewait(override_tag)) {
 			/*
 			 * It must be in the time-wait hash, we put it there
@@ -1466,6 +1463,9 @@ sctp_timeout_handler(void *t)
 		SCTP_INP_INCR_REF(inp);
 		if ((inp->sctp_socket == 0) &&
 		    ((tmr->type != SCTP_TIMER_TYPE_INPKILL) &&
+		    (tmr->type != SCTP_TIMER_TYPE_SEND) &&
+		    (tmr->type != SCTP_TIMER_TYPE_RECV) &&
+		    (tmr->type != SCTP_TIMER_TYPE_HEARTBEAT) &&
 		    (tmr->type != SCTP_TIMER_TYPE_SHUTDOWN) &&
 		    (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNACK) &&
 		    (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNGUARD) &&



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