aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b>2009-08-05 20:07:09 +0000
committerrmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b>2009-08-05 20:07:09 +0000
commitf910a089d9a2cfd67e446b5c5e9a3ad6e28c8648 (patch)
tree81c443a212d3f60b3fad764541f0b99ecd50e28b
parent821d9fc1e4d591fceede07f99a35c4e8038ad335 (diff)
Merged revisions 210640 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ................ r210640 | rmudgett | 2009-08-05 14:40:03 -0500 (Wed, 05 Aug 2009) | 21 lines Merged revisions 210575 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r210575 | rmudgett | 2009-08-05 14:18:56 -0500 (Wed, 05 Aug 2009) | 14 lines Dialplan starts execution before the channel setup is complete. * Issue 15655: For the case where dialing is complete for an incoming call, dahdi_new() was asked to start the PBX and then the code set more channel variables. If the dialplan hungup before these channel variables got set, asterisk would likely crash. * Fixed potential for overlap incoming call to erroneously set channel variables as global dialplan variables if the ast_channel structure failed to get allocated. * Added missing set of CALLINGSUBADDR in the dialing is complete case. (closes issue #15655) Reported by: alecdavis ........ ................ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.0@210647 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_dahdi.c111
1 files changed, 62 insertions, 49 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 9adebfed6..d425ad3d7 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -11155,6 +11155,7 @@ static void *pri_dchannel(void *vpri)
pri->pvts[chanpos]->exten[0] = 's';
pri->pvts[chanpos]->exten[1] = '\0';
}
+
/* Make sure extension exists (or in overlap dial mode, can exist) */
if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
@@ -11190,8 +11191,13 @@ static void *pri_dchannel(void *vpri)
pri->pvts[chanpos]->callingpres = e->ring.callingpres;
/* Start PBX */
- if (!e->ring.complete && (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
- /* Release the PRI lock while we create the channel */
+ if (!e->ring.complete
+ && (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
+ && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
+ /*
+ * Release the PRI lock while we create the channel
+ * so other threads can send D channel messages.
+ */
ast_mutex_unlock(&pri->lock);
if (crv) {
/* Set bearer and such */
@@ -11202,37 +11208,34 @@ static void *pri_dchannel(void *vpri)
} else {
c = dahdi_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
}
-
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-
- if (!ast_strlen_zero(e->ring.callingsubaddr)) {
- pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
- }
- if (e->ring.ani2 >= 0) {
- snprintf(ani2str, 5, "%.2d", e->ring.ani2);
- pbx_builtin_setvar_helper(c, "ANI2", ani2str);
- pri->pvts[chanpos]->cid_ani2 = e->ring.ani2;
- }
+ ast_mutex_lock(&pri->lock);
+ if (c) {
+ if (!ast_strlen_zero(e->ring.callingsubaddr)) {
+ pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
+ }
+ if (e->ring.ani2 >= 0) {
+ snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
+ pbx_builtin_setvar_helper(c, "ANI2", ani2str);
+ pri->pvts[chanpos]->cid_ani2 = e->ring.ani2;
+ }
#ifdef SUPPORT_USERUSER
- if (!ast_strlen_zero(e->ring.useruserinfo)) {
- pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
- }
+ if (!ast_strlen_zero(e->ring.useruserinfo)) {
+ pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
+ }
#endif
- snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
- pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
- if (e->ring.redirectingreason >= 0)
- pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
-
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- ast_mutex_lock(&pri->lock);
+ snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
+ pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
+ if (e->ring.redirectingreason >= 0)
+ pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
+ }
if (c && !ast_pthread_create_detached(&threadid, NULL, ss_thread, c)) {
ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
- plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
+ plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
+ pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
} else {
- ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
+ ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
if (c)
ast_hangup(c);
@@ -11241,17 +11244,28 @@ static void *pri_dchannel(void *vpri)
pri->pvts[chanpos]->call = NULL;
}
}
- } else {
+ } else {
+ /*
+ * Release the PRI lock while we create the channel
+ * so other threads can send D channel messages.
+ */
ast_mutex_unlock(&pri->lock);
- /* Release PRI lock while we create the channel */
- c = dahdi_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
+ c = dahdi_new(pri->pvts[chanpos], AST_STATE_RING, 0, SUB_REAL, law, e->ring.ctype);
+ ast_mutex_lock(&pri->lock);
if (c) {
- char calledtonstr[10];
-
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-
+ /*
+ * It is reasonably safe to set the following
+ * channel variables while the PRI and DAHDI private
+ * structures are locked. The PBX has not been
+ * started yet and it is unlikely that any other task
+ * will do anything with the channel we have just
+ * created.
+ */
+ if (!ast_strlen_zero(e->ring.callingsubaddr)) {
+ pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
+ }
if (e->ring.ani2 >= 0) {
- snprintf(ani2str, 5, "%d", e->ring.ani2);
+ snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
pbx_builtin_setvar_helper(c, "ANI2", ani2str);
pri->pvts[chanpos]->cid_ani2 = e->ring.ani2;
}
@@ -11264,32 +11278,31 @@ static void *pri_dchannel(void *vpri)
if (e->ring.redirectingreason >= 0)
pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
-
+
snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
-
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- ast_mutex_lock(&pri->lock);
-
+ }
+ if (c && !ast_pbx_start(c)) {
ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
- plancallingnum, pri->pvts[chanpos]->exten,
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
+ plancallingnum, pri->pvts[chanpos]->exten,
+ pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
dahdi_enable_ec(pri->pvts[chanpos]);
} else {
-
- ast_mutex_lock(&pri->lock);
-
- ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
+ ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
- pri->pvts[chanpos]->call = NULL;
+ if (c) {
+ ast_hangup(c);
+ } else {
+ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
+ pri->pvts[chanpos]->call = NULL;
+ }
}
}
} else {
ast_verb(3, "Extension '%s' in context '%s' from '%s' does not exist. Rejecting call on channel %d/%d, span %d\n",
- pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan,
- pri->pvts[chanpos]->prioffset, pri->span);
+ pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan,
+ pri->pvts[chanpos]->prioffset, pri->span);
pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
pri->pvts[chanpos]->call = NULL;
pri->pvts[chanpos]->exten[0] = '\0';