local c2s_timeout = module:get_option_number("c2s_timeout");
local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5);
-local opt_keepalives = module:get_option_boolean("tcp_keepalives", false);
+local opt_keepalives = module:get_option_boolean("c2s_tcp_keepalives", module:get_option_boolean("tcp_keepalives", true));
local sessions = module:shared("sessions");
local core_process_stanza = prosody.core_process_stanza;
session.streamid = uuid_generate();
(session.log or session)("debug", "Client sent opening <stream:stream> to %s", session.host);
- if not hosts[session.host] then
+ if not hosts[session.host] or not hosts[session.host].users then
-- We don't serve this host...
session:close{ condition = "host-unknown", text = "This server does not serve "..tostring(session.host)};
return;
function stream_callbacks.error(session, error, data)
if error == "no-stream" then
- session.log("debug", "Invalid opening stream header");
+ session.log("debug", "Invalid opening stream header (%s)", (data:gsub("^([^\1]+)\1", "{%1}")));
session:close("invalid-namespace");
elseif error == "parse-error" then
(session.log or log)("debug", "Client XML parse error: %s", tostring(data));
session.send(st.stanza("stream:stream", default_stream_attr):top_tag());
end
if reason then -- nil == no err, initiated by us, false == initiated by client
+ local stream_error = st.stanza("stream:error");
if type(reason) == "string" then -- assume stream error
- log("debug", "Disconnecting client, <stream:error> is: %s", reason);
- session.send(st.stanza("stream:error"):tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' }));
+ 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();
+ stream_error:tag(reason.condition, stream_xmlns_attr):up();
if reason.text then
- stanza:tag("text", stream_xmlns_attr):text(reason.text):up();
+ stream_error:tag("text", stream_xmlns_attr):text(reason.text):up();
end
if reason.extra then
- stanza:add_child(reason.extra);
+ stream_error:add_child(reason.extra);
end
- log("debug", "Disconnecting client, <stream:error> is: %s", tostring(stanza));
- session.send(stanza);
elseif reason.name then -- a stanza
- log("debug", "Disconnecting client, <stream:error> is: %s", tostring(reason));
- session.send(reason);
+ stream_error = reason;
end
end
+ stream_error = tostring(stream_error);
+ log("debug", "Disconnecting client, <stream:error> is: %s", stream_error);
+ session.send(stream_error);
end
session.send("</stream:stream>");
function session.send() return false; end
- local reason = (reason and (reason.text or reason.condition)) or reason;
+ local reason = (reason and (reason.name or reason.text or reason.condition)) or reason;
session.log("info", "c2s stream for %s closed: %s", session.full_jid or ("<"..session.ip..">"), reason or "session closed");
-- Authenticated incoming stream may still be sending us stanzas, so wait for </stream:stream> from remote
sessions[conn] = session;
end
+function listener.ondetach(conn)
+ sessions[conn] = nil;
+end
+
module:hook("server-stopping", function(event)
local reason = event.reason;
for _, session in pairs(sessions) do