Internal component support

Tue, 04 Nov 2008 17:25:12 +0500

author
Waqas Hussain <waqas20@gmail.com>
date
Tue, 04 Nov 2008 17:25:12 +0500
changeset 212
9d6da9ed9063
parent 211
22e17cfab36c
child 213
181f5cc6215b

Internal component support

core/componentmanager.lua file | annotate | diff | comparison | revisions
core/stanza_router.lua file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/componentmanager.lua	Tue Nov 04 17:25:12 2008 +0500
@@ -0,0 +1,35 @@
+
+
+local log = require "util.logger".init("componentmanager")
+local jid_split = require "util.jid".split;
+local hosts = hosts;
+
+local components = {};
+
+module "componentmanager"
+
+function handle_stanza(origin, stanza)
+	local node, host = jid_split(stanza.attr.to);
+	local component = components[host];
+	if not component then component = components[node.."@"..host]; end -- hack to allow hooking node@server
+	if not component then component = components[stanza.attr.to]; end -- hack to allow hooking node@server/resource and server/resource
+	if component then
+		log("debug", "stanza being handled by component: "..host);
+		component(origin, stanza);
+	else
+		log("error", "Component manager recieved a stanza for a non-existing component: " .. stanza.attr.to);
+	end
+end
+
+function register_component(host, component)
+	if not hosts[host] then
+		-- TODO check for host well-formedness
+		components[host] = component;
+		hosts[host] = {type = "component", connected = true};
+		log("debug", "component added: "..host);
+	else
+		log("error", "Attempt to set component for existing host: "..host);
+	end
+end
+
+return _M;
\ No newline at end of file
--- a/core/stanza_router.lua	Tue Nov 04 17:21:27 2008 +0500
+++ b/core/stanza_router.lua	Tue Nov 04 17:25:12 2008 +0500
@@ -18,6 +18,7 @@
 local s2s_make_authenticated = require "core.s2smanager".make_authenticated;
 
 local modules_handle_stanza = require "core.modulemanager".handle_stanza;
+local component_handle_stanza = require "core.componentmanager".handle_stanza;
 
 local format = string.format;
 local tostring = tostring;
@@ -31,6 +32,7 @@
 
 function core_process_stanza(origin, stanza)
 	log("debug", "Received["..origin.type.."]: "..tostring(stanza))
+
 	-- TODO verify validity of stanza (as well as JID validity)
 	if stanza.name == "iq" and not(#stanza.tags == 1 and stanza.tags[1].attr.xmlns) then
 		if stanza.attr.type == "set" or stanza.attr.type == "get" then
@@ -46,28 +48,47 @@
 		error("Client MUST bind resource after auth");
 	end
 
-	local to = stanza.attr.to;
 	-- TODO also, stazas should be returned to their original state before the function ends
 	if origin.type == "c2s" then
-		stanza.attr.from = origin.full_jid; -- quick fix to prevent impersonation (FIXME this would be incorrect when the origin is not c2s)
+		stanza.attr.from = origin.full_jid;
+	end
+	local to = stanza.attr.to;
+	local node, host, resource = jid_split(to);
+	local to_bare = node and (node.."@"..host) or host; -- bare JID
+	local from = stanza.attr.from;
+	local from_node, from_host, from_resource = jid_split(from);
+	local from_bare = from_node and (from_node.."@"..from_host) or from_host; -- bare JID
+
+	if origin.type == "s2sin" then
+		if origin.host ~= from_host then -- remote server trying to impersonate some other server?
+			return; -- FIXME what should we do here? does this work with subdomains?
+		end
+	end
+	if to and not(hosts[to]) and not(hosts[to_bare]) and (not(hosts[host]) or hosts[host].type ~= "local") then -- not for us?
+		return; -- FIXME what should we do here?
 	end
 
+	-- FIXME do stanzas not of jabber:client get handled by components?
 	if not to then
 		core_handle_stanza(origin, stanza);
+	elseif hosts[to] and hosts[to].type == "local" then -- directed at a local server
+		core_handle_stanza(origin, stanza);
+	elseif hosts[to_bare] and hosts[to_bare].type == "component" then -- hack to allow components to handle node@server
+		component_handle_stanza(origin, stanza);
+	elseif hosts[to] and hosts[to].type == "component" then -- hack to allow components to handle node@server/resource and server/resource
+		component_handle_stanza(origin, stanza);
+	elseif hosts[host].type == "component" then -- directed at a component
+		component_handle_stanza(origin, stanza);
 	elseif origin.type == "c2s" and stanza.name == "presence" and stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable" then
-		local node, host = jid_split(stanza.attr.to);
-		local to_bare = node and (node.."@"..host) or host; -- bare JID
-		local from_node, from_host = jid_split(stanza.attr.from);
-		local from_bare = from_node and (from_node.."@"..from_host) or from_host; -- bare JID
 		handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare);
-	elseif hosts[to] and hosts[to].type == "local" then
-		core_handle_stanza(origin, stanza);
-	elseif stanza.name == "iq" and not select(3, jid_split(to)) then
+	elseif stanza.name == "iq" and not resource then -- directed at bare JID
 		core_handle_stanza(origin, stanza);
 	elseif stanza.attr.xmlns and stanza.attr.xmlns ~= "jabber:client" and stanza.attr.xmlns ~= "jabber:server" then
 		modules_handle_stanza(origin, stanza);
 	elseif origin.type == "c2s" or origin.type == "s2sin" then
 		core_route_stanza(origin, stanza);
+	else
+		log("warn", "stanza not processed");
 	end
 end
 
@@ -144,9 +165,9 @@
 			else
 				-- TODO error, bad type
 			end
-		end
+		end -- TODO handle other stanzas
 	else
-		log("warn", "Unhandled origin: %s", origin.type);
+		log("warn", "Unhandled origin: %s", origin.type); -- FIXME reply with error
 	end
 end
 

mercurial