diff options
author | Michael Tuexen <tuexen@FreeBSD.org> | 2017-09-20 21:29:54 +0000 |
---|---|---|
committer | Michael Tuexen <tuexen@FreeBSD.org> | 2017-09-20 21:29:54 +0000 |
commit | 2c62ba737707294f6bc4b6b31a73967ec63df003 (patch) | |
tree | 17de6901dd55ed7eb5b832b7aa8b4c4258c083da /sys/netinet/sctputil.c | |
parent | 89d26636f349949e84ad23c28b22ec85fcd80cf8 (diff) | |
download | src-2c62ba737707294f6bc4b6b31a73967ec63df003.tar.gz src-2c62ba737707294f6bc4b6b31a73967ec63df003.zip |
Protect the address workqueue timer by a mutex.
MFC after: 1 week
Notes
Notes:
svn path=/head/; revision=323833
Diffstat (limited to 'sys/netinet/sctputil.c')
-rw-r--r-- | sys/netinet/sctputil.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 618dbbc02d3f..c7bb60eb1be4 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1462,13 +1462,11 @@ sctp_handle_addr_wq(void) LIST_INIT(&asc->list_of_work); asc->cnt = 0; - SCTP_WQ_ADDR_LOCK(); LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) { LIST_REMOVE(wi, sctp_nxt_addr); LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr); asc->cnt++; } - SCTP_WQ_ADDR_UNLOCK(); if (asc->cnt == 0) { SCTP_FREE(asc, SCTP_M_ASC_IT); @@ -1492,11 +1490,9 @@ sctp_handle_addr_wq(void) if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) { sctp_asconf_iterator_end(asc, 0); } else { - SCTP_WQ_ADDR_LOCK(); LIST_FOREACH(wi, &asc->list_of_work, sctp_nxt_addr) { LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr); } - SCTP_WQ_ADDR_UNLOCK(); SCTP_FREE(asc, SCTP_M_ASC_IT); } } @@ -1565,8 +1561,7 @@ sctp_timeout_handler(void *t) (tmr->type != SCTP_TIMER_TYPE_SHUTDOWN) && (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNACK) && (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNGUARD) && - (tmr->type != SCTP_TIMER_TYPE_ASOCKILL)) - ) { + (tmr->type != SCTP_TIMER_TYPE_ASOCKILL))) { SCTP_INP_DECR_REF(inp); CURVNET_RESTORE(); return; @@ -1612,6 +1607,12 @@ sctp_timeout_handler(void *t) CURVNET_RESTORE(); return; } + } else if (inp != NULL) { + if (type != SCTP_TIMER_TYPE_INPKILL) { + SCTP_INP_WLOCK(inp); + } + } else { + SCTP_WQ_ADDR_LOCK(); } /* record in stopped what t-o occurred */ tmr->stopped_from = type; @@ -1759,7 +1760,6 @@ sctp_timeout_handler(void *t) } SCTP_STAT_INCR(sctps_timosecret); (void)SCTP_GETTIME_TIMEVAL(&tv); - SCTP_INP_WLOCK(inp); inp->sctp_ep.time_of_secret_change = tv.tv_sec; inp->sctp_ep.last_secret_number = inp->sctp_ep.current_secret_number; @@ -1773,7 +1773,6 @@ sctp_timeout_handler(void *t) inp->sctp_ep.secret_key[secret][i] = sctp_select_initial_TSN(&inp->sctp_ep); } - SCTP_INP_WUNLOCK(inp); sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, stcb, net); } did_output = 0; @@ -1921,7 +1920,12 @@ sctp_timeout_handler(void *t) get_out: if (stcb) { SCTP_TCB_UNLOCK(stcb); + } else if (inp != NULL) { + SCTP_INP_WUNLOCK(inp); + } else { + SCTP_WQ_ADDR_UNLOCK(); } + out_decr: if (inp) { SCTP_INP_DECR_REF(inp); @@ -6146,11 +6150,11 @@ sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id) * newest first :-0 */ LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr); - SCTP_WQ_ADDR_UNLOCK(); sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ, (struct sctp_inpcb *)NULL, (struct sctp_tcb *)NULL, (struct sctp_nets *)NULL); + SCTP_WQ_ADDR_UNLOCK(); return (0); } |