From 7c1372811acef73a712f6182c5a268b500b40ee8 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 22 Jul 2012 16:45:27 +0100 Subject: mod_s2s: Make unauthed session timeout a little more aggressive... otherwise it's possible for sessions to slip under the net and never get killed off --- plugins/mod_s2s/mod_s2s.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'plugins/mod_s2s/mod_s2s.lua') diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index f6c20606..1dbdc6ee 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -413,11 +413,9 @@ local function initialize_session(session) return handlestanza(session, stanza); end - local conn = session.conn; add_task(connect_timeout, function () - if session.conn ~= conn or session.connecting - or session.type == "s2sin" or session.type == "s2sout" then - return; -- Ok, we're connect[ed|ing] + if session.type == "s2sin" or session.type == "s2sout" then + return; -- Ok, we're connected end -- Not connected, need to close session and clean up (session.log or log)("debug", "Destroying incomplete session %s->%s due to inactivity", -- cgit v1.2.3 From ef597cb9a9a2793fe9b071f887848ca1c4d73d4d Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 22 Jul 2012 17:04:02 +0100 Subject: mod_s2s: Don't treat a stanza as delivered if session.sends2s() returns false --- plugins/mod_s2s/mod_s2s.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'plugins/mod_s2s/mod_s2s.lua') diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 1dbdc6ee..8b1c7dab 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -97,9 +97,10 @@ function route_to_existing_session(event) log("error", "WARNING! This might, possibly, be a bug, but it might not..."); log("error", "We are going to send from %s instead of %s", tostring(host.from_host), tostring(from_host)); end - host.sends2s(stanza); - host.log("debug", "stanza sent over "..host.type); - return true; + if host.sends2s(stanza) then + host.log("debug", "stanza sent over "..host.type); + return true; + end end end end -- cgit v1.2.3 From 193ea4ef3030ab24da31f86031f6ea8386331099 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 22 Jul 2012 17:07:21 +0100 Subject: mod_s2s: Don't call ondisconnect manually, don't call conn:close() 3 times (!) and merge its logic and streamdisconnected into session_close - including now waiting for a reply if there is the chance of further stanzas requiring delivery arriving. session.sends2s() on a half-closed stream returns false. --- plugins/mod_s2s/mod_s2s.lua | 48 +++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'plugins/mod_s2s/mod_s2s.lua') diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 8b1c7dab..f686fcfb 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -31,6 +31,7 @@ local cert_verify_identity = require "util.x509".verify_identity; local s2sout = module:require("s2sout"); local connect_timeout = module:get_option_number("s2s_timeout", 60); +local stream_close_timeout = module:get_option_number("s2s_close_timeout", 5); local sessions = module:shared("sessions"); @@ -292,18 +293,6 @@ function stream_callbacks.streamclosed(session) session:close(); end -function stream_callbacks.streamdisconnected(session, err) - if err and err ~= "closed" and session.direction == "outgoing" and session.notopen then - (session.log or log)("debug", "s2s connection attempt failed: %s", err); - if s2sout.attempt_connection(session, err) then - (session.log or log)("debug", "...so we're going to try another target"); - return true; -- Session lives for now - end - end - (session.log or log)("info", "s2s disconnected: %s->%s (%s)", tostring(session.from_host), tostring(session.to_host), tostring(err or "closed")); - s2s_destroy_session(session, err); -end - function stream_callbacks.error(session, error, data) if error == "no-stream" then session:close("invalid-namespace"); @@ -375,11 +364,26 @@ local function session_close(session, reason, remote_reason) end end session.sends2s(""); - if session.notopen or not session.conn:close() then - session.conn:close(true); -- Force FIXME: timer? + + function session.sends2s() return false; end + + local reason = remote_reason or (reason and (reason.text or reason.condition)) or reason or "stream closed"; + session.log("info", "%s s2s stream %s->%s closed: %s", session.direction, session.from_host or "(unknown host)", session.to_host or "(unknown host)", reason); + + -- Authenticated incoming stream may still be sending us stanzas, so wait for from remote + local conn = session.conn; + if not session.notopen and session.type == "s2sin" then + add_task(stream_close_timeout, function () + if not session.destroyed then + session.log("warn", "Failed to receive a stream close response, closing connection anyway..."); + s2s_destroy_session(session, reason); + conn:close(); + end + end); + else + s2s_destroy_session(session, reason); + conn:close(); -- Close immediately, as this is an outgoing connection or is not authed end - session.conn:close(); - listener.ondisconnect(session.conn, remote_reason or (reason and (reason.text or reason.condition)) or reason or "stream closed"); end end @@ -473,11 +477,17 @@ end function listener.ondisconnect(conn, err) local session = sessions[conn]; if session then - if stream_callbacks.streamdisconnected(session, err) then - return; -- Connection lives, for now + if err and session.direction == "outgoing" and session.notopen then + (session.log or log)("debug", "s2s connection attempt failed: %s", err); + if s2sout.attempt_connection(session, err) then + (session.log or log)("debug", "...so we're going to try another target"); + return; -- Session lives for now + end end + (session.log or log)("debug", "s2s disconnected: %s->%s (%s)", tostring(session.from_host), tostring(session.to_host), tostring(err or "connection closed")); + s2s_destroy_session(session, err); + sessions[conn] = nil; end - sessions[conn] = nil; end function listener.register_outgoing(conn, session) -- cgit v1.2.3