diff options
author | Matt Jordan <mjordan@digium.com> | 2016-08-11 11:13:07 -0500 |
---|---|---|
committer | Matt Jordan <mjordan@digium.com> | 2016-08-11 13:56:19 -0500 |
commit | 225fd1003fa3016e4a8030cbcaa5b5d0d99a7f45 (patch) | |
tree | e0d341f0074535290492e626ec98899275c1b601 /apps/app_queue.c | |
parent | 8d84c8edfff0f18ef4f469103c154616206022cf (diff) |
app_queue: Prevent crash when a call is forwarded to an invalid location
When a call forward attempt is made from a Queue member, the current
code will hang up the forwarding channel in an off-nominal condition
prior to raising the Stasis events informing the rest of Asterisk that
the call was forwarded. This will result in a slew of dreaded FRACKs,
most likely leading to a crash.
This patch modifies the code such that we don't hang up the forwarding
channel even in an off-nominal condition until we've safely raised the
Stasis messages.
ASTERISK-25797 #close
Change-Id: Ife5abed351691fd79105321636eaa8ea8dcdba38
Diffstat (limited to 'apps/app_queue.c')
-rw-r--r-- | apps/app_queue.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c index 39413f9a6..a5cb12640 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -4865,6 +4865,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte char tmpchan[256]; char *stuff; char *tech; + int failed = 0; ast_copy_string(tmpchan, ast_channel_call_forward(o->chan), sizeof(tmpchan)); ast_copy_string(forwarder, ast_channel_name(o->chan), sizeof(forwarder)); @@ -4977,14 +4978,20 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte if (ast_call(o->chan, stuff, 0)) { ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n", tech, stuff); - do_hang(o); - numnochan++; + failed = 1; } } - ast_channel_publish_dial(qe->chan, o->chan, stuff, NULL); ast_channel_publish_dial_forward(qe->chan, original, o->chan, NULL, "CANCEL", ast_channel_call_forward(original)); + if (o->chan) { + ast_channel_publish_dial(qe->chan, o->chan, stuff, NULL); + } + + if (failed) { + do_hang(o); + numnochan++; + } /* Hangup the original channel now, in case we needed it */ ast_hangup(winner); |