X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=core%2Fsessionmanager.lua;h=3122c7b5d6936ed04078b3450d633b982b785d56;hb=090bf617e12f1a84c0d1d04917f771c9684a5304;hp=5d7c1c398f88c21289671b8501425949eb753311;hpb=d1f8a1a9eb85c87794145d4f269373569e4eaa1e;p=prosody.git diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua index 5d7c1c39..3122c7b5 100644 --- a/core/sessionmanager.lua +++ b/core/sessionmanager.lua @@ -1,4 +1,4 @@ --- Prosody IM v0.4 +-- Prosody IM -- Copyright (C) 2008-2009 Matthew Wild -- Copyright (C) 2008-2009 Waqas Hussain -- @@ -10,8 +10,6 @@ local tonumber, tostring = tonumber, tostring; local ipairs, pairs, print, next= ipairs, pairs, print, next; -local collectgarbage = collectgarbage; -local m_random = import("math", "random"); local format = import("string", "format"); local hosts = hosts; @@ -19,19 +17,23 @@ local full_sessions = full_sessions; local bare_sessions = bare_sessions; local modulemanager = require "core.modulemanager"; -local log = require "util.logger".init("sessionmanager"); +local logger = require "util.logger"; +local log = logger.init("sessionmanager"); local error = error; local uuid_generate = require "util.uuid".generate; local rm_load_roster = require "core.rostermanager".load_roster; local config_get = require "core.configmanager".get; local nameprep = require "util.encodings".stringprep.nameprep; +local resourceprep = require "util.encodings".stringprep.resourceprep; local fire_event = require "core.eventmanager".fire_event; - +local add_task = require "util.timer".add_task; local gettime = require "socket".gettime; local st = require "util.stanza"; +local c2s_timeout = config_get("*", "core", "c2s_timeout"); + local newproxy = newproxy; local getmetatable = getmetatable; @@ -48,8 +50,19 @@ function new_session(conn) open_sessions = open_sessions + 1; log("debug", "open sessions now: ".. open_sessions); local w = conn.write; - session.send = function (t) w(tostring(t)); end - session.ip = conn.ip(); + session.send = function (t) w(conn, tostring(t)); end + session.ip = conn:ip(); + local conn_name = "c2s"..tostring(conn):match("[a-f0-9]+$"); + session.log = logger.init(conn_name); + + if c2s_timeout then + add_task(c2s_timeout, function () + if session.type == "c2s_unauthed" then + session:close("connection-timeout"); + end + end); + end + return session; end @@ -58,16 +71,16 @@ function destroy_session(session, err) -- Remove session/resource from user's session list if session.full_jid then - hosts[session.host].events.fire_event("resource-unbind", {session=session, error=err}); - hosts[session.host].sessions[session.username].sessions[session.resource] = nil; full_sessions[session.full_jid] = nil; - + if not next(hosts[session.host].sessions[session.username].sessions) then log("debug", "All resources of %s are now offline", session.username); hosts[session.host].sessions[session.username] = nil; bare_sessions[session.username..'@'..session.host] = nil; end + + hosts[session.host].events.fire_event("resource-unbind", {session=session, error=err}); end for k in pairs(session) do @@ -93,7 +106,8 @@ function bind_resource(session, resource) if session.resource then return nil, "cancel", "already-bound", "Cannot bind multiple resources on a single connection"; end -- We don't support binding multiple resources - resource = resource or uuid_generate(); + resource = resourceprep(resource); + resource = resource ~= "" and resource or uuid_generate(); --FIXME: Randomly-generated resources must be unique per-user, and never conflict with existing if not hosts[session.host].sessions[session.username] then @@ -154,31 +168,32 @@ function streamopened(session, attr) session.host = attr.to or error("Client failed to specify destination hostname"); session.host = nameprep(session.host); session.version = tonumber(attr.version) or 0; - session.streamid = m_random(1000000, 99999999); + session.streamid = uuid_generate(); (session.log or session)("debug", "Client sent opening to %s", session.host); - - send(""); - send(format("", session.streamid, session.host)); if not hosts[session.host] then -- We don't serve this host... session:close{ condition = "host-unknown", text = "This server does not serve "..tostring(session.host)}; return; end - + + send(""); + send(format("", session.streamid, session.host)); + + (session.log or log)("debug", "Sent reply to client"); + session.notopen = nil; + -- If session.secure is *false* (not nil) then it means we /were/ encrypting -- since we now have a new stream header, session is secured if session.secure == false then session.secure = true; end - + local features = st.stanza("stream:features"); fire_event("stream-features", session, features); - + send(features); - - (session.log or log)("debug", "Sent reply to client"); - session.notopen = nil; + end function streamclosed(session) @@ -187,22 +202,32 @@ function streamclosed(session) end function send_to_available_resources(user, host, stanza) + local jid = user.."@"..host; local count = 0; - local to = stanza.attr.to; - stanza.attr.to = nil; - local h = hosts[host]; - if h and h.type == "local" then - local u = h.sessions[user]; - if u then - for k, session in pairs(u.sessions) do - if session.presence then - session.send(stanza); - count = count + 1; - end + local user = bare_sessions[jid]; + if user then + for k, session in pairs(user.sessions) do + if session.presence then + session.send(stanza); + count = count + 1; + end + end + end + return count; +end + +function send_to_interested_resources(user, host, stanza) + local jid = user.."@"..host; + local count = 0; + local user = bare_sessions[jid]; + if user then + for k, session in pairs(user.sessions) do + if session.interested then + session.send(stanza); + count = count + 1; end end end - stanza.attr.to = to; return count; end