mod_smacks: Persist old counter values to storage
authorKim Alvefur <zash@zash.se>
Wed, 01 Dec 2021 16:41:10 +0100
changeset 12055 c32ef09ab452
parent 12054 7b87a1747eb2
child 12056 d17b8fcf11c7
mod_smacks: Persist old counter values to storage This allows clients that try to resume a session after a server restart to at least know which of their pending outgoing stanzas were received and which need to be re-sent. This removes the limit on how many of those counters are kept, which should be fixed eventually.
plugins/mod_smacks.lua
--- a/plugins/mod_smacks.lua	Wed Dec 15 12:09:30 2021 +0100
+++ b/plugins/mod_smacks.lua	Wed Dec 01 16:41:10 2021 +0100
@@ -45,10 +45,8 @@
 local max_inactive_unacked_stanzas = module:get_option_number("smacks_max_inactive_unacked_stanzas", 256);
 local delayed_ack_timeout = module:get_option_number("smacks_max_ack_delay", 30);
 local max_hibernated_sessions = module:get_option_number("smacks_max_hibernated_sessions", 10);
-local max_old_sessions = module:get_option_number("smacks_max_old_sessions", 10);
 
 assert(max_hibernated_sessions > 0, "smacks_max_hibernated_sessions must be greater than 0");
-assert(max_old_sessions > 0, "smacks_max_old_sessions must be greater than 0");
 
 local c2s_sessions = module:shared("/*/c2s/sessions");
 
@@ -76,13 +74,13 @@
 			end;
 		};
 end
-local old_session_registry = init_session_cache(max_old_sessions, nil);
+local old_session_registry = module:open_store("smacks_h", "map");
 local session_registry = init_session_cache(max_hibernated_sessions, function(resumption_token, session)
 	if session.destroyed then return true; end -- destroyed session can always be removed from cache
 	session.log("warn", "User has too much hibernated sessions, removing oldest session (token: %s)", resumption_token);
 	-- store old session's h values on force delete
 	-- save only actual h value and username/host (for security)
-	old_session_registry.set(session.username, resumption_token, {
+	old_session_registry:set(session.username, resumption_token, {
 		h = session.handled_stanza_count,
 	});
 	return true; -- allow session to be removed from full cache to make room for new one
@@ -248,7 +246,7 @@
 	local session = event.session;
 	if session.resumption_token then
 		session_registry.set(session.username, session.resumption_token, nil);
-		old_session_registry.set(session.username, session.resumption_token, nil);
+		old_session_registry:set(session.username, session.resumption_token, nil);
 		session.resumption_token = nil;
 	end
 	-- send out last ack as per revision 1.5.2 of XEP-0198
@@ -493,7 +491,7 @@
 					session.log("debug", "Destroying session for hibernating too long");
 					session_registry.set(session.username, session.resumption_token, nil);
 					-- save only actual h value and username/host (for security)
-					old_session_registry.set(session.username, session.resumption_token, {
+					old_session_registry:set(session.username, session.resumption_token, {
 						h = session.handled_stanza_count,
 					});
 					session.resumption_token = nil;
@@ -546,7 +544,7 @@
 	local original_session = session_registry.get(session.username, id);
 	if not original_session then
 		session.log("debug", "Tried to resume non-existent session with id %s", id);
-		local old_session = old_session_registry.get(session.username, id);
+		local old_session = old_session_registry:get(session.username, id);
 		if old_session then
 			session.send(st.stanza("failed", { xmlns = xmlns_sm, h = format_h(old_session.h) })
 				:tag("item-not-found", { xmlns = xmlns_errors })