[xmppd-dev] commit r1531 - in trunk/jabberd14: . jabberd jabberd/base jabberd/lib jsm/modules

mail at jabberd.org mail at jabberd.org
Sun Sep 7 17:37:11 CEST 2008


Author: mawis
Date: Sun Sep  7 17:33:12 2008
New Revision: 1531

Log:
Fixing problem with dynamic routing: domains got unregistered on process shutdown, but not reregistered after reconnect of new process
Fixing problem with UTF-8 handling in JabberIDs: Glib::ustring has to much logic when being written to a stream, cast to std::string
Started working on duplicate item on roster problem: new code produces duplicate entries on roster, this to filter already existing dupes when loading xdb

Modified:
   trunk/jabberd14/ChangeLog
   trunk/jabberd14/jabberd/base/base_accept.cc
   trunk/jabberd14/jabberd/base/base_connect.cc
   trunk/jabberd14/jabberd/deliver.cc
   trunk/jabberd14/jabberd/jabberd.h
   trunk/jabberd14/jabberd/lib/jabberid.cc
   trunk/jabberd14/jsm/modules/mod_roster.cc

Modified: trunk/jabberd14/ChangeLog
==============================================================================
--- trunk/jabberd14/ChangeLog	Fri Jul  4 01:44:32 2008	(r1530)
+++ trunk/jabberd14/ChangeLog	Sun Sep  7 17:33:12 2008	(r1531)
@@ -1,3 +1,12 @@
+2008-09-07  Matthias Wimmer  <m at tthias.eu>
+
+    * jabberd/lib/jabberid.cc: fix UTF-8 handling in JabberIDs
+    * jsm/modules/mod_roster.cc: start fixing duplicate roster item problem
+    * jabberd/jabberd.h: fixing problem with dynamic routing
+    * jabberd/base/base_connect.cc: same
+    * jabberd/base/base_accept.cc: same
+    * jabberd/deliver.cc: same
+
 2008-05-05  Matthias Wimmer  <m at tthias.eu>
 
     * jabberd/mio_tls.cc: patch by Martin Matuschka to support newer GnuTLS

Modified: trunk/jabberd14/jabberd/base/base_accept.cc
==============================================================================
--- trunk/jabberd14/jabberd/base/base_accept.cc	Fri Jul  4 01:44:32 2008	(r1530)
+++ trunk/jabberd14/jabberd/base/base_accept.cc	Sun Sep  7 17:33:12 2008	(r1531)
@@ -195,6 +195,22 @@
             }
             ai->q = NULL;
 
+	    // if we are configured as uplink, request the routings to the other instances of this process from our peer process
+	    if (deliver_is_uplink(ai->i)) {
+		std::set<Glib::ustring> hosts_to_route = deliver_routed_hosts(p_NORM, ai->i);
+
+		for (std::set<Glib::ustring>::const_iterator p = hosts_to_route.begin(); p != hosts_to_route.end(); ++p) {
+		    log_debug2(ZONE, LOGT_DYNAMIC, "base_accept is uplink. Sending routing request: %s", p->c_str());
+		    xmlnode route_stanza = xmlnode_new_tag_ns("xdb", NULL, NS_SERVER);
+		    xmlnode_put_attrib_ns(route_stanza, "ns", NULL, NULL, "");
+		    xmlnode_put_attrib_ns(route_stanza, "from", NULL, NULL, ai->i->id);
+		    jid magic_jid = jid_new(xmlnode_pool(route_stanza), "host at -internal");
+		    jid_set(magic_jid, p->c_str(), JID_RESOURCE);
+		    xmlnode_put_attrib_ns(route_stanza, "to", NULL, NULL, jid_full(magic_jid));
+		    mio_write(m, route_stanza, NULL, 0);
+		}
+	    }
+
             break;
 
         case MIO_ERROR:

Modified: trunk/jabberd14/jabberd/base/base_connect.cc
==============================================================================
--- trunk/jabberd14/jabberd/base/base_connect.cc	Fri Jul  4 01:44:32 2008	(r1530)
+++ trunk/jabberd14/jabberd/base/base_connect.cc	Sun Sep  7 17:33:12 2008	(r1531)
@@ -188,6 +188,22 @@
                     mio_write(ci->io, b->packet->x, NULL, 0);
                 /* Update connection state flag */
                 ci->state = conn_AUTHD;
+
+		// if we are configured as uplink, request the routings to the other instances of this process from our peer process
+		if (deliver_is_uplink(ci->inst)) {
+		    std::set<Glib::ustring> hosts_to_route = deliver_routed_hosts(p_NORM, ci->inst);
+
+		    for (std::set<Glib::ustring>::const_iterator p = hosts_to_route.begin(); p != hosts_to_route.end(); ++p) {
+			log_debug2(ZONE, LOGT_DYNAMIC, "base_connect is uplink. Sending routing request: %s", p->c_str());
+			xmlnode route_stanza = xmlnode_new_tag_ns("xdb", NULL, NS_SERVER);
+			xmlnode_put_attrib_ns(route_stanza, "ns", NULL, NULL, "");
+			xmlnode_put_attrib_ns(route_stanza, "from", NULL, NULL, ci->inst->id);
+			jid magic_jid = jid_new(xmlnode_pool(route_stanza), "host at -internal");
+			jid_set(magic_jid, p->c_str(), JID_RESOURCE);
+			xmlnode_put_attrib_ns(route_stanza, "to", NULL, NULL, jid_full(magic_jid));
+			mio_write(ci->io, route_stanza, NULL, 0);
+		    }
+		}
             }
             xmlnode_free(x);
             return;

Modified: trunk/jabberd14/jabberd/deliver.cc
==============================================================================
--- trunk/jabberd14/jabberd/deliver.cc	Fri Jul  4 01:44:32 2008	(r1530)
+++ trunk/jabberd14/jabberd/deliver.cc	Sun Sep  7 17:33:12 2008	(r1531)
@@ -217,18 +217,84 @@
  * @return the correct hashtable used for the routing of this stanza type
  */
 static xht deliver_hashtable(ptype type) {
-    switch(type)
-    {
-    case p_LOG:
-        return deliver__hlog;
-    case p_XDB:
-        return deliver__hxdb;
-    default:
-        return deliver__hnorm;
+    switch(type) {
+	case p_LOG:
+	    return deliver__hlog;
+	case p_XDB:
+	    return deliver__hxdb;
+	default:
+	    return deliver__hnorm;
     }
 }
 
 /**
+ * arguments for the deliver_routed_hosts_walk xhash walker function
+ */
+struct deliver_routed_hosts_walk_args {
+    std::set<Glib::ustring>*	result;	/**< where to place the results */
+    instance			i;	/**< the instance to exclude */
+};
+
+/**
+ * helper function that walks a deliver hash to check for which domains explicit routings exist
+ *
+ * @param h the xhash to walk
+ * @param key the currently processed host
+ * @param value the instances responsible for this host
+ * @param arg arguments provided by the user of this walker
+ */
+static void deliver_routed_hosts_walk(xht h, char const* key, void* value, void* arg) {
+    // sanity checks
+    if (!h || !key || !value || !arg) {
+	return;
+    }
+
+    // restore types of void* params
+    deliver_routed_hosts_walk_args* args = static_cast<deliver_routed_hosts_walk_args*>(arg);
+    ilist instances = static_cast<ilist>(value);
+
+    // check if some other instance than args->i is responsible for this host
+    bool do_include = false;
+    for (ilist cur = instances; cur; cur = cur->next) {
+	if (cur->i != args->i) {
+	    do_include = true;
+	}
+    }
+
+    // include in result
+    if (do_include) {
+	args->result->insert(key);
+    }
+}
+
+/**
+ * get list of hosts with explicit routing
+ *
+ * @param type the type to get the routing for
+ * @param i the instance to exclude from the result (NULL for not excluding any instance)
+ * @return list of the hosts that have explicit routings to other components than i for the given type
+ */
+std::set<Glib::ustring> deliver_routed_hosts(ptype type, instance i) {
+    std::set<Glib::ustring> result;
+
+    // get the correct table
+    xht deliver_table = deliver_hashtable(type);
+
+    // create walker params
+    deliver_routed_hosts_walk_args* args = new deliver_routed_hosts_walk_args();
+    args->result = &result;
+    args->i = i;
+
+    // walk the table
+    xhash_walk(deliver_table, deliver_routed_hosts_walk, args);
+
+    // destroy arguments struct
+    delete args;
+
+    return result;
+}
+
+/**
  * utility to find the right ilist in the hashtable
  *
  * @param ht the hashtable for the routing of a stanzatype

Modified: trunk/jabberd14/jabberd/jabberd.h
==============================================================================
--- trunk/jabberd14/jabberd/jabberd.h	Fri Jul  4 01:44:32 2008	(r1530)
+++ trunk/jabberd14/jabberd/jabberd.h	Sun Sep  7 17:33:12 2008	(r1531)
@@ -210,6 +210,7 @@
 void deliver_instance(instance i, dpacket p); /* deliver packet TO the instance, if the result != r_DONE, you have to handle the packet! */
 instance deliver_hostcheck(char const* host); /* util that returns the instance handling this hostname for normal packets */
 bool deliver_is_uplink(instance i); // checks if an instance is configured to be the uplink
+std::set<Glib::ustring> deliver_routed_hosts(ptype type, instance i);
 
 /*** global logging/signal symbols ***/
 #define LOGT_LEGACY 1

Modified: trunk/jabberd14/jabberd/lib/jabberid.cc
==============================================================================
--- trunk/jabberd14/jabberd/lib/jabberid.cc	Fri Jul  4 01:44:32 2008	(r1530)
+++ trunk/jabberd14/jabberd/lib/jabberid.cc	Sun Sep  7 17:33:12 2008	(r1531)
@@ -281,11 +281,11 @@
     Glib::ustring jabberid::full() {
 	std::ostringstream result;
 	if (node.size() > 0) {
-	    result << node << "@";
+	    result << std::string(node) << "@";
 	}
-	result << domain;
+	result << std::string(domain);
 	if (resource.size() > 0) {
-	    result << "/" << resource;
+	    result << "/" << std::string(resource);
 	}
 
 	return result.str();

Modified: trunk/jabberd14/jsm/modules/mod_roster.cc
==============================================================================
--- trunk/jabberd14/jsm/modules/mod_roster.cc	Fri Jul  4 01:44:32 2008	(r1530)
+++ trunk/jabberd14/jsm/modules/mod_roster.cc	Sun Sep  7 17:33:12 2008	(r1531)
@@ -43,7 +43,7 @@
  * @param u for which user we want to get the roster
  * @return the user's roster
  */
-static xmlnode mod_roster_get(udata u) {
+static xmlnode mod_roster_get(mapi m, udata u) {
     xmlnode ret;
 
     log_debug2(ZONE, LOGT_ROSTER, "getting %s's roster", u->id->get_node().c_str());
@@ -56,6 +56,34 @@
         ret = xmlnode_new_tag_ns("query", NULL, NS_ROSTER);
     }
 
+    // check for duplicate items on the roster
+    bool removed_duplicate = false;
+    std::set<Glib::ustring> seen_jids;
+    xmlnode_vector items = xmlnode_get_tags(ret, "roster:item", m->si->std_namespace_prefixes);
+    for (xmlnode_vector::iterator p = items.begin(); p != items.end(); ++p) {
+	const char* item_jid = xmlnode_get_attrib(*p, "jid");
+	log_debug2(ZONE, LOGT_ROSTER, "has item: %s", item_jid);
+
+	// does the item have a JID?
+	if (!item_jid) {
+	    log_debug2(ZONE, LOGT_ROSTER, "removing this item, that has no JID");
+	    removed_duplicate = true;
+	    xmlnode_hide(*p);
+	    continue;
+	}
+
+	Glib::ustring item_jid_string = item_jid;
+	if (seen_jids.find(item_jid_string) == seen_jids.end()) {
+	    // new JID
+	    seen_jids.insert(item_jid_string);
+	} else {
+	    // duplicate JID
+	    removed_duplicate = true;
+	    xmlnode_hide(*p);
+	    log_debug2(ZONE, LOGT_ROSTER, "DUPLICATE ... removing");
+	}
+    }
+
     return ret;
 }
 
@@ -190,7 +218,7 @@
     log_debug2(ZONE, LOGT_ROSTER, "handling outgoing s10n");
 
     /* get the roster item */
-    roster = mod_roster_get(m->user);
+    roster = mod_roster_get(m, m->user);
     item = mod_roster_get_item(m, roster, m->packet->to, &newflag);
 
     /* vars containing the old subscription state */
@@ -338,7 +366,7 @@
 
     if (!NSCHECK(m->packet->iq,NS_ROSTER)) return M_PASS;
 
-    roster = mod_roster_get(m->user);
+    roster = mod_roster_get(m, m->user);
 
     switch(jpacket_subtype(m->packet)) {
 	case JPACKET__GET:
@@ -517,7 +545,7 @@
     if (jid_cmpx(m->packet->from, m->packet->to, JID_USER|JID_SERVER) == 0) return M_PASS; /* vanity complex */
 
     /* now we can get to work and handle this user's incoming subscription crap */
-    roster = mod_roster_get(m->user);
+    roster = mod_roster_get(m, m->user);
     item = mod_roster_get_item(m, roster, m->packet->from, &newflag);
     reply2 = reply = NULL;
     jid_set(m->packet->to, NULL, JID_RESOURCE); /* make sure we're only dealing w/ the user id */


More information about the dev mailing list