core/stanza_router.lua

changeset 785
31d5be1371cf
parent 774
4885c6e101b4
parent 784
1de8a32f81e9
child 789
ced87939984e
equal deleted inserted replaced
776:89eb9f59993c 785:31d5be1371cf
32 local tostring = tostring; 32 local tostring = tostring;
33 local t_concat = table.concat; 33 local t_concat = table.concat;
34 local t_insert = table.insert; 34 local t_insert = table.insert;
35 local tonumber = tonumber; 35 local tonumber = tonumber;
36 local s_find = string.find; 36 local s_find = string.find;
37 local pairs = pairs;
38 local ipairs = ipairs;
37 39
38 local jid_split = require "util.jid".split; 40 local jid_split = require "util.jid".split;
39 local jid_prepped_split = require "util.jid".prepped_split; 41 local jid_prepped_split = require "util.jid".prepped_split;
40 local print = print; 42 local print = print;
41 local function checked_error_reply(origin, stanza) 43 local function checked_error_reply(origin, stanza)
102 local host_status = origin.hosts[from_host]; 104 local host_status = origin.hosts[from_host];
103 if not host_status or not host_status.authed then -- remote server trying to impersonate some other server? 105 if not host_status or not host_status.authed then -- remote server trying to impersonate some other server?
104 log("warn", "Received a stanza claiming to be from %s, over a conn authed for %s!", from_host, origin.from_host); 106 log("warn", "Received a stanza claiming to be from %s, over a conn authed for %s!", from_host, origin.from_host);
105 return; -- FIXME what should we do here? does this work with subdomains? 107 return; -- FIXME what should we do here? does this work with subdomains?
106 end 108 end
109 end
110 if origin.type == "c2s" and stanza.name == "presence" and to ~= nil and not(origin.roster[to_bare] and (origin.roster[to_bare].subscription == "both" or origin.roster[to_bare].subscription == "from")) then -- directed presence
111 origin.directed = origin.directed or {};
112 origin.directed[to] = true;
113 --t_insert(origin.directed, to); -- FIXME does it make more sense to add to_bare rather than to?
107 end 114 end
108 if not to then 115 if not to then
109 core_handle_stanza(origin, stanza); 116 core_handle_stanza(origin, stanza);
110 elseif hosts[to] and hosts[to].type == "local" then -- directed at a local server 117 elseif hosts[to] and hosts[to].type == "local" then -- directed at a local server
111 core_handle_stanza(origin, stanza); 118 core_handle_stanza(origin, stanza);
120 elseif origin.type == "c2s" and stanza.name == "presence" and stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable" then 127 elseif origin.type == "c2s" and stanza.name == "presence" and stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable" then
121 handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare, core_route_stanza); 128 handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare, core_route_stanza);
122 elseif origin.type ~= "c2s" and stanza.name == "iq" and not resource then -- directed at bare JID 129 elseif origin.type ~= "c2s" and stanza.name == "iq" and not resource then -- directed at bare JID
123 core_handle_stanza(origin, stanza); 130 core_handle_stanza(origin, stanza);
124 else 131 else
125 if origin.type == "c2s" and stanza.name == "presence" and to ~= nil and not(origin.roster[to_bare] and (origin.roster[to_bare].subscription == "both" or origin.roster[to_bare].subscription == "from")) then
126 origin.directed = origin.directed or {};
127 t_insert(origin.directed, to); -- FIXME does it make more sense to add to_bare rather than to?
128 end
129 core_route_stanza(origin, stanza); 132 core_route_stanza(origin, stanza);
130 end 133 end
131 else 134 else
132 core_handle_stanza(origin, stanza); 135 core_handle_stanza(origin, stanza);
133 end 136 end
175 178
176 -- Auto-detect origin if not specified 179 -- Auto-detect origin if not specified
177 origin = origin or hosts[from_host]; 180 origin = origin or hosts[from_host];
178 if not origin then return false; end 181 if not origin then return false; end
179 182
183 if hosts[to] and hosts[to].type == "component" then -- hack to allow components to handle node@server/resource and server/resource
184 return component_handle_stanza(origin, stanza);
185 elseif hosts[to_bare] and hosts[to_bare].type == "component" then -- hack to allow components to handle node@server
186 return component_handle_stanza(origin, stanza);
187 elseif hosts[host] and hosts[host].type == "component" then -- directed at a component
188 return component_handle_stanza(origin, stanza);
189 end
190
180 if stanza.name == "presence" and (stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable") then resource = nil; end 191 if stanza.name == "presence" and (stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable") then resource = nil; end
181 192
182 local host_session = hosts[host] 193 local host_session = hosts[host]
183 if host_session and host_session.type == "local" then 194 if host_session and host_session.type == "local" then
184 -- Local host 195 -- Local host
197 session.send(stanza); 208 session.send(stanza);
198 end 209 end
199 end 210 end
200 end 211 end
201 elseif stanza.name == "message" then -- select a resource to recieve message 212 elseif stanza.name == "message" then -- select a resource to recieve message
202 local priority = 0; 213 stanza.attr.to = to_bare;
203 local recipients = {}; 214 if stanza.attr.type == 'headline' then
204 for _, session in pairs(user.sessions) do -- find resource with greatest priority 215 for _, session in pairs(user.sessions) do -- find resource with greatest priority
205 local p = session.priority or -1; 216 if session.presence and session.priority >= 0 then
206 if p > priority then 217 session.send(stanza);
207 priority = p; 218 end
208 recipients = {session}; 219 end
209 elseif p == priority then 220 else
210 t_insert(recipients, session); 221 local priority = 0;
211 end 222 local recipients = {};
212 end 223 for _, session in pairs(user.sessions) do -- find resource with greatest priority
213 local count = 0; 224 if session.presence then
214 for _, session in pairs(recipients) do 225 local p = session.priority;
215 session.send(stanza); 226 if p > priority then
216 count = count + 1; 227 priority = p;
217 end 228 recipients = {session};
218 if count == 0 then 229 elseif p == priority then
219 offlinemanager.store(node, host, stanza); 230 t_insert(recipients, session);
220 -- TODO deal with storage errors 231 end
232 end
233 end
234 local count = 0;
235 for _, session in ipairs(recipients) do
236 session.send(stanza);
237 count = count + 1;
238 end
239 if count == 0 and (stanza.attr.type == "chat" or stanza.attr.type == "normal" or not stanza.attr.type) then
240 offlinemanager.store(node, host, stanza);
241 -- TODO deal with storage errors
242 end
221 end 243 end
222 else 244 else
223 -- TODO send IQ error 245 -- TODO send IQ error
224 end 246 end
225 else 247 else
235 handle_inbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare, core_route_stanza); 257 handle_inbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare, core_route_stanza);
236 else 258 else
237 -- TODO send unavailable presence or unsubscribed 259 -- TODO send unavailable presence or unsubscribed
238 end 260 end
239 elseif stanza.name == "message" then -- FIXME if full jid, then send out to resources with highest priority 261 elseif stanza.name == "message" then -- FIXME if full jid, then send out to resources with highest priority
262 stanza.attr.to = to_bare; -- TODO not in RFC, but seems obvious. Should discuss on the mailing list.
240 if stanza.attr.type == "chat" or stanza.attr.type == "normal" or not stanza.attr.type then 263 if stanza.attr.type == "chat" or stanza.attr.type == "normal" or not stanza.attr.type then
241 offlinemanager.store(node, host, stanza); 264 offlinemanager.store(node, host, stanza);
242 -- FIXME don't store messages with only chat state notifications 265 -- FIXME don't store messages with only chat state notifications
243 end 266 end
244 -- TODO allow configuration of offline storage 267 -- TODO allow configuration of offline storage

mercurial