Merge "asterisk: Audit locking of channel when manipulating flags." into 13

certified/13.18
Jenkins2 9 years ago committed by Gerrit Code Review
commit d4ccd3a6c0

@ -676,9 +676,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto
} }
} }
ast_channel_lock(chan); ast_channel_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
ast_set_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
ast_channel_unlock(chan);
csth.volfactor = *volfactor; csth.volfactor = *volfactor;
@ -808,9 +806,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto
else else
ast_deactivate_generator(chan); ast_deactivate_generator(chan);
ast_channel_lock(chan); ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
ast_channel_unlock(chan);
if (ast_test_flag(flags, OPTION_WHISPER | OPTION_BARGE | OPTION_DTMF_SWITCH_MODES)) { if (ast_test_flag(flags, OPTION_WHISPER | OPTION_BARGE | OPTION_DTMF_SWITCH_MODES)) {
ast_audiohook_lock(&csth.whisper_audiohook); ast_audiohook_lock(&csth.whisper_audiohook);
@ -904,7 +900,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
if (ast_channel_state(chan) != AST_STATE_UP) if (ast_channel_state(chan) != AST_STATE_UP)
ast_answer(chan); ast_answer(chan);
ast_set_flag(ast_channel_flags(chan), AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */ ast_channel_set_flag(chan, AST_FLAG_SPYING);
waitms = 100; waitms = 100;
@ -917,7 +913,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
if (!res) if (!res)
res = ast_waitstream(chan, ""); res = ast_waitstream(chan, "");
else if (res < 0) { else if (res < 0) {
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING); ast_channel_clear_flag(chan, AST_FLAG_SPYING);
break; break;
} }
if (!ast_strlen_zero(exitcontext)) { if (!ast_strlen_zero(exitcontext)) {
@ -960,7 +956,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
res = ast_waitfordigit(chan, waitms); res = ast_waitfordigit(chan, waitms);
if (res < 0) { if (res < 0) {
iter = ast_channel_iterator_destroy(iter); iter = ast_channel_iterator_destroy(iter);
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING); ast_channel_clear_flag(chan, AST_FLAG_SPYING);
break; break;
} }
if (!ast_strlen_zero(exitcontext)) { if (!ast_strlen_zero(exitcontext)) {
@ -1179,7 +1175,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
} }
exit: exit:
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING); ast_channel_clear_flag(chan, AST_FLAG_SPYING);
ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0); ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);

@ -2870,7 +2870,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]); ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]);
} }
ast_set_flag(ast_channel_flags(peer), AST_FLAG_END_DTMF_ONLY); ast_channel_set_flag(peer, AST_FLAG_END_DTMF_ONLY);
while (ast_channel_stream(peer)) { while (ast_channel_stream(peer)) {
int ms; int ms;
@ -2934,13 +2934,13 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
} }
ast_sched_runq(ast_channel_sched(peer)); ast_sched_runq(ast_channel_sched(peer));
} }
ast_clear_flag(ast_channel_flags(peer), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(peer, AST_FLAG_END_DTMF_ONLY);
} }
if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) { if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
/* chan and peer are going into the PBX; as such neither are considered /* chan and peer are going into the PBX; as such neither are considered
* outgoing channels any longer */ * outgoing channels any longer */
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING); ast_channel_clear_flag(chan, AST_FLAG_OUTGOING);
ast_replace_subargument_delimiter(opt_args[OPT_ARG_GOTO]); ast_replace_subargument_delimiter(opt_args[OPT_ARG_GOTO]);
ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]); ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);

@ -210,7 +210,7 @@ static int disa_exec(struct ast_channel *chan, const char *data)
play_dialtone(chan, args.mailbox); play_dialtone(chan, args.mailbox);
ast_set_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); ast_channel_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
for (;;) { for (;;) {
/* if outa time, give em reorder */ /* if outa time, give em reorder */
@ -226,7 +226,7 @@ static int disa_exec(struct ast_channel *chan, const char *data)
} }
if (!(f = ast_read(chan))) { if (!(f = ast_read(chan))) {
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
return -1; return -1;
} }
@ -234,7 +234,7 @@ static int disa_exec(struct ast_channel *chan, const char *data)
if (f->data.uint32) if (f->data.uint32)
ast_channel_hangupcause_set(chan, f->data.uint32); ast_channel_hangupcause_set(chan, f->data.uint32);
ast_frfree(f); ast_frfree(f);
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
return -1; return -1;
} }
@ -263,7 +263,7 @@ static int disa_exec(struct ast_channel *chan, const char *data)
fp = fopen(args.passcode,"r"); fp = fopen(args.passcode,"r");
if (!fp) { if (!fp) {
ast_log(LOG_WARNING,"DISA password file %s not found on chan %s\n",args.passcode,ast_channel_name(chan)); ast_log(LOG_WARNING,"DISA password file %s not found on chan %s\n",args.passcode,ast_channel_name(chan));
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
return -1; return -1;
} }
pwline[0] = 0; pwline[0] = 0;
@ -359,7 +359,7 @@ static int disa_exec(struct ast_channel *chan, const char *data)
} }
} }
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
if (k == 3) { if (k == 3) {
int recheck = 0; int recheck = 0;

@ -90,8 +90,6 @@ static int serialize_showchan(struct ast_channel *c, char *buf, size_t size)
ast_channel_lock(c); ast_channel_lock(c);
bridge = ast_channel_get_bridge(c); bridge = ast_channel_get_bridge(c);
ast_channel_unlock(c);
snprintf(buf,size, snprintf(buf,size,
"Name= %s\n" "Name= %s\n"
"Type= %s\n" "Type= %s\n"
@ -168,7 +166,7 @@ static int serialize_showchan(struct ast_channel *c, char *buf, size_t size)
ast_channel_appl(c) ? ast_channel_appl(c) : "(N/A)", ast_channel_appl(c) ? ast_channel_appl(c) : "(N/A)",
ast_channel_data(c) ? S_OR(ast_channel_data(c), "(Empty)") : "(None)", ast_channel_data(c) ? S_OR(ast_channel_data(c), "(Empty)") : "(None)",
(ast_test_flag(ast_channel_flags(c), AST_FLAG_BLOCKING) ? ast_channel_blockproc(c) : "(Not Blocking)")); (ast_test_flag(ast_channel_flags(c), AST_FLAG_BLOCKING) ? ast_channel_blockproc(c) : "(Not Blocking)"));
ast_channel_unlock(c);
ao2_cleanup(bridge); ao2_cleanup(bridge);
return 0; return 0;
} }

@ -645,9 +645,9 @@ static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u,
setvbuf(eivr_errors, NULL, _IONBF, 0); setvbuf(eivr_errors, NULL, _IONBF, 0);
} }
while (1) { while (1) {
if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)) { if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)) {
ast_chan_log(LOG_ERROR, chan, "Is a zombie\n"); ast_chan_log(LOG_ERROR, chan, "Is a zombie\n");
break; break;
} }
if (!hangup_info_sent && !(ast_test_flag(&flags, run_dead)) && ast_check_hangup(chan)) { if (!hangup_info_sent && !(ast_test_flag(&flags, run_dead)) && ast_check_hangup(chan)) {

@ -4329,6 +4329,31 @@ void ast_channel_dialed_causes_clear(const struct ast_channel *chan);
struct ast_flags *ast_channel_flags(struct ast_channel *chan); struct ast_flags *ast_channel_flags(struct ast_channel *chan);
/*!
* \since 13.17.0
* \brief Set a flag on a channel
*
* \param chan The channel to set the flag on
* \param flag The flag to set
*
* \note This will lock the channel internally. If the channel is already
* locked it is still safe to call.
*/
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag);
/*!
* \since 13.17.0
* \param Clear a flag on a channel
*
* \param chan The channel to clear the flag from
* \param flag The flag to clear
*
* \note This will lock the channel internally. If the channel is already
* locked it is still safe to call.
*/
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag);
/*! /*!
* \since 12.4.0 * \since 12.4.0
* \brief Return whether or not any manager variables have been set * \brief Return whether or not any manager variables have been set

@ -300,11 +300,11 @@ int ast_autoservice_stop(struct ast_channel *chan)
res = 0; res = 0;
} }
ast_channel_lock(chan);
if (!as->orig_end_dtmf_flag) { if (!as->orig_end_dtmf_flag) {
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
} }
ast_channel_lock(chan);
while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) { while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) {
if (!((1 << f->frametype) & as->ignore_frame_types)) { if (!((1 << f->frametype) & as->ignore_frame_types)) {
ast_queue_frame_head(chan, f); ast_queue_frame_head(chan, f);

@ -484,7 +484,7 @@ int ast_bridge_setup_after_goto(struct ast_channel *chan)
} }
} else if (!ast_check_hangup(chan)) { } else if (!ast_check_hangup(chan)) {
/* Clear the outgoing flag */ /* Clear the outgoing flag */
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING); ast_channel_clear_flag(chan, AST_FLAG_OUTGOING);
if (after_bridge->specific) { if (after_bridge->specific) {
goto_failed = ast_explicit_goto(chan, after_bridge->context, goto_failed = ast_explicit_goto(chan, after_bridge->context,

@ -2092,7 +2092,7 @@ void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)
&& (ast_channel_is_leaving_bridge(bridge_channel->chan) && (ast_channel_is_leaving_bridge(bridge_channel->chan)
|| bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT)) { || bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT)) {
ast_debug(2, "Channel %s will survive this bridge; clearing outgoing (dialed) flag\n", ast_channel_name(bridge_channel->chan)); ast_debug(2, "Channel %s will survive this bridge; clearing outgoing (dialed) flag\n", ast_channel_name(bridge_channel->chan));
ast_clear_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_OUTGOING); ast_channel_clear_flag(bridge_channel->chan, AST_FLAG_OUTGOING);
} }
bridge->reconfigured = 1; bridge->reconfigured = 1;

@ -1296,8 +1296,10 @@ int ast_channel_defer_dtmf(struct ast_channel *chan)
int pre = 0; int pre = 0;
if (chan) { if (chan) {
ast_channel_lock(chan);
pre = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF); pre = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF);
ast_set_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF); ast_set_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF);
ast_channel_unlock(chan);
} }
return pre; return pre;
} }
@ -1305,8 +1307,9 @@ int ast_channel_defer_dtmf(struct ast_channel *chan)
/*! \brief Unset defer DTMF flag on channel */ /*! \brief Unset defer DTMF flag on channel */
void ast_channel_undefer_dtmf(struct ast_channel *chan) void ast_channel_undefer_dtmf(struct ast_channel *chan)
{ {
if (chan) if (chan) {
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF); ast_channel_clear_flag(chan, AST_FLAG_DEFER_DTMF);
}
} }
struct ast_channel *ast_channel_callback(ao2_callback_data_fn *cb_fn, void *arg, struct ast_channel *ast_channel_callback(ao2_callback_data_fn *cb_fn, void *arg,
@ -3518,7 +3521,7 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
return -1; return -1;
/* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
ast_set_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_set_flag(c, AST_FLAG_END_DTMF_ONLY);
/* Wait for a digit, no more than timeout_ms milliseconds total. /* Wait for a digit, no more than timeout_ms milliseconds total.
* Or, wait indefinitely if timeout_ms is <0. * Or, wait indefinitely if timeout_ms is <0.
@ -3537,12 +3540,12 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
if (errno == 0 || errno == EINTR) if (errno == 0 || errno == EINTR)
continue; continue;
ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return -1; return -1;
} else if (outfd > -1) { } else if (outfd > -1) {
/* The FD we were watching has something waiting */ /* The FD we were watching has something waiting */
ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return 1; return 1;
} else if (rchan) { } else if (rchan) {
int res; int res;
@ -3556,13 +3559,13 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
case AST_FRAME_DTMF_END: case AST_FRAME_DTMF_END:
res = f->subclass.integer; res = f->subclass.integer;
ast_frfree(f); ast_frfree(f);
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res; return res;
case AST_FRAME_CONTROL: case AST_FRAME_CONTROL:
switch (f->subclass.integer) { switch (f->subclass.integer) {
case AST_CONTROL_HANGUP: case AST_CONTROL_HANGUP:
ast_frfree(f); ast_frfree(f);
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return -1; return -1;
case AST_CONTROL_STREAM_STOP: case AST_CONTROL_STREAM_STOP:
case AST_CONTROL_STREAM_SUSPEND: case AST_CONTROL_STREAM_SUSPEND:
@ -3573,7 +3576,7 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
* that perform stream control will handle this. */ * that perform stream control will handle this. */
res = f->subclass.integer; res = f->subclass.integer;
ast_frfree(f); ast_frfree(f);
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res; return res;
case AST_CONTROL_PVT_CAUSE_CODE: case AST_CONTROL_PVT_CAUSE_CODE:
case AST_CONTROL_RINGING: case AST_CONTROL_RINGING:
@ -3608,7 +3611,7 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
} }
} }
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return 0; /* Time is up */ return 0; /* Time is up */
} }
@ -5873,9 +5876,9 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
} else if (caller) { /* no outgoing helper so use caller if available */ } else if (caller) { /* no outgoing helper so use caller if available */
call_forward_inherit(new_chan, caller, orig); call_forward_inherit(new_chan, caller, orig);
} }
ast_set_flag(ast_channel_flags(new_chan), AST_FLAG_ORIGINATED);
ast_channel_lock_both(orig, new_chan); ast_channel_lock_both(orig, new_chan);
ast_channel_set_flag(new_chan, AST_FLAG_ORIGINATED);
pbx_builtin_setvar_helper(new_chan, "FORWARDERNAME", forwarder); pbx_builtin_setvar_helper(new_chan, "FORWARDERNAME", forwarder);
ast_party_connected_line_copy(ast_channel_connected(new_chan), ast_channel_connected(orig)); ast_party_connected_line_copy(ast_channel_connected(new_chan), ast_channel_connected(orig));
ast_party_redirecting_copy(ast_channel_redirecting(new_chan), ast_channel_redirecting(orig)); ast_party_redirecting_copy(ast_channel_redirecting(new_chan), ast_channel_redirecting(orig));
@ -10996,3 +10999,18 @@ enum ast_channel_error ast_channel_errno(void)
{ {
return ast_channel_internal_errno(); return ast_channel_internal_errno();
} }
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
{
ast_channel_lock(chan);
ast_set_flag(ast_channel_flags(chan), flag);
ast_channel_unlock(chan);
}
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
{
ast_channel_lock(chan);
ast_clear_flag(ast_channel_flags(chan), flag);
ast_channel_unlock(chan);
}

@ -1545,7 +1545,7 @@ static int waitstream_core(struct ast_channel *c,
reverse = ""; reverse = "";
/* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */ /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
ast_set_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_set_flag(c, AST_FLAG_END_DTMF_ONLY);
if (ast_test_flag(ast_channel_flags(c), AST_FLAG_MASQ_NOSTREAM)) if (ast_test_flag(ast_channel_flags(c), AST_FLAG_MASQ_NOSTREAM))
orig_chan_name = ast_strdupa(ast_channel_name(c)); orig_chan_name = ast_strdupa(ast_channel_name(c));
@ -1577,7 +1577,7 @@ static int waitstream_core(struct ast_channel *c,
res = ast_waitfor(c, ms); res = ast_waitfor(c, ms);
if (res < 0) { if (res < 0) {
ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res; return res;
} }
} else { } else {
@ -1588,11 +1588,11 @@ static int waitstream_core(struct ast_channel *c,
if (errno == EINTR) if (errno == EINTR)
continue; continue;
ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return -1; return -1;
} else if (outfd > -1) { /* this requires cmdfd set */ } else if (outfd > -1) { /* this requires cmdfd set */
/* The FD we were watching has something waiting */ /* The FD we were watching has something waiting */
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return 1; return 1;
} }
/* if rchan is set, it is 'c' */ /* if rchan is set, it is 'c' */
@ -1601,7 +1601,7 @@ static int waitstream_core(struct ast_channel *c,
if (res > 0) { if (res > 0) {
struct ast_frame *fr = ast_read(c); struct ast_frame *fr = ast_read(c);
if (!fr) { if (!fr) {
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return -1; return -1;
} }
switch (fr->frametype) { switch (fr->frametype) {
@ -1612,7 +1612,7 @@ static int waitstream_core(struct ast_channel *c,
S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) { S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
res = fr->subclass.integer; res = fr->subclass.integer;
ast_frfree(fr); ast_frfree(fr);
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res; return res;
} }
} else { } else {
@ -1628,7 +1628,7 @@ static int waitstream_core(struct ast_channel *c,
"Break"); "Break");
ast_frfree(fr); ast_frfree(fr);
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res; return res;
} }
} }
@ -1645,7 +1645,7 @@ static int waitstream_core(struct ast_channel *c,
"Break"); "Break");
res = fr->subclass.integer; res = fr->subclass.integer;
ast_frfree(fr); ast_frfree(fr);
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res; return res;
case AST_CONTROL_STREAM_REVERSE: case AST_CONTROL_STREAM_REVERSE:
if (!skip_ms) { if (!skip_ms) {
@ -1663,7 +1663,7 @@ static int waitstream_core(struct ast_channel *c,
case AST_CONTROL_BUSY: case AST_CONTROL_BUSY:
case AST_CONTROL_CONGESTION: case AST_CONTROL_CONGESTION:
ast_frfree(fr); ast_frfree(fr);
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return -1; return -1;
case AST_CONTROL_RINGING: case AST_CONTROL_RINGING:
case AST_CONTROL_ANSWER: case AST_CONTROL_ANSWER:
@ -1700,7 +1700,7 @@ static int waitstream_core(struct ast_channel *c,
ast_sched_runq(ast_channel_sched(c)); ast_sched_runq(ast_channel_sched(c));
} }
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return (err || ast_channel_softhangup_internal_flag(c)) ? -1 : 0; return (err || ast_channel_softhangup_internal_flag(c)) ? -1 : 0;
} }

@ -4819,14 +4819,10 @@ static int action_redirect(struct mansession *s, const struct message *m)
/* Release the bridge wait. */ /* Release the bridge wait. */
if (chan1_wait) { if (chan1_wait) {
ast_channel_lock(chan); ast_channel_clear_flag(chan, AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
ast_channel_unlock(chan);
} }
if (chan2_wait) { if (chan2_wait) {
ast_channel_lock(chan2); ast_channel_clear_flag(chan, AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
ast_clear_flag(ast_channel_flags(chan2), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
ast_channel_unlock(chan2);
} }
chan2 = ast_channel_unref(chan2); chan2 = ast_channel_unref(chan2);

@ -4257,8 +4257,10 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
ast_channel_pbx(c)->rtimeoutms = 10000; ast_channel_pbx(c)->rtimeoutms = 10000;
ast_channel_pbx(c)->dtimeoutms = 5000; ast_channel_pbx(c)->dtimeoutms = 5000;
ast_channel_lock(c);
autoloopflag = ast_test_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */ autoloopflag = ast_test_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
ast_set_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP); ast_set_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP);
ast_channel_unlock(c);
if (ast_strlen_zero(ast_channel_exten(c))) { if (ast_strlen_zero(ast_channel_exten(c))) {
/* If not successful fall back to 's' - but only if there is no given exten */ /* If not successful fall back to 's' - but only if there is no given exten */
@ -4503,8 +4505,10 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
ast_pbx_hangup_handler_run(c); ast_pbx_hangup_handler_run(c);
} }
ast_channel_lock(c);
ast_set2_flag(ast_channel_flags(c), autoloopflag, AST_FLAG_IN_AUTOLOOP); ast_set2_flag(ast_channel_flags(c), autoloopflag, AST_FLAG_IN_AUTOLOOP);
ast_clear_flag(ast_channel_flags(c), AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */ ast_clear_flag(ast_channel_flags(c), AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */
ast_channel_unlock(c);
pbx_destroy(ast_channel_pbx(c)); pbx_destroy(ast_channel_pbx(c));
ast_channel_pbx_set(c, NULL); ast_channel_pbx_set(c, NULL);

@ -3144,12 +3144,14 @@ static int handle_exec(struct ast_channel *chan, AGI *agi, int argc, const char
ast_verb(3, "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argc >= 3 ? argv[2] : ""); ast_verb(3, "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argc >= 3 ? argv[2] : "");
if ((app_to_exec = pbx_findapp(argv[1]))) { if ((app_to_exec = pbx_findapp(argv[1]))) {
ast_channel_lock(chan);
if (!(workaround = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS))) { if (!(workaround = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS))) {
ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS); ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS);
} }
ast_channel_unlock(chan);
res = pbx_exec(chan, app_to_exec, argc == 2 ? "" : argv[2]); res = pbx_exec(chan, app_to_exec, argc == 2 ? "" : argv[2]);
if (!workaround) { if (!workaround) {
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS); ast_channel_clear_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS);
} }
} else { } else {
ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]); ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);

@ -1548,8 +1548,10 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con
} }
} }
if (!res) { if (!res) {
ast_channel_lock(chan);
ast_channel_latest_musicclass_set(chan, mohclass->name); ast_channel_latest_musicclass_set(chan, mohclass->name);
ast_set_flag(ast_channel_flags(chan), AST_FLAG_MOH); ast_set_flag(ast_channel_flags(chan), AST_FLAG_MOH);
ast_channel_unlock(chan);
} }
mohclass = mohclass_unref(mohclass, "unreffing local reference to mohclass in local_ast_moh_start"); mohclass = mohclass_unref(mohclass, "unreffing local reference to mohclass in local_ast_moh_start");
@ -1559,10 +1561,10 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con
static void local_ast_moh_stop(struct ast_channel *chan) static void local_ast_moh_stop(struct ast_channel *chan)
{ {
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_MOH);
ast_deactivate_generator(chan); ast_deactivate_generator(chan);
ast_channel_lock(chan); ast_channel_lock(chan);
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_MOH);
if (ast_channel_music_state(chan)) { if (ast_channel_music_state(chan)) {
if (ast_channel_stream(chan)) { if (ast_channel_stream(chan)) {
ast_closestream(ast_channel_stream(chan)); ast_closestream(ast_channel_stream(chan));

Loading…
Cancel
Save