From e5c9046575cb25296da54bd44c59f4ab78bf8986 Mon Sep 17 00:00:00 2001 From: rmudgett Date: Thu, 1 Oct 2009 19:48:58 +0000 Subject: Prevent deadlock if chan_dahdi attempts to change PRI channel names. The PRI channels can no longer change the channel name if a different B channel is selected during call negotiation. To prevent using the channel name to infer what B channel a call is using and to avoid name collisions, the channel name format is changed. The new channel naming for PRI channels is: DAHDI/ISDN-- git-svn-id: http://svn.digium.com/svn/asterisk/trunk@221701 f38db490-d61c-443f-a65b-d21fe96a405b --- CHANGES | 6 ++++++ channels/chan_dahdi.c | 42 ++++++++++++++++++++++++------------------ channels/sig_pri.h | 1 + 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/CHANGES b/CHANGES index 5062283a9..96d4be66d 100644 --- a/CHANGES +++ b/CHANGES @@ -205,6 +205,12 @@ libpri channel driver (chan_dahdi) DAHDI changes LibPRI). * Added the ability to ignore calls that are not in a Multiple Subscriber Number (MSN) list for PTMP CPE interfaces. + * The PRI channels can no longer change the channel name if a different B + channel is selected during call negotiation. To prevent using the channel + name to infer what B channel a call is using and to avoid name collisions, + the channel name format is changed. + The new channel naming for PRI channels is: + DAHDI/ISDN-- Asterisk Manager Interface -------------------------- diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index c38e253ab..33d17d64a 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -2588,17 +2588,10 @@ static void my_pri_fixup_chans(void *chan_old, void *chan_new) { struct dahdi_pvt *old_chan = chan_old; struct dahdi_pvt *new_chan = chan_new; - struct sig_pri_chan *pchan = new_chan->sig_pvt; - struct sig_pri_pri *pri = pchan->pri; new_chan->owner = old_chan->owner; old_chan->owner = NULL; if (new_chan->owner) { - char newname[AST_CHANNEL_NAME]; - - snprintf(newname, sizeof(newname), "DAHDI/%d:%d-%d", pri->trunkgroup, new_chan->channel, 1); - ast_change_name(new_chan->owner, newname); - new_chan->owner->tech_pvt = new_chan; new_chan->owner->fds[0] = new_chan->subs[SUB_REAL].dfd; new_chan->subs[SUB_REAL].owner = old_chan->subs[SUB_REAL].owner; @@ -8200,23 +8193,36 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb struct ast_str *chan_name; struct ast_variable *v; struct dahdi_params ps; + if (i->subs[idx].owner) { ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[idx]); return NULL; } - y = 1; + + /* Create the new channel name tail. */ chan_name = ast_str_alloca(32); - do { - if (i->channel == CHAN_PSEUDO) - ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random()); - else + if (i->channel == CHAN_PSEUDO) { + ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random()); +#if defined(HAVE_PRI) + } else if (i->pri) { + ast_mutex_lock(&i->pri->lock); + ast_str_set(&chan_name, 0, "ISDN-%d-%d", i->pri->span, ++i->pri->new_chan_seq); + ast_mutex_unlock(&i->pri->lock); +#endif /* defined(HAVE_PRI) */ + } else { + y = 1; + do { ast_str_set(&chan_name, 0, "%d-%d", i->channel, y); - for (x = 0; x < 3; x++) { - if ((idx != x) && i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name), i->subs[x].owner->name + 6)) - break; - } - y++; - } while (x < 3); + for (x = 0; x < 3; ++x) { + if (i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name), + i->subs[x].owner->name + 6)) { + break; + } + } + ++y; + } while (x < 3); + } + tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name)); if (!tmp) return NULL; diff --git a/channels/sig_pri.h b/channels/sig_pri.h index fb4668082..41bd53c83 100644 --- a/channels/sig_pri.h +++ b/channels/sig_pri.h @@ -211,6 +211,7 @@ struct sig_pri_pri { int resetting; /*!< true if span is being reset/restarted */ int resetpos; /*!< current position during a reset (-1 if not started) */ int sig; /*!< ISDN signalling type (SIG_PRI, SIG_BRI, SIG_BRI_PTMP, etc...) */ + int new_chan_seq; /*!< New struct ast_channel sequence number */ /* Everything after here is internally set */ struct pri *dchans[NUM_DCHANS]; /*!< Actual d-channels */ -- cgit v1.2.3