3 local lxp = require "lxp" |
3 local lxp = require "lxp" |
4 local init_xmlhandlers = require "core.xmlhandlers" |
4 local init_xmlhandlers = require "core.xmlhandlers" |
5 local sm_new_session = require "core.sessionmanager".new_session; |
5 local sm_new_session = require "core.sessionmanager".new_session; |
6 local s2s_new_incoming = require "core.s2smanager".new_incoming; |
6 local s2s_new_incoming = require "core.s2smanager".new_incoming; |
7 local s2s_streamopened = require "core.s2smanager".streamopened; |
7 local s2s_streamopened = require "core.s2smanager".streamopened; |
|
8 local s2s_streamclosed = require "core.s2smanager".streamclosed; |
8 local s2s_destroy_session = require "core.s2smanager".destroy_session; |
9 local s2s_destroy_session = require "core.s2smanager".destroy_session; |
|
10 |
|
11 local stream_callbacks = { streamopened = s2s_streamopened, streamclosed = s2s_streamclosed }; |
9 |
12 |
10 local connlisteners_register = require "net.connlisteners".register; |
13 local connlisteners_register = require "net.connlisteners".register; |
11 |
14 |
12 local t_insert = table.insert; |
15 local t_insert = table.insert; |
13 local t_concat = table.concat; |
16 local t_concat = table.concat; |
22 |
25 |
23 -- These are session methods -- |
26 -- These are session methods -- |
24 |
27 |
25 local function session_reset_stream(session) |
28 local function session_reset_stream(session) |
26 -- Reset stream |
29 -- Reset stream |
27 local parser = lxp.new(init_xmlhandlers(session, s2s_streamopened), "|"); |
30 local parser = lxp.new(init_xmlhandlers(session, stream_callbacks), "|"); |
28 session.parser = parser; |
31 session.parser = parser; |
29 |
32 |
30 session.notopen = true; |
33 session.notopen = true; |
31 |
34 |
32 function session.data(conn, data) |
35 function session.data(conn, data) |
33 parser:parse(data); |
36 parser:parse(data); |
34 end |
37 end |
35 return true; |
38 return true; |
36 end |
39 end |
|
40 |
|
41 |
|
42 local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'}; |
|
43 local function session_close(session, reason) |
|
44 local log = session.log or log; |
|
45 if session.conn then |
|
46 if reason then |
|
47 if type(reason) == "string" then -- assume stream error |
|
48 log("info", "Disconnecting %s[%s], <stream:error> is: %s", session.host or "(unknown host)", session.type, reason); |
|
49 session.sends2s(st.stanza("stream:error"):tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' })); |
|
50 elseif type(reason) == "table" then |
|
51 if reason.condition then |
|
52 local stanza = st.stanza("stream:error"):tag(reason.condition, stream_xmlns_attr):up(); |
|
53 if reason.text then |
|
54 stanza:tag("text", stream_xmlns_attr):text(reason.text):up(); |
|
55 end |
|
56 if reason.extra then |
|
57 stanza:add_child(reason.extra); |
|
58 end |
|
59 log("info", "Disconnecting %s[%s], <stream:error> is: %s", session.host or "(unknown host)", session.type, tostring(stanza)); |
|
60 session.sends2s(stanza); |
|
61 elseif reason.name then -- a stanza |
|
62 log("info", "Disconnecting %s->%s[%s], <stream:error> is: %s", session.from_host or "(unknown host)", session.to_host or "(unknown host)", session.type, tostring(reason)); |
|
63 session.sends2s(reason); |
|
64 end |
|
65 end |
|
66 end |
|
67 session.sends2s("</stream:stream>"); |
|
68 session.conn.close(); |
|
69 xmppserver.disconnect(session.conn, "stream error"); |
|
70 end |
|
71 end |
|
72 |
37 |
73 |
38 -- End of session methods -- |
74 -- End of session methods -- |
39 |
75 |
40 function xmppserver.listener(conn, data) |
76 function xmppserver.listener(conn, data) |
41 local session = sessions[conn]; |
77 local session = sessions[conn]; |
54 session.log = log; |
90 session.log = log; |
55 |
91 |
56 print("Incoming s2s connection"); |
92 print("Incoming s2s connection"); |
57 |
93 |
58 session.reset_stream = session_reset_stream; |
94 session.reset_stream = session_reset_stream; |
|
95 session.close = session_close; |
59 |
96 |
60 session_reset_stream(session); -- Initialise, ready for use |
97 session_reset_stream(session); -- Initialise, ready for use |
61 |
98 |
62 -- FIXME: Below function should be session,stanza - and xmlhandlers should use :method() notation to call, |
99 -- FIXME: Below function should be session,stanza - and xmlhandlers should use :method() notation to call, |
63 -- this will avoid the useless indirection we have atm |
100 -- this will avoid the useless indirection we have atm |
64 -- (I'm on a mission, no time to fix now) |
101 -- (I'm on a mission, no time to fix now) |
65 |
102 |
66 -- Debug version -- |
103 -- Debug version -- |
67 local function handleerr(err) print("Traceback:", err, debug.traceback()); end |
104 local function handleerr(err) print("Traceback:", err, debug.traceback()); end |
68 session.stanza_dispatch = function (stanza) return select(2, xpcall(function () return core_process_stanza(session, stanza); end, handleerr)); end |
105 session.stanza_dispatch = function (stanza) return select(2, xpcall(function () return core_process_stanza(session, stanza); end, handleerr)); end |
69 |
|
70 -- session.stanza_dispatch = function (stanza) return core_process_stanza(session, stanza); end |
|
71 |
|
72 end |
106 end |
73 if data then |
107 if data then |
74 session.data(conn, data); |
108 session.data(conn, data); |
75 end |
109 end |
76 end |
110 end |
77 |
111 |
78 function xmppserver.disconnect(conn) |
112 function xmppserver.disconnect(conn) |
79 local session = sessions[conn]; |
113 local session = sessions[conn]; |
80 if session then |
114 if session then |
|
115 (session.log or log)("info", "s2s disconnected: %s->%s", tostring(session.from_host), tostring(session.to_host)); |
81 s2s_destroy_session(session); |
116 s2s_destroy_session(session); |
82 sessions[conn] = nil; |
117 sessions[conn] = nil; |
83 session = nil; |
118 session = nil; |
84 collectgarbage("collect"); |
119 collectgarbage("collect"); |
85 end |
120 end |