aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_c2s.lua
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2012-07-22 16:59:12 +0100
committerMatthew Wild <mwild1@gmail.com>2012-07-22 16:59:12 +0100
commit3424d79abb28d65288331e5ff7c2cca17c280e89 (patch)
tree7c298aa9603c19f3284b56563aaf4c78bcc59af0 /plugins/mod_c2s.lua
parentef888131115082b3a54a568128101cf442475dce (diff)
downloadprosody-3424d79abb28d65288331e5ff7c2cca17c280e89.tar.gz
prosody-3424d79abb28d65288331e5ff7c2cca17c280e89.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/mod_c2s.lua')
-rw-r--r--plugins/mod_c2s.lua27
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