Annotate

plugins/mod_smacks.lua @ 11936:3f49c35607ca

mod_smacks: Fix timer lifetimes to follow session instead of module module:add_timer() creates a timer that stops working after the module is reloaded or unloaded, in order to prevent leaks. However, when the timers control vital session behavior, breakage occurs after reload. E.g. sessions would stop requesting acks and stop responding to acks.
author Kim Alvefur <zash@zash.se>
date Wed, 24 Nov 2021 21:27:45 +0100
parent 11935:4d0d10fabb82
child 11937:364c3f018e3a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
1 -- XEP-0198: Stream Management for Prosody IM
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
2 --
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
3 -- Copyright (C) 2010-2015 Matthew Wild
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
4 -- Copyright (C) 2010 Waqas Hussain
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
5 -- Copyright (C) 2012-2021 Kim Alvefur
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
6 -- Copyright (C) 2012 Thijs Alkemade
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
7 -- Copyright (C) 2014 Florian Zeitz
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
8 -- Copyright (C) 2016-2020 Thilo Molitor
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
9 --
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
10 -- This project is MIT/X11 licensed. Please see the
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
11 -- COPYING file in the source package for more information.
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
12 --
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
13
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
14 local st = require "util.stanza";
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
15 local cache = require "util.cache";
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
16 local uuid_generate = require "util.uuid".generate;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
17 local jid = require "util.jid";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
18
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
19 local t_remove = table.remove;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
20 local math_min = math.min;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
21 local math_max = math.max;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
22 local os_time = os.time;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23 local tonumber, tostring = tonumber, tostring;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24 local add_filter = require "util.filters".add_filter;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25 local timer = require "util.timer";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
26 local datetime = require "util.datetime";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28 local xmlns_mam2 = "urn:xmpp:mam:2";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29 local xmlns_sm2 = "urn:xmpp:sm:2";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30 local xmlns_sm3 = "urn:xmpp:sm:3";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31 local xmlns_errors = "urn:ietf:params:xml:ns:xmpp-stanzas";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
32 local xmlns_delay = "urn:xmpp:delay";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
34 local sm2_attr = { xmlns = xmlns_sm2 };
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
35 local sm3_attr = { xmlns = xmlns_sm3 };
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
36
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
37 local resume_timeout = module:get_option_number("smacks_hibernation_time", 600);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
38 local s2s_smacks = module:get_option_boolean("smacks_enabled_s2s", true);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
39 local s2s_resend = module:get_option_boolean("smacks_s2s_resend", false);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
40 local max_unacked_stanzas = module:get_option_number("smacks_max_unacked_stanzas", 0);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
41 local max_inactive_unacked_stanzas = module:get_option_number("smacks_max_inactive_unacked_stanzas", 256);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
42 local delayed_ack_timeout = module:get_option_number("smacks_max_ack_delay", 30);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
43 local max_hibernated_sessions = module:get_option_number("smacks_max_hibernated_sessions", 10);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
44 local max_old_sessions = module:get_option_number("smacks_max_old_sessions", 10);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
45 local core_process_stanza = prosody.core_process_stanza;
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
46 local sessionmanager = require "core.sessionmanager";
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
47
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
48 assert(max_hibernated_sessions > 0, "smacks_max_hibernated_sessions must be greater than 0");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49 assert(max_old_sessions > 0, "smacks_max_old_sessions must be greater than 0");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
50
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
51 local c2s_sessions = module:shared("/*/c2s/sessions");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
52
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
53 local function init_session_cache(max_entries, evict_callback)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
54 -- old prosody version < 0.10 (no limiting at all!)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
55 if not cache then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
56 local store = {};
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
57 return {
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
58 get = function(user, key)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
59 if not user then return nil; end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
60 if not key then return nil; end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
61 return store[key];
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
62 end;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
63 set = function(user, key, value)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
64 if not user then return nil; end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
65 if not key then return nil; end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
66 store[key] = value;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
67 end;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
68 };
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
69 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
70
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
71 -- use per user limited cache for prosody >= 0.10
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
72 local stores = {};
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
73 return {
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
74 get = function(user, key)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
75 if not user then return nil; end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
76 if not key then return nil; end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
77 if not stores[user] then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
78 stores[user] = cache.new(max_entries, evict_callback);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
79 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
80 return stores[user]:get(key);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
81 end;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
82 set = function(user, key, value)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
83 if not user then return nil; end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
84 if not key then return nil; end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
85 if not stores[user] then stores[user] = cache.new(max_entries, evict_callback); end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 stores[user]:set(key, value);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
87 -- remove empty caches completely
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
88 if not stores[user]:count() then stores[user] = nil; end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
89 end;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
90 };
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
91 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
92 local old_session_registry = init_session_cache(max_old_sessions, nil);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
93 local session_registry = init_session_cache(max_hibernated_sessions, function(resumption_token, session)
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
94 if session.destroyed then return true; end -- destroyed session can always be removed from cache
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
95 session.log("warn", "User has too much hibernated sessions, removing oldest session (token: %s)", resumption_token);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
96 -- store old session's h values on force delete
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
97 -- save only actual h value and username/host (for security)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
98 old_session_registry.set(session.username, resumption_token, {
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
99 h = session.handled_stanza_count,
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
100 username = session.username,
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
101 host = session.host
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
102 });
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
103 return true; -- allow session to be removed from full cache to make room for new one
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
104 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
105
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
106 local function ack_delayed(session, stanza)
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
107 -- fire event only if configured to do so and our session is not already hibernated or destroyed
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
108 if delayed_ack_timeout > 0 and session.awaiting_ack
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
109 and not session.hibernating and not session.destroyed then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
110 session.log("debug", "Firing event 'smacks-ack-delayed', queue = %d",
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
111 session.outgoing_stanza_queue and #session.outgoing_stanza_queue or 0);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
112 module:fire_event("smacks-ack-delayed", {origin = session, queue = session.outgoing_stanza_queue, stanza = stanza});
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
113 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
114 session.delayed_ack_timer = nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
115 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
116
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
117 local function can_do_smacks(session, advertise_only)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
118 if session.smacks then return false, "unexpected-request", "Stream management is already enabled"; end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
119
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
120 local session_type = session.type;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
121 if session.username then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
122 if not(advertise_only) and not(session.resource) then -- Fail unless we're only advertising sm
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
123 return false, "unexpected-request", "Client must bind a resource before enabling stream management";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
124 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
125 return true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
126 elseif s2s_smacks and (session_type == "s2sin" or session_type == "s2sout") then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
127 return true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
128 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
129 return false, "service-unavailable", "Stream management is not available for this stream";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
130 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
131
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
132 module:hook("stream-features",
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
133 function (event)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
134 if can_do_smacks(event.origin, true) then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
135 event.features:tag("sm", sm2_attr):tag("optional"):up():up();
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
136 event.features:tag("sm", sm3_attr):tag("optional"):up():up();
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
137 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
138 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
139
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
140 module:hook("s2s-stream-features",
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
141 function (event)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
142 if can_do_smacks(event.origin, true) then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
143 event.features:tag("sm", sm2_attr):tag("optional"):up():up();
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
144 event.features:tag("sm", sm3_attr):tag("optional"):up():up();
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
145 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
146 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
147
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
148 local function request_ack_if_needed(session, force, reason, stanza)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
149 local queue = session.outgoing_stanza_queue;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
150 local expected_h = session.last_acknowledged_stanza + #queue;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
151 local max_unacked = max_unacked_stanzas;
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
152 if session.state == "inactive" then
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
153 max_unacked = max_inactive_unacked_stanzas;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
154 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
155 if session.awaiting_ack == nil and not session.hibernating then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
156 -- this check of last_requested_h prevents ack-loops if missbehaving clients report wrong
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
157 -- stanza counts. it is set when an <r> is really sent (e.g. inside timer), preventing any
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
158 -- further requests until a higher h-value would be expected.
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
159 if (#queue > max_unacked and expected_h ~= session.last_requested_h) or force then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
160 session.log("debug", "Queuing <r> (in a moment) from %s - #queue=%d", reason, #queue);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
161 session.awaiting_ack = false;
11936
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
162 session.awaiting_ack_timer = timer.add_task(1e-06, function ()
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
163 -- session.log("debug", "*** SMACKS(3) ***: awaiting_ack=%s, hibernating=%s", tostring(session.awaiting_ack), tostring(session.hibernating));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
164 -- only request ack if needed and our session is not already hibernated or destroyed
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
165 if not session.awaiting_ack and not session.hibernating and not session.destroyed then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
166 session.log("debug", "Sending <r> (inside timer, before send) from %s - #queue=%d", reason, #queue);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
167 (session.sends2s or session.send)(st.stanza("r", { xmlns = session.smacks }))
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
168 if session.destroyed then return end -- sending something can trigger destruction
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
169 session.awaiting_ack = true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
170 -- expected_h could be lower than this expression e.g. more stanzas added to the queue meanwhile)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
171 session.last_requested_h = session.last_acknowledged_stanza + #queue;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
172 session.log("debug", "Sending <r> (inside timer, after send) from %s - #queue=%d", reason, #queue);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
173 if not session.delayed_ack_timer then
11936
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
174 session.delayed_ack_timer = timer.add_task(delayed_ack_timeout, function()
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
175 ack_delayed(session, nil); -- we don't know if this is the only new stanza in the queue
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
176 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
177 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
178 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
179 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
180 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
181 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
182
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
183 -- Trigger "smacks-ack-delayed"-event if we added new (ackable) stanzas to the outgoing queue
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
184 -- and there isn't already a timer for this event running.
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
185 -- If we wouldn't do this, stanzas added to the queue after the first "smacks-ack-delayed"-event
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
186 -- would not trigger this event (again).
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
187 if #queue > max_unacked and session.awaiting_ack and session.delayed_ack_timer == nil then
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
188 session.log("debug", "Calling ack_delayed directly (still waiting for ack)");
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
189 ack_delayed(session, stanza); -- this is the only new stanza in the queue --> provide it to other modules
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
190 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
191 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
192
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
193 local function outgoing_stanza_filter(stanza, session)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
194 -- XXX: Normally you wouldn't have to check the xmlns for a stanza as it's
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
195 -- supposed to be nil.
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
196 -- However, when using mod_smacks with mod_websocket, then mod_websocket's
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
197 -- stanzas/out filter can get called before this one and adds the xmlns.
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
198 local is_stanza = stanza.attr and
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
199 (not stanza.attr.xmlns or stanza.attr.xmlns == 'jabber:client')
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
200 and not stanza.name:find":";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
201
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
202 if is_stanza and not stanza._cached then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
203 local queue = session.outgoing_stanza_queue;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
204 local cached_stanza = st.clone(stanza);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
205 cached_stanza._cached = true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
206
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
207 if cached_stanza and cached_stanza.name ~= "iq" and cached_stanza:get_child("delay", xmlns_delay) == nil then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
208 cached_stanza = cached_stanza:tag("delay", {
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
209 xmlns = xmlns_delay,
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
210 from = jid.bare(session.full_jid or session.host),
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
211 stamp = datetime.datetime()
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
212 });
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
213 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
214
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
215 queue[#queue+1] = cached_stanza;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
216 if session.hibernating then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
217 session.log("debug", "hibernating since %s, stanza queued", datetime.datetime(session.hibernating));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
218 module:fire_event("smacks-hibernation-stanza-queued", {origin = session, queue = queue, stanza = cached_stanza});
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
219 return nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
220 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
221 request_ack_if_needed(session, false, "outgoing_stanza_filter", stanza);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
222 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
223 return stanza;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
224 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
225
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
226 local function count_incoming_stanzas(stanza, session)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
227 if not stanza.attr.xmlns then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
228 session.handled_stanza_count = session.handled_stanza_count + 1;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
229 session.log("debug", "Handled %d incoming stanzas", session.handled_stanza_count);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
230 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
231 return stanza;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
232 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
233
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
234 local function wrap_session_out(session, resume)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
235 if not resume then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
236 session.outgoing_stanza_queue = {};
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
237 session.last_acknowledged_stanza = 0;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
238 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
239
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
240 add_filter(session, "stanzas/out", outgoing_stanza_filter, -999);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
241
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
242 local session_close = session.close;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
243 function session.close(...)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
244 if session.resumption_token then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
245 session_registry.set(session.username, session.resumption_token, nil);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
246 old_session_registry.set(session.username, session.resumption_token, nil);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
247 session.resumption_token = nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
248 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
249 -- send out last ack as per revision 1.5.2 of XEP-0198
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
250 if session.smacks and session.conn and session.handled_stanza_count then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
251 (session.sends2s or session.send)(st.stanza("a", { xmlns = session.smacks, h = string.format("%d", session.handled_stanza_count) }));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
252 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
253 return session_close(...);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
254 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
255 return session;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
256 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
257
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
258 local function wrap_session_in(session, resume)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
259 if not resume then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
260 session.handled_stanza_count = 0;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
261 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
262 add_filter(session, "stanzas/in", count_incoming_stanzas, 999);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
263
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
264 return session;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
265 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
266
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
267 local function wrap_session(session, resume)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
268 wrap_session_out(session, resume);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
269 wrap_session_in(session, resume);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
270 return session;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
271 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
272
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
273 function handle_enable(session, stanza, xmlns_sm)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
274 local ok, err, err_text = can_do_smacks(session);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
275 if not ok then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
276 session.log("warn", "Failed to enable smacks: %s", err_text); -- TODO: XEP doesn't say we can send error text, should it?
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
277 (session.sends2s or session.send)(st.stanza("failed", { xmlns = xmlns_sm }):tag(err, { xmlns = xmlns_errors}));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
278 return true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
279 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
280
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
281 module:log("debug", "Enabling stream management");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
282 session.smacks = xmlns_sm;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
283
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
284 wrap_session(session, false);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
285
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
286 local resume_token;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
287 local resume = stanza.attr.resume;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
288 if resume == "true" or resume == "1" then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
289 resume_token = uuid_generate();
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
290 session_registry.set(session.username, resume_token, session);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
291 session.resumption_token = resume_token;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
292 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
293 (session.sends2s or session.send)(st.stanza("enabled", { xmlns = xmlns_sm, id = resume_token, resume = resume, max = tostring(resume_timeout) }));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
294 return true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
295 end
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
296 module:hook_tag(xmlns_sm2, "enable", function (session, stanza) return handle_enable(session, stanza, xmlns_sm2); end, 100);
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
297 module:hook_tag(xmlns_sm3, "enable", function (session, stanza) return handle_enable(session, stanza, xmlns_sm3); end, 100);
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
298
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
299 module:hook_tag("http://etherx.jabber.org/streams", "features",
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
300 function (session, stanza)
11936
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
301 -- Needs to be done after flushing sendq since those aren't stored as
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
302 -- stanzas and counting them is weird.
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
303 timer.add_task(1e-6, function ()
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
304 if can_do_smacks(session) then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
305 if stanza:get_child("sm", xmlns_sm3) then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
306 session.sends2s(st.stanza("enable", sm3_attr));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
307 session.smacks = xmlns_sm3;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
308 elseif stanza:get_child("sm", xmlns_sm2) then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
309 session.sends2s(st.stanza("enable", sm2_attr));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
310 session.smacks = xmlns_sm2;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
311 else
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
312 return;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
313 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
314 wrap_session_out(session, false);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
315 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
316 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
317 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
318
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
319 function handle_enabled(session, stanza, xmlns_sm) -- luacheck: ignore 212/stanza
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
320 module:log("debug", "Enabling stream management");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
321 session.smacks = xmlns_sm;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
322
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
323 wrap_session_in(session, false);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
324
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
325 -- FIXME Resume?
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
326
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
327 return true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
328 end
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
329 module:hook_tag(xmlns_sm2, "enabled", function (session, stanza) return handle_enabled(session, stanza, xmlns_sm2); end, 100);
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
330 module:hook_tag(xmlns_sm3, "enabled", function (session, stanza) return handle_enabled(session, stanza, xmlns_sm3); end, 100);
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
331
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
332 function handle_r(origin, stanza, xmlns_sm) -- luacheck: ignore 212/stanza
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
333 if not origin.smacks then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
334 module:log("debug", "Received ack request from non-smack-enabled session");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
335 return;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
336 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
337 module:log("debug", "Received ack request, acking for %d", origin.handled_stanza_count);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
338 -- Reply with <a>
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
339 (origin.sends2s or origin.send)(st.stanza("a", { xmlns = xmlns_sm, h = string.format("%d", origin.handled_stanza_count) }));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
340 -- piggyback our own ack request if needed (see request_ack_if_needed() for explanation of last_requested_h)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
341 local expected_h = origin.last_acknowledged_stanza + #origin.outgoing_stanza_queue;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
342 if #origin.outgoing_stanza_queue > 0 and expected_h ~= origin.last_requested_h then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
343 request_ack_if_needed(origin, true, "piggybacked by handle_r", nil);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
344 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
345 return true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
346 end
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
347 module:hook_tag(xmlns_sm2, "r", function (origin, stanza) return handle_r(origin, stanza, xmlns_sm2); end);
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
348 module:hook_tag(xmlns_sm3, "r", function (origin, stanza) return handle_r(origin, stanza, xmlns_sm3); end);
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
349
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
350 function handle_a(origin, stanza)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
351 if not origin.smacks then return; end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
352 origin.awaiting_ack = nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
353 if origin.awaiting_ack_timer then
11936
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
354 timer.stop(origin.awaiting_ack_timer);
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
355 origin.awaiting_ack_timer = nil;
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
356 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
357 if origin.delayed_ack_timer then
11936
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
358 timer.stop(origin.delayed_ack_timer)
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
359 origin.delayed_ack_timer = nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
360 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
361 -- Remove handled stanzas from outgoing_stanza_queue
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
362 -- origin.log("debug", "ACK: h=%s, last=%s", stanza.attr.h or "", origin.last_acknowledged_stanza or "");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
363 local h = tonumber(stanza.attr.h);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
364 if not h then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
365 origin:close{ condition = "invalid-xml"; text = "Missing or invalid 'h' attribute"; };
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
366 return;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
367 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
368 local handled_stanza_count = h-origin.last_acknowledged_stanza;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
369 local queue = origin.outgoing_stanza_queue;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
370 if handled_stanza_count > #queue then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
371 origin.log("warn", "The client says it handled %d new stanzas, but we only sent %d :)",
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
372 handled_stanza_count, #queue);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
373 origin.log("debug", "Client h: %d, our h: %d", tonumber(stanza.attr.h), origin.last_acknowledged_stanza);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
374 for i=1,#queue do
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
375 origin.log("debug", "Q item %d: %s", i, tostring(queue[i]));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
376 end
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
377 origin:close{ condition = "undefined-condition"; text = "Client acknowledged more stanzas than sent by server"; };
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
378 return;
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
379 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
380
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
381 for _=1,math_min(handled_stanza_count,#queue) do
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
382 local handled_stanza = t_remove(origin.outgoing_stanza_queue, 1);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
383 module:fire_event("delivery/success", { session = origin, stanza = handled_stanza });
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
384 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
385
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
386 origin.log("debug", "#queue = %d", #queue);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
387 origin.last_acknowledged_stanza = origin.last_acknowledged_stanza + handled_stanza_count;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
388 request_ack_if_needed(origin, false, "handle_a", nil)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
389 return true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
390 end
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
391 module:hook_tag(xmlns_sm2, "a", handle_a);
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
392 module:hook_tag(xmlns_sm3, "a", handle_a);
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
393
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
394 --TODO: Optimise... incoming stanzas should be handled by a per-session
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
395 -- function that has a counter as an upvalue (no table indexing for increments,
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
396 -- and won't slow non-198 sessions). We can also then remove the .handled flag
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
397 -- on stanzas
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
398
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
399 local function handle_unacked_stanzas(session)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
400 local queue = session.outgoing_stanza_queue;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
401 local error_attr = { type = "cancel" };
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
402 if #queue > 0 then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
403 session.outgoing_stanza_queue = {};
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
404 for i=1,#queue do
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
405 if not module:fire_event("delivery/failure", { session = session, stanza = queue[i] }) then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
406 if queue[i].attr.type ~= "error" then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
407 local reply = st.reply(queue[i]);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
408 if reply.attr.to ~= session.full_jid then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
409 reply.attr.type = "error";
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
410 reply:tag("error", error_attr)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
411 :tag("recipient-unavailable", {xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas"});
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
412 core_process_stanza(session, reply);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
413 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
414 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
415 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
416 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
417 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
418 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
419
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
420 -- don't send delivery errors for messages which will be delivered by mam later on
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
421 -- check if stanza was archived --> this will allow us to send back errors for stanzas not archived
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
422 -- because the user configured the server to do so ("no-archive"-setting for one special contact for example)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
423 local function get_stanza_id(stanza, by_jid)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
424 for tag in stanza:childtags("stanza-id", "urn:xmpp:sid:0") do
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
425 if tag.attr.by == by_jid then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
426 return tag.attr.id;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
427 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
428 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
429 return nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
430 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
431 module:hook("delivery/failure", function(event)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
432 local session, stanza = event.session, event.stanza;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
433 -- Only deal with authenticated (c2s) sessions
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
434 if session.username then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
435 if stanza.name == "message" and stanza.attr.xmlns == nil and
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
436 ( stanza.attr.type == "chat" or ( stanza.attr.type or "normal" ) == "normal" ) then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
437 -- don't store messages in offline store if they are mam results
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
438 local mam_result = stanza:get_child("result", xmlns_mam2);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
439 if mam_result ~= nil then
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
440 return true; -- stanza already "handled", don't send an error and don't add it to offline storage
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
441 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
442 -- do nothing here for normal messages and don't send out "message delivery errors",
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
443 -- because messages are already in MAM at this point (no need to frighten users)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
444 local stanza_id = get_stanza_id(stanza, jid.bare(session.full_jid));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
445 if session.mam_requested and stanza_id ~= nil then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
446 session.log("debug", "mod_smacks delivery/failure returning true for mam-handled stanza: mam-archive-id=%s", tostring(stanza_id));
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
447 return true; -- stanza handled, don't send an error
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
448 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
449 -- store message in offline store, if this client does not use mam *and* was the last client online
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
450 local sessions = prosody.hosts[module.host].sessions[session.username] and
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
451 prosody.hosts[module.host].sessions[session.username].sessions or nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
452 if sessions and next(sessions) == session.resource and next(sessions, session.resource) == nil then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
453 local ok = module:fire_event("message/offline/handle", { origin = session, username = session.username, stanza = stanza });
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
454 session.log("debug", "mod_smacks delivery/failuere returning %s for offline-handled stanza", tostring(ok));
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
455 return ok; -- if stanza was handled, don't send an error
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
456 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
457 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
458 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
459 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
460
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
461 module:hook("pre-resource-unbind", function (event)
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
462 local session = event.session;
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
463 if session.smacks then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
464 if not session.resumption_token then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
465 local queue = session.outgoing_stanza_queue;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
466 if #queue > 0 then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
467 session.log("debug", "Destroying session with %d unacked stanzas", #queue);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
468 handle_unacked_stanzas(session);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
469 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
470 else
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
471 session.log("debug", "mod_smacks hibernating session for up to %d seconds", resume_timeout);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
472 local hibernate_time = os_time(); -- Track the time we went into hibernation
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
473 session.hibernating = hibernate_time;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
474 local resumption_token = session.resumption_token;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
475 module:fire_event("smacks-hibernation-start", {origin = session, queue = session.outgoing_stanza_queue});
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
476 timer.add_task(resume_timeout, function ()
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
477 session.log("debug", "mod_smacks hibernation timeout reached...");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
478 -- We need to check the current resumption token for this resource
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
479 -- matches the smacks session this timer is for in case it changed
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
480 -- (for example, the client may have bound a new resource and
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
481 -- started a new smacks session, or not be using smacks)
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
482 local curr_session = prosody.full_sessions[session.full_jid];
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
483 if session.destroyed then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
484 session.log("debug", "The session has already been destroyed");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
485 elseif curr_session and curr_session.resumption_token == resumption_token
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
486 -- Check the hibernate time still matches what we think it is,
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
487 -- otherwise the session resumed and re-hibernated.
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
488 and session.hibernating == hibernate_time then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
489 -- wait longer if the timeout isn't reached because push was enabled for this session
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
490 -- session.first_hibernated_push is the starting point for hibernation timeouts of those push enabled clients
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
491 -- wait for an additional resume_timeout seconds if no push occurred since hibernation at all
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
492 local current_time = os_time();
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
493 local timeout_start = math_max(session.hibernating, session.first_hibernated_push or session.hibernating);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
494 if session.push_identifier ~= nil and not session.first_hibernated_push then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
495 session.log("debug", "No push happened since hibernation started, hibernating session for up to %d extra seconds", resume_timeout);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
496 return resume_timeout;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
497 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
498 if session.push_identifier ~= nil and current_time-timeout_start < resume_timeout then
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
499 session.log("debug", "A push happened since hibernation started, hibernating session for up to %d extra seconds",
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
500 resume_timeout - (current_time - timeout_start));
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
501 return resume_timeout-(current_time-timeout_start); -- time left to wait
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
502 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
503 session.log("debug", "Destroying session for hibernating too long");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
504 session_registry.set(session.username, session.resumption_token, nil);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
505 -- save only actual h value and username/host (for security)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
506 old_session_registry.set(session.username, session.resumption_token, {
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
507 h = session.handled_stanza_count,
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
508 username = session.username,
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
509 host = session.host
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
510 });
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
511 session.resumption_token = nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
512 sessionmanager.destroy_session(session);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
513 else
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
514 session.log("debug", "Session resumed before hibernation timeout, all is well")
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
515 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
516 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
517 return true; -- Postpone destruction for now
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
518 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
519 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
520 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
521
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
522 local function handle_s2s_destroyed(event)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
523 local session = event.session;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
524 local queue = session.outgoing_stanza_queue;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
525 if queue and #queue > 0 then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
526 session.log("warn", "Destroying session with %d unacked stanzas", #queue);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
527 if s2s_resend then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
528 for i = 1, #queue do
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
529 module:send(queue[i]);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
530 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
531 session.outgoing_stanza_queue = nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
532 else
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
533 handle_unacked_stanzas(session);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
534 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
535 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
536 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
537
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
538 module:hook("s2sout-destroyed", handle_s2s_destroyed);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
539 module:hook("s2sin-destroyed", handle_s2s_destroyed);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
540
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
541 local function get_session_id(session)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
542 return session.id or (tostring(session):match("[a-f0-9]+$"));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
543 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
544
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
545 function handle_resume(session, stanza, xmlns_sm)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
546 if session.full_jid then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
547 session.log("warn", "Tried to resume after resource binding");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
548 session.send(st.stanza("failed", { xmlns = xmlns_sm })
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
549 :tag("unexpected-request", { xmlns = xmlns_errors })
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
550 );
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
551 return true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
552 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
553
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
554 local id = stanza.attr.previd;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
555 local original_session = session_registry.get(session.username, id);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
556 if not original_session then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
557 session.log("debug", "Tried to resume non-existent session with id %s", id);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
558 local old_session = old_session_registry.get(session.username, id);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
559 if old_session and session.username == old_session.username
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
560 and session.host == old_session.host
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
561 and old_session.h then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
562 session.send(st.stanza("failed", { xmlns = xmlns_sm, h = string.format("%d", old_session.h) })
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
563 :tag("item-not-found", { xmlns = xmlns_errors })
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
564 );
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
565 else
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
566 session.send(st.stanza("failed", { xmlns = xmlns_sm })
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
567 :tag("item-not-found", { xmlns = xmlns_errors })
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
568 );
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
569 end;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
570 elseif session.username == original_session.username
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
571 and session.host == original_session.host then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
572 session.log("debug", "mod_smacks resuming existing session %s...", get_session_id(original_session));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
573 original_session.log("debug", "mod_smacks session resumed from %s...", get_session_id(session));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
574 -- TODO: All this should move to sessionmanager (e.g. session:replace(new_session))
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
575 if original_session.conn then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
576 original_session.log("debug", "mod_smacks closing an old connection for this session");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
577 local conn = original_session.conn;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
578 c2s_sessions[conn] = nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
579 conn:close();
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
580 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
581 local migrated_session_log = session.log;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
582 original_session.ip = session.ip;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
583 original_session.conn = session.conn;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
584 original_session.send = session.send;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
585 original_session.close = session.close;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
586 original_session.filter = session.filter;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
587 original_session.filter.session = original_session;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
588 original_session.filters = session.filters;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
589 original_session.stream = session.stream;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
590 original_session.secure = session.secure;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
591 original_session.hibernating = nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
592 session.log = original_session.log;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
593 session.type = original_session.type;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
594 wrap_session(original_session, true);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
595 -- Inform xmppstream of the new session (passed to its callbacks)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
596 original_session.stream:set_session(original_session);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
597 -- Similar for connlisteners
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
598 c2s_sessions[session.conn] = original_session;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
599
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
600 original_session.send(st.stanza("resumed", { xmlns = xmlns_sm,
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
601 h = string.format("%d", original_session.handled_stanza_count), previd = id }));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
602
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
603 -- Fake an <a> with the h of the <resume/> from the client
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
604 original_session:dispatch_stanza(st.stanza("a", { xmlns = xmlns_sm,
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
605 h = stanza.attr.h }));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
606
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
607 -- Ok, we need to re-send any stanzas that the client didn't see
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
608 -- ...they are what is now left in the outgoing stanza queue
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
609 -- We have to use the send of "session" because we don't want to add our resent stanzas
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
610 -- to the outgoing queue again
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
611 local queue = original_session.outgoing_stanza_queue;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
612 session.log("debug", "resending all unacked stanzas that are still queued after resume, #queue = %d", #queue);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
613 for i=1,#queue do
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
614 session.send(queue[i]);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
615 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
616 session.log("debug", "all stanzas resent, now disabling send() in this migrated session, #queue = %d", #queue);
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
617 function session.send(stanza) -- luacheck: ignore 432
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
618 migrated_session_log("error", "Tried to send stanza on old session migrated by smacks resume (maybe there is a bug?): %s", tostring(stanza));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
619 return false;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
620 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
621 module:fire_event("smacks-hibernation-end", {origin = session, resumed = original_session, queue = queue});
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
622 request_ack_if_needed(original_session, true, "handle_resume", nil);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
623 else
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
624 module:log("warn", "Client %s@%s[%s] tried to resume stream for %s@%s[%s]",
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
625 session.username or "?", session.host or "?", session.type,
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
626 original_session.username or "?", original_session.host or "?", original_session.type);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
627 session.send(st.stanza("failed", { xmlns = xmlns_sm })
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
628 :tag("not-authorized", { xmlns = xmlns_errors }));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
629 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
630 return true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
631 end
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
632 module:hook_tag(xmlns_sm2, "resume", function (session, stanza) return handle_resume(session, stanza, xmlns_sm2); end);
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
633 module:hook_tag(xmlns_sm3, "resume", function (session, stanza) return handle_resume(session, stanza, xmlns_sm3); end);
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
634
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
635 module:hook("csi-client-active", function (event)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
636 if event.origin.smacks then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
637 request_ack_if_needed(event.origin, true, "csi-active", nil);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
638 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
639 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
640
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
641 module:hook("csi-flushing", function(event)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
642 local session = event.session;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
643 if session.smacks then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
644 if not session.awaiting_ack and not session.hibernating and not session.destroyed then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
645 session.log("debug", "Sending <r> (csi-flushing)");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
646 session.awaiting_ack = true; -- The send() call may invoke this event again, so set this first
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
647 (session.sends2s or session.send)(st.stanza("r", { xmlns = session.smacks }))
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
648 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
649 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
650 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
651
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
652 local function handle_read_timeout(event)
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
653 local session = event.session;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
654 if session.smacks then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
655 if session.awaiting_ack then
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
656 if session.awaiting_ack_timer then
11936
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
657 timer.stop(session.awaiting_ack_timer);
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
658 session.awaiting_ack_timer = nil;
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
659 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
660 if session.delayed_ack_timer then
11936
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
661 timer.stop(session.delayed_ack_timer);
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
662 session.delayed_ack_timer = nil;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
663 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
664 return false; -- Kick the session
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
665 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
666 session.log("debug", "Sending <r> (read timeout)");
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
667 (session.sends2s or session.send)(st.stanza("r", { xmlns = session.smacks }));
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
668 session.awaiting_ack = true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
669 if not session.delayed_ack_timer then
11936
3f49c35607ca mod_smacks: Fix timer lifetimes to follow session instead of module
Kim Alvefur <zash@zash.se>
parents: 11935
diff changeset
670 session.delayed_ack_timer = timer.add_task(delayed_ack_timeout, function()
11935
4d0d10fabb82 mod_smacks: Clean up compat code etc
Kim Alvefur <zash@zash.se>
parents: 11934
diff changeset
671 ack_delayed(session, nil);
11934
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
672 end);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
673 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
674 return true;
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
675 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
676 end
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
677
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
678 module:hook("s2s-read-timeout", handle_read_timeout);
65cdb1b21db3 mod_smacks: Import from prosody-modules @ eb63890ae8fc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
679 module:hook("c2s-read-timeout", handle_read_timeout);