2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
11 local hosts
= prosody
.hosts
;
12 local pairs
, setmetatable
= pairs
, setmetatable
;
14 local logger_init
= require
"util.logger".init
;
15 local sessionlib
= require
"util.session";
17 local log = logger_init("s2smanager");
19 local prosody
= _G
.prosody
;
20 local incoming_s2s
= {};
21 _G
.incoming_s2s
= incoming_s2s
;
22 prosody
.incoming_s2s
= incoming_s2s
;
23 local fire_event
= prosody
.events
.fire_event
;
28 local function new_incoming(conn
)
29 local host_session
= sessionlib
.new("s2sin");
30 sessionlib
.set_id(host_session
);
31 sessionlib
.set_logger(host_session
);
32 sessionlib
.set_conn(host_session
, conn
);
33 host_session
.direction
= "incoming";
34 host_session
.incoming
= true;
35 host_session
.hosts
= {};
36 incoming_s2s
[host_session
] = true;
40 local function new_outgoing(from_host
, to_host
)
41 local host_session
= sessionlib
.new("s2sout");
42 sessionlib
.set_id(host_session
);
43 sessionlib
.set_logger(host_session
);
44 host_session
.to_host
= to_host
;
45 host_session
.from_host
= from_host
;
46 host_session
.host
= from_host
;
47 host_session
.notopen
= true;
48 host_session
.direction
= "outgoing";
49 host_session
.outgoing
= true;
50 host_session
.hosts
= {};
51 hosts
[from_host
].s2sout
[to_host
] = host_session
;
55 local resting_session
= { -- Resting, not dead
57 type = "s2s_destroyed";
58 open_stream
= function (session
)
59 session
.log("debug", "Attempt to open stream on resting session");
61 close
= function (session
)
62 session
.log("debug", "Attempt to close already-closed session");
64 reset_stream
= function (session
)
65 session
.log("debug", "Attempt to reset stream of already-closed session");
67 filter
= function (type, data
) return data
; end; --luacheck: ignore 212/type
68 }; resting_session
.__index
= resting_session
;
70 local function retire_session(session
, reason
)
71 local log = session
.log or log; --luacheck: ignore 431/log
72 for k
in pairs(session
) do
73 if k
~= "log" and k
~= "id" and k
~= "conn" then
78 session
.destruction_reason
= reason
;
80 function session
.send(data
) log("debug", "Discarding data sent to resting session: %s", data
); end
81 function session
.data(data
) log("debug", "Discarding data received from resting session: %s", data
); end
82 session
.thread
= { run
= function (_
, data
) return session
.data(data
) end };
83 session
.sends2s
= session
.send
;
84 return setmetatable(session
, resting_session
);
87 local function destroy_session(session
, reason
)
88 if session
.destroyed
then return; end
89 local log = session
.log or log;
90 log("debug", "Destroying %s session %s->%s%s%s", session
.direction
, session
.from_host
, session
.to_host
, reason
and ": " or "", reason
or "");
92 if session
.direction
== "outgoing" then
93 hosts
[session
.from_host
].s2sout
[session
.to_host
] = nil;
94 session
:bounce_sendq(reason
);
95 elseif session
.direction
== "incoming" then
96 incoming_s2s
[session
] = nil;
99 local event_data
= { session
= session
, reason
= reason
};
100 if session
.type == "s2sout" then
101 fire_event("s2sout-destroyed", event_data
);
102 if hosts
[session
.from_host
] then
103 hosts
[session
.from_host
].events
.fire_event("s2sout-destroyed", event_data
);
105 elseif session
.type == "s2sin" then
106 fire_event("s2sin-destroyed", event_data
);
107 if hosts
[session
.to_host
] then
108 hosts
[session
.to_host
].events
.fire_event("s2sin-destroyed", event_data
);
112 retire_session(session
, reason
); -- Clean session until it is GC'd
117 incoming_s2s
= incoming_s2s
;
118 new_incoming
= new_incoming
;
119 new_outgoing
= new_outgoing
;
120 retire_session
= retire_session
;
121 destroy_session
= destroy_session
;