mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-29 18:19:30 +00:00
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 ........ Merged revisions 346086 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 346087 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@346088 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -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);
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user