]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 210640 via svnmerge from
authorRichard Mudgett <rmudgett@digium.com>
Wed, 5 Aug 2009 20:28:07 +0000 (20:28 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Wed, 5 Aug 2009 20:28:07 +0000 (20:28 +0000)
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: https://origsvn.digium.com/svn/asterisk/branches/1.6.1@210681 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_dahdi.c

index c0cf77e6625af54b55d6a68a4b857733b681c272..07c774a28e799d840015fc56d70143e5662ec92c 100644 (file)
@@ -11343,6 +11343,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)) {
@@ -11378,8 +11379,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 */
@@ -11390,37 +11396,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);
@@ -11429,17 +11432,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;
                                                                }
@@ -11452,32 +11466,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';