Fix a crash as a result of propagating MWI or device state over XMPP when the client is disconnected.
The MWI and device state propagation code wrongly assumes that an XMPP client connection will remain established at all times. This fix corrects that by making the lifetime of the subscription the same as the lifetime of the connection itself. As the connection is established and disconnected the subscription itself is created and destroyed. (closes issue ASTERISK-18078) Reported by: elguero git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@370152 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
6027b26fa7
commit
44345b0973
|
@ -134,6 +134,8 @@ struct ast_xmpp_client {
|
|||
pthread_t thread;
|
||||
int timeout;
|
||||
unsigned int reconnect:1; /*!< Reconnect this client */
|
||||
struct ast_event_sub *mwi_sub; /*!< If distributing event information the MWI subscription */
|
||||
struct ast_event_sub *device_state_sub; /*!< If distributing event information the device state subscription */
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -387,9 +387,6 @@ static const char *app_ajistatus = "JabberStatus";
|
|||
static const char *app_ajijoin = "JabberJoin";
|
||||
static const char *app_ajileave = "JabberLeave";
|
||||
|
||||
static struct ast_event_sub *mwi_sub = NULL;
|
||||
static struct ast_event_sub *device_state_sub = NULL;
|
||||
|
||||
static ast_cond_t message_received_condition;
|
||||
static ast_mutex_t messagelock;
|
||||
|
||||
|
@ -1379,18 +1376,24 @@ static void xmpp_init_event_distribution(struct ast_xmpp_client *client)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!mwi_sub) {
|
||||
mwi_sub = ast_event_subscribe(AST_EVENT_MWI, xmpp_pubsub_mwi_cb, "xmpp_pubsub_mwi_subscription",
|
||||
client, AST_EVENT_IE_END);
|
||||
if (!(client->mwi_sub = ast_event_subscribe(AST_EVENT_MWI, xmpp_pubsub_mwi_cb, "xmpp_pubsub_mwi_subscription",
|
||||
client, AST_EVENT_IE_END))) {
|
||||
return;
|
||||
}
|
||||
if (!device_state_sub) {
|
||||
if (ast_enable_distributed_devstate()) {
|
||||
return;
|
||||
}
|
||||
device_state_sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE_CHANGE,
|
||||
xmpp_pubsub_devstate_cb, "xmpp_pubsub_devstate_subscription", client, AST_EVENT_IE_END);
|
||||
ast_event_dump_cache(device_state_sub);
|
||||
|
||||
if (ast_enable_distributed_devstate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!(client->device_state_sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE_CHANGE,
|
||||
xmpp_pubsub_devstate_cb, "xmpp_pubsub_devstate_subscription", client, AST_EVENT_IE_END))) {
|
||||
ast_event_unsubscribe(client->mwi_sub);
|
||||
client->mwi_sub = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
ast_event_dump_cache(client->device_state_sub);
|
||||
|
||||
xmpp_pubsub_subscribe(client, "device_state");
|
||||
xmpp_pubsub_subscribe(client, "message_waiting");
|
||||
|
@ -3278,18 +3281,30 @@ static int xmpp_action_hook(void *data, int type, iks *node)
|
|||
|
||||
int ast_xmpp_client_disconnect(struct ast_xmpp_client *client)
|
||||
{
|
||||
if (client->thread != AST_PTHREADT_NULL) {
|
||||
if ((client->thread != AST_PTHREADT_NULL) && !pthread_equal(pthread_self(), client->thread)) {
|
||||
client->state = XMPP_STATE_DISCONNECTING;
|
||||
pthread_join(client->thread, NULL);
|
||||
client->thread = AST_PTHREADT_NULL;
|
||||
}
|
||||
|
||||
if (client->mwi_sub) {
|
||||
ast_event_unsubscribe(client->mwi_sub);
|
||||
client->mwi_sub = NULL;
|
||||
}
|
||||
|
||||
if (client->device_state_sub) {
|
||||
ast_event_unsubscribe(client->device_state_sub);
|
||||
client->device_state_sub = NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (client->stream_flags & SECURE) {
|
||||
SSL_shutdown(client->ssl_session);
|
||||
SSL_CTX_free(client->ssl_context);
|
||||
SSL_free(client->ssl_session);
|
||||
}
|
||||
|
||||
client->stream_flags = 0;
|
||||
#endif
|
||||
|
||||
if (client->parser) {
|
||||
|
@ -3318,11 +3333,8 @@ static int xmpp_client_reconnect(struct ast_xmpp_client *client)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
client->stream_flags = 0;
|
||||
#endif
|
||||
ast_xmpp_client_disconnect(client);
|
||||
|
||||
client->state = XMPP_STATE_DISCONNECTED;
|
||||
client->timeout = 50;
|
||||
iks_parser_reset(client->parser);
|
||||
|
||||
|
@ -3459,6 +3471,7 @@ static void *xmpp_client_thread(void *data)
|
|||
ast_debug(3, "Connecting client '%s'\n", client->name);
|
||||
if ((res = xmpp_client_reconnect(client)) != IKS_OK) {
|
||||
sleep(4);
|
||||
res = IKS_NET_RWERR;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -4141,12 +4154,6 @@ static int unload_module(void)
|
|||
ast_unregister_application(app_ajileave);
|
||||
ast_manager_unregister("JabberSend");
|
||||
ast_custom_function_unregister(&jabberstatus_function);
|
||||
if (mwi_sub) {
|
||||
ast_event_unsubscribe(mwi_sub);
|
||||
}
|
||||
if (device_state_sub) {
|
||||
ast_event_unsubscribe(device_state_sub);
|
||||
}
|
||||
ast_custom_function_unregister(&jabberreceive_function);
|
||||
|
||||
ast_cond_destroy(&message_received_condition);
|
||||
|
|
Loading…
Reference in New Issue