Fix res_jabber resource leaks

This should fix almost all resource leaks in res_jabber that involve
ASTOBJ_CONTAINER_FIND and resolves an ambiguous situation where
ast_aji_get_client would sometimes bump an object's refcount and sometimes not.

Review: https://reviewboard.asterisk.org/r/1553


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@346086 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Kinsey Moore
2011-11-23 17:12:46 +00:00
parent ac656bc6fe
commit c4b7983866
4 changed files with 154 additions and 90 deletions

View File

@@ -978,7 +978,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;
@@ -1006,8 +1006,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;
@@ -1268,6 +1274,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);
@@ -1868,6 +1877,9 @@ static struct ast_channel *gtalk_request(const char *type, format_t format, cons
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);
@@ -2157,6 +2169,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);

View File

@@ -740,7 +740,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;
@@ -748,8 +748,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) {
@@ -762,8 +763,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;
@@ -978,15 +985,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) {
@@ -1523,6 +1533,9 @@ static struct ast_channel *jingle_request(const char *type, format_t format, con
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);
@@ -1852,6 +1865,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);