core/sessionmanager.lua
author Waqas Hussain <waqas20@gmail.com>
Sun, 16 Nov 2008 05:06:38 +0500
changeset 317 dcb5bce69a0f
parent 312 63e523629389
child 329 3be63719428e
permissions -rw-r--r--
Removed unused function send_to_session from sessionmanager (send_to_session replaced by session.send)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
40
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
     2
local tonumber, tostring = tonumber, tostring;
126
63863534b1f1 Final fix for marking user offline when all resources are gone :)
Matthew Wild <mwild1@gmail.com>
parents: 125
diff changeset
     3
local ipairs, pairs, print, next= ipairs, pairs, print, next;
53
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
     4
local collectgarbage = collectgarbage;
49
1cd2a8db392d New "import" module to help tidy up all the local declarations at the top of modules
Matthew Wild <mwild1@gmail.com>
parents: 44
diff changeset
     5
local m_random = import("math", "random");
1cd2a8db392d New "import" module to help tidy up all the local declarations at the top of modules
Matthew Wild <mwild1@gmail.com>
parents: 44
diff changeset
     6
local format = import("string", "format");
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
     7
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
     8
local hosts = hosts;
53
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
     9
local sessions = sessions;
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    10
40
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    11
local modulemanager = require "core.modulemanager";
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
local log = require "util.logger".init("sessionmanager");
40
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    13
local error = error;
145
fbb3a4ff9cf1 dialback keys now verified
Matthew Wild <mwild1@gmail.com>
parents: 126
diff changeset
    14
local uuid_generate = require "util.uuid".generate;
101
c690fa382743 Added some roster management functions
Waqas Hussain <waqas20@gmail.com>
parents: 77
diff changeset
    15
local rm_load_roster = require "core.rostermanager".load_roster;
53
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    16
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    17
local newproxy = newproxy;
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    18
local getmetatable = getmetatable;
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    19
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
module "sessionmanager"
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
123
ebd65feb188c Fix for not destroying sessions when connection closed.
Matthew Wild <mwild1@gmail.com>
parents: 118
diff changeset
    22
local open_sessions = 0;
ebd65feb188c Fix for not destroying sessions when connection closed.
Matthew Wild <mwild1@gmail.com>
parents: 118
diff changeset
    23
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
function new_session(conn)
99
ba08b8a4eeef Abstract connections with "connection listeners"
Matthew Wild <mwild1@gmail.com>
parents: 77
diff changeset
    25
	local session = { conn = conn,  priority = 0, type = "c2s_unauthed" };
53
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    26
	if true then
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    27
		session.trace = newproxy(true);
123
ebd65feb188c Fix for not destroying sessions when connection closed.
Matthew Wild <mwild1@gmail.com>
parents: 118
diff changeset
    28
		getmetatable(session.trace).__gc = function () open_sessions = open_sessions - 1; print("Session got collected, now "..open_sessions.." sessions are allocated") end;
53
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    29
	end
123
ebd65feb188c Fix for not destroying sessions when connection closed.
Matthew Wild <mwild1@gmail.com>
parents: 118
diff changeset
    30
	open_sessions = open_sessions + 1;
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
	local w = conn.write;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
	session.send = function (t) w(tostring(t)); end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
	return session;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    36
function destroy_session(session)
156
884c43c7028a Fix for sessionmanager to not throw error when session doesn't have a private logger
Matthew Wild <mwild1@gmail.com>
parents: 150
diff changeset
    37
	(session.log or log)("info", "Destroying session");
148
4c0dcd245d34 s2s works! \o/ \o/
Matthew Wild <mwild1@gmail.com>
parents: 145
diff changeset
    38
	if session.host and session.username then
53
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    39
		if session.resource then
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    40
			hosts[session.host].sessions[session.username].sessions[session.resource] = nil;
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    41
		end
148
4c0dcd245d34 s2s works! \o/ \o/
Matthew Wild <mwild1@gmail.com>
parents: 145
diff changeset
    42
		if hosts[session.host] and hosts[session.host].sessions[session.username] then
4c0dcd245d34 s2s works! \o/ \o/
Matthew Wild <mwild1@gmail.com>
parents: 145
diff changeset
    43
			if not next(hosts[session.host].sessions[session.username].sessions) then
4c0dcd245d34 s2s works! \o/ \o/
Matthew Wild <mwild1@gmail.com>
parents: 145
diff changeset
    44
				log("debug", "All resources of %s are now offline", session.username);
4c0dcd245d34 s2s works! \o/ \o/
Matthew Wild <mwild1@gmail.com>
parents: 145
diff changeset
    45
				hosts[session.host].sessions[session.username] = nil;
4c0dcd245d34 s2s works! \o/ \o/
Matthew Wild <mwild1@gmail.com>
parents: 145
diff changeset
    46
			end
53
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    47
		end
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    48
	end
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    49
	session.conn = nil;
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    50
	session.disconnect = nil;
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    51
	for k in pairs(session) do
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    52
		if k ~= "trace" then
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    53
			session[k] = nil;
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    54
		end
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    55
	end
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    56
end
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    57
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    58
function make_authenticated(session, username)
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    59
	session.username = username;
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    60
	if session.type == "c2s_unauthed" then
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    61
		session.type = "c2s";
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    62
	end
53
14ea0fe6ca86 Session destruction fixes, some debugging code while we fix the rest. Also change logger to be more useful.
Matthew Wild <mwild1@gmail.com>
parents: 49
diff changeset
    63
	return true;
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    64
end
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    65
304
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    66
-- returns true, nil on success
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    67
-- returns nil, err_type, err, err_message on failure
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    68
function bind_resource(session, resource)
304
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    69
	if not session.username then return nil, "auth", "not-authorized", "Cannot bind resource before authentication"; end
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    70
	if session.resource then return nil, "cancel", "already-bound", "Cannot bind multiple resources on a single connection"; end
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    71
	-- We don't support binding multiple resources
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    72
44
80d2ade0fd69 Add "uuid" library and make sessionmanager use this.
Matthew Wild <mwild1@gmail.com>
parents: 41
diff changeset
    73
	resource = resource or uuid_generate();
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    74
	--FIXME: Randomly-generated resources must be unique per-user, and never conflict with existing
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    75
	
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    76
	if not hosts[session.host].sessions[session.username] then
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    77
		hosts[session.host].sessions[session.username] = { sessions = {} };
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    78
	else
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    79
		if hosts[session.host].sessions[session.username].sessions[resource] then
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    80
			-- Resource conflict
304
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    81
			return nil, "cancel", "conflict", "Resource already exists"; -- TODO kick old resource
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    82
		end
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    83
	end
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    84
	
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    85
	session.resource = resource;
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    86
	session.full_jid = session.username .. '@' .. session.host .. '/' .. resource;
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    87
	hosts[session.host].sessions[session.username].sessions[resource] = session;
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    88
	
101
c690fa382743 Added some roster management functions
Waqas Hussain <waqas20@gmail.com>
parents: 77
diff changeset
    89
	session.roster = rm_load_roster(session.username, session.host);
77
531b981f2d17 Load roster on resource bind
Waqas Hussain <waqas20@gmail.com>
parents: 57
diff changeset
    90
	
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    91
	return true;
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    92
end
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    93
40
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    94
function streamopened(session, attr)
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    95
						local send = session.send;
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    96
						session.host = attr.to or error("Client failed to specify destination hostname");
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    97
			                        session.version = tonumber(attr.version) or 0;
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    98
			                        session.streamid = m_random(1000000, 99999999);
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    99
			                        print(session, session.host, "Client opened stream");
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   100
			                        send("<?xml version='1.0'?>");
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   101
			                        send(format("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='%s' from='%s' version='1.0'>", session.streamid, session.host));
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   102
						
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   103
						local features = {};
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   104
						modulemanager.fire_event("stream-features", session, features);
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   105
						
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   106
						send("<stream:features>");
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   107
						
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   108
						for _, feature in ipairs(features) do
312
63e523629389 Fixed sessionmanager to not send session in place of stream features...
Waqas Hussain <waqas20@gmail.com>
parents: 309
diff changeset
   109
							send(tostring(feature));
40
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   110
						end
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   111
 
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   112
        			                send("</stream:features>");
49
1cd2a8db392d New "import" module to help tidy up all the local declarations at the top of modules
Matthew Wild <mwild1@gmail.com>
parents: 44
diff changeset
   113
						log("info", "Stream opened successfully");
40
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   114
						session.notopen = nil;
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   115
end
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   116
175
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   117
function send_to_available_resources(user, host, stanza)
176
e5cd2a03891d Outbound presence subscription
Waqas Hussain <waqas20@gmail.com>
parents: 175
diff changeset
   118
	local count = 0;
175
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   119
	local to = stanza.attr.to;
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   120
	stanza.attr.to = nil;
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   121
	local h = hosts[host];
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   122
	if h and h.type == "local" then
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   123
		local u = h.sessions[user];
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   124
		if u then
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   125
			for k, session in pairs(u.sessions) do
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   126
				if session.presence then
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   127
					session.send(stanza);
176
e5cd2a03891d Outbound presence subscription
Waqas Hussain <waqas20@gmail.com>
parents: 175
diff changeset
   128
					count = count + 1;
175
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   129
				end
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   130
			end
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   131
		end
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   132
	end
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   133
	stanza.attr.to = to;
176
e5cd2a03891d Outbound presence subscription
Waqas Hussain <waqas20@gmail.com>
parents: 175
diff changeset
   134
	return count;
175
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   135
end
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   136
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   137
return _M;