From 3243f13045cc3d541392afbab65235bf7d77b979 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 11 Feb 2009 17:56:42 +0500 Subject: Component-host module loading code was breaking module reload, andduplicated older code. Changed to reuse older code. --- core/componentmanager.lua | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/core/componentmanager.lua b/core/componentmanager.lua index 0d61bbb1..04909a07 100644 --- a/core/componentmanager.lua +++ b/core/componentmanager.lua @@ -27,21 +27,13 @@ function load_enabled_components(config) for host, host_config in pairs(defined_hosts) do if host ~= "*" and ((host_config.core.enabled == nil or host_config.core.enabled) and type(host_config.core.component_module) == "string") then - hosts[host] = { type = "component", host = host, connected = true, s2sout = {} }; - modulemanager.load(host, "dialback"); + hosts[host] = { type = "component", host = host, connected = false, s2sout = {} }; local ok, err = modulemanager.load(host, host_config.core.component_module); if not ok then log("error", "Error loading %s component %s: %s", tostring(host_config.core.component_module), tostring(host), tostring(err)); else log("info", "Activated %s component: %s", host_config.core.component_module, host); end - - local ok, component_handler = modulemanager.call_module_method(modulemanager.get_module(host, host_config.core.component_module), "load_component"); - if not ok then - log("error", "Error loading %s component %s: %s", tostring(host_config.core.component_module), tostring(host), tostring(component_handler)); - else - components[host] = component_handler; - end end end end @@ -63,7 +55,7 @@ function handle_stanza(origin, stanza) end function register_component(host, component) - if not hosts[host] then + if not hosts[host] or (hosts[host].type == 'component' and not hosts[host].connected) then -- TODO check for host well-formedness components[host] = component; hosts[host] = { type = "component", host = host, connected = true, s2sout = {} }; -- cgit v1.2.3 From 0310a8be6e2a62ceaa30ff693a4e2947ae57d493 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 11 Feb 2009 17:57:48 +0500 Subject: modulemanager initializes hosts[host] if it isn't already initialized when loading a module. --- core/modulemanager.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/core/modulemanager.lua b/core/modulemanager.lua index 12cf9ce8..5afe3144 100644 --- a/core/modulemanager.lua +++ b/core/modulemanager.lua @@ -112,6 +112,7 @@ function load(host, module_name, config) local pluginenv = setmetatable({ module = api_instance }, { __index = _G }); setfenv(mod, pluginenv); + if not hosts[host] then hosts[host] = { type = "component", host = host, connected = false, s2sout = {} }; end local success, ret = pcall(mod); if not success then -- cgit v1.2.3 From c11c83d1b4762c251fdf69d3cbd9ed025f0073fd Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 11 Feb 2009 18:07:20 +0500 Subject: Changed mod_muc to work with changed component manager --- plugins/mod_muc.lua | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/plugins/mod_muc.lua b/plugins/mod_muc.lua index 602fb5bc..79fcbdb6 100644 --- a/plugins/mod_muc.lua +++ b/plugins/mod_muc.lua @@ -266,7 +266,7 @@ function handle_to_domain(origin, stanza) end end -function handle_stanza(origin, stanza) +register_component(muc_domain, function(origin, stanza) local to_node, to_host, to_resource = jid_split(stanza.attr.to); if stanza.name == "presence" and stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable" then if type == "error" or type == "result" then return; end @@ -282,11 +282,7 @@ function handle_stanza(origin, stanza) if type == "error" or type == "result" then return; end handle_to_domain(origin, stanza); end -end - -module.load_component = function() - return handle_stanza; -- Return the function that we want to handle incoming stanzas -end +end); module.unload = function() deregister_component(muc_domain); -- cgit v1.2.3 From 2f24ab95fe28c13d85faf1dbfa16b0c3a90b46b1 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 11 Feb 2009 18:09:41 +0500 Subject: Fixed directed presence handling to work correctly for components --- core/presencemanager.lua | 2 +- core/stanza_router.lua | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/presencemanager.lua b/core/presencemanager.lua index 3a216d7c..8fdf3612 100644 --- a/core/presencemanager.lua +++ b/core/presencemanager.lua @@ -97,7 +97,7 @@ function handle_normal_presence(origin, stanza, core_route_stanza) if stanza.attr.type == "unavailable" then origin.presence = nil; if origin.directed then - for _, jid in ipairs(origin.directed) do + for jid in pairs(origin.directed) do stanza.attr.to = jid; core_route_stanza(origin, stanza); end diff --git a/core/stanza_router.lua b/core/stanza_router.lua index 3c905c6d..52a18eed 100644 --- a/core/stanza_router.lua +++ b/core/stanza_router.lua @@ -105,6 +105,11 @@ function core_process_stanza(origin, stanza) return; -- FIXME what should we do here? does this work with subdomains? end end + if origin.type == "c2s" and stanza.name == "presence" and to ~= nil and not(origin.roster[to_bare] and (origin.roster[to_bare].subscription == "both" or origin.roster[to_bare].subscription == "from")) then -- directed presence + origin.directed = origin.directed or {}; + origin.directed[to] = true; + --t_insert(origin.directed, to); -- FIXME does it make more sense to add to_bare rather than to? + end if not to then core_handle_stanza(origin, stanza); elseif hosts[to] and hosts[to].type == "local" then -- directed at a local server @@ -122,10 +127,6 @@ function core_process_stanza(origin, stanza) elseif origin.type ~= "c2s" and stanza.name == "iq" and not resource then -- directed at bare JID core_handle_stanza(origin, stanza); else - if origin.type == "c2s" and stanza.name == "presence" and to ~= nil and not(origin.roster[to_bare] and (origin.roster[to_bare].subscription == "both" or origin.roster[to_bare].subscription == "from")) then - origin.directed = origin.directed or {}; - t_insert(origin.directed, to); -- FIXME does it make more sense to add to_bare rather than to? - end core_route_stanza(origin, stanza); end else -- cgit v1.2.3 From 33306b3fb77d532af2213ab876f059c70feb599e Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 11 Feb 2009 18:11:41 +0500 Subject: Fixed: Some presence stanzas from local users were not being routed correctly to components (ghosts in mod_muc) --- core/stanza_router.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/stanza_router.lua b/core/stanza_router.lua index 52a18eed..c27a6579 100644 --- a/core/stanza_router.lua +++ b/core/stanza_router.lua @@ -178,6 +178,14 @@ function core_route_stanza(origin, stanza) origin = origin or hosts[from_host]; if not origin then return false; end + if hosts[to] and hosts[to].type == "component" then -- hack to allow components to handle node@server/resource and server/resource + return component_handle_stanza(origin, stanza); + elseif hosts[to_bare] and hosts[to_bare].type == "component" then -- hack to allow components to handle node@server + return component_handle_stanza(origin, stanza); + elseif hosts[host] and hosts[host].type == "component" then -- directed at a component + return component_handle_stanza(origin, stanza); + end + if stanza.name == "presence" and (stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable") then resource = nil; end local host_session = hosts[host] -- cgit v1.2.3 From e711e847ddb176bb45b7c5a70cac99039a384aa7 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 11 Feb 2009 19:41:37 +0500 Subject: mod_muc: Room history --- plugins/mod_muc.lua | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/plugins/mod_muc.lua b/plugins/mod_muc.lua index 79fcbdb6..bd36bd8f 100644 --- a/plugins/mod_muc.lua +++ b/plugins/mod_muc.lua @@ -7,14 +7,15 @@ local jid_bare = require "util.jid".bare; local st = require "util.stanza"; local log = require "util.logger".init("mod_muc"); local multitable_new = require "util.multitable".new; +local t_insert, t_remove = table.insert, table.remove; if module:get_host_type() ~= "component" then error("MUC should be loaded as a component, please see http://prosody.im/doc/components", 0); end local muc_domain = module:get_host(); - local muc_name = "MUCMUCMUC!!!"; +local history_length = 20; -- room_name -> room -- occupant_room_nick -> data @@ -30,6 +31,7 @@ local jid_nick = multitable_new(); -- real jid -> room's jid -> room nick -- subject - the room's subject -- non-anonymous = true|nil -- persistent = true|nil + -- history = {preserialized stanzas} local rooms_info = multitable_new(); local persist_list = datamanager.load(nil, muc_domain, 'room_list') or {}; @@ -131,6 +133,15 @@ function broadcast_message(from, room, subject, body) stanza.attr.to = o_data.jid; core_route_stanza(component, stanza); end + if not subject and body then -- add to history + local history = rooms_info:get(room, 'history'); + if not history then history = {}; rooms_info:set(room, 'history', history); end + -- stanza = st.deserialize(st.preserialize(stanza)); + stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = muc_domain, stamp = datetime.datetime()}):up(); -- XEP-0203 + stanza:tag("x", {xmlns = "jabber:x:delay", from = muc_domain, stamp = datetime.legacy()}):up(); -- XEP-0091 (deprecated) + t_insert(history, st.preserialize(stanza)); + while #history > history_length do t_remove(history, 1) end + end end end @@ -200,7 +211,14 @@ function handle_to_occupant(origin, stanza) -- PM, vCards, etc end end broadcast_presence(nil, to, room); - -- TODO send discussion history + local history = rooms_info:get(room, 'history'); -- send discussion history + if history then + for _, msg in ipairs(history) do + msg = st.deserialize(msg); + msg.attr.to=from; + core_route_stanza(component, msg); + end + end if rooms_info:get(room, 'subject') then core_route_stanza(component, st.message({type='groupchat', from=room, to=from}):tag("subject"):text(rooms_info:get(room, 'subject'))); end -- cgit v1.2.3 From 55223db764c36726db0bbf69ddff3703abe4bd1f Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 11 Feb 2009 23:16:14 +0500 Subject: Stanza router: Message to bare JID fixes - headline messages get sent to all non-negative priority available resource - all other messages get sent to the set of highest non-negative priority available resources - only messages of type chat and normal or missing type go into offline storage --- core/stanza_router.lua | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/core/stanza_router.lua b/core/stanza_router.lua index c27a6579..f83619c6 100644 --- a/core/stanza_router.lua +++ b/core/stanza_router.lua @@ -34,6 +34,8 @@ local t_concat = table.concat; local t_insert = table.insert; local tonumber = tonumber; local s_find = string.find; +local pairs = pairs; +local ipairs = ipairs; local jid_split = require "util.jid".split; local jid_prepped_split = require "util.jid".prepped_split; @@ -208,25 +210,36 @@ function core_route_stanza(origin, stanza) end end elseif stanza.name == "message" then -- select a resource to recieve message - local priority = 0; - local recipients = {}; - for _, session in pairs(user.sessions) do -- find resource with greatest priority - local p = session.priority; - if p > priority then - priority = p; - recipients = {session}; - elseif p == priority then - t_insert(recipients, session); + if message.attr.type == 'headline' then + for _, session in pairs(user.sessions) do -- find resource with greatest priority + if session.presence and session.priority >= 0 then + stanza.attr.to = session.full_jid; + session.send(stanza); + end + end + else + local priority = 0; + local recipients = {}; + for _, session in pairs(user.sessions) do -- find resource with greatest priority + if session.presence then + local p = session.priority; + if p > priority then + priority = p; + recipients = {session}; + elseif p == priority then + t_insert(recipients, session); + end + end + end + local count = 0; + for _, session in ipairs(recipients) do + session.send(stanza); + count = count + 1; + end + if count == 0 and (stanza.attr.type == "chat" or stanza.attr.type == "normal" or not stanza.attr.type) then + offlinemanager.store(node, host, stanza); + -- TODO deal with storage errors end - end - local count = 0; - for _, session in pairs(recipients) do - session.send(stanza); - count = count + 1; - end - if count == 0 then - offlinemanager.store(node, host, stanza); - -- TODO deal with storage errors end else -- TODO send IQ error -- cgit v1.2.3 From 5833e92990f5035f3b4b2c8f7c3c0651b28aa23f Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 11 Feb 2009 23:26:18 +0500 Subject: Change the to attribute of messages to the recipients' bare JID when the recipient/resource is offline. --- core/stanza_router.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/stanza_router.lua b/core/stanza_router.lua index f83619c6..a8de6b4a 100644 --- a/core/stanza_router.lua +++ b/core/stanza_router.lua @@ -210,10 +210,10 @@ function core_route_stanza(origin, stanza) end end elseif stanza.name == "message" then -- select a resource to recieve message - if message.attr.type == 'headline' then + stanza.attr.to = to_bare; + if stanza.attr.type == 'headline' then for _, session in pairs(user.sessions) do -- find resource with greatest priority if session.presence and session.priority >= 0 then - stanza.attr.to = session.full_jid; session.send(stanza); end end @@ -259,6 +259,7 @@ function core_route_stanza(origin, stanza) -- TODO send unavailable presence or unsubscribed end elseif stanza.name == "message" then -- FIXME if full jid, then send out to resources with highest priority + stanza.attr.to = to_bare; -- TODO not in RFC, but seems obvious. Should discuss on the mailing list. if stanza.attr.type == "chat" or stanza.attr.type == "normal" or not stanza.attr.type then offlinemanager.store(node, host, stanza); -- FIXME don't store messages with only chat state notifications -- cgit v1.2.3