[asterisk-commits] rmudgett: branch 1.8 r312509 - /branches/1.8/channels/chan_misdn.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Apr 1 18:15:47 CDT 2011
Author: rmudgett
Date: Fri Apr 1 18:15:42 2011
New Revision: 312509
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=312509
Log:
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
Modified:
branches/1.8/channels/chan_misdn.c
Modified: branches/1.8/channels/chan_misdn.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_misdn.c?view=diff&rev=312509&r1=312508&r2=312509
==============================================================================
--- branches/1.8/channels/chan_misdn.c (original)
+++ branches/1.8/channels/chan_misdn.c Fri Apr 1 18:15:42 2011
@@ -679,7 +679,7 @@
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);
@@ -8365,8 +8365,7 @@
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;
@@ -8374,13 +8373,15 @@
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");
}
@@ -8654,26 +8655,31 @@
}
}
-
-
-static void send_cause2ast(struct ast_channel *ast, 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;
+
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:
@@ -8700,15 +8706,16 @@
chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n");
break;
}
+ 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);
- ch->need_busy = 0;
-
- break;
- }
+ /* The BUSY is likely to cause a hangup or the user needs to hear it. */
+ can_hangup = 0;
+ break;
+ }
+ return can_hangup;
}
More information about the asterisk-commits
mailing list