diff options
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_local.c | 32 | ||||
-rw-r--r-- | channels/chan_mgcp.c | 2 | ||||
-rw-r--r-- | channels/chan_sip.c | 5 |
3 files changed, 37 insertions, 2 deletions
diff --git a/channels/chan_local.c b/channels/chan_local.c index d1f66f8dd..aebca441a 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -409,6 +409,38 @@ static void check_bridge(struct local_pvt *p) p->chan->audiohooks = p->owner->audiohooks; p->owner->audiohooks = audiohooks_swapper; } + + /* If any Caller ID was set, preserve it after masquerade like above. We must check + * to see if Caller ID was set because otherwise we'll mistakingly copy info not + * set from the dialplan and will overwrite the real channel Caller ID. The reason + * for this whole preswapping action is because the Caller ID is set on the channel + * thread (which is the to be masqueraded away local channel) before both local + * channels are optimized away. + */ + if (p->owner->caller.id.name.valid || p->owner->caller.id.number.valid + || p->owner->caller.id.subaddress.valid || p->owner->caller.ani.name.valid + || p->owner->caller.ani.number.valid || p->owner->caller.ani.subaddress.valid) { + struct ast_party_caller tmp; + tmp = p->owner->caller; + p->owner->caller = p->chan->_bridge->caller; + p->chan->_bridge->caller = tmp; + } + if (p->owner->redirecting.from.name.valid || p->owner->redirecting.from.number.valid + || p->owner->redirecting.from.subaddress.valid || p->owner->redirecting.to.name.valid + || p->owner->redirecting.to.number.valid || p->owner->redirecting.to.subaddress.valid) { + struct ast_party_redirecting tmp; + tmp = p->owner->redirecting; + p->owner->redirecting = p->chan->_bridge->redirecting; + p->chan->_bridge->redirecting = tmp; + } + if (p->owner->dialed.number.str || p->owner->dialed.subaddress.valid) { + struct ast_party_dialed tmp; + tmp = p->owner->dialed; + p->owner->dialed = p->chan->_bridge->dialed; + p->chan->_bridge->dialed = tmp; + } + + ast_app_group_update(p->chan, p->owner); ast_channel_masquerade(p->owner, p->chan->_bridge); ast_set_flag(p, LOCAL_ALREADY_MASQED); diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index 485b39aad..a787eab72 100644 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -3580,7 +3580,7 @@ static int find_and_retrans(struct mgcp_subchannel *sub, struct mgcp_request *re if (sscanf(req->identifier, "%30d", &seqno) != 1) { seqno = 0; } - for (cur = sub->parent->parent->responses, next = cur->next; cur; cur = next, next = cur->next) { + for (cur = sub->parent->parent->responses, next = cur ? cur->next : NULL; cur; cur = next, next = cur ? cur->next : NULL) { if (now - cur->whensent > RESPONSE_TIMEOUT) { /* Delete this entry */ if (prev) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 47dc2610d..cdf598a66 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -12652,7 +12652,6 @@ static int expire_register(const void *data) peer->expire = -1; peer->portinuri = 0; - memset(&peer->addr, 0, sizeof(peer->addr)); destroy_association(peer); /* remove registration data from storage */ set_socket_transport(&peer->socket, peer->default_outbound_transport); @@ -12681,6 +12680,10 @@ static int expire_register(const void *data) } } + /* Only clear the addr after we check for destruction. The addr must remain + * in order to unlink from the peers_by_ip container correctly */ + memset(&peer->addr, 0, sizeof(peer->addr)); + unref_peer(peer, "removing peer ref for expire_register"); return 0; |