core/stanza_router.lua
author Matthew Wild <mwild1@gmail.com>
Wed, 01 May 2013 13:54:44 +0100
branchtls
changeset 5556 7407b1160b46
parent 66 018705d57f09
child 68 ceb7a55676a4
permissions -rw-r--r--
Close 'tls' branch
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
-- The code in this file should be self-explanatory, though the logic is horrible
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
-- for more info on that, see doc/stanza_routing.txt, which attempts to condense
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
-- the rules from the RFCs (mainly 3921)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
require "core.servermanager"
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
local log = require "util.logger".init("stanzarouter")
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
require "util.jid"
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
local jid_split = jid.split;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
function core_process_stanza(origin, stanza)
66
018705d57f09 Working TLS!
Matthew Wild <mwild1@gmail.com>
parents: 31
diff changeset
    14
	log("debug", "Received: "..tostring(stanza))
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
	local to = stanza.attr.to;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
	
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
	if not to or (hosts[to] and hosts[to].type == "local") then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
		core_handle_stanza(origin, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
	elseif origin.type == "c2s" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
		core_route_stanza(origin, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
	end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
		
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
function core_handle_stanza(origin, stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
	-- Handlers
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
	if origin.type == "c2s" or origin.type == "c2s_unauthed" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
		local session = origin;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
		stanza.attr.from = session.full_jid;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
		
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
		log("debug", "Routing stanza");
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
		-- Stanza has no to attribute
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
		--local to_node, to_host, to_resource = jid_split(stanza.attr.to);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
		--if not to_host then error("Invalid destination JID: "..string.format("{ %q, %q, %q } == %q", to_node or "", to_host or "", to_resource or "", stanza.attr.to or "nil")); end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
		
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
		-- Stanza is to this server, or a user on this server
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
		log("debug", "Routing stanza to local");
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
		handle_stanza(session, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
	end	
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
function core_route_stanza(origin, stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
	-- Hooks
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
	-- Deliver
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
function handle_stanza_nodest(stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
	if stanza.name == "iq" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
		handle_stanza_iq_no_to(session, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
	elseif stanza.name == "presence" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
		-- Broadcast to this user's contacts
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
		handle_stanza_presence_broadcast(session, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
		-- also, if it is initial presence, send out presence probes
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
		if not session.last_presence then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
			handle_stanza_presence_probe_broadcast(session, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
		end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
		session.last_presence = stanza;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
	elseif stanza.name == "message" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
		-- Treat as if message was sent to bare JID of the sender
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
		handle_stanza_to_local_user(stanza);
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
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
function handle_stanza_tolocal(stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
	local node, host, resource = jid.split(stanza.attr.to);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
	if host and hosts[host] and hosts[host].type == "local" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
			-- Is a local host, handle internally
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
			if node then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
				-- Is a local user, send to their session
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
				log("debug", "Routing stanza to %s@%s", node, host);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
				if not session.username then return; end --FIXME: Correct response when trying to use unauthed stream is what?
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
				handle_stanza_to_local_user(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
			else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
				-- Is sent to this server, let's handle it...
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
				log("debug", "Routing stanza to %s", host);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
				handle_stanza_to_server(stanza, session);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
			end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    78
	end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    79
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    80
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    81
function handle_stanza_toremote(stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    82
	log("error", "Stanza bound for remote host, but s2s is not implemented");
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    83
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    84
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
--[[
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    87
local function route_c2s_stanza(session, stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    88
	stanza.attr.from = session.full_jid;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    89
	if not stanza.attr.to and session.username then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
		-- Has no 'to' attribute, handle internally
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    91
		if stanza.name == "iq" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    92
			handle_stanza_iq_no_to(session, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    93
		elseif stanza.name == "presence" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    94
			-- Broadcast to this user's contacts
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    95
			handle_stanza_presence_broadcast(session, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    96
			-- also, if it is initial presence, send out presence probes
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    97
			if not session.last_presence then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    98
				handle_stanza_presence_probe_broadcast(session, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    99
			end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   100
			session.last_presence = stanza;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   101
		elseif stanza.name == "message" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   102
			-- Treat as if message was sent to bare JID of the sender
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   103
			handle_stanza_to_local_user(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   104
		end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   105
	end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   106
	local node, host, resource = jid.split(stanza.attr.to);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   107
	if host and hosts[host] and hosts[host].type == "local" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   108
			-- Is a local host, handle internally
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   109
			if node then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   110
				-- Is a local user, send to their session
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   111
				if not session.username then return; end --FIXME: Correct response when trying to use unauthed stream is what?
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   112
				handle_stanza_to_local_user(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   113
			else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   114
				-- Is sent to this server, let's handle it...
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   115
				handle_stanza_to_server(stanza, session);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   116
			end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   117
	else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   118
		-- Is not for us or a local user, route accordingly
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   119
		route_s2s_stanza(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   120
	end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   121
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   122
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   123
function handle_stanza_no_to(session, stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   124
	if not stanza.attr.id then log("warn", "<iq> without id attribute is invalid"); end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   125
	local xmlns = (stanza.tags[1].attr and stanza.tags[1].attr.xmlns);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   126
	if stanza.attr.type == "get" or stanza.attr.type == "set" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   127
		if iq_handlers[xmlns] then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   128
			if iq_handlers[xmlns](stanza) then return; end; -- If handler returns true, it handled it
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   129
		end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   130
		-- Oh, handler didn't handle it. Need to send service-unavailable now.
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   131
		log("warn", "Unhandled namespace: "..xmlns);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   132
		session:send(format("<iq type='error' id='%s'><error type='cancel'><service-unavailable/></error></iq>", stanza.attr.id));
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   133
		return; -- All done!
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   134
	end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   135
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   136
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   137
function handle_stanza_to_local_user(stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   138
	if stanza.name == "message" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   139
		handle_stanza_message_to_local_user(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   140
	elseif stanza.name == "presence" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   141
		handle_stanza_presence_to_local_user(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   142
	elseif stanza.name == "iq" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   143
		handle_stanza_iq_to_local_user(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   144
	end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   145
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   146
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   147
function handle_stanza_message_to_local_user(stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   148
	local node, host, resource = stanza.to.node, stanza.to.host, stanza.to.resource;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   149
	local destuser = hosts[host].sessions[node];
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   150
	if destuser then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   151
		if resource and destuser[resource] then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   152
			destuser[resource]:send(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   153
		else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   154
			-- Bare JID, or resource offline
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   155
			local best_session;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   156
			for resource, session in pairs(destuser.sessions) do
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   157
				if not best_session then best_session = session;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   158
				elseif session.priority >= best_session.priority and session.priority >= 0 then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   159
					best_session = session;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   160
				end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   161
			end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   162
			if not best_session then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   163
				offlinemessage.new(node, host, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   164
			else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   165
				print("resource '"..resource.."' was not online, have chosen to send to '"..best_session.username.."@"..best_session.host.."/"..best_session.resource.."'");
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   166
				destuser[best_session]:send(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   167
			end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   168
		end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   169
	else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   170
		-- User is offline
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   171
		offlinemessage.new(node, host, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   172
	end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   173
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   174
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   175
function handle_stanza_presence_to_local_user(stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   176
	local node, host, resource = stanza.to.node, stanza.to.host, stanza.to.resource;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   177
	local destuser = hosts[host].sessions[node];
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   178
	if destuser then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   179
		if resource then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   180
			if destuser[resource] then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   181
				destuser[resource]:send(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   182
			else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   183
				return;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   184
			end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   185
		else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   186
			-- Broadcast to all user's resources
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   187
			for resource, session in pairs(destuser.sessions) do
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   188
				session:send(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   189
			end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   190
		end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   191
	end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   192
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   193
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   194
function handle_stanza_iq_to_local_user(stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   195
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   196
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   197
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   198
function foo()
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   199
		local node, host, resource = stanza.to.node, stanza.to.host, stanza.to.resource;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   200
		local destuser = hosts[host].sessions[node];
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   201
		if destuser and destuser.sessions then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   202
			-- User online
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   203
			if resource and destuser.sessions[resource] then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   204
				stanza.to:send(stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   205
			else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   206
				--User is online, but specified resource isn't (or no resource specified)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   207
				local best_session;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   208
				for resource, session in pairs(destuser.sessions) do
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   209
					if not best_session then best_session = session;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   210
					elseif session.priority >= best_session.priority and session.priority >= 0 then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   211
						best_session = session;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   212
					end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   213
				end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   214
				if not best_session then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   215
					offlinemessage.new(node, host, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   216
				else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   217
					print("resource '"..resource.."' was not online, have chosen to send to '"..best_session.username.."@"..best_session.host.."/"..best_session.resource.."'");
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   218
					resource = best_session.resource;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   219
				end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   220
			end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   221
			if destuser.sessions[resource] == session then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   222
				log("warn", "core", "Attempt to send stanza to self, dropping...");
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   223
			else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   224
				print("...sending...", tostring(stanza));
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   225
				--destuser.sessions[resource].conn.write(tostring(data));
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   226
				print("   to conn ", destuser.sessions[resource].conn);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   227
				destuser.sessions[resource].conn.write(tostring(stanza));
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   228
				print("...sent")
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   229
			end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   230
		elseif stanza.name == "message" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   231
			print("   ...will be stored offline");
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   232
			offlinemessage.new(node, host, stanza);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   233
		elseif stanza.name == "iq" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   234
			print("   ...is an iq");
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   235
			stanza.from:send(st.reply(stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   236
				:tag("error", { type = "cancel" })
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   237
					:tag("service-unavailable", { xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas" }));
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   238
		end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   239
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   240
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   241
-- Broadcast a presence stanza to all of a user's contacts
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   242
function handle_stanza_presence_broadcast(session, stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   243
	if session.roster then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   244
		local initial_presence = not session.last_presence;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   245
		session.last_presence = stanza;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   246
		
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   247
		-- Broadcast presence and probes
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   248
		local broadcast = st.presence({ from = session.full_jid, type = stanza.attr.type });
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   249
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   250
		for child in stanza:childtags() do
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   251
			broadcast:add_child(child);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   252
		end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   253
		for contact_jid in pairs(session.roster) do
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   254
			broadcast.attr.to = contact_jid;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   255
			send_to(contact_jid, broadcast);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   256
			if initial_presence then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   257
				local node, host = jid.split(contact_jid);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   258
				if hosts[host] and hosts[host].type == "local" then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   259
					local contact = hosts[host].sessions[node]
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   260
					if contact then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   261
						local pres = st.presence { to = session.full_jid };
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   262
						for resource, contact_session in pairs(contact.sessions) do
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   263
							if contact_session.last_presence then
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   264
								pres.tags = contact_session.last_presence.tags;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   265
								pres.attr.from = contact_session.full_jid;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   266
								send(pres);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   267
							end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   268
						end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   269
					end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   270
					--FIXME: Do we send unavailable if they are offline?
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   271
				else
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   272
					probe.attr.to = contact;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   273
					send_to(contact, probe);
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   274
				end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   275
			end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   276
		end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   277
		
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   278
		-- Probe for our contacts' presence
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   279
	end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   280
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   281
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   282
-- Broadcast presence probes to all of a user's contacts
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   283
function handle_stanza_presence_probe_broadcast(session, stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   284
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   285
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   286
-- 
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   287
function handle_stanza_to_server(stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   288
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   289
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   290
function handle_stanza_iq_no_to(session, stanza)
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   291
end
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   292
]]