prevent seg fault with attempt_transfer (bug #2741)

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/v1-0@4146 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Russell Bryant 21 years ago
parent 808ecc893a
commit d612a5ce42

@ -1,5 +1,5 @@
-- chan_h323 -- chan_sip
-- fix summaries for CLI commands -- fix to prevent seg fault when attempting a transfer
Asterisk 1.0.2 Asterisk 1.0.2
-- Major bugfix release -- Major bugfix release
Asterisk 1.0.1 Asterisk 1.0.1

@ -7007,54 +7007,69 @@ static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct
return -1; return -1;
} }
static void ast_quiet_chan(struct ast_channel *chan) {
if(chan && chan->_state == AST_STATE_UP) {
if(chan->generatordata)
ast_deactivate_generator(chan);
}
}
/*--- attempt_transfer: Attempt transfer of SIP call ---*/ /*--- attempt_transfer: Attempt transfer of SIP call ---*/
static int attempt_transfer(struct sip_pvt *p1, struct sip_pvt *p2) static int attempt_transfer(struct sip_pvt *p1, struct sip_pvt *p2)
{ {
int res = 0;
struct ast_channel
*chana = NULL,
*chanb = NULL,
*bridgea = NULL,
*bridgeb = NULL,
*peera = NULL,
*peerb = NULL,
*peerc = NULL;
if (!p1->owner || !p2->owner) { if (!p1->owner || !p2->owner) {
ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n"); ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
return -1; return -1;
} }
if (p1->owner->bridge) { chana = p1->owner;
if (p2->owner->bridge) chanb = p2->owner;
ast_moh_stop(p2->owner->bridge); bridgea = p1->owner->bridge;
ast_moh_stop(p1->owner->bridge); bridgeb = p2->owner->bridge;
ast_moh_stop(p1->owner);
ast_moh_stop(p2->owner); if (bridgea) {
if (p1->owner->cdr) { peera = chana;
p2->owner->cdr = ast_cdr_append(p2->owner->cdr, p1->owner->cdr); peerb = chanb;
p1->owner->cdr = NULL; peerc = bridgea;
} } else if(bridgeb) {
if (p1->owner->bridge->cdr) { peera = chanb;
p2->owner->cdr = ast_cdr_append(p2->owner->cdr, p1->owner->bridge->cdr); peerb = chana;
p1->owner->bridge->cdr = NULL; peerc = bridgeb;
}
if (ast_channel_masquerade(p2->owner, p1->owner->bridge)) {
ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", p2->owner->name, p1->owner->bridge->name);
return -1;
} }
} else if (p2->owner->bridge) {
ast_moh_stop(p2->owner->bridge); if(peera && peerb && peerc) {
ast_moh_stop(p2->owner); ast_quiet_chan(peera);
ast_moh_stop(p1->owner); ast_quiet_chan(peerb);
if (p2->owner->cdr) { ast_quiet_chan(peerc);
p1->owner->cdr = ast_cdr_append(p1->owner->cdr, p2->owner->cdr);
p2->owner->cdr = NULL; if (peera->cdr && peerb->cdr) {
peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
} else if(peera->cdr) {
peerb->cdr = peera->cdr;
} }
if (p2->owner->bridge->cdr) { peera->cdr = NULL;
p1->owner->cdr = ast_cdr_append(p1->owner->cdr, p2->owner->bridge->cdr);
p2->owner->bridge->cdr = NULL; if (peerb->cdr && peerc->cdr) {
peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
} else if(peerc->cdr) {
peerb->cdr = peerc->cdr;
} }
if (ast_channel_masquerade(p1->owner, p2->owner->bridge)) { peerc->cdr = NULL;
ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", p1->owner->name, p2->owner->bridge->name); if (ast_channel_masquerade(peerb, peerc)) {
return -1; ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
res = -1;
} }
return res;
} else { } else {
ast_log(LOG_NOTICE, "Transfer attempted with no bridged calls to transfer\n");
if (p1->owner)
ast_softhangup_nolock(p1->owner, AST_SOFTHANGUP_DEV);
if (p2->owner)
ast_softhangup_nolock(p2->owner, AST_SOFTHANGUP_DEV);
return -1; return -1;
} }
return 0; return 0;

@ -302,6 +302,12 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
int allowdisconnect_in,allowdisconnect_out,allowredirect_in,allowredirect_out; int allowdisconnect_in,allowdisconnect_out,allowredirect_in,allowredirect_out;
char *monitor_exec; char *monitor_exec;
if (chan && peer) {
pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
} else if (chan)
pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
if (monitor_ok) { if (monitor_ok) {
if (!monitor_app) { if (!monitor_app) {
if (!(monitor_app = pbx_findapp("Monitor"))) if (!(monitor_app = pbx_findapp("Monitor")))
@ -480,6 +486,8 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
} }
/* XXX Maybe we should have another message here instead of invalid extension XXX */ /* XXX Maybe we should have another message here instead of invalid extension XXX */
} else if (ast_exists_extension(transferee, transferer_real_context, newext, 1, transferer->callerid)) { } else if (ast_exists_extension(transferee, transferer_real_context, newext, 1, transferer->callerid)) {
pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name);
pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name);
ast_moh_stop(transferee); ast_moh_stop(transferee);
res=ast_autoservice_stop(transferee); res=ast_autoservice_stop(transferee);
if (!transferee->pbx) { if (!transferee->pbx) {

Loading…
Cancel
Save