diff options
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_gtalk.c | 25 | ||||
-rw-r--r-- | channels/chan_jingle.c | 46 |
2 files changed, 59 insertions, 12 deletions
diff --git a/channels/chan_gtalk.c b/channels/chan_gtalk.c index cf58d6c4b..855c89ba2 100644 --- a/channels/chan_gtalk.c +++ b/channels/chan_gtalk.c @@ -248,9 +248,17 @@ static struct gtalk_container gtalk_list; static void gtalk_member_destroy(struct gtalk *obj) { obj->cap = ast_format_cap_destroy(obj->cap); + if (obj->connection) { + ASTOBJ_UNREF(obj->connection, ast_aji_client_destroy); + } + if (obj->buddy) { + ASTOBJ_UNREF(obj->buddy, ast_aji_buddy_destroy); + } ast_free(obj); } +/* XXX This could be a source of reference leaks given that the CONTAINER_FIND + * macros bump the refcount while the traversal does not. */ static struct gtalk *find_gtalk(char *name, char *connection) { struct gtalk *gtalk = NULL; @@ -995,7 +1003,7 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const { struct gtalk_pvt *tmp = NULL; struct aji_resource *resources = NULL; - struct aji_buddy *buddy; + struct aji_buddy *buddy = NULL; char idroster[200]; char *data, *exten = NULL; struct ast_sockaddr bindaddr_tmp; @@ -1023,8 +1031,14 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const snprintf(idroster, sizeof(idroster), "%s", them); } else { ast_log(LOG_ERROR, "no gtalk capable clients to talk to.\n"); + if (buddy) { + ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy); + } return NULL; } + if (buddy) { + ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy); + } } if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { return NULL; @@ -1309,6 +1323,9 @@ static int gtalk_newcall(struct gtalk *client, ikspak *pak) if (!strcasecmp(client->name, "guest")){ /* the guest account is not tied to any configured XMPP client, let's set it now */ + if (client->connection) { + ASTOBJ_UNREF(client->connection, ast_aji_client_destroy); + } client->connection = ast_aji_get_client(from); if (!client->connection) { ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", from); @@ -1909,6 +1926,9 @@ static struct ast_channel *gtalk_request(const char *type, struct ast_format_cap if (!strcasecmp(client->name, "guest")){ /* the guest account is not tied to any configured XMPP client, let's set it now */ + if (client->connection) { + ASTOBJ_UNREF(client->connection, ast_aji_client_destroy); + } client->connection = ast_aji_get_client(sender); if (!client->connection) { ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", sender); @@ -2239,6 +2259,9 @@ static int gtalk_load_config(void) ASTOBJ_CONTAINER_TRAVERSE(clients, 1, { ASTOBJ_WRLOCK(iterator); ASTOBJ_WRLOCK(member); + if (member->connection) { + ASTOBJ_UNREF(member->connection, ast_aji_client_destroy); + } member->connection = NULL; iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, GOOGLE_NS, IKS_RULE_DONE); iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, GOOGLE_JINGLE_NS, IKS_RULE_DONE); diff --git a/channels/chan_jingle.c b/channels/chan_jingle.c index 86a6410db..233ec7e2e 100644 --- a/channels/chan_jingle.c +++ b/channels/chan_jingle.c @@ -228,9 +228,17 @@ static struct jingle_container jingle_list; static void jingle_member_destroy(struct jingle *obj) { obj->cap = ast_format_cap_destroy(obj->cap); + if (obj->connection) { + ASTOBJ_UNREF(obj->connection, ast_aji_client_destroy); + } + if (obj->buddy) { + ASTOBJ_UNREF(obj->buddy, ast_aji_buddy_destroy); + } ast_free(obj); } +/* XXX This could be a source of reference leaks given that the CONTAINER_FIND + * macros bump the refcount while the traversal does not. */ static struct jingle *find_jingle(char *name, char *connection) { struct jingle *jingle = NULL; @@ -744,7 +752,7 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from, { struct jingle_pvt *tmp = NULL; struct aji_resource *resources = NULL; - struct aji_buddy *buddy; + struct aji_buddy *buddy = NULL; char idroster[200]; struct ast_sockaddr bindaddr_tmp; @@ -752,8 +760,9 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from, if (!sid && !strchr(from, '/')) { /* I started call! */ if (!strcasecmp(client->name, "guest")) { buddy = ASTOBJ_CONTAINER_FIND(&client->connection->buddies, from); - if (buddy) + if (buddy) { resources = buddy->resources; + } } else if (client->buddy) resources = client->buddy->resources; while (resources) { @@ -766,8 +775,14 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from, snprintf(idroster, sizeof(idroster), "%s/%s", from, resources->resource); else { ast_log(LOG_ERROR, "no jingle capable clients to talk to.\n"); + if (buddy) { + ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy); + } return NULL; } + if (buddy) { + ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy); + } } if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { return NULL; @@ -1007,15 +1022,18 @@ static int jingle_newcall(struct jingle *client, ikspak *pak) tmp = tmp->next; } - if (!strcasecmp(client->name, "guest")){ - /* the guest account is not tied to any configured XMPP client, - let's set it now */ - client->connection = ast_aji_get_client(from); - if (!client->connection) { - ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", from); - return -1; - } - } + if (!strcasecmp(client->name, "guest")){ + /* the guest account is not tied to any configured XMPP client, + let's set it now */ + if (client->connection) { + ASTOBJ_UNREF(client->connection, ast_aji_client_destroy); + } + client->connection = ast_aji_get_client(from); + if (!client->connection) { + ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", from); + return -1; + } + } p = jingle_alloc(client, pak->from->partial, iks_find_attrib(pak->query, JINGLE_SID)); if (!p) { @@ -1552,6 +1570,9 @@ static struct ast_channel *jingle_request(const char *type, struct ast_format_ca if (!strcasecmp(client->name, "guest")){ /* the guest account is not tied to any configured XMPP client, let's set it now */ + if (client->connection) { + ASTOBJ_UNREF(client->connection, ast_aji_client_destroy); + } client->connection = ast_aji_get_client(sender); if (!client->connection) { ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", sender); @@ -1882,6 +1903,9 @@ static int jingle_load_config(void) ASTOBJ_CONTAINER_TRAVERSE(clients, 1, { ASTOBJ_WRLOCK(iterator); ASTOBJ_WRLOCK(member); + if (member->connection) { + ASTOBJ_UNREF(member->connection, ast_aji_client_destroy); + } member->connection = NULL; iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_NS, IKS_RULE_DONE); iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_DTMF_NS, IKS_RULE_DONE); |