core/sessionmanager.lua
author Waqas Hussain <waqas20@gmail.com>
Sun, 16 Nov 2008 04:37:54 +0500
changeset 309 d9c8825b7332
parent 304 7b28fa8bbfe5
child 312 63e523629389
permissions -rw-r--r--
Fixed sessionmanager to use appropriate method for sending stream features
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
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
function send_to_session(session, data)
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    59
	log("debug", "Sending: %s", tostring(data));
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
	session.conn.write(tostring(data));
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    63
function make_authenticated(session, username)
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    64
	session.username = username;
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    65
	if session.type == "c2s_unauthed" then
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    66
		session.type = "c2s";
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    67
	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
    68
	return true;
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    69
end
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    70
304
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    71
-- returns true, nil on success
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    72
-- returns nil, err_type, err, err_message on failure
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    73
function bind_resource(session, resource)
304
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    74
	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
    75
	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
    76
	-- We don't support binding multiple resources
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    77
44
80d2ade0fd69 Add "uuid" library and make sessionmanager use this.
Matthew Wild <mwild1@gmail.com>
parents: 41
diff changeset
    78
	resource = resource or uuid_generate();
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    79
	--FIXME: Randomly-generated resources must be unique per-user, and never conflict with existing
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    80
	
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    81
	if not hosts[session.host].sessions[session.username] then
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    82
		hosts[session.host].sessions[session.username] = { sessions = {} };
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    83
	else
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    84
		if hosts[session.host].sessions[session.username].sessions[resource] then
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    85
			-- Resource conflict
304
7b28fa8bbfe5 Code cleanup for resource binding
Waqas Hussain <waqas20@gmail.com>
parents: 176
diff changeset
    86
			return nil, "cancel", "conflict", "Resource already exists"; -- TODO kick old resource
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    87
		end
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    88
	end
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    89
	
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    90
	session.resource = resource;
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    91
	session.full_jid = session.username .. '@' .. session.host .. '/' .. resource;
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    92
	hosts[session.host].sessions[session.username].sessions[resource] = session;
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    93
	
101
c690fa382743 Added some roster management functions
Waqas Hussain <waqas20@gmail.com>
parents: 77
diff changeset
    94
	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
    95
	
38
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    96
	return true;
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    97
end
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
    98
40
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    99
function streamopened(session, attr)
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   100
						local send = session.send;
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   101
						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
   102
			                        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
   103
			                        session.streamid = m_random(1000000, 99999999);
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   104
			                        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
   105
			                        send("<?xml version='1.0'?>");
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   106
			                        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
   107
						
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   108
						local features = {};
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   109
						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
   110
						
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   111
						send("<stream:features>");
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   112
						
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   113
						for _, feature in ipairs(features) do
309
d9c8825b7332 Fixed sessionmanager to use appropriate method for sending stream features
Waqas Hussain <waqas20@gmail.com>
parents: 304
diff changeset
   114
							send(session, tostring(feature));
40
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
 
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   117
        			                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
   118
						log("info", "Stream opened successfully");
40
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   119
						session.notopen = nil;
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   120
end
2c0147bbd81a Move stream opening handling from xmlhandlers to sessionmanager
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   121
175
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   122
function send_to_available_resources(user, host, stanza)
176
e5cd2a03891d Outbound presence subscription
Waqas Hussain <waqas20@gmail.com>
parents: 175
diff changeset
   123
	local count = 0;
175
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   124
	local to = stanza.attr.to;
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   125
	stanza.attr.to = nil;
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   126
	local h = hosts[host];
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   127
	if h and h.type == "local" then
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   128
		local u = h.sessions[user];
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   129
		if u then
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   130
			for k, session in pairs(u.sessions) do
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   131
				if session.presence then
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   132
					session.send(stanza);
176
e5cd2a03891d Outbound presence subscription
Waqas Hussain <waqas20@gmail.com>
parents: 175
diff changeset
   133
					count = count + 1;
175
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   134
				end
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
		end
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   137
	end
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   138
	stanza.attr.to = to;
176
e5cd2a03891d Outbound presence subscription
Waqas Hussain <waqas20@gmail.com>
parents: 175
diff changeset
   139
	return count;
175
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   140
end
5f71d290bb44 Routing code reorganization
Waqas Hussain <waqas20@gmail.com>
parents: 156
diff changeset
   141
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   142
return _M;