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;
}