summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2009-11-17 13:13:58 +0000
committertuexen <tuexen@FreeBSD.org>2009-11-17 13:13:58 +0000
commit1daec1ba972eb0c5814dfce458470c929f945284 (patch)
treef141563a510c8274db5a7d1670c8de5552c6600c /sys/netinet
parentca50a585fce88097cae9f5c40c6222d40b0f3a18 (diff)
downloadFreeBSD-src-1daec1ba972eb0c5814dfce458470c929f945284.zip
FreeBSD-src-1daec1ba972eb0c5814dfce458470c929f945284.tar.gz
Fix a memory leak when destroying an SCTP stack.
Clean up sctp_pcb_finish(). Approved by: rrs (mentor) MFC after: 1 month
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/sctp_pcb.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 7d12f37..8370dcc 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -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();
OpenPOWER on IntegriCloud