Changeset

13504:2159a206684e

mod_c2s,mod_s2s: Advertise idle-seconds per XEP-0478 This is the time after liveness checks are performed via the respective read-timeout event, which by default involves sending a space character but could be overridden e.g. as is done by mod_smacks. Only advertised, unsure what we would do with it.
author Kim Alvefur <zash@zash.se>
date Sat, 03 Aug 2024 16:28:59 +0200
parents 13503:8b68e8faab52
children 13506:1b81a7b7c9b8
files plugins/mod_c2s.lua plugins/mod_s2s.lua
diffstat 2 files changed, 37 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_c2s.lua	Fri Jul 12 15:06:42 2024 +0200
+++ b/plugins/mod_c2s.lua	Sat Aug 03 16:28:59 2024 +0200
@@ -30,6 +30,12 @@
 local opt_keepalives = module:get_option_boolean("c2s_tcp_keepalives", module:get_option_boolean("tcp_keepalives", true));
 local stanza_size_limit = module:get_option_integer("c2s_stanza_size_limit", 1024*256,10000);
 
+local advertised_idle_timeout = 14*60; -- default in all net.server implementations
+local network_settings = module:get_option("network_settings");
+if type(network_settings) == "table" and type(network_settings.read_timeout) == "number" then
+	advertised_idle_timeout = network_settings.read_timeout;
+end
+
 local measure_connections = module:metric("gauge", "connections", "", "Established c2s connections", {"host", "type", "ip_family"});
 
 local sessions = module:shared("sessions");
@@ -130,10 +136,16 @@
 	local features = st.stanza("stream:features");
 	hosts[session.host].events.fire_event("stream-features", { origin = session, features = features, stream = attr });
 	if features.tags[1] or session.full_jid then
-		if stanza_size_limit then
+		if stanza_size_limit or advertised_idle_timeout then
 			features:reset();
-			features:tag("limits", { xmlns = "urn:xmpp:stream-limits:0" })
-				:text_tag("max-bytes", string.format("%d", stanza_size_limit)):up();
+			local limits = features:tag("limits", { xmlns = "urn:xmpp:stream-limits:0" });
+			if stanza_size_limit then
+				limits:text_tag("max-bytes", string.format("%d", stanza_size_limit));
+			end
+			if advertised_idle_timeout then
+				limits:text_tag("idle-seconds", string.format("%d", advertised_idle_timeout));
+			end
+			limits:reset();
 		end
 		send(features);
 	else
--- a/plugins/mod_s2s.lua	Fri Jul 12 15:06:42 2024 +0200
+++ b/plugins/mod_s2s.lua	Sat Aug 03 16:28:59 2024 +0200
@@ -43,6 +43,12 @@
 local require_encryption = module:get_option_boolean("s2s_require_encryption", true);
 local stanza_size_limit = module:get_option_integer("s2s_stanza_size_limit", 1024*512, 10000);
 
+local advertised_idle_timeout = 14*60; -- default in all net.server implementations
+local network_settings = module:get_option("network_settings");
+if type(network_settings) == "table" and type(network_settings.read_timeout) == "number" then
+	advertised_idle_timeout = network_settings.read_timeout;
+end
+
 local measure_connections_inbound = module:metric(
 	"gauge", "connections_inbound", "",
 	"Established incoming s2s connections",
@@ -258,10 +264,15 @@
 	module:hook("route/remote", route_to_existing_session, -1);
 	module:hook("route/remote", route_to_new_session, -10);
 	module:hook("s2sout-stream-features", function (event)
+		if not (stanza_size_limit or advertised_idle_timeout) then return end
+		local limits = event.features:tag("limits", { xmlns = "urn:xmpp:stream-limits:0" })
 		if stanza_size_limit then
-			event.features:tag("limits", { xmlns = "urn:xmpp:stream-limits:0" })
-				:text_tag("max-bytes", string.format("%d", stanza_size_limit)):up();
+			limits:text_tag("max-bytes", string.format("%d", stanza_size_limit));
 		end
+		if advertised_idle_timeout then
+			limits:text_tag("idle-seconds", string.format("%d", advertised_idle_timeout));
+		end
+		limits:up();
 	end);
 	module:hook_tag("urn:xmpp:bidi", "bidi", function(session, stanza)
 		-- Advertising features on bidi connections where no <stream:features> is sent in the other direction
@@ -551,10 +562,16 @@
 			end
 
 			if ( session.type == "s2sin" or session.type == "s2sout" ) or features.tags[1] then
-				if stanza_size_limit then
+				if stanza_size_limit or advertised_idle_timeout then
 					features:reset();
-					features:tag("limits", { xmlns = "urn:xmpp:stream-limits:0" })
-						:text_tag("max-bytes", string.format("%d", stanza_size_limit)):up();
+					local limits = features:tag("limits", { xmlns = "urn:xmpp:stream-limits:0" });
+					if stanza_size_limit then
+						limits:text_tag("max-bytes", string.format("%d", stanza_size_limit));
+					end
+					if advertised_idle_timeout then
+						limits:text_tag("idle-seconds", string.format("%d", advertised_idle_timeout));
+					end
+					features:reset();
 				end
 
 				log("debug", "Sending stream features: %s", features);