Cleanup timer handling.

Submitted by:	Taylor Brandstetter
MFC after:	1 week
This commit is contained in:
tuexen 2020-02-09 22:05:41 +00:00
parent 50d6d1f145
commit 15dd098e15
5 changed files with 72 additions and 58 deletions

View File

@ -2663,7 +2663,8 @@ sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap)
* is pending, we got our first packet OR
* there are gaps or duplicates.
*/
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_19);
sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
}
} else {

View File

@ -10074,7 +10074,8 @@ sctp_chunk_output(struct sctp_inpcb *inp,
*/
if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
sctp_send_sack(stcb, so_locked);
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL,
SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_3);
}
while (asoc->sent_queue_retran_cnt) {
/*-
@ -10603,7 +10604,7 @@ sctp_send_sack(struct sctp_tcb *stcb, int so_locked
if (stcb->asoc.delayed_ack) {
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
stcb->sctp_ep, stcb, NULL,
SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_3);
SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_4);
sctp_timer_start(SCTP_TIMER_TYPE_RECV,
stcb->sctp_ep, stcb, NULL);
} else {
@ -10672,7 +10673,7 @@ sctp_send_sack(struct sctp_tcb *stcb, int so_locked
if (stcb->asoc.delayed_ack) {
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
stcb->sctp_ep, stcb, NULL,
SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_4);
SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_5);
sctp_timer_start(SCTP_TIMER_TYPE_RECV,
stcb->sctp_ep, stcb, NULL);
} else {
@ -12834,7 +12835,7 @@ sctp_lower_sosend(struct socket *so,
if (control) {
if (sctp_process_cmsgs_for_init(stcb, control, &error)) {
sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE,
SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_5);
SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_6);
hold_tcblock = 0;
stcb = NULL;
goto out_unlocked;

View File

@ -3547,7 +3547,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
}
if (cnt) {
/* Ok we have someone out there that will kill us */
(void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, NULL, 3);
#endif
@ -3566,7 +3565,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
if ((inp->refcount) ||
(being_refed) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_CLOSE_IP)) {
(void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, NULL, 4);
#endif
@ -4761,35 +4759,8 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
return (0);
}
}
/* now clean up any other timers */
(void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
asoc->dack_timer.self = NULL;
(void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
/*-
* For stream reset we don't blast this unless
* it is a str-reset timer, it might be the
* free-asoc timer which we DON'T want to
* disturb.
*/
if (asoc->strreset_timer.type == SCTP_TIMER_TYPE_STRRESET)
asoc->strreset_timer.self = NULL;
(void)SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
asoc->asconf_timer.self = NULL;
(void)SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
asoc->autoclose_timer.self = NULL;
(void)SCTP_OS_TIMER_STOP(&asoc->shut_guard_timer.timer);
asoc->shut_guard_timer.self = NULL;
/* Mobility adaptation */
(void)SCTP_OS_TIMER_STOP(&asoc->delete_prim_timer.timer);
asoc->delete_prim_timer.self = NULL;
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
(void)SCTP_OS_TIMER_STOP(&net->rxt_timer.timer);
net->rxt_timer.self = NULL;
(void)SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
net->pmtu_timer.self = NULL;
(void)SCTP_OS_TIMER_STOP(&net->hb_timer.timer);
net->hb_timer.self = NULL;
}
/* Now clean up any other timers */
sctp_stop_association_timers(stcb, false);
/* Now the read queue needs to be cleaned up (only once) */
if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0) {
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_ABOUT_TO_BE_FREED);
@ -4957,19 +4928,8 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
/*
* Now restop the timers to be sure this is paranoia at is finest!
*/
(void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
(void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
(void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
(void)SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
(void)SCTP_OS_TIMER_STOP(&asoc->shut_guard_timer.timer);
(void)SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
(void)SCTP_OS_TIMER_STOP(&net->rxt_timer.timer);
(void)SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
(void)SCTP_OS_TIMER_STOP(&net->hb_timer.timer);
}
sctp_stop_association_timers(stcb, true);
asoc->strreset_timer.type = SCTP_TIMER_TYPE_NONE;
/*
* The chunk lists and such SHOULD be empty but we check them just
* in case.
@ -7033,7 +6993,8 @@ sctp_drain_mbufs(struct sctp_tcb *stcb)
* asoc->highest_tsn_inside_map?
*/
asoc->last_revoke_count = cnt;
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL,
SCTP_FROM_SCTP_PCB + SCTP_LOC_16);
/* sa_ignore NO_NULL_CHK */
sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_DRAIN, SCTP_SO_NOT_LOCKED);

View File

@ -780,18 +780,66 @@ sctp_audit_log(uint8_t ev, uint8_t fd)
void
sctp_stop_timers_for_shutdown(struct sctp_tcb *stcb)
{
struct sctp_association *asoc;
struct sctp_inpcb *inp;
struct sctp_nets *net;
asoc = &stcb->asoc;
inp = stcb->sctp_ep;
(void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
(void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
(void)SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
(void)SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
(void)SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
(void)SCTP_OS_TIMER_STOP(&net->hb_timer.timer);
sctp_timer_stop(SCTP_TIMER_TYPE_RECV, inp, stcb, NULL,
SCTP_FROM_SCTPUTIL + SCTP_LOC_12);
sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, inp, stcb, NULL,
SCTP_FROM_SCTPUTIL + SCTP_LOC_13);
sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, inp, stcb, NULL,
SCTP_FROM_SCTPUTIL + SCTP_LOC_14);
sctp_timer_stop(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL,
SCTP_FROM_SCTPUTIL + SCTP_LOC_15);
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
SCTP_FROM_SCTPUTIL + SCTP_LOC_16);
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
SCTP_FROM_SCTPUTIL + SCTP_LOC_17);
}
}
void
sctp_stop_association_timers(struct sctp_tcb *stcb, bool stop_assoc_kill_timer)
{
struct sctp_inpcb *inp;
struct sctp_nets *net;
inp = stcb->sctp_ep;
sctp_timer_stop(SCTP_TIMER_TYPE_RECV, inp, stcb, NULL,
SCTP_FROM_SCTPUTIL + SCTP_LOC_18);
sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, inp, stcb, NULL,
SCTP_FROM_SCTPUTIL + SCTP_LOC_19);
if (stop_assoc_kill_timer) {
sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL,
SCTP_FROM_SCTPUTIL + SCTP_LOC_20);
}
sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, inp, stcb, NULL,
SCTP_FROM_SCTPUTIL + SCTP_LOC_21);
sctp_timer_stop(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL,
SCTP_FROM_SCTPUTIL + SCTP_LOC_22);
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNGUARD, inp, stcb, NULL,
SCTP_FROM_SCTPUTIL + SCTP_LOC_23);
/* Mobility adaptation */
sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, inp, stcb, NULL,
SCTP_FROM_SCTPUTIL + SCTP_LOC_24);
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, inp, stcb, net,
SCTP_FROM_SCTPUTIL + SCTP_LOC_25);
sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net,
SCTP_FROM_SCTPUTIL + SCTP_LOC_26);
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, net,
SCTP_FROM_SCTPUTIL + SCTP_LOC_27);
sctp_timer_stop(SCTP_TIMER_TYPE_COOKIE, inp, stcb, net,
SCTP_FROM_SCTPUTIL + SCTP_LOC_28);
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, inp, stcb, net,
SCTP_FROM_SCTPUTIL + SCTP_LOC_29);
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
SCTP_FROM_SCTPUTIL + SCTP_LOC_30);
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
SCTP_FROM_SCTPUTIL + SCTP_LOC_31);
}
}

View File

@ -164,6 +164,9 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
void sctp_stop_timers_for_shutdown(struct sctp_tcb *);
/* Stop all timers for association and remote addresses. */
void sctp_stop_association_timers(struct sctp_tcb *, bool);
void
sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int, int
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)