diff options
Diffstat (limited to 'core/s2smanager.lua')
-rw-r--r-- | core/s2smanager.lua | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/core/s2smanager.lua b/core/s2smanager.lua new file mode 100644 index 00000000..06d3f2c9 --- /dev/null +++ b/core/s2smanager.lua @@ -0,0 +1,98 @@ +-- Prosody IM +-- Copyright (C) 2008-2010 Matthew Wild +-- Copyright (C) 2008-2010 Waqas Hussain +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- + + + +local hosts = prosody.hosts; +local tostring, pairs, setmetatable + = tostring, pairs, setmetatable; + +local logger_init = require "util.logger".init; + +local log = logger_init("s2smanager"); + +local prosody = _G.prosody; +incoming_s2s = {}; +prosody.incoming_s2s = incoming_s2s; +local incoming_s2s = incoming_s2s; +local fire_event = prosody.events.fire_event; + +module "s2smanager" + +function new_incoming(conn) + local session = { conn = conn, type = "s2sin_unauthed", direction = "incoming", hosts = {} }; + session.log = logger_init("s2sin"..tostring(session):match("[a-f0-9]+$")); + incoming_s2s[session] = true; + return session; +end + +function new_outgoing(from_host, to_host) + local host_session = { to_host = to_host, from_host = from_host, host = from_host, + notopen = true, type = "s2sout_unauthed", direction = "outgoing" }; + hosts[from_host].s2sout[to_host] = host_session; + local conn_name = "s2sout"..tostring(host_session):match("[a-f0-9]*$"); + host_session.log = logger_init(conn_name); + return host_session; +end + +local resting_session = { -- Resting, not dead + destroyed = true; + type = "s2s_destroyed"; + open_stream = function (session) + session.log("debug", "Attempt to open stream on resting session"); + end; + close = function (session) + session.log("debug", "Attempt to close already-closed session"); + end; + filter = function (type, data) return data; end; + }; resting_session.__index = resting_session; + +function retire_session(session, reason) + local log = session.log or log; + for k in pairs(session) do + if k ~= "log" and k ~= "id" and k ~= "conn" then + session[k] = nil; + end + end + + session.destruction_reason = reason; + + function session.send(data) log("debug", "Discarding data sent to resting session: %s", tostring(data)); end + function session.data(data) log("debug", "Discarding data received from resting session: %s", tostring(data)); end + return setmetatable(session, resting_session); +end + +function destroy_session(session, reason) + if session.destroyed then return; end + (session.log or log)("debug", "Destroying "..tostring(session.direction).." session "..tostring(session.from_host).."->"..tostring(session.to_host)..(reason and (": "..reason) or "")); + + if session.direction == "outgoing" then + hosts[session.from_host].s2sout[session.to_host] = nil; + session:bounce_sendq(reason); + elseif session.direction == "incoming" then + incoming_s2s[session] = nil; + end + + local event_data = { session = session, reason = reason }; + if session.type == "s2sout" then + fire_event("s2sout-destroyed", event_data); + if hosts[session.from_host] then + hosts[session.from_host].events.fire_event("s2sout-destroyed", event_data); + end + elseif session.type == "s2sin" then + fire_event("s2sin-destroyed", event_data); + if hosts[session.to_host] then + hosts[session.to_host].events.fire_event("s2sin-destroyed", event_data); + end + end + + retire_session(session, reason); -- Clean session until it is GC'd + return true; +end + +return _M; |