Index: res/res_jabber.c =================================================================== --- res/res_jabber.c (revision 338373) +++ res/res_jabber.c (working copy) @@ -297,6 +297,7 @@ static int aji_io_recv(struct aji_client *client, char *buffer, size_t buf_len, int timeout); static int aji_recv(struct aji_client *client, int timeout); static int aji_send_header(struct aji_client *client, const char *to); +static int aji_send_raw_full(struct aji_client *client, const char *xmlstr, int keep_alive); static int aji_send_raw(struct aji_client *client, const char *xmlstr); static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incoming); static int aji_start_sasl(struct aji_client *client, enum ikssasltype type, char *username, char *pass); @@ -1431,8 +1432,10 @@ case IKS_NOMEM: ast_log(LOG_WARNING, "Parsing failure: Out of memory.\n"); break; - case IKS_BADXML: - ast_log(LOG_WARNING, "Parsing failure: Invalid XML.\n"); + case IKS_BADXML: /* Empty element is valid when connecting as component to XMPP, so absorb this*/ + if (!(client->component && client->state == AJI_CONNECTING)) { + ast_log(LOG_WARNING, "Parsing failure: Invalid XML.\n"); + } break; case IKS_HOOK: ast_log(LOG_WARNING, "Parsing failure: Hook returned an error.\n"); @@ -1495,6 +1498,11 @@ */ static int aji_send_raw(struct aji_client *client, const char *xmlstr) { + return aji_send_raw_full(client, xmlstr, 0); +} + +static int aji_send_raw_full(struct aji_client *client, const char *xmlstr, int keep_alive) +{ int ret; #ifdef HAVE_OPENSSL int len = strlen(xmlstr); @@ -1511,11 +1519,9 @@ #endif /* If needed, data will be sent unencrypted, and logHook will be called inside iks_send_raw */ - if((client->timeout != 0 && client->state == AJI_CONNECTED) || (client->state == AJI_CONNECTING)) - { + if (keep_alive || (client->timeout != 0 && client->state == AJI_CONNECTED) || (client->state == AJI_CONNECTING)) { ret = iks_send_raw(client->p, xmlstr); - } - else { + } else { ast_log(LOG_WARNING, "JABBER: Unable to send message to %s, we are not connected", client->name); return -1; } @@ -1748,6 +1754,7 @@ ast_log(LOG_ERROR, "JABBER: encryption failure. possible bad password.\n"); } else if (!strcmp("success", iks_name(node))) { client->authorized = 1; + client->state = AJI_CONNECTED; aji_send_header(client, client->jid->server); } break; @@ -1765,7 +1772,7 @@ } else if (client->state != AJI_CONNECTED && client->component) { switch (type) { case IKS_NODE_START: - if (client->state == AJI_DISCONNECTED) { + if (client->state == AJI_CONNECTING) { char secret[160], shasum[320], *handshake; sprintf(secret, "%s%s", pak->id, client->password); @@ -1776,12 +1783,16 @@ ast_free(handshake); handshake = NULL; } - client->state = AJI_CONNECTING; - if (aji_recv(client, 1) == 2) /*XXX proper result for iksemel library on iks_recv of XXX*/ + + /* Upon successful authentication, the server will send empty handshake element, "", + which is proper, but iksemel returns IKS_BADXML; so check for this return code and + indicate we are connected; this probably should be improved upon */ + if (aji_recv(client, 1) == IKS_BADXML) { client->state = AJI_CONNECTED; - else + } else { ast_log(LOG_WARNING, "Jabber didn't seem to handshake, failed to authenticate.\n"); - break; + client->state = AJI_DISCONNECTED; + } } break; @@ -2818,7 +2829,7 @@ } else if (res == IKS_NET_TLSFAIL) { ast_log(LOG_ERROR, "JABBER: Failure in TLS.\n"); } else if (client->timeout == 0 && client->state == AJI_CONNECTED) { - res = client->keepalive ? aji_send_raw(client, " ") : IKS_OK; + res = client->keepalive ? aji_send_raw_full(client, " ", 1) : IKS_OK; if (res == IKS_OK) { client->timeout = 50; } else { @@ -3191,6 +3202,8 @@ return IKS_HOOK; } + client->state = AJI_CONNECTING; + return IKS_OK; }