diff options
author | rmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-08-05 20:07:09 +0000 |
---|---|---|
committer | rmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-08-05 20:07:09 +0000 |
commit | f910a089d9a2cfd67e446b5c5e9a3ad6e28c8648 (patch) | |
tree | 81c443a212d3f60b3fad764541f0b99ecd50e28b /channels/chan_dahdi.c | |
parent | 821d9fc1e4d591fceede07f99a35c4e8038ad335 (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
Diffstat (limited to 'channels/chan_dahdi.c')
-rw-r--r-- | channels/chan_dahdi.c | 111 |
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'; |