# HG changeset patch # User Matthew Wild # Date 1342972752 -3600 # Node ID c9b8ec3eb1e9388f033a3b5fd548f7cdcc3b4585 # Parent 54e2c83af127fff417c503e8932b178f4d1c93b7 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 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). diff -r 54e2c83af127 -r c9b8ec3eb1e9 plugins/mod_c2s.lua --- a/plugins/mod_c2s.lua Sun Jul 22 16:54:58 2012 +0100 +++ b/plugins/mod_c2s.lua Sun Jul 22 16:59:12 2012 +0100 @@ -24,6 +24,7 @@ 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 @@ end end session.send(""); - 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 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 @@ 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