-
---- Closing a component connection
-local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'};
-local function session_close(session, reason)
- local log = session.log or log;
- if session.conn then
- if reason then
- if type(reason) == "string" then -- assume stream error
- log("info", "Disconnecting component, <stream:error> is: %s", reason);
- session.send(st.stanza("stream:error"):tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' }));
- elseif type(reason) == "table" then
- if reason.condition then
- local stanza = st.stanza("stream:error"):tag(reason.condition, stream_xmlns_attr):up();
- if reason.text then
- stanza:tag("text", stream_xmlns_attr):text(reason.text):up();
- end
- if reason.extra then
- stanza:add_child(reason.extra);
- end
- log("info", "Disconnecting component, <stream:error> is: %s", tostring(stanza));
- session.send(stanza);
- elseif reason.name then -- a stanza
- log("info", "Disconnecting component, <stream:error> is: %s", tostring(reason));
- session.send(reason);
- end
- end
- end
- session.send("</stream:stream>");
- session.conn.close();
- component_listener.disconnect(session.conn, "stream error");
- end
-end
-
---- Component connlistener
-function component_listener.listener(conn, data)
- local session = sessions[conn];
- if not session then
- local _send = conn.write;
- session = { type = "component", conn = conn, send = function (data) return _send(tostring(data)); end };
- sessions[conn] = session;
-
- -- Logging functions --
-
- local conn_name = "xep114-"..tostring(conn):match("[a-f0-9]+$");
- session.log = logger.init(conn_name);
- session.close = session_close;
-
- session.log("info", "Incoming XEP-0114 connection");
-
- local parser = lxp.new(init_xmlhandlers(session, stream_callbacks), "|");
- session.parser = parser;
-
- session.notopen = true;
-
- function session.data(conn, data)
- local ok, err = parser:parse(data);
- if ok then return; end
- session:close("xml-not-well-formed");
- end
-
- session.dispatch_stanza = stream_callbacks.handlestanza;
-
- end
- if data then
- session.data(conn, data);
- end
-end
-
-function component_listener.disconnect(conn, err)
- local session = sessions[conn];
- if session then
- (session.log or log)("info", "component disconnected: %s (%s)", tostring(session.host), tostring(err));
- if session.host then
- log("debug", "deregistering component");
- cm_deregister_component(session.host);
- hosts[session.host].connected = nil;
- end
- sessions[conn] = nil;
- session = nil;
- collectgarbage("collect");
- end
-end
-
-connlisteners.register('component', component_listener);
-
-module:add_event_hook("server-started",
- function ()
- if _G.net_activate_ports then
- _G.net_activate_ports("component", "component", {5437}, "tcp");
- else
- error("No net_activate_ports: Using an incompatible version of Prosody?");
- end
- end);