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:
parent
76394a727f
commit
e6ca768081
|
@ -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);
|
||||
|
|
|
@ -213,7 +213,12 @@ int ast_aji_invite_chat(struct aji_client *client, char *user, char *room, char
|
|||
/*! Join/leave existing Chat session */
|
||||
int ast_aji_join_chat(struct aji_client *client, char *room, char *nick);
|
||||
int ast_aji_leave_chat(struct aji_client *client, char *room, char *nick);
|
||||
/*! Get a client via its name. Increases refcount of client by 1 */
|
||||
struct aji_client *ast_aji_get_client(const char *name);
|
||||
struct aji_client_container *ast_aji_get_clients(void);
|
||||
/*! Destructor function for buddies to be used with ASTOBJ_UNREF */
|
||||
void ast_aji_buddy_destroy(struct aji_buddy *obj);
|
||||
/*! Destructor function for clients to be used with ASTOBJ_UNREF after calls to ast_aji_get_client */
|
||||
void ast_aji_client_destroy(struct aji_client *obj);
|
||||
|
||||
#endif
|
||||
|
|
198
res/res_jabber.c
198
res/res_jabber.c
|
@ -287,8 +287,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||
|
||||
/*-- Forward declarations */
|
||||
static void aji_message_destroy(struct aji_message *obj);
|
||||
static void aji_buddy_destroy(struct aji_buddy *obj);
|
||||
static void aji_client_destroy(struct aji_client *obj);
|
||||
static int aji_is_secure(struct aji_client *client);
|
||||
#ifdef HAVE_OPENSSL
|
||||
static int aji_start_tls(struct aji_client *client);
|
||||
|
@ -419,10 +417,10 @@ static struct ast_flags pubsubflags = { 0 };
|
|||
* \param obj aji_client The structure we will delete.
|
||||
* \return void.
|
||||
*/
|
||||
static void aji_client_destroy(struct aji_client *obj)
|
||||
void ast_aji_client_destroy(struct aji_client *obj)
|
||||
{
|
||||
struct aji_message *tmp;
|
||||
ASTOBJ_CONTAINER_DESTROYALL(&obj->buddies, aji_buddy_destroy);
|
||||
ASTOBJ_CONTAINER_DESTROYALL(&obj->buddies, ast_aji_buddy_destroy);
|
||||
ASTOBJ_CONTAINER_DESTROY(&obj->buddies);
|
||||
iks_filter_delete(obj->f);
|
||||
iks_parser_delete(obj->p);
|
||||
|
@ -441,7 +439,7 @@ static void aji_client_destroy(struct aji_client *obj)
|
|||
* \param obj aji_buddy The structure we will delete.
|
||||
* \return void.
|
||||
*/
|
||||
static void aji_buddy_destroy(struct aji_buddy *obj)
|
||||
void ast_aji_buddy_destroy(struct aji_buddy *obj)
|
||||
{
|
||||
struct aji_resource *tmp;
|
||||
|
||||
|
@ -677,12 +675,15 @@ static int aji_status_exec(struct ast_channel *chan, const char *data)
|
|||
buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, jid.screenname);
|
||||
if (!buddy) {
|
||||
ast_log(LOG_WARNING, "Could not find buddy in list: '%s'\n", jid.screenname);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return -1;
|
||||
}
|
||||
r = aji_find_resource(buddy, jid.resource);
|
||||
if (!r && buddy->resources) {
|
||||
r = buddy->resources;
|
||||
}
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
if (!r) {
|
||||
ast_log(LOG_NOTICE, "Resource '%s' of buddy '%s' was not found\n", jid.resource, jid.screenname);
|
||||
} else {
|
||||
|
@ -741,12 +742,15 @@ static int acf_jabberstatus_read(struct ast_channel *chan, const char *name, cha
|
|||
buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, jid.screenname);
|
||||
if (!buddy) {
|
||||
ast_log(LOG_WARNING, "Could not find buddy in list: '%s'\n", jid.screenname);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return -1;
|
||||
}
|
||||
r = aji_find_resource(buddy, jid.resource);
|
||||
if (!r && buddy->resources) {
|
||||
r = buddy->resources;
|
||||
}
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
if (!r) {
|
||||
ast_log(LOG_NOTICE, "Resource %s of buddy %s was not found.\n", jid.resource, jid.screenname);
|
||||
} else {
|
||||
|
@ -803,17 +807,10 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch
|
|||
return -1;
|
||||
}
|
||||
|
||||
client = ast_aji_get_client(args.account);
|
||||
if (!client) {
|
||||
ast_log(LOG_WARNING, "Could not find client %s, exiting\n", args.account);
|
||||
return -1;
|
||||
}
|
||||
|
||||
parse = ast_strdupa(args.jid);
|
||||
AST_NONSTANDARD_APP_ARGS(jid, parse, '/');
|
||||
if (jid.argc < 1 || jid.argc > 2 || strlen(args.jid) > AJI_MAX_JIDLEN) {
|
||||
ast_log(LOG_WARNING, "Invalid JID : %s\n", parse);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -823,7 +820,6 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch
|
|||
sscanf(args.timeout, "%d", &timeout);
|
||||
if (timeout <= 0) {
|
||||
ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -831,12 +827,19 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch
|
|||
jidlen = strlen(jid.screenname);
|
||||
resourcelen = ast_strlen_zero(jid.resource) ? 0 : strlen(jid.resource);
|
||||
|
||||
client = ast_aji_get_client(args.account);
|
||||
if (!client) {
|
||||
ast_log(LOG_WARNING, "Could not find client %s, exiting\n", args.account);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ast_debug(3, "Waiting for an XMPP message from %s\n", args.jid);
|
||||
|
||||
start = ast_tvnow();
|
||||
|
||||
if (ast_autoservice_start(chan) < 0) {
|
||||
ast_log(LOG_WARNING, "Cannot start autoservice for channel %s\n", chan->name);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -905,7 +908,7 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch
|
|||
diff = ast_tvdiff_ms(ast_tvnow(), start);
|
||||
}
|
||||
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
if (ast_autoservice_stop(chan) < 0) {
|
||||
ast_log(LOG_WARNING, "Cannot stop autoservice for channel %s\n", chan->name);
|
||||
}
|
||||
|
@ -1017,14 +1020,13 @@ static int aji_join_exec(struct ast_channel *chan, const char *data)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!(client = ast_aji_get_client(args.sender))) {
|
||||
ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
|
||||
if (strchr(args.jid, '/')) {
|
||||
ast_log(LOG_ERROR, "Invalid room name : resource must not be appended\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strchr(args.jid, '/')) {
|
||||
ast_log(LOG_ERROR, "Invalid room name : resource must not be appended\n");
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
if (!(client = ast_aji_get_client(args.sender))) {
|
||||
ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1044,7 +1046,7 @@ static int aji_join_exec(struct ast_channel *chan, const char *data)
|
|||
ast_log(LOG_ERROR, "Problem with specified jid of '%s'\n", args.jid);
|
||||
}
|
||||
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1078,16 +1080,16 @@ static int aji_leave_exec(struct ast_channel *chan, const char *data)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (strchr(args.jid, '/')) {
|
||||
ast_log(LOG_ERROR, "Invalid room name, resource must not be appended\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(client = ast_aji_get_client(args.sender))) {
|
||||
ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strchr(args.jid, '/')) {
|
||||
ast_log(LOG_ERROR, "Invalid room name, resource must not be appended\n");
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
return -1;
|
||||
}
|
||||
if (!ast_strlen_zero(args.nick)) {
|
||||
snprintf(nick, AJI_MAX_RESJIDLEN, "%s", args.nick);
|
||||
} else {
|
||||
|
@ -1101,7 +1103,7 @@ static int aji_leave_exec(struct ast_channel *chan, const char *data)
|
|||
if (!ast_strlen_zero(args.jid) && strchr(args.jid, '@')) {
|
||||
ast_aji_leave_chat(client, args.jid, nick);
|
||||
}
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1142,6 +1144,7 @@ static int aji_send_exec(struct ast_channel *chan, const char *data)
|
|||
if (strchr(args.recipient, '@') && !ast_strlen_zero(args.message)) {
|
||||
ast_aji_send_chat(client, args.recipient, args.message);
|
||||
}
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1167,7 +1170,6 @@ static int msg_send_cb(const struct ast_msg *msg, const char *to, const char *fr
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ast_debug(1, "Sending message to '%s' from '%s'\n", dest, client->name);
|
||||
|
||||
res = ast_aji_send_chat(client, dest, ast_msg_get_body(msg));
|
||||
|
@ -1175,11 +1177,7 @@ static int msg_send_cb(const struct ast_msg *msg, const char *to, const char *fr
|
|||
ast_log(LOG_WARNING, "Failed to send xmpp message (%d).\n", res);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX Reference leak here. See note with ast_aji_get_client() about the problems
|
||||
* with that function.
|
||||
*/
|
||||
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return res == IKS_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
|
@ -1234,7 +1232,7 @@ static int aji_sendgroup_exec(struct ast_channel *chan, const char *data)
|
|||
res = ast_aji_send_groupchat(client, nick, args.groupchat, args.message);
|
||||
}
|
||||
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
if (res != IKS_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1549,7 +1547,7 @@ static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incom
|
|||
}
|
||||
|
||||
}
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1621,12 +1619,12 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|||
|
||||
if (!node) {
|
||||
ast_log(LOG_ERROR, "aji_act_hook was called with out a packet\n"); /* most likely cause type is IKS_NODE_ERROR lost connection */
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_HOOK;
|
||||
}
|
||||
|
||||
if (client->state == AJI_DISCONNECTING) {
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_HOOK;
|
||||
}
|
||||
|
||||
|
@ -1655,13 +1653,13 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|||
if (client->usetls && !aji_is_secure(client)) {
|
||||
#ifndef HAVE_OPENSSL
|
||||
ast_log(LOG_ERROR, "TLS connection cannot be established. Please install OpenSSL and its development libraries on this system, or disable the TLS option in your configuration file\n");
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_HOOK;
|
||||
#else
|
||||
if (aji_start_tls(client) == IKS_NET_TLSFAIL) {
|
||||
ast_log(LOG_ERROR, "Could not start TLS\n");
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
return IKS_HOOK;
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_HOOK;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
@ -1730,7 +1728,7 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|||
|
||||
ret = aji_start_sasl(client, features, client->jid->user, client->password);
|
||||
if (ret != IKS_OK) {
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_HOOK;
|
||||
}
|
||||
break;
|
||||
|
@ -1745,12 +1743,12 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|||
break;
|
||||
case IKS_NODE_ERROR:
|
||||
ast_log(LOG_ERROR, "JABBER: Node Error\n");
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_HOOK;
|
||||
break;
|
||||
case IKS_NODE_STOP:
|
||||
ast_log(LOG_WARNING, "JABBER: Disconnected\n");
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_HOOK;
|
||||
break;
|
||||
}
|
||||
|
@ -1782,12 +1780,12 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|||
|
||||
case IKS_NODE_ERROR:
|
||||
ast_log(LOG_ERROR, "JABBER: Node Error\n");
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_HOOK;
|
||||
|
||||
case IKS_NODE_STOP:
|
||||
ast_log(LOG_WARNING, "JABBER: Disconnected\n");
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_HOOK;
|
||||
}
|
||||
}
|
||||
|
@ -1822,7 +1820,7 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|||
if (node)
|
||||
iks_delete(node);
|
||||
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_OK;
|
||||
}
|
||||
/*!
|
||||
|
@ -1865,7 +1863,7 @@ static int aji_register_approve_handler(void *data, ikspak *pak)
|
|||
iks_delete(presence);
|
||||
iks_delete(x);
|
||||
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
}
|
||||
/*!
|
||||
|
@ -1936,7 +1934,8 @@ static int aji_register_query_handler(void *data, ikspak *pak)
|
|||
}
|
||||
iks_delete(iq);
|
||||
iks_delete(query);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
}
|
||||
|
||||
|
@ -2032,7 +2031,7 @@ static int aji_ditems_handler(void *data, ikspak *pak)
|
|||
iks_delete(feature);
|
||||
}
|
||||
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
|
||||
}
|
||||
|
@ -2054,7 +2053,8 @@ static int aji_client_info_handler(void *data, ikspak *pak)
|
|||
if (pak->subtype == IKS_TYPE_RESULT) {
|
||||
if (!resource) {
|
||||
ast_log(LOG_NOTICE, "JABBER: Received client info from %s when not requested.\n", pak->from->full);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
}
|
||||
if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
|
||||
|
@ -2097,7 +2097,8 @@ static int aji_client_info_handler(void *data, ikspak *pak)
|
|||
} else if (pak->subtype == IKS_TYPE_ERROR) {
|
||||
ast_log(LOG_NOTICE, "User %s does not support discovery.\n", pak->from->full);
|
||||
}
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
}
|
||||
|
||||
|
@ -2115,16 +2116,17 @@ static int aji_dinfo_handler(void *data, ikspak *pak)
|
|||
struct aji_resource *resource = NULL;
|
||||
struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
|
||||
|
||||
resource = aji_find_resource(buddy, pak->from->resource);
|
||||
if (pak->subtype == IKS_TYPE_ERROR) {
|
||||
ast_log(LOG_WARNING, "Received error from a client, turn on jabber debug!\n");
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
}
|
||||
resource = aji_find_resource(buddy, pak->from->resource);
|
||||
if (pak->subtype == IKS_TYPE_RESULT) {
|
||||
if (!resource) {
|
||||
ast_log(LOG_NOTICE, "JABBER: Received client info from %s when not requested.\n", pak->from->full);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
}
|
||||
if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
|
||||
|
@ -2239,7 +2241,8 @@ static int aji_dinfo_handler(void *data, ikspak *pak)
|
|||
iks_delete(feature);
|
||||
}
|
||||
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
}
|
||||
|
||||
|
@ -2448,6 +2451,8 @@ static void aji_handle_presence(struct aji_client *client, ikspak *pak)
|
|||
|
||||
if (!found) {
|
||||
ast_log(LOG_ERROR, "Out of memory!\n");
|
||||
ASTOBJ_UNLOCK(buddy);
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
return;
|
||||
}
|
||||
ast_copy_string(found->resource, pak->from->resource, sizeof(found->resource));
|
||||
|
@ -2481,7 +2486,7 @@ static void aji_handle_presence(struct aji_client *client, ikspak *pak)
|
|||
}
|
||||
|
||||
ASTOBJ_UNLOCK(buddy);
|
||||
ASTOBJ_UNREF(buddy, aji_buddy_destroy);
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
|
||||
node = iks_find_attrib(iks_find(pak->x, "c"), "node");
|
||||
ver = iks_find_attrib(iks_find(pak->x, "c"), "ver");
|
||||
|
@ -2606,6 +2611,8 @@ static void aji_handle_subscribe(struct aji_client *client, ikspak *pak)
|
|||
buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
|
||||
if (!buddy && pak->from->partial) {
|
||||
aji_create_buddy(pak->from->partial, client);
|
||||
} else if (buddy) {
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
}
|
||||
default:
|
||||
if (option_verbose > 4) {
|
||||
|
@ -2821,7 +2828,7 @@ static void *aji_recv_loop(void *data)
|
|||
ast_log(LOG_WARNING, "JABBER: socket read error\n");
|
||||
}
|
||||
} while (client);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2877,7 +2884,7 @@ static int aji_register_transport(void *data, ikspak *pak)
|
|||
|
||||
if (send)
|
||||
iks_delete(send);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
|
||||
}
|
||||
|
@ -2927,7 +2934,7 @@ static int aji_register_transport2(void *data, ikspak *pak)
|
|||
iks_delete(reguser);
|
||||
if (regpass)
|
||||
iks_delete(regpass);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
}
|
||||
#endif
|
||||
|
@ -2983,7 +2990,7 @@ static void aji_pruneregister(struct aji_client *client)
|
|||
iks_delete(removeitem);
|
||||
iks_delete(send);
|
||||
|
||||
ASTOBJ_CONTAINER_PRUNE_MARKED(&client->buddies, aji_buddy_destroy);
|
||||
ASTOBJ_CONTAINER_PRUNE_MARKED(&client->buddies, ast_aji_buddy_destroy);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -3042,7 +3049,7 @@ static int aji_filter_roster(void *data, ikspak *pak)
|
|||
buddy = ast_calloc(1, sizeof(*buddy));
|
||||
if (!buddy) {
|
||||
ast_log(LOG_WARNING, "Out of memory\n");
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return 0;
|
||||
}
|
||||
ASTOBJ_INIT(buddy);
|
||||
|
@ -3062,7 +3069,7 @@ static int aji_filter_roster(void *data, ikspak *pak)
|
|||
ASTOBJ_UNLOCK(buddy);
|
||||
if (buddy) {
|
||||
ASTOBJ_CONTAINER_LINK(&client->buddies, buddy);
|
||||
ASTOBJ_UNREF(buddy, aji_buddy_destroy);
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
}
|
||||
}
|
||||
x = iks_next(x);
|
||||
|
@ -3071,7 +3078,7 @@ static int aji_filter_roster(void *data, ikspak *pak)
|
|||
iks_delete(x);
|
||||
aji_pruneregister(client);
|
||||
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
}
|
||||
|
||||
|
@ -3155,7 +3162,7 @@ static int aji_client_connect(void *data, ikspak *pak)
|
|||
ast_log(LOG_ERROR, "Out of memory.\n");
|
||||
}
|
||||
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -3206,7 +3213,7 @@ int ast_aji_disconnect(struct aji_client *client)
|
|||
#endif
|
||||
iks_disconnect(client->p);
|
||||
iks_parser_delete(client->p);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -3240,7 +3247,7 @@ static void aji_mwi_cb(const struct ast_event *ast_event, void *data)
|
|||
snprintf(newmsgs, sizeof(newmsgs), "%d",
|
||||
ast_event_get_ie_uint(ast_event, AST_EVENT_IE_NEWMSGS));
|
||||
aji_publish_mwi(client, mailbox, context, oldmsgs, newmsgs);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
|
||||
}
|
||||
/*!
|
||||
|
@ -3265,7 +3272,7 @@ static void aji_devstate_cb(const struct ast_event *ast_event, void *data)
|
|||
device = ast_event_get_ie_str(ast_event, AST_EVENT_IE_DEVICE);
|
||||
device_state = ast_devstate_str(ast_event_get_ie_uint(ast_event, AST_EVENT_IE_STATE));
|
||||
aji_publish_device_state(client, device, device_state);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -3556,7 +3563,7 @@ static int aji_handle_pubsub_error(void *data, ikspak *pak)
|
|||
iks_insert_node(request, orig_pubsub);
|
||||
ast_aji_send(client, request);
|
||||
iks_delete(request);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
} else if (!strcasecmp(iks_name(orig_request), "subscribe")) {
|
||||
if (ast_test_flag(&pubsubflags, AJI_XEP0248)) {
|
||||
|
@ -3565,7 +3572,7 @@ static int aji_handle_pubsub_error(void *data, ikspak *pak)
|
|||
aji_create_pubsub_node(client, NULL, node_name, NULL);
|
||||
}
|
||||
}
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
}
|
||||
|
||||
|
@ -3627,7 +3634,7 @@ static int aji_receive_node_list(void *data, ikspak* pak)
|
|||
if (item) {
|
||||
iks_delete(item);
|
||||
}
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return IKS_FILTER_EAT;
|
||||
}
|
||||
|
||||
|
@ -3666,13 +3673,14 @@ ast_cli_args *a)
|
|||
if (a->argc == 5) {
|
||||
collection = a->argv[4];
|
||||
}
|
||||
if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) {
|
||||
if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) {
|
||||
ast_cli(a->fd, "Unable to find client '%s'!\n", name);
|
||||
return CLI_FAILURE;
|
||||
}
|
||||
|
||||
ast_cli(a->fd, "Listing pubsub nodes.\n");
|
||||
aji_request_pubsub_nodes(client, collection);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return CLI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3715,6 +3723,7 @@ static char *aji_cli_purge_pubsub_nodes(struct ast_cli_entry *e, int cmd, struct
|
|||
} else {
|
||||
aji_delete_pubsub_node(client, a->argv[4]);
|
||||
}
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return CLI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3790,6 +3799,7 @@ static char *aji_cli_delete_pubsub_node(struct ast_cli_entry *e, int cmd, struct
|
|||
return CLI_FAILURE;
|
||||
}
|
||||
aji_delete_pubsub_node(client, a->argv[4]);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return CLI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3939,6 +3949,7 @@ static char *aji_cli_create_collection(struct ast_cli_entry *e, int cmd, struct
|
|||
|
||||
ast_cli(a->fd, "Creating test PubSub node collection.\n");
|
||||
aji_create_pubsub_collection(client, collection_name);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return CLI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3979,6 +3990,7 @@ static char *aji_cli_create_leafnode(struct ast_cli_entry *e, int cmd, struct as
|
|||
|
||||
ast_cli(a->fd, "Creating test PubSub node collection.\n");
|
||||
aji_create_pubsub_leaf(client, collection_name, leaf_name);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return CLI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -4288,7 +4300,7 @@ static char *aji_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
|||
//ast_verbose(" Message from: %s with id %s @ %s %s\n",tmp->from, S_OR(tmp->id,""), ctime(&tmp->arrived), S_OR(tmp->message, ""));
|
||||
}
|
||||
AST_LIST_UNLOCK(&client->messages);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
|
||||
return CLI_SUCCESS;
|
||||
}
|
||||
|
@ -4448,7 +4460,7 @@ static int aji_create_client(char *label, struct ast_variable *var, int debug)
|
|||
}
|
||||
if (!flag) {
|
||||
ASTOBJ_UNLOCK(client);
|
||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -4505,9 +4517,11 @@ static int aji_create_transport(char *label, struct aji_client *client)
|
|||
{
|
||||
char *server = NULL, *buddyname = NULL, *user = NULL, *pass = NULL;
|
||||
struct aji_buddy *buddy = NULL;
|
||||
int needs_unref = 1;
|
||||
|
||||
buddy = ASTOBJ_CONTAINER_FIND(&client->buddies,label);
|
||||
if (!buddy) {
|
||||
needs_unref = 0;
|
||||
buddy = ast_calloc(1, sizeof(*buddy));
|
||||
if (!buddy) {
|
||||
ast_log(LOG_WARNING, "Out of memory\n");
|
||||
|
@ -4532,6 +4546,10 @@ static int aji_create_transport(char *label, struct aji_client *client)
|
|||
ast_copy_string(buddy->user, user, sizeof(buddy->user));
|
||||
ast_copy_string(buddy->name, buddyname, sizeof(buddy->name));
|
||||
ast_copy_string(buddy->server, server, sizeof(buddy->server));
|
||||
if (needs_unref) {
|
||||
ASTOBJ_UNMARK(buddy);
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -4539,8 +4557,12 @@ static int aji_create_transport(char *label, struct aji_client *client)
|
|||
}
|
||||
}
|
||||
ASTOBJ_UNLOCK(buddy);
|
||||
ASTOBJ_UNMARK(buddy);
|
||||
ASTOBJ_CONTAINER_LINK(&client->buddies, buddy);
|
||||
if (needs_unref) {
|
||||
ASTOBJ_UNMARK(buddy);
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
} else {
|
||||
ASTOBJ_CONTAINER_LINK(&client->buddies, buddy);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -4555,10 +4577,10 @@ static int aji_create_transport(char *label, struct aji_client *client)
|
|||
static int aji_create_buddy(char *label, struct aji_client *client)
|
||||
{
|
||||
struct aji_buddy *buddy = NULL;
|
||||
int flag = 0;
|
||||
int needs_unref = 1;
|
||||
buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, label);
|
||||
if (!buddy) {
|
||||
flag = 1;
|
||||
needs_unref = 0;
|
||||
buddy = ast_calloc(1, sizeof(*buddy));
|
||||
if (!buddy) {
|
||||
ast_log(LOG_WARNING, "Out of memory\n");
|
||||
|
@ -4569,11 +4591,11 @@ static int aji_create_buddy(char *label, struct aji_client *client)
|
|||
ASTOBJ_WRLOCK(buddy);
|
||||
ast_copy_string(buddy->name, label, sizeof(buddy->name));
|
||||
ASTOBJ_UNLOCK(buddy);
|
||||
if (flag) {
|
||||
ASTOBJ_CONTAINER_LINK(&client->buddies, buddy);
|
||||
} else {
|
||||
if (needs_unref) {
|
||||
ASTOBJ_UNMARK(buddy);
|
||||
ASTOBJ_UNREF(buddy, aji_buddy_destroy);
|
||||
ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
|
||||
} else {
|
||||
ASTOBJ_CONTAINER_LINK(&client->buddies, buddy);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -4632,17 +4654,10 @@ static int aji_load_config(int reload)
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief grab a aji_client structure by label name or JID
|
||||
* \brief grab a aji_client structure by label name or JID. Bumps the refcount.
|
||||
* (without the resource string)
|
||||
* \param name label or JID
|
||||
* \return aji_client.
|
||||
*
|
||||
* XXX \bug This function leads to reference leaks all over the place.
|
||||
* ASTOBJ_CONTAINER_FIND() returns a reference, but if the
|
||||
* client is found via the traversal, no reference is returned.
|
||||
* None of the calling code releases references. This code needs
|
||||
* to be changed to always return a reference, and all of the users
|
||||
* need to be fixed to release them.
|
||||
*/
|
||||
struct aji_client *ast_aji_get_client(const char *name)
|
||||
{
|
||||
|
@ -4658,7 +4673,7 @@ struct aji_client *ast_aji_get_client(const char *name)
|
|||
aux = strsep(&aux, "/");
|
||||
}
|
||||
if (!strncasecmp(aux, name, strlen(aux))) {
|
||||
client = iterator;
|
||||
client = ASTOBJ_REF(iterator);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -4711,6 +4726,7 @@ static int manager_jabber_send(struct mansession *s, const struct message *m)
|
|||
} else {
|
||||
astman_append(s, "Response: Error\r\n");
|
||||
}
|
||||
ASTOBJ_UNREF(client, ast_aji_client_destroy);
|
||||
if (!ast_strlen_zero(id)) {
|
||||
astman_append(s, "ActionID: %s\r\n", id);
|
||||
}
|
||||
|
@ -4733,7 +4749,7 @@ static int aji_reload(int reload)
|
|||
} else if (res == -1)
|
||||
return 1;
|
||||
|
||||
ASTOBJ_CONTAINER_PRUNE_MARKED(&clients, aji_client_destroy);
|
||||
ASTOBJ_CONTAINER_PRUNE_MARKED(&clients, ast_aji_client_destroy);
|
||||
ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, {
|
||||
ASTOBJ_RDLOCK(iterator);
|
||||
if (iterator->state == AJI_DISCONNECTED) {
|
||||
|
@ -4784,7 +4800,7 @@ static int unload_module(void)
|
|||
ast_aji_disconnect(iterator);
|
||||
});
|
||||
|
||||
ASTOBJ_CONTAINER_DESTROYALL(&clients, aji_client_destroy);
|
||||
ASTOBJ_CONTAINER_DESTROYALL(&clients, ast_aji_client_destroy);
|
||||
ASTOBJ_CONTAINER_DESTROY(&clients);
|
||||
|
||||
ast_cond_destroy(&message_received_condition);
|
||||
|
|
Loading…
Reference in New Issue