diff mod_smacks/mod_smacks.lua @ 591:36003cae2370

mod_smacks: Consolidate logic for deciding whether to advertise or allow smacks for a given session, and fix an issue with not allowing s2s connections to enable smacks because of not binding a resource... (thanks xnyphs)
author Matthew Wild <mwild1@gmail.com>
date Wed, 01 Feb 2012 23:57:07 +0000
parents 40b707d7a809
children f9c73c1249cd
line wrap: on
line diff
--- a/mod_smacks/mod_smacks.lua	Wed Feb 01 23:29:05 2012 +0000
+++ b/mod_smacks/mod_smacks.lua	Wed Feb 01 23:57:07 2012 +0000
@@ -19,26 +19,38 @@
 
 local session_registry = {};
 
+local function can_do_smacks(session, advertise_only)
+	if session.smacks then return false, "unexpected-request", "Stream management is already enabled"; end
+	
+	local session_type = session.type;
+	if type == "c2s" then
+		if not(advertise_only) and not(session.resource) then -- Fail unless we're only advertising sm
+			return false, "unexpected-request", "Client must bind a resource before enabling stream management"; end
+		end
+		return true;
+	elseif s2s_smacks and (type == "s2sin" or type == "s2sout") then
+		return true;
+	end
+	return false, "service-unavailable", "Stream management is not available for this stream";
+end
+
 module:hook("stream-features",
 		function (event)
-			local origin = event.origin;
-			if not(origin.smacks) and origin.type == "c2s" then
+			if can_do_smacks(event.origin, true) then
 				event.features:tag("sm", sm_attr):tag("optional"):up():up();
 			end
 		end);
 
 module:hook("s2s-stream-features",
 		function (event)
-			local origin = event.origin;
-			if s2s_smacks and not(origin.smacks) and (origin.type == "s2sin" or origin.type == "s2sout") then
+			if can_do_smacks(event.origin, true) then
 				event.features:tag("sm", sm_attr):tag("optional"):up():up();
 			end
 		end);
 
 module:hook_stanza("http://etherx.jabber.org/streams", "features",
 		function (session, stanza)
-			if s2s_smacks and (session.type == "s2sin" or session.type == "s2sout")
-					and not session.smacks and stanza:get_child("sm", xmlns_sm) then
+			if can_do_smacks(session) and stanza:get_child("sm", xmlns_sm) then
 				session.sends2s(st.stanza("enable", sm_attr));
 			end
 end);
@@ -89,13 +101,8 @@
 end
 
 module:hook_stanza(xmlns_sm, "enable", function (session, stanza)
-	local err, err_text;
-	if session.smacks then
-		err, err_text = "unexpected-request", "Stream management already enabled for this stream";
-	elseif not session.resource then
-		err, err_text = "unexpected-request", "Attempted to enable stream management before resource binding";
-	end
-	if err then
+	local ok, err, err_text = can_do_smacks(session);
+	if not ok then
 		session.log("warn", "Failed to enable smacks: %s", err_text); -- TODO: XEP doesn't say we can send error text, should it?
 		session.send(st.stanza("failed", { xmlns = xmlns_sm }):tag(err, { xmlns = xmlns_errors}));
 		return true;