mod_s2s: Distinguish between high and low level errors in bounces
authorKim Alvefur <zash@zash.se>
Thu, 01 Aug 2019 05:25:34 +0200
changeset 10119 c0bd5daa9c7f
parent 10118 2f7628804db6
child 10120 4807535b8673
mod_s2s: Distinguish between high and low level errors in bounces `remote-server-not-found` is reported for problems occurring without a reply `<stream>` having been opened, e.g. DNS records were not found or no TCP stream could be established to a functioning XMPP entity. `remote-server-timeout` is reported for problems that occurring after a stream has been opened, such as configuration problems, inability to perform TLS or unsuccessful certificate validation. Related: #770
plugins/mod_s2s/mod_s2s.lua
--- a/plugins/mod_s2s/mod_s2s.lua	Tue Jul 30 02:36:15 2019 +0200
+++ b/plugins/mod_s2s/mod_s2s.lua	Thu Aug 01 05:25:34 2019 +0200
@@ -77,12 +77,19 @@
 			(session.log or log)("error", "Attempting to close the dummy origin of s2s error replies, please report this! Traceback: %s", traceback());
 		end;
 	};
+	-- FIXME Allow for more specific error conditions
+	-- TODO use util.error ?
+	local error_type = "cancel";
+	local condition = "remote-server-not-found";
+	if session.had_stream then -- set when a stream is opened by the remote
+		error_type, condition = "wait", "remote-server-timeout";
+	end
 	for i, data in ipairs(sendq) do
 		local reply = data[2];
 		if reply and not(reply.attr.xmlns) and bouncy_stanzas[reply.name] then
 			reply.attr.type = "error";
-			reply:tag("error", {type = "cancel", by = session.from_host})
-				:tag("remote-server-not-found", {xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas"}):up();
+			reply:tag("error", {type = error_type, by = session.from_host})
+				:tag(condition, {xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas"}):up();
 			if reason then
 				reply:tag("text", {xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas"})
 					:text("Server-to-server connection failed: "..reason):up();
@@ -301,6 +308,7 @@
 
 function stream_callbacks._streamopened(session, attr)
 	session.version = tonumber(attr.version) or 0;
+	session.had_stream = true; -- Had a stream opened at least once
 
 	-- TODO: Rename session.secure to session.encrypted
 	if session.secure == false then