[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