50 local smqueue = require "util.smqueue"; |
50 local smqueue = require "util.smqueue"; |
51 local st = require "util.stanza"; |
51 local st = require "util.stanza"; |
52 local timer = require "util.timer"; |
52 local timer = require "util.timer"; |
53 local new_id = require "util.id".short; |
53 local new_id = require "util.id".short; |
54 local watchdog = require "util.watchdog"; |
54 local watchdog = require "util.watchdog"; |
|
55 local it = require"util.iterators"; |
55 |
56 |
56 local sessionmanager = require "core.sessionmanager"; |
57 local sessionmanager = require "core.sessionmanager"; |
57 local core_process_stanza = prosody.core_process_stanza; |
58 local core_process_stanza = prosody.core_process_stanza; |
58 |
59 |
59 local xmlns_errors = "urn:ietf:params:xml:ns:xmpp-stanzas"; |
60 local xmlns_errors = "urn:ietf:params:xml:ns:xmpp-stanzas"; |
70 local s2s_smacks = module:get_option_boolean("smacks_enabled_s2s", true); |
71 local s2s_smacks = module:get_option_boolean("smacks_enabled_s2s", true); |
71 local s2s_resend = module:get_option_boolean("smacks_s2s_resend", false); |
72 local s2s_resend = module:get_option_boolean("smacks_s2s_resend", false); |
72 local max_unacked_stanzas = module:get_option_number("smacks_max_unacked_stanzas", 0); |
73 local max_unacked_stanzas = module:get_option_number("smacks_max_unacked_stanzas", 0); |
73 local max_inactive_unacked_stanzas = module:get_option_number("smacks_max_inactive_unacked_stanzas", 256); |
74 local max_inactive_unacked_stanzas = module:get_option_number("smacks_max_inactive_unacked_stanzas", 256); |
74 local delayed_ack_timeout = module:get_option_number("smacks_max_ack_delay", 30); |
75 local delayed_ack_timeout = module:get_option_number("smacks_max_ack_delay", 30); |
|
76 local max_old_sessions = module:get_option_number("smacks_max_old_sessions", 10); |
75 |
77 |
76 local c2s_sessions = module:shared("/*/c2s/sessions"); |
78 local c2s_sessions = module:shared("/*/c2s/sessions"); |
77 local local_sessions = prosody.hosts[module.host].sessions; |
79 local local_sessions = prosody.hosts[module.host].sessions; |
78 |
80 |
79 local function format_h(h) if h then return string.format("%d", h) end end |
81 local function format_h(h) if h then return string.format("%d", h) end end |
80 |
82 |
|
83 local all_old_sessions = module:open_store("smacks_h"); |
81 local old_session_registry = module:open_store("smacks_h", "map"); |
84 local old_session_registry = module:open_store("smacks_h", "map"); |
82 local session_registry = module:shared "/*/smacks/resumption-tokens"; -- > user@host/resumption-token --> resource |
85 local session_registry = module:shared "/*/smacks/resumption-tokens"; -- > user@host/resumption-token --> resource |
83 |
86 |
84 local ack_errors = require"util.error".init("mod_smacks", xmlns_sm3, { |
87 local ack_errors = require"util.error".init("mod_smacks", xmlns_sm3, { |
85 head = { condition = "undefined-condition"; text = "Client acknowledged more stanzas than sent by server" }; |
88 head = { condition = "undefined-condition"; text = "Client acknowledged more stanzas than sent by server" }; |
277 local ok, err, err_text = can_do_smacks(session); |
280 local ok, err, err_text = can_do_smacks(session); |
278 if not ok then |
281 if not ok then |
279 session.log("warn", "Failed to enable smacks: %s", err_text); -- TODO: XEP doesn't say we can send error text, should it? |
282 session.log("warn", "Failed to enable smacks: %s", err_text); -- TODO: XEP doesn't say we can send error text, should it? |
280 (session.sends2s or session.send)(st.stanza("failed", { xmlns = xmlns_sm }):tag(err, { xmlns = xmlns_errors})); |
283 (session.sends2s or session.send)(st.stanza("failed", { xmlns = xmlns_sm }):tag(err, { xmlns = xmlns_errors})); |
281 return true; |
284 return true; |
|
285 end |
|
286 |
|
287 if session.username then |
|
288 local old_sessions, err = all_old_sessions:get(session.username); |
|
289 module:log("debug", "Old sessions: %q", old_sessions) |
|
290 if old_sessions then |
|
291 local keep, count = {}, 0; |
|
292 for token, info in it.sorted_pairs(old_sessions, function(a, b) |
|
293 return (old_sessions[a].t or 0) > (old_sessions[b].t or 0); |
|
294 end) do |
|
295 count = count + 1; |
|
296 if count > max_old_sessions then break end |
|
297 keep[token] = info; |
|
298 end |
|
299 all_old_sessions:set(session.username, keep); |
|
300 end |
282 end |
301 end |
283 |
302 |
284 module:log("debug", "Enabling stream management"); |
303 module:log("debug", "Enabling stream management"); |
285 session.smacks = xmlns_sm; |
304 session.smacks = xmlns_sm; |
286 |
305 |