Software /
code /
prosody
Comparison
core/stanza_router.lua @ 785:31d5be1371cf
Merge with waqas for MUC/routing fixes
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Wed, 11 Feb 2009 18:30:44 +0000 |
parent | 774:4885c6e101b4 |
parent | 784:1de8a32f81e9 |
child | 789:ced87939984e |
comparison
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 |