9 |
9 |
10 |
10 |
11 local logger = require "logger"; |
11 local logger = require "logger"; |
12 local log = logger.init("xmppserver_listener"); |
12 local log = logger.init("xmppserver_listener"); |
13 local lxp = require "lxp" |
13 local lxp = require "lxp" |
14 local init_xmlhandlers = require "core.xmlhandlers" |
14 local new_xmpp_stream = require "util.xmppstream".new; |
15 local s2s_new_incoming = require "core.s2smanager".new_incoming; |
15 local s2s_new_incoming = require "core.s2smanager".new_incoming; |
16 local s2s_streamopened = require "core.s2smanager".streamopened; |
16 local s2s_streamopened = require "core.s2smanager".streamopened; |
17 local s2s_streamclosed = require "core.s2smanager".streamclosed; |
17 local s2s_streamclosed = require "core.s2smanager".streamclosed; |
18 local s2s_destroy_session = require "core.s2smanager".destroy_session; |
18 local s2s_destroy_session = require "core.s2smanager".destroy_session; |
19 local s2s_attempt_connect = require "core.s2smanager".attempt_connection; |
19 local s2s_attempt_connect = require "core.s2smanager".attempt_connection; |
69 |
69 |
70 local sessions = {}; |
70 local sessions = {}; |
71 local xmppserver = { default_port = 5269, default_mode = "*a" }; |
71 local xmppserver = { default_port = 5269, default_mode = "*a" }; |
72 |
72 |
73 -- These are session methods -- |
73 -- These are session methods -- |
74 |
|
75 local function session_reset_stream(session) |
|
76 -- Reset stream |
|
77 local parser = lxp.new(init_xmlhandlers(session, stream_callbacks), "\1"); |
|
78 session.parser = parser; |
|
79 |
|
80 session.notopen = true; |
|
81 |
|
82 function session.data(conn, data) |
|
83 local ok, err = parser:parse(data); |
|
84 if ok then return; end |
|
85 (session.log or log)("warn", "Received invalid XML: %s", data); |
|
86 (session.log or log)("warn", "Problem was: %s", err); |
|
87 session:close("xml-not-well-formed"); |
|
88 end |
|
89 |
|
90 return true; |
|
91 end |
|
92 |
74 |
93 local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'}; |
75 local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'}; |
94 local default_stream_attr = { ["xmlns:stream"] = "http://etherx.jabber.org/streams", xmlns = stream_callbacks.default_ns, version = "1.0", id = "" }; |
76 local default_stream_attr = { ["xmlns:stream"] = "http://etherx.jabber.org/streams", xmlns = stream_callbacks.default_ns, version = "1.0", id = "" }; |
95 local function session_close(session, reason, remote_reason) |
77 local function session_close(session, reason, remote_reason) |
96 local log = session.log or log; |
78 local log = session.log or log; |
130 end |
112 end |
131 |
113 |
132 |
114 |
133 -- End of session methods -- |
115 -- End of session methods -- |
134 |
116 |
135 function xmppserver.onincoming(conn, data) |
117 local function initialize_session(session) |
136 local session = sessions[conn]; |
118 local stream = new_xmpp_stream(session, stream_callbacks); |
137 if not session then |
119 session.stream = stream; |
138 session = s2s_new_incoming(conn); |
120 |
|
121 session.notopen = true; |
|
122 |
|
123 function session.reset_stream() |
|
124 session.notopen = true; |
|
125 session.stream:reset(); |
|
126 end |
|
127 |
|
128 function session.data(data) |
|
129 local ok, err = stream:feed(data); |
|
130 if ok then return; end |
|
131 (session.log or log)("warn", "Received invalid XML: %s", data); |
|
132 (session.log or log)("warn", "Problem was: %s", err); |
|
133 session:close("xml-not-well-formed"); |
|
134 end |
|
135 |
|
136 session.close = session_close; |
|
137 session.dispatch_stanza = stream_callbacks.handlestanza; |
|
138 end |
|
139 |
|
140 function xmppserver.onconnect(conn) |
|
141 if not sessions[conn] then -- May be an existing outgoing session |
|
142 local session = s2s_new_incoming(conn); |
139 sessions[conn] = session; |
143 sessions[conn] = session; |
140 |
144 |
141 -- Logging functions -- |
145 -- Logging functions -- |
142 |
|
143 |
|
144 local conn_name = "s2sin"..tostring(conn):match("[a-f0-9]+$"); |
146 local conn_name = "s2sin"..tostring(conn):match("[a-f0-9]+$"); |
145 session.log = logger.init(conn_name); |
147 session.log = logger.init(conn_name); |
146 |
148 |
147 session.log("info", "Incoming s2s connection"); |
149 session.log("info", "Incoming s2s connection"); |
148 |
150 |
149 session.reset_stream = session_reset_stream; |
151 initialize_session(session); |
150 session.close = session_close; |
152 end |
151 |
153 end |
152 session_reset_stream(session); -- Initialise, ready for use |
154 |
153 |
155 function xmppserver.onincoming(conn, data) |
154 session.dispatch_stanza = stream_callbacks.handlestanza; |
156 local session = sessions[conn]; |
155 end |
157 if session then |
156 if data then |
158 session.data(data); |
157 session.data(conn, data); |
|
158 end |
159 end |
159 end |
160 end |
160 |
161 |
161 function xmppserver.onstatus(conn, status) |
162 function xmppserver.onstatus(conn, status) |
162 if status == "ssl-handshake-complete" then |
163 if status == "ssl-handshake-complete" then |
188 |
189 |
189 function xmppserver.register_outgoing(conn, session) |
190 function xmppserver.register_outgoing(conn, session) |
190 session.direction = "outgoing"; |
191 session.direction = "outgoing"; |
191 sessions[conn] = session; |
192 sessions[conn] = session; |
192 |
193 |
193 session.reset_stream = session_reset_stream; |
194 initialize_session(session); |
194 session.close = session_close; |
|
195 session_reset_stream(session); -- Initialise, ready for use |
|
196 |
|
197 --local function handleerr(err) print("Traceback:", err, debug.traceback()); end |
|
198 --session.stanza_dispatch = function (stanza) return select(2, xpcall(function () return core_process_stanza(session, stanza); end, handleerr)); end |
|
199 end |
195 end |
200 |
196 |
201 connlisteners_register("xmppserver", xmppserver); |
197 connlisteners_register("xmppserver", xmppserver); |
202 |
198 |
203 |
199 |