Changeset

11526:15a3db955ad3

s2s et al.: Add counters for connection state transitions
author Jonas Schäfer <jonas@wielicki.name>
date Wed, 21 Apr 2021 17:11:58 +0200
parents 11525:5f99fcc43938
children 11527:eaff6e548f12
files plugins/mod_dialback.lua plugins/mod_s2s.lua plugins/mod_saslauth.lua
diffstat 3 files changed, 50 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_dialback.lua	Sun Apr 18 12:35:16 2021 +0200
+++ b/plugins/mod_dialback.lua	Wed Apr 21 17:11:58 2021 +0200
@@ -115,7 +115,7 @@
 				return
 			elseif origin.cert_chain_status == "valid" and origin.cert_identity_status == "valid" then
 				origin.sends2s(st.stanza("db:result", { to = from, from = to, id = attr.id, type = "valid" }));
-				module:fire_event("s2s-authenticated", { session = origin, host = from });
+				module:fire_event("s2s-authenticated", { session = origin, host = from, mechanism = "dialback" });
 				return true;
 			end
 		end
@@ -151,7 +151,7 @@
 		if dialback_verifying and attr.from == origin.to_host then
 			local valid;
 			if attr.type == "valid" then
-				module:fire_event("s2s-authenticated", { session = dialback_verifying, host = attr.from });
+				module:fire_event("s2s-authenticated", { session = dialback_verifying, host = attr.from, mechanism = "dialback" });
 				valid = "valid";
 			else
 				-- Warn the original connection that is was not verified successfully
@@ -188,7 +188,7 @@
 			return true;
 		end
 		if stanza.attr.type == "valid" then
-			module:fire_event("s2s-authenticated", { session = origin, host = attr.from });
+			module:fire_event("s2s-authenticated", { session = origin, host = attr.from, mechanism = "dialback" });
 		else
 			origin:close("not-authorized", "dialback authentication failed");
 		end
--- a/plugins/mod_s2s.lua	Sun Apr 18 12:35:16 2021 +0200
+++ b/plugins/mod_s2s.lua	Wed Apr 21 17:11:58 2021 +0200
@@ -52,6 +52,26 @@
 	{"host", "type", "ip_family"}
 );
 
+local m_accepted_tcp_connections = module:metric(
+	"counter", "accepted_tcp", "",
+	"Accepted incoming connections on the TCP layer"
+);
+local m_authn_connections = module:metric(
+	"counter", "authenticated", "",
+	"Authenticated incoming connections",
+	{"host", "direction", "mechanism"}
+);
+local m_initiated_connections = module:metric(
+	"counter", "initiated", "",
+	"Initiated outbound connections",
+	{"host"}
+);
+local m_closed_connections = module:metric(
+	"counter", "closed", "",
+	"Closed connections",
+	{"host", "direction", "error"}
+);
+
 local sessions = module:shared("sessions");
 
 local runner_callbacks = {};
@@ -190,6 +210,7 @@
 	host_session.sendq = { {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)} };
 	log("debug", "stanza [%s] queued until connection complete", stanza.name);
 	connect(service.new(to_host, "xmpp-server", "tcp", s2s_service_options), listener, nil, { session = host_session });
+	m_initiated_connections:with_labels(from_host):add(1)
 	return true;
 end
 
@@ -310,6 +331,9 @@
 	end
 	session.log("debug", "connection %s->%s is now authenticated for %s", session.from_host, session.to_host, host);
 
+	local local_host = session.direction == "incoming" and session.to_host or session.from_host
+	m_authn_connections:with_labels(local_host, session.direction, event.mechanism or "other"):add(1)
+
 	if (session.type == "s2sout" and session.external_auth ~= "succeeded") or session.type == "s2sin" then
 		-- Stream either used dialback for authentication or is an incoming stream.
 		mark_connected(session);
@@ -528,25 +552,39 @@
 				session:open_stream(session.from_host, session.to_host);
 			end
 		end
+
+		local this_host = session.direction == "incoming" and session.to_host or session.from_host
+
 		if reason then -- nil == no err, initiated by us, false == initiated by remote
 			local stream_error;
+			local condition, text, extra
 			if type(reason) == "string" then -- assume stream error
-				stream_error = st.stanza("stream:error"):tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' });
+				condition = reason
 			elseif type(reason) == "table" and not st.is_stanza(reason) then
-				stream_error = st.stanza("stream:error"):tag(reason.condition or "undefined-condition", stream_xmlns_attr):up();
-				if reason.text then
-					stream_error:tag("text", stream_xmlns_attr):text(reason.text):up();
+				condition = reason.condition or "undefined-condition"
+				text = reason.text
+				extra = reason.extra
+			end
+			if condition then
+				stream_error = st.stanza("stream:error"):tag(condition, stream_xmlns_attr):up();
+				if text then
+					stream_error:tag("text", stream_xmlns_attr):text(text):up();
 				end
-				if reason.extra then
-					stream_error:add_child(reason.extra);
+				if extra then
+					stream_error:add_child(extra);
 				end
 			end
+			if this_host and condition then
+				m_closed_connections:with_labels(this_host, session.direction, condition):add(1)
+			end
 			if st.is_stanza(stream_error) then
 				-- to and from are never unknown on outgoing connections
 				log("debug", "Disconnecting %s->%s[%s], <stream:error> is: %s",
 					session.from_host or "(unknown host)" or session.ip, session.to_host or "(unknown host)", session.type, reason);
 				session.sends2s(stream_error);
 			end
+		else
+			m_closed_connections:with_labels(this_host, session.direction, reason == false and ":remote-choice" or ":local-choice"):add(1)
 		end
 
 		session.sends2s("</stream:stream>");
@@ -690,6 +728,7 @@
 		sessions[conn] = session;
 		session.log("debug", "Incoming s2s connection");
 		initialize_session(session);
+		m_accepted_tcp_connections:with_labels():add(1)
 	else -- Outgoing session connected
 		session:open_stream(session.from_host, session.to_host);
 	end
--- a/plugins/mod_saslauth.lua	Sun Apr 18 12:35:16 2021 +0200
+++ b/plugins/mod_saslauth.lua	Wed Apr 21 17:11:58 2021 +0200
@@ -91,7 +91,7 @@
 	session:reset_stream();
 	session:open_stream(session.from_host, session.to_host);
 
-	module:fire_event("s2s-authenticated", { session = session, host = session.to_host });
+	module:fire_event("s2s-authenticated", { session = session, host = session.to_host, mechanism = "EXTERNAL" });
 	return true;
 end)
 
@@ -192,7 +192,7 @@
 	session.external_auth = "succeeded";
 	session.sends2s(build_reply("success"));
 	module:log("info", "Accepting SASL EXTERNAL identity from %s", session.from_host);
-	module:fire_event("s2s-authenticated", { session = session, host = session.from_host });
+	module:fire_event("s2s-authenticated", { session = session, host = session.from_host, mechanism = mechanism });
 	session:reset_stream();
 	return true;
 end