Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 149279) +++ channels/chan_sip.c (working copy) @@ -2463,6 +2463,23 @@ return peer; } +/* The idea here is to set the pvt's outboundproxy pointer to the parameter + * pointed to by proxy. We need to maintain a proper refcount here, though. + */ +static struct sip_proxy *ref_proxy(struct sip_pvt *pvt, struct sip_proxy *proxy) +{ + struct sip_proxy *old_obproxy = pvt->outboundproxy; + /* Cool, now get the refs correct */ + if (proxy && proxy != &global_outboundproxy) { + ao2_ref(proxy, +1); + } + pvt->outboundproxy = proxy; + if (old_obproxy && old_obproxy != &global_outboundproxy) { + ao2_ref(old_obproxy, -1); + } + return proxy; +} + /*! * \brief Unlink a dialog from the dialogs container, as well as any other places * that it may be currently stored. @@ -2597,7 +2614,7 @@ static struct sip_proxy *proxy_allocate(char *name, char *port, int force) { struct sip_proxy *proxy; - proxy = ast_calloc(1, sizeof(*proxy)); + proxy = ao2_alloc(sizeof(*proxy), NULL); if (!proxy) return NULL; proxy->force = force; @@ -3244,8 +3261,12 @@ If obforcing is set, we will keep the outbound proxy during the whole dialog, regardless of what the SIP rfc says */ - if (p->outboundproxy && !p->outboundproxy->force) + if (p->outboundproxy && !p->outboundproxy->force){ + if (p->outboundproxy != &global_outboundproxy) { + ao2_ref(p->outboundproxy, -1); + } p->outboundproxy = NULL; + } for (cur = p->packets; cur; prev = cur, cur = cur->next) { if (cur->seqno != seqno || cur->is_resp != resp) @@ -3780,7 +3801,7 @@ { ast_debug(3, "Destroying SIP peer %s\n", peer->name); if (peer->outboundproxy) - ast_free(peer->outboundproxy); + ao2_ref(peer->outboundproxy, -1); peer->outboundproxy = NULL; /* Delete it, it needs to disappear */ @@ -4258,7 +4279,7 @@ ast_string_field_set(dialog, fullcontact, peer->fullcontact); ast_string_field_set(dialog, context, peer->context); ast_string_field_set(dialog, parkinglot, peer->parkinglot); - dialog->outboundproxy = obproxy_get(dialog, peer); + ref_proxy(dialog, obproxy_get(dialog, peer)); dialog->callgroup = peer->callgroup; dialog->pickupgroup = peer->pickupgroup; dialog->allowtransfer = peer->allowtransfer; @@ -4354,7 +4375,7 @@ ast_string_field_set(dialog, tohost, peername); /* Get the outbound proxy information */ - dialog->outboundproxy = obproxy_get(dialog, NULL); + ref_proxy(dialog, obproxy_get(dialog, NULL)); /* If we have an outbound proxy, don't bother with DNS resolution at all */ if (dialog->outboundproxy) @@ -9747,7 +9768,7 @@ if (p->do_history) append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); - p->outboundproxy = obproxy_get(p, NULL); + ref_proxy(p, obproxy_get(p, NULL)); /* Use port number specified if no SRV record was found */ if (!r->us.sin_port && r->portno)