svn commit: r199373 - head/sys/netinet

Michael Tuexen tuexen at FreeBSD.org
Tue Nov 17 13:13:59 UTC 2009


Author: tuexen
Date: Tue Nov 17 13:13:58 2009
New Revision: 199373
URL: http://svn.freebsd.org/changeset/base/199373

Log:
  Fix a memory leak when destroying an SCTP stack.
  Clean up sctp_pcb_finish().
  Approved by: rrs (mentor)
  MFC after: 1 month

Modified:
  head/sys/netinet/sctp_pcb.c

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c	Tue Nov 17 13:11:23 2009	(r199372)
+++ head/sys/netinet/sctp_pcb.c	Tue Nov 17 13:13:58 2009	(r199373)
@@ -5558,36 +5558,54 @@ sctp_pcb_finish(void)
 	struct sctp_ifa *ifa;
 	struct sctpvtaghead *chain;
 	struct sctp_tagblock *twait_block, *prev_twait_block;
+	struct sctp_laddr *wi;
+	struct sctp_iterator *it;
 	int i;
 
+#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
+	SCTP_BASE_INFO(threads_must_exit) = 1;
+	/* Wake the thread up so it will exit now */
+	sctp_wakeup_iterator();
+
+#endif
+	SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer));
+	SCTP_IPI_ITERATOR_WQ_LOCK();
+	while ((wi = LIST_FIRST(&SCTP_BASE_INFO(addr_wq))) != NULL) {
+		LIST_REMOVE(wi, sctp_nxt_addr);
+		SCTP_DECR_LADDR_COUNT();
+		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi);
+	}
+	SCTP_IPI_ITERATOR_WQ_UNLOCK();
+	while ((it = TAILQ_FIRST(&SCTP_BASE_INFO(iteratorhead))) != NULL) {
+		if (it->function_atend != NULL) {
+			(*it->function_atend) (it->pointer, it->val);
+		}
+		TAILQ_REMOVE(&SCTP_BASE_INFO(iteratorhead), it, sctp_nxt_itr);
+		SCTP_FREE(it, SCTP_M_ITER);
+	}
+
 	/*
 	 * free the vrf/ifn/ifa lists and hashes (be sure address monitor is
 	 * destroyed first).
 	 */
 	vrf_bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(SCTP_DEFAULT_VRFID & SCTP_BASE_INFO(hashvrfmark))];
-	vrf = LIST_FIRST(vrf_bucket);
-	while (vrf) {
-		ifn = LIST_FIRST(&vrf->ifnlist);
-		while (ifn) {
-			ifa = LIST_FIRST(&ifn->ifalist);
-			while (ifa) {
+	while ((vrf = LIST_FIRST(vrf_bucket)) != NULL) {
+		while ((ifn = LIST_FIRST(&vrf->ifnlist)) != NULL) {
+			while ((ifa = LIST_FIRST(&ifn->ifalist)) != NULL) {
 				/* free the ifa */
 				LIST_REMOVE(ifa, next_bucket);
 				LIST_REMOVE(ifa, next_ifa);
 				SCTP_FREE(ifa, SCTP_M_IFA);
-				ifa = LIST_FIRST(&ifn->ifalist);
 			}
 			/* free the ifn */
 			LIST_REMOVE(ifn, next_bucket);
 			LIST_REMOVE(ifn, next_ifn);
 			SCTP_FREE(ifn, SCTP_M_IFN);
-			ifn = LIST_FIRST(&vrf->ifnlist);
 		}
 		SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
 		/* free the vrf */
 		LIST_REMOVE(vrf, next_vrf);
 		SCTP_FREE(vrf, SCTP_M_VRF);
-		vrf = LIST_FIRST(vrf_bucket);
 	}
 	/* free the vrf hashes */
 	SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_vrfhash), SCTP_BASE_INFO(hashvrfmark));
@@ -5614,7 +5632,6 @@ sctp_pcb_finish(void)
 	/* free the locks and mutexes */
 #ifdef SCTP_PACKET_LOGGING
 	SCTP_IP_PKTLOG_DESTROY();
-
 #endif
 	SCTP_IPI_ADDR_DESTROY();
 	SCTP_ITERATOR_LOCK_DESTROY();


More information about the svn-src-all mailing list