6 local os_time = os.time; |
6 local os_time = os.time; |
7 local tonumber, tostring = tonumber, tostring; |
7 local tonumber, tostring = tonumber, tostring; |
8 local add_filter = require "util.filters".add_filter; |
8 local add_filter = require "util.filters".add_filter; |
9 local timer = require "util.timer"; |
9 local timer = require "util.timer"; |
10 local datetime = require "util.datetime"; |
10 local datetime = require "util.datetime"; |
11 local tb = require"util.debug".traceback; |
|
12 |
11 |
13 local xmlns_sm2 = "urn:xmpp:sm:2"; |
12 local xmlns_sm2 = "urn:xmpp:sm:2"; |
14 local xmlns_sm3 = "urn:xmpp:sm:3"; |
13 local xmlns_sm3 = "urn:xmpp:sm:3"; |
15 local xmlns_errors = "urn:ietf:params:xml:ns:xmpp-stanzas"; |
14 local xmlns_errors = "urn:ietf:params:xml:ns:xmpp-stanzas"; |
16 local xmlns_delay = "urn:xmpp:delay"; |
15 local xmlns_delay = "urn:xmpp:delay"; |
83 |
82 |
84 local _send = session.sends2s or session.send; |
83 local _send = session.sends2s or session.send; |
85 local function new_send(stanza) |
84 local function new_send(stanza) |
86 local attr = stanza.attr; |
85 local attr = stanza.attr; |
87 if attr and not attr.xmlns then -- Stanza in default stream namespace |
86 if attr and not attr.xmlns then -- Stanza in default stream namespace |
88 session.log("debug", "Sending stanza %s", stanza:top_tag()); |
|
89 local cached_stanza = st.clone(stanza); |
87 local cached_stanza = st.clone(stanza); |
90 |
88 |
91 if cached_stanza and cached_stanza:get_child("delay", xmlns_delay) == nil then |
89 if cached_stanza and cached_stanza:get_child("delay", xmlns_delay) == nil then |
92 cached_stanza = cached_stanza:tag("delay", { xmlns = xmlns_delay, from = session.host, stamp = datetime.datetime()}); |
90 cached_stanza = cached_stanza:tag("delay", { xmlns = xmlns_delay, from = session.host, stamp = datetime.datetime()}); |
93 end |
91 end |
94 |
92 |
95 queue[#queue+1] = cached_stanza; |
93 queue[#queue+1] = cached_stanza; |
96 session.log("debug", "#queue = %d", #queue); |
|
97 end |
94 end |
98 if session.hibernating then |
95 if session.hibernating then |
99 session.log("debug", "hibernating, stanza queued") |
|
100 -- The session is hibernating, no point in sending the stanza |
96 -- The session is hibernating, no point in sending the stanza |
101 -- over a dead connection. It will be delivered upon resumption. |
97 -- over a dead connection. It will be delivered upon resumption. |
102 return true; |
98 return true; |
103 end |
99 end |
104 local ok, err = _send(stanza); |
100 local ok, err = _send(stanza); |
206 end |
202 end |
207 end |
203 end |
208 for i=1,math_min(handled_stanza_count,#queue) do |
204 for i=1,math_min(handled_stanza_count,#queue) do |
209 t_remove(origin.outgoing_stanza_queue, 1); |
205 t_remove(origin.outgoing_stanza_queue, 1); |
210 end |
206 end |
211 origin.log("debug", "#queue = %d", #queue); |
|
212 origin.last_acknowledged_stanza = origin.last_acknowledged_stanza + handled_stanza_count; |
207 origin.last_acknowledged_stanza = origin.last_acknowledged_stanza + handled_stanza_count; |
213 return true; |
208 return true; |
214 end |
209 end |
215 module:hook_stanza(xmlns_sm2, "a", handle_a); |
210 module:hook_stanza(xmlns_sm2, "a", handle_a); |
216 module:hook_stanza(xmlns_sm3, "a", handle_a); |
211 module:hook_stanza(xmlns_sm3, "a", handle_a); |
336 h = stanza.attr.h })); |
331 h = stanza.attr.h })); |
337 |
332 |
338 -- Ok, we need to re-send any stanzas that the client didn't see |
333 -- Ok, we need to re-send any stanzas that the client didn't see |
339 -- ...they are what is now left in the outgoing stanza queue |
334 -- ...they are what is now left in the outgoing stanza queue |
340 local queue = original_session.outgoing_stanza_queue; |
335 local queue = original_session.outgoing_stanza_queue; |
341 session.log("debug", "#queue = %d", #queue); |
|
342 for i=1,#queue do |
336 for i=1,#queue do |
343 session.send(queue[i]); |
337 session.send(queue[i]); |
344 end |
338 end |
345 session.log("debug", "#queue = %d -- after send", #queue); |
|
346 else |
339 else |
347 module:log("warn", "Client %s@%s[%s] tried to resume stream for %s@%s[%s]", |
340 module:log("warn", "Client %s@%s[%s] tried to resume stream for %s@%s[%s]", |
348 session.username or "?", session.host or "?", session.type, |
341 session.username or "?", session.host or "?", session.type, |
349 original_session.username or "?", original_session.host or "?", original_session.type); |
342 original_session.username or "?", original_session.host or "?", original_session.type); |
350 session.send(st.stanza("failed", { xmlns = xmlns_sm }) |
343 session.send(st.stanza("failed", { xmlns = xmlns_sm }) |