mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
Merged revisions 312509 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8 ........ r312509 | rmudgett | 2011-04-01 18:15:42 -0500 (Fri, 01 Apr 2011) | 22 lines When a call going out an NT-PTMP port gets rejected, Asterisk crashes. If a call is sent to an ISDN phone that rejects the call with RELEASE_COMPLETE(cause: call reject(21), or busy(17)) Asterisk crashes. I could not get my setup to crash. However, I could see the possibility from a race condition between queuing an AST_CONTROL_BUSY to the core and then queueing an AST_CONTROL_HANGUP. If the AST_CONTROL_BUSY is processed before the AST_CONTROL_HANGUP is queued, the ast_channel could be destroyed out from under chan_misdn. Avoid this particular crash scenario by not queueing the AST_CONTROL_HANGUP if the AST_CONTROL_BUSY was queued. (closes issue #18408) Reported by: wimpy Patches: issue18408_v1.8.patch uploaded by rmudgett (license 664) Tested by: rmudgett, wimpy JIRA SWP-2679 ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@312510 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -681,7 +681,7 @@ static ast_mutex_t cl_te_lock;
|
||||
static enum event_response_e
|
||||
cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data);
|
||||
|
||||
static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, struct chan_list *ch);
|
||||
static int send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch);
|
||||
|
||||
static void cl_queue_chan(struct chan_list *chan);
|
||||
|
||||
@@ -8364,8 +8364,7 @@ static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
|
||||
cb_log(2, port, " --> hangup\n");
|
||||
ch->need_hangup = 0;
|
||||
ch->need_queue_hangup = 0;
|
||||
if (ch->ast) {
|
||||
send_cause2ast(ch->ast, bc, ch);
|
||||
if (ch->ast && send_cause2ast(ch->ast, bc, ch)) {
|
||||
ast_hangup(ch->ast);
|
||||
}
|
||||
return;
|
||||
@@ -8373,13 +8372,15 @@ static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
|
||||
|
||||
if (!ch->need_queue_hangup) {
|
||||
cb_log(2, port, " --> No need to queue hangup\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ch->need_queue_hangup = 0;
|
||||
if (ch->ast) {
|
||||
send_cause2ast(ch->ast, bc, ch);
|
||||
ast_queue_hangup_with_cause(ch->ast, bc->cause);
|
||||
cb_log(2, port, " --> queue_hangup\n");
|
||||
if (send_cause2ast(ch->ast, bc, ch)) {
|
||||
ast_queue_hangup_with_cause(ch->ast, bc->cause);
|
||||
cb_log(2, port, " --> queue_hangup\n");
|
||||
}
|
||||
} else {
|
||||
cb_log(1, port, "Cannot hangup chan, no ast\n");
|
||||
}
|
||||
@@ -8653,26 +8654,31 @@ static void do_immediate_setup(struct misdn_bchannel *bc, struct chan_list *ch,
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \retval -1 if can hangup after calling.
|
||||
* \retval 0 if cannot hangup after calling.
|
||||
*/
|
||||
static int send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch)
|
||||
{
|
||||
int can_hangup;
|
||||
|
||||
|
||||
static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch) {
|
||||
if (!ast) {
|
||||
chan_misdn_log(1, 0, "send_cause2ast: No Ast\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (!bc) {
|
||||
chan_misdn_log(1, 0, "send_cause2ast: No BC\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (!ch) {
|
||||
chan_misdn_log(1, 0, "send_cause2ast: No Ch\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ast->hangupcause = bc->cause;
|
||||
|
||||
can_hangup = -1;
|
||||
switch (bc->cause) {
|
||||
|
||||
case AST_CAUSE_UNALLOCATED:
|
||||
case AST_CAUSE_NO_ROUTE_TRANSIT_NET:
|
||||
case AST_CAUSE_NO_ROUTE_DESTINATION:
|
||||
@@ -8699,15 +8705,16 @@ static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, s
|
||||
chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n");
|
||||
break;
|
||||
}
|
||||
|
||||
chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1);
|
||||
|
||||
ast_queue_control(ast, AST_CONTROL_BUSY);
|
||||
|
||||
ch->need_busy = 0;
|
||||
|
||||
chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1);
|
||||
ast_queue_control(ast, AST_CONTROL_BUSY);
|
||||
|
||||
/* The BUSY is likely to cause a hangup or the user needs to hear it. */
|
||||
can_hangup = 0;
|
||||
break;
|
||||
}
|
||||
return can_hangup;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user