Index: include/asterisk/jabber.h
===================================================================
--- include/asterisk/jabber.h	(revision 67714)
+++ include/asterisk/jabber.h	(working copy)
@@ -24,7 +24,8 @@
 #include "asterisk/linkedlists.h"
 
 enum aji_state {
-	AJI_DISCONNECTED = 0,
+	AJI_DISCONNECTING = 0,
+	AJI_DISCONNECTED,
 	AJI_CONNECTING,
 	AJI_CONNECTED
 };
Index: res/res_jabber.c
===================================================================
--- res/res_jabber.c	(revision 67714)
+++ res/res_jabber.c	(working copy)
@@ -54,6 +54,10 @@
 #include "asterisk/manager.h"
 
 #define JABBER_CONFIG "jabber.conf"
+     
+/*! \brief Needed to handle the timeout global variable in the iksemel 
+  library */
+AST_MUTEX_DEFINE_STATIC(timeoutlock);
 
 /*-- Forward declarations */
 static int aji_highest_bit(int number);
@@ -62,6 +66,7 @@
 static int aji_send_exec(struct ast_channel *chan, void *data);
 static int aji_status_exec(struct ast_channel *chan, void *data);
 static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incoming);
+static int aji_iks_recv (iksparser *p, int timeout);
 static int aji_act_hook(void *data, int type, iks *node);
 static void aji_handle_iq(struct aji_client *client, iks *node);
 static void aji_handle_message(struct aji_client *client, ikspak *pak);
@@ -465,6 +470,31 @@
 }
 
 /*!
+ * \brief Wrapper function for iks_recv.
+ *
+ * This function locks the client structure, waits for data on the socket,
+ * and returns upon data reception or timeout expiration.
+ * Locking is needed because of the modification of the global timeout 
+ * variable in the iksemel library, introduced because of the lack of timeout
+ * handling in gnutls. See http://bugs.digium.com/view.php?id=9738
+ *
+ * \param p an iksemel parser, int the timeout value.
+ * \return the value returned by iks_recv.
+ */
+static int aji_iks_recv (iksparser *p, int timeout)
+{
+	int res;	
+	
+	/* Locking needed if we want to properly set the timeout in case of
+	   a TLS connection */
+	ast_mutex_lock(&timeoutlock);
+	res = iks_recv(p, timeout);
+	ast_mutex_unlock(&timeoutlock);
+	
+	return res;
+}
+
+/*!
  * \brief The action hook parses the inbound packets, constantly running.
  * \param aji client structure, type of packet, the actual packet.
  * \return IKS_OK or IKS_HOOK .
@@ -481,6 +511,12 @@
 		return IKS_HOOK;
 	}
 
+	if (client->state == AJI_DISCONNECTING) {
+		ast_log(LOG_NOTICE, "Disconnecting\n");
+		ASTOBJ_UNREF(client, aji_client_destroy);
+		return IKS_HOOK;
+	}
+
 	pak = iks_packet(node);
 
 	if (!client->component) { /*client */
@@ -611,7 +647,7 @@
 					handshake = NULL;
 				}
 				client->state = AJI_CONNECTING;
-				if(iks_recv(client->p,1) == 2) /*XXX proper result for iksemel library on iks_recv of <handshake/> XXX*/
+				if(aji_iks_recv(client->p,1) == 2) /*XXX proper result for iksemel library on iks_recv of <handshake/> XXX*/
 					client->state = AJI_CONNECTED;
 				else
 					ast_log(LOG_WARNING,"Jabber didn't seem to handshake, failed to authenicate.\n");
@@ -1504,7 +1540,14 @@
 			}
 		}
 
-		res = iks_recv(client->p, 1);
+		res = aji_iks_recv(client->p, 1);
+
+		if (client->state == AJI_DISCONNECTING) {
+			if (option_debug)
+				ast_log(LOG_DEBUG, "Ending our Jabber client's thread\n");
+			pthread_exit(NULL);
+		}
+
 		client->timeout--;
 		if (res == IKS_HOOK) 
 			ast_log(LOG_WARNING, "JABBER: Got hook event.\n");
@@ -1838,7 +1881,7 @@
 		ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to  %s\n", client->name, S_OR(client->serverhost, client->jid->server));
 		return IKS_HOOK;
 	} else
-		iks_recv(client->p, 30);
+		aji_iks_recv(client->p, 30);
 	return IKS_OK;
 }
 
@@ -1858,8 +1901,9 @@
 	} else if (connected == IKS_NET_NODNS) {
 		ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to  %s\n", client->name, S_OR(client->serverhost, client->jid->server));
 		return IKS_HOOK;
-	} else if (!connected) 
-		iks_recv(client->p, 30);
+	} else if (!connected)
+		aji_iks_recv(client->p, 30);
+
 	return IKS_OK;
 }
 
@@ -2402,7 +2446,7 @@
 		ASTOBJ_RDLOCK(iterator);
 		if (option_verbose > 2)
 			ast_verbose(VERBOSE_PREFIX_3 "JABBER: %s\n", iterator->name);
-		iterator->state = AJI_DISCONNECTED;
+		iterator->state = AJI_DISCONNECTING;
 		ast_aji_disconnect(iterator);
 		pthread_join(iterator->thread, NULL);
 		ASTOBJ_UNLOCK(iterator);
