changeset 26257:ce23e32a0ada

Don't match in the disco callbacks hashtable on remote JID. Use IQ id instead. This won't break if there are concurrent disco queries out to a remote node.
author Paul Aurich <paul@darkrain42.org>
date Tue, 31 Mar 2009 06:43:54 +0000
parents cda9031ecabc
children b5fe3f47487b
files libpurple/protocols/jabber/disco.c
diffstat 1 files changed, 11 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/disco.c	Tue Mar 31 05:40:13 2009 +0000
+++ b/libpurple/protocols/jabber/disco.c	Tue Mar 31 06:43:54 2009 +0000
@@ -98,6 +98,7 @@
 void jabber_disco_info_parse(JabberStream *js, xmlnode *packet) {
 	const char *from = xmlnode_get_attrib(packet, "from");
 	const char *type = xmlnode_get_attrib(packet, "type");
+	const char *id   = xmlnode_get_attrib(packet, "id");
 
 	if(!from || !type)
 		return;
@@ -117,7 +118,7 @@
 		iq = jabber_iq_new_query(js, JABBER_IQ_RESULT,
 				"http://jabber.org/protocol/disco#info");
 
-		jabber_iq_set_id(iq, xmlnode_get_attrib(packet, "id"));
+		jabber_iq_set_id(iq, id);
 
 		xmlnode_set_attrib(iq->node, "to", from);
 		query = xmlnode_get_child(iq->node, "query");
@@ -295,9 +296,9 @@
 		if(jbr)
 			jbr->capabilities = capabilities;
 
-		if((jdicd = g_hash_table_lookup(js->disco_callbacks, from))) {
+		if((jdicd = g_hash_table_lookup(js->disco_callbacks, id))) {
 			jdicd->callback(js, from, capabilities, jdicd->data);
-			g_hash_table_remove(js->disco_callbacks, from);
+			g_hash_table_remove(js->disco_callbacks, id);
 		}
 	} else if(!strcmp(type, "error")) {
 		JabberID *jid;
@@ -306,7 +307,7 @@
 		JabberCapabilities capabilities = JABBER_CAP_NONE;
 		struct _jabber_disco_info_cb_data *jdicd;
 
-		if(!(jdicd = g_hash_table_lookup(js->disco_callbacks, from)))
+		if(!(jdicd = g_hash_table_lookup(js->disco_callbacks, id)))
 			return;
 
 		if((jid = jabber_id_new(from))) {
@@ -319,7 +320,7 @@
 			capabilities = jbr->capabilities;
 
 		jdicd->callback(js, from, capabilities, jdicd->data);
-		g_hash_table_remove(js->disco_callbacks, from);
+		g_hash_table_remove(js->disco_callbacks, id);
 	}
 }
 
@@ -552,6 +553,7 @@
 	JabberBuddy *jb;
 	JabberBuddyResource *jbr = NULL;
 	struct _jabber_disco_info_cb_data *jdicd;
+	const char *id;
 	JabberIq *iq;
 
 	if((jid = jabber_id_new(who))) {
@@ -569,11 +571,13 @@
 	jdicd->data = data;
 	jdicd->callback = callback;
 
-	g_hash_table_insert(js->disco_callbacks, g_strdup(who), jdicd);
-
 	iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info");
 	xmlnode_set_attrib(iq->node, "to", who);
 
+	id = jabber_get_next_id(js);
+	jabber_iq_set_id(iq, id);
+	g_hash_table_insert(js->disco_callbacks, id, jdicd);
+
 	jabber_iq_send(iq);
 }