diff plugins/mod_c2s.lua @ 14138:c1469296190d

Merge 13.0->trunk
author Matthew Wild <mwild1@gmail.com>
date Fri, 17 Apr 2026 14:35:32 +0100
parents 97d15552d364 836a70deb3c9
children 320e1d49aa9e
line wrap: on
line diff
--- a/plugins/mod_c2s.lua	Thu Apr 02 20:54:46 2026 +0100
+++ b/plugins/mod_c2s.lua	Fri Apr 17 14:35:32 2026 +0100
@@ -8,7 +8,9 @@
 
 module:set_global();
 
-local add_task = require "prosody.util.timer".add_task;
+local timer = require "prosody.util.timer";
+local add_task = timer.add_task;
+local stop_task = timer.stop;
 local new_xmpp_stream = require "prosody.util.xmppstream".new;
 local nameprep = require "prosody.util.encodings".stringprep.nameprep;
 local sessionmanager = require "prosody.core.sessionmanager";
@@ -25,10 +27,19 @@
 
 local log = module._log;
 
+local function stop_session_timers(session)
+	if session.c2s_timeout then
+		stop_task(session.c2s_timeout);
+		session.c2s_timeout = nil;
+	end
+end
+
 local c2s_timeout = module:get_option_period("c2s_timeout", "5 minutes");
 local stream_close_timeout = module:get_option_period("c2s_close_timeout", 5);
 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 unauthed_stanza_size_limit = module:get_option_integer("c2s_unauthed_stanza_size_limit", 10000,1000);
+local authed_stanza_size_limit = module:get_option_integer("c2s_stanza_size_limit", 1024*256,10000);
+local max_child_elements = module:get_option_integer("c2s_max_child_elements", 25000, 0);
 
 local advertised_idle_timeout = 14*60; -- default in all net.server implementations
 local network_settings = module:get_option("network_settings");
@@ -137,11 +148,11 @@
 	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 or advertised_idle_timeout then
+		if session.stanza_size_limit or advertised_idle_timeout then
 			features:reset();
 			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));
+			if session.stanza_size_limit then
+				limits:text_tag("max-bytes", string.format("%d", session.stanza_size_limit));
 			end
 			if advertised_idle_timeout then
 				limits:text_tag("idle-seconds", string.format("%d", advertised_idle_timeout));
@@ -215,6 +226,7 @@
 	context:fire_event("pre-session-close", close_event_payload);
 
 	reason = close_event_payload.reason;
+	stop_session_timers(session);
 	if session.conn then
 		if session.notopen then
 			session:open_stream();
@@ -355,7 +367,11 @@
 
 	session.close = session_close;
 
-	local stream = new_xmpp_stream(session, stream_callbacks, stanza_size_limit);
+	session.stanza_size_limit = unauthed_stanza_size_limit;
+
+	local stream = new_xmpp_stream(session, stream_callbacks, session.stanza_size_limit, {
+		max_elements = max_child_elements;
+	});
 	session.stream = stream;
 	session.notopen = true;
 
@@ -409,6 +425,8 @@
 	session.dispatch_stanza = stream_callbacks.handlestanza;
 
 	sessions[conn] = session;
+
+	module:fire_event("c2s-connected", { conn = conn, session = session });
 end
 
 function listener.onincoming(conn, data)
@@ -422,6 +440,7 @@
 	local session = sessions[conn];
 	if session then
 		(session.log or log)("info", "Client disconnected: %s", err or "connection closed");
+		stop_session_timers(session);
 		sm_destroy_session(session, err);
 		session.conn = nil;
 		sessions[conn]  = nil;
@@ -463,6 +482,13 @@
 
 function module.add_host(module)
 	module:hook("c2s-read-timeout", keepalive, -1);
+	module:hook("authentication-success", function(event)
+		local session = event.session;
+		if session.stream then
+			session.stanza_size_limit = authed_stanza_size_limit;
+			session.stream:set_stanza_size_limit(session.stanza_size_limit);
+		end
+	end);
 end
 
 module:hook("c2s-read-timeout", keepalive, -1);