Don't match in the disco callbacks hashtable on remote JID. Use IQ id instead.

Tue, 31 Mar 2009 06:43:54 +0000

author
Paul Aurich <darkrain42@pidgin.im>
date
Tue, 31 Mar 2009 06:43:54 +0000
changeset 26593
338e4056ac4c
parent 26592
2ffecd246bfb
child 26594
73f09a0501f4

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.

libpurple/protocols/jabber/disco.c file | annotate | diff | comparison | revisions
--- 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);
 }
 

mercurial