diff options
author | Matthew Wild <mwild1@gmail.com> | 2012-07-22 16:59:12 +0100 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2012-07-22 16:59:12 +0100 |
commit | efc4ec5efea1a4160a2651973e5cf5f5a2c3b6c3 (patch) | |
tree | 7c298aa9603c19f3284b56563aaf4c78bcc59af0 /plugins | |
parent | 16d3a8809791d5f038782617779466cc4f9321ae (diff) | |
download | prosody-efc4ec5efea1a4160a2651973e5cf5f5a2c3b6c3.tar.gz prosody-efc4ec5efea1a4160a2651973e5cf5f5a2c3b6c3.zip |
mod_c2s: Don't call ondisconnect manually on close, it is now called by net.server. Replace with inline code for destroying the session, and also waiting for a reply </stream:stream> if there is a chance of further data sent by the client. session.send() on a half-closed stream returns false (and does not deliver the data).
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/mod_c2s.lua | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 55c53e2d..75a6f689 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -24,6 +24,7 @@ local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; local log = module._log; local c2s_timeout = module:get_option_number("c2s_timeout"); +local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5); local opt_keepalives = module:get_option_boolean("tcp_keepalives", false); local sessions = module:shared("sessions"); @@ -143,8 +144,27 @@ local function session_close(session, reason) end end session.send("</stream:stream>"); - session.conn:close(); - listener.ondisconnect(session.conn, (reason and (reason.text or reason.condition)) or reason or "session closed"); + + function session.send() return false; end + + local reason = (reason and (reason.text or reason.condition)) or reason or "session closed"; + session.log("info", "c2s stream for %s closed: %s", session.full_jid or ("<"..session.ip..">"), reason); + + -- Authenticated incoming stream may still be sending us stanzas, so wait for </stream:stream> from remote + local conn = session.conn; + if reason == "session closed" and not session.notopen and session.type == "c2s" then + -- Grace time to process data from authenticated cleanly-closed stream + add_task(stream_close_timeout, function () + if not session.destroyed then + session.log("warn", "Failed to receive a stream close response, closing connection anyway..."); + sm_destroy_session(session, reason); + conn:close(); + end + end); + else + sm_destroy_session(session, reason); + conn:close(); + end end end @@ -208,10 +228,9 @@ end function listener.ondisconnect(conn, err) local session = sessions[conn]; if session then - (session.log or log)("info", "Client disconnected: %s", err); + (session.log or log)("info", "Client disconnected: %s", err or "connection closed"); sm_destroy_session(session, err); sessions[conn] = nil; - session = nil; end end |