[xmppd-dev] commit r1541 - in branches/RELEASE-1_6_1: . jabberd jabberd/lib jsm jsm/modules
mail at jabberd.org
mail at jabberd.org
Fri Sep 26 15:14:33 CEST 2008
Author: mawis
Date: Fri Sep 26 15:14:33 2008
New Revision: 1541
Log:
Extended mod_dynamic:
Hosts that are added to or removed again from the server are now persistent across server restarts.
This allows it to keep the list of existing hosts on the jabber server in an SQL server.
Modified:
branches/RELEASE-1_6_1/ChangeLog
branches/RELEASE-1_6_1/jabber.xml.dist.in
branches/RELEASE-1_6_1/jabberd/deliver.cc
branches/RELEASE-1_6_1/jabberd/jabberd.h
branches/RELEASE-1_6_1/jabberd/lib/jabberdlib.h
branches/RELEASE-1_6_1/jabberd/xdb.cc
branches/RELEASE-1_6_1/jsm/jsm.cc
branches/RELEASE-1_6_1/jsm/modules/mod_dynamic.cc
branches/RELEASE-1_6_1/mysql.sql
Modified: branches/RELEASE-1_6_1/ChangeLog
==============================================================================
--- branches/RELEASE-1_6_1/ChangeLog Fri Sep 26 13:46:18 2008 (r1540)
+++ branches/RELEASE-1_6_1/ChangeLog Fri Sep 26 15:14:33 2008 (r1541)
@@ -4,6 +4,9 @@
* jabberd/lib/jabberdlib.h: same
* jabberd/deliver.cc: same
* jabberd/config.cc: logging filters
+ * jsm/modules/mod_dynamic.cc: making dynamic hosts persistent
+ * jsm/jsm.cc: same
+ * jabberd/xdb.cc: same
2008-09-08 Matthias Wimmer <m at tthias.eu>
Modified: branches/RELEASE-1_6_1/jabber.xml.dist.in
==============================================================================
--- branches/RELEASE-1_6_1/jabber.xml.dist.in Fri Sep 26 13:46:18 2008 (r1540)
+++ branches/RELEASE-1_6_1/jabber.xml.dist.in Fri Sep 26 15:14:33 2008 (r1541)
@@ -553,6 +553,7 @@
<namespace prefix='private'>jabber:iq:private</namespace>
<namespace prefix='privacy'>jabber:iq:privacy</namespace>
<namespace prefix='jabberd'>http://jabberd.org/ns/wrapper</namespace>
+ <namespace prefix='dhost'>http://xmppd.org/ns/dynamichost</namespace>
</nsprefixes>
<!-- remove the following line, if you are using a MySQL version -->
<!-- that is older than MySQL 4.1. -->
@@ -589,6 +590,14 @@
<set>INSERT INTO messages (user, realm, node, correspondent, type, storetime, subject, body, xml) VALUES (SUBSTRING('{attribute::to}', 1, INSTR('{attribute::to}', '@')-1), SUBSTRING('{attribute::to}', INSTR('{attribute::to}', '@')+1), IF('{message/attribute::node}'='', NULL, '{message/attribute::node}'), SUBSTRING('{message/attribute::from}/', 1, INSTR('{message/attribute::from}/', '/')-1), 'offline', now(), IF ('{message/subject}'='', NULL, '{message/subject/text()}'), '{message/body/text()}', '{message}')</set>
<delete>DELETE FROM messages WHERE realm=SUBSTRING('{attribute::to}', INSTR('{attribute::to}', '@')+1) AND user=SUBSTRING('{attribute::to}', 1, INSTR('{attribute::to}', '@')-1) AND type='offline' AND IF ('{attribute::matchpath}'='', 1=1, node=SUBSTRING(SUBSTRING('{attribute::matchpath}', 1, LENGTH('{attribute::matchpath}')-2), 16) AND SUBSTRING('{attribute::matchpath}', 1, 14)='message[@node=')</delete>
</handler>
+ <handler ns='http://xmppd.org/ns/dynamichost'>
+ <get>
+ <query>SELECT xml FROM dynamichost WHERE basehost='{attribute::to}' ORDER BY host</query>
+ <result group='foo'><value xmlns='http://jabberd.org/ns/xdbsql' value='1' parsed='parsed'/></result>
+ </get>
+ <set>INSERT INTO dynamichost (basehost, host, xml) VALUES ('{attribute::to}', '{dhost:host/attribute::jid}', '{dhost:host}')</set>
+ <delete>DELETE FROM dynamichost WHERE basehost='{attribute::to}' AND IF ('{attribute::matchpath}'='', 1=1, host=SUBSTRING(SUBSTRING('{attribute::matchpath}', 1, LENGTH('{attribute::matchpath}')-2), 18) AND SUBSTRING('{attribute::matchpath}', 1, 16)='dhost:host[@jid=')</delete>
+ </handler>
<handler ns='http://jabberd.org/ns/history'>
<get>
<query>SELECT xml FROM messages WHERE realm=SUBSTRING('{attribute::to}', INSTR('{attribute::to}', '@')+1) AND user=SUBSTRING('{attribute::to}', 1, INSTR('{attribute::to}', '@')-1) AND type!='offline'</query>
Modified: branches/RELEASE-1_6_1/jabberd/deliver.cc
==============================================================================
--- branches/RELEASE-1_6_1/jabberd/deliver.cc Fri Sep 26 13:46:18 2008 (r1540)
+++ branches/RELEASE-1_6_1/jabberd/deliver.cc Fri Sep 26 15:14:33 2008 (r1541)
@@ -479,7 +479,7 @@
* @param i the instance to register
* @param host the domain to register this instance for (or "*" to register as the default routing)
*/
-void register_instance(instance i, char *host) {
+void register_instance(instance i, char const* host) {
ilist l;
xht ht = NULL;
xht namespaces = NULL;
@@ -527,7 +527,7 @@
* @param i the instance to unregister
* @param host the domain to unregister (or "*" to unregister as the default routing)
*/
-void unregister_instance(instance i, char *host) {
+void unregister_instance(instance i, char const* host) {
ilist l;
xht ht;
register_notifier notify_callback = NULL;
Modified: branches/RELEASE-1_6_1/jabberd/jabberd.h
==============================================================================
--- branches/RELEASE-1_6_1/jabberd/jabberd.h Fri Sep 26 13:46:18 2008 (r1540)
+++ branches/RELEASE-1_6_1/jabberd/jabberd.h Fri Sep 26 15:14:33 2008 (r1541)
@@ -195,8 +195,8 @@
/*** public functions for base modules ***/
void register_config(pool p, const char *node, cfhandler f, void *arg); /* register a function to handle that node in the config file */
-void register_instance(instance i, char *host); /* associate an id with a hostname for that packet type */
-void unregister_instance(instance i, char *host); /* disassociate an id with a hostname for that packet type */
+void register_instance(instance i, char const* host); /* associate an id with a hostname for that packet type */
+void unregister_instance(instance i, char const* host); /* disassociate an id with a hostname for that packet type */
void register_routing_update_callback(instance i, register_notify f, void *arg); /**< register a function that gets called on registering/unregistering a host for an instance */
void register_phandler(instance id, order o, phandler f, void *arg); /* register a function to handle delivery for this instance */
void register_beat(int freq, beathandler f, void *arg); /* register the function to be called from the heartbeat, freq is how often, <= 0 is ignored */
@@ -267,9 +267,9 @@
int id;
const char *ns;
int set; /**< flag that this is a set */
- char *act; /**< for set */
- char *match; /**< for set */
- char *matchpath; /**< for set, namespace aware version of match */
+ char const* act; /**< for set */
+ char const* match; /**< for set */
+ char const* matchpath; /**< for set, namespace aware version of match */
xht namespaces; /**< for set, namespace prefix declarations for matchpath */
xmlnode data; /**< for set */
jid owner;
@@ -283,8 +283,8 @@
xdbcache xdb_cache(instance i); /**< create a new xdb cache for this instance */
xmlnode xdb_get(xdbcache xc, jid owner, const char *ns); /**< blocks until namespace is retrieved, returns xmlnode or NULL if failed */
-int xdb_act(xdbcache xc, jid owner, const char *ns, char *act, char *match, xmlnode data); /**< sends new xml action, returns non-zero if failure */
-int xdb_act_path(xdbcache xc, jid owner, const char *ns, char *act, char *matchpath, xht namespaces, xmlnode data); /**< sends new xml action, returns non-zero if failure */
+int xdb_act(xdbcache xc, jid owner, const char *ns, char const* act, char const* match, xmlnode data); /**< sends new xml action, returns non-zero if failure */
+int xdb_act_path(xdbcache xc, jid owner, const char *ns, char const* act, char const* matchpath, xht namespaces, xmlnode data); /**< sends new xml action, returns non-zero if failure */
int xdb_set(xdbcache xc, jid owner, const char *ns, xmlnode data); /**< sends new xml to replace old, returns non-zero if failure */
/* Error messages */
Modified: branches/RELEASE-1_6_1/jabberd/lib/jabberdlib.h
==============================================================================
--- branches/RELEASE-1_6_1/jabberd/lib/jabberdlib.h Fri Sep 26 13:46:18 2008 (r1540)
+++ branches/RELEASE-1_6_1/jabberd/lib/jabberdlib.h Fri Sep 26 15:14:33 2008 (r1541)
@@ -978,6 +978,7 @@
#define NS_JABBERD_CONFIG_JSM "jabber:config:jsm" /**< namespace of the jsm component configuration */
#define NS_JABBERD_CONFIG_PTHCSOCK "jabber:config:pth-csock" /**< namespace of the pthsock_client component configuration */
#define NS_JABBERD_CONFIG_XDBSQL "jabber:config:xdb_sql" /**< namepace of the xdb_sql component configuration */
+#define NS_JABBERD_CONFIG_DYNAMICHOST "http://xmppd.org/ns/dynamichost" /**< namespace of the dynamic configuration of additional hosts for components */
/* --------------------------------------------------------- */
/* */
Modified: branches/RELEASE-1_6_1/jabberd/xdb.cc
==============================================================================
--- branches/RELEASE-1_6_1/jabberd/xdb.cc Fri Sep 26 13:46:18 2008 (r1540)
+++ branches/RELEASE-1_6_1/jabberd/xdb.cc Fri Sep 26 15:14:33 2008 (r1541)
@@ -280,7 +280,7 @@
/* act must be NULL, "check", or "insert" for now, insert will either blindly insert data into the parent (creating one if needed) or use match */
/* match will find a child in the parent, and either replace (if it's an insert) or remove (if data is NULL) */
/* XXX for the check action, read the comment in xdb_file/xdb_file.c, it might be buggy and not needed anyway */
-static int _xdb_act(xdbcache xc, jid owner, const char *ns, char *act, char *match, char *matchpath, xht namespaces, xmlnode data) {
+static int _xdb_act(xdbcache xc, jid owner, const char *ns, char const* act, char const* match, char const* matchpath, xht namespaces, xmlnode data) {
_xdbcache newx;
if (xc == NULL || owner == NULL || ns == NULL) {
@@ -332,11 +332,11 @@
return 0;
}
-int xdb_act(xdbcache xc, jid owner, const char *ns, char *act, char *match, xmlnode data) {
+int xdb_act(xdbcache xc, jid owner, const char *ns, char const* act, char const* match, xmlnode data) {
return _xdb_act(xc, owner, ns, act, match, NULL, NULL, data);
}
-int xdb_act_path(xdbcache xc, jid owner, const char *ns, char *act, char *matchpath, xht namespaces, xmlnode data) {
+int xdb_act_path(xdbcache xc, jid owner, const char *ns, char const* act, char const* matchpath, xht namespaces, xmlnode data) {
return _xdb_act(xc, owner, ns, act, NULL, matchpath, namespaces, data);
}
Modified: branches/RELEASE-1_6_1/jsm/jsm.cc
==============================================================================
--- branches/RELEASE-1_6_1/jsm/jsm.cc Fri Sep 26 13:46:18 2008 (r1540)
+++ branches/RELEASE-1_6_1/jsm/jsm.cc Fri Sep 26 15:14:33 2008 (r1541)
@@ -201,6 +201,7 @@
xhash_put(si->std_namespace_prefixes, "jabberd", const_cast<char*>(NS_JABBERD_WRAPPER));
xhash_put(si->std_namespace_prefixes, "cmd", const_cast<char*>(NS_COMMAND));
xhash_put(si->std_namespace_prefixes, "data", const_cast<char*>(NS_DATA));
+ xhash_put(si->std_namespace_prefixes, "dhost", const_cast<char*>(NS_JABBERD_CONFIG_DYNAMICHOST));
si->xc = xdb_cache(i); /* getting xdb_* handle and fetching config */
config = js_config(si, NULL, NULL);
si->hosts = xhash_new(j_atoi(xmlnode_get_data(xmlnode_get_list_item(xmlnode_get_tags(config, "jsm:maxhosts", si->std_namespace_prefixes), 0)), HOSTS_PRIME));
Modified: branches/RELEASE-1_6_1/jsm/modules/mod_dynamic.cc
==============================================================================
--- branches/RELEASE-1_6_1/jsm/modules/mod_dynamic.cc Fri Sep 26 13:46:18 2008 (r1540)
+++ branches/RELEASE-1_6_1/jsm/modules/mod_dynamic.cc Fri Sep 26 15:14:33 2008 (r1541)
@@ -30,9 +30,6 @@
*
* With this module an administrator can dynamically add or remove hosts from
* the session manager without the need to restart the instance.
- * But the chances made by this module are not presistant. To get them persistant,
- * you have to add them as well to the configuration file, so the new hosts get
- * (not) configured after a restart. (At least for now.)
*/
static mreturn mod_dynamic_server_disco_items(mapi m) {
@@ -140,9 +137,10 @@
* handle our server commands
*
* @param m the ::mapi_struct that contains the request
+ * @param config_jid the jid where dynamically hosts are stored to
* @return signalling if this method processed the request
*/
-static mreturn mod_dynamic_server_command(mapi m) {
+static mreturn mod_dynamic_server_command(mapi m, jid config_jid) {
// we only handle set requests
if (jpacket_subtype(m->packet) != JPACKET__SET)
return M_PASS;
@@ -252,18 +250,31 @@
} else {
xmlnode_put_attrib_ns(note, "type", NULL, NULL, "info");
+ std::ostringstream replace_path;
+ replace_path << "dhost:host[@jid='" << preped_hostname->server << "']";
+
// execute
+ xmlnode newhost = NULL;
switch (given_command) {
case host:
xmlnode_insert_cdata(note, messages_get(xmlnode_get_lang(m->packet->x), N_("Hostname has been added.")), -1);
log_debug2(ZONE, LOGT_DYNAMIC, "registering hostname %s on server %s", preped_hostname->server, m->si->i->id);
register_instance(m->si->i, preped_hostname->server);
+
+ // store in xdb
+ newhost = xmlnode_new_tag_ns("host", NULL, NS_JABBERD_CONFIG_DYNAMICHOST);
+ xmlnode_put_attrib_ns(newhost, "jid", NULL, NULL, preped_hostname->server);
+ xdb_act_path(m->si->xc, config_jid, NS_JABBERD_CONFIG_DYNAMICHOST, "insert", replace_path.str().c_str(), m->si->std_namespace_prefixes, newhost);
+ xmlnode_free(newhost);
break;
case unhost:
// XXX kick existing sessions and remove local data about this domain
xmlnode_insert_cdata(note, messages_get(xmlnode_get_lang(m->packet->x), N_("Hostname has been removed.")), -1);
log_debug2(ZONE, LOGT_DYNAMIC, "unregistering hostname %s on server %s", preped_hostname->server, m->si->i->id);
unregister_instance(m->si->i, preped_hostname->server);
+
+ // remove in xdb
+ xdb_act_path(m->si->xc, config_jid, NS_JABBERD_CONFIG_DYNAMICHOST, "insert", replace_path.str().c_str(), m->si->std_namespace_prefixes, NULL);
break;
}
}
@@ -296,12 +307,12 @@
* handle requests to add or remove hosts from the server
*
* @param m the ::mapi_struct that contains the request to handle
- * @param arg unused/ignored
+ * @param arg jid used for xdb access
* @return signalling if this method processed the request
*/
static mreturn mod_dynamic_server(mapi m, void *arg) {
/* sanity check */
- if (m == NULL || m->packet == NULL)
+ if (m == NULL || m->packet == NULL || !arg)
return M_PASS;
/* only handle iqs */
@@ -315,16 +326,44 @@
return mod_dynamic_server_disco_items(m);
if (NSCHECK(m->packet->iq, NS_COMMAND))
- return mod_dynamic_server_command(m);
+ return mod_dynamic_server_command(m, static_cast<jid>(arg));
return M_PASS;
}
/**
- * init the module, register callbacks
+ * init the module, register callbacks, load persisted hosts
*
* @param si the session manager instance
*/
extern "C" void mod_dynamic(jsmi si) {
- js_mapi_register(si, e_SERVER, mod_dynamic_server, NULL);
+ jid config_jid = jid_new(si->p, si->i->id);
+
+ js_mapi_register(si, e_SERVER, mod_dynamic_server, config_jid);
+
+ // get additional hostnames of the session manager, that have been dynamically added
+ xmlnode dynhosts = xdb_get(si->xc, config_jid, NS_JABBERD_CONFIG_DYNAMICHOST);
+ for (xmlnode iter = xmlnode_get_firstchild(dynhosts); iter; iter = xmlnode_get_nextsibling(iter)) {
+ // skip what we do not care about
+ if (xmlnode_get_type(iter) != NTYPE_TAG) {
+ continue;
+ }
+ if (j_strcmp(xmlnode_get_namespace(iter), NS_JABBERD_CONFIG_DYNAMICHOST)) {
+ continue;
+ }
+ if (j_strcmp(xmlnode_get_localname(iter), "host")) {
+ continue;
+ }
+
+ char const* dynhost = xmlnode_get_attrib_ns(iter, "jid", NULL);
+ if (!dynhost) {
+ log_notice(si->i->id, "ignoring empty dynamic host in configuration: %s", xmlnode_serialize_string(iter, xmppd::ns_decl_list(), 0));
+ continue;
+ }
+
+ // actually register the hostname
+ log_notice(si->i->id, "loading dynamic host: %s", dynhost);
+ register_instance(si->i, dynhost);
+ }
+ xmlnode_free(dynhosts);
}
Modified: branches/RELEASE-1_6_1/mysql.sql
==============================================================================
--- branches/RELEASE-1_6_1/mysql.sql Fri Sep 26 13:46:18 2008 (r1540)
+++ branches/RELEASE-1_6_1/mysql.sql Fri Sep 26 15:14:33 2008 (r1541)
@@ -180,6 +180,14 @@
`xml` longtext,
UNIQUE KEY `jid` (`realm`(16),`user`(16))
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- DROP TABLE IF EXISTS `dynamichost`;
+CREATE TABLE `dynamichost` (
+ `basehost` tinytext NOT NULL,
+ `host` text NOT NULL,
+ `xml` longtext NOT NULL,
+ KEY `bhost` (`basehost`(16))
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
More information about the dev
mailing list