29 function core_route_stanza(origin, stanza) |
29 function core_route_stanza(origin, stanza) |
30 if stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable" and stanza.attr.type ~= "error" then |
30 if stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable" and stanza.attr.type ~= "error" then |
31 local node, host = jid_split(stanza.attr.to); |
31 local node, host = jid_split(stanza.attr.to); |
32 host = hosts[host]; |
32 host = hosts[host]; |
33 if node and host and host.type == "local" then |
33 if node and host and host.type == "local" then |
34 handle_inbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to), core_route_stanza); |
34 handle_inbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to)); |
35 return; |
35 return; |
36 end |
36 end |
37 end |
37 end |
38 _core_route_stanza(origin, stanza); |
38 _core_route_stanza(origin, stanza); |
39 end |
39 end |
62 end |
62 end |
63 end |
63 end |
64 |
64 |
65 local ignore_presence_priority = module:get_option("ignore_presence_priority"); |
65 local ignore_presence_priority = module:get_option("ignore_presence_priority"); |
66 |
66 |
67 function handle_normal_presence(origin, stanza, core_route_stanza) |
67 function handle_normal_presence(origin, stanza) |
68 if ignore_presence_priority then |
68 if ignore_presence_priority then |
69 local priority = stanza:child_with_name("priority"); |
69 local priority = stanza:child_with_name("priority"); |
70 if priority and priority[1] ~= "0" then |
70 if priority and priority[1] ~= "0" then |
71 for i=#priority.tags,1,-1 do priority.tags[i] = nil; end |
71 for i=#priority.tags,1,-1 do priority.tags[i] = nil; end |
72 for i=#priority,1,-1 do priority[i] = nil; end |
72 for i=#priority,1,-1 do priority[i] = nil; end |
179 end |
179 end |
180 log("debug", "broadcasted presence of "..count.." resources from "..user.."@"..host.." to "..jid); |
180 log("debug", "broadcasted presence of "..count.." resources from "..user.."@"..host.." to "..jid); |
181 return count; |
181 return count; |
182 end |
182 end |
183 |
183 |
184 function handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare, core_route_stanza) |
184 function handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare) |
185 local node, host = jid_split(from_bare); |
185 local node, host = jid_split(from_bare); |
186 if to_bare == origin.username.."@"..origin.host then return; end -- No self contacts |
186 if to_bare == origin.username.."@"..origin.host then return; end -- No self contacts |
187 local st_from, st_to = stanza.attr.from, stanza.attr.to; |
187 local st_from, st_to = stanza.attr.from, stanza.attr.to; |
188 stanza.attr.from, stanza.attr.to = from_bare, to_bare; |
188 stanza.attr.from, stanza.attr.to = from_bare, to_bare; |
189 log("debug", "outbound presence "..stanza.attr.type.." from "..from_bare.." for "..to_bare); |
189 log("debug", "outbound presence "..stanza.attr.type.." from "..from_bare.." for "..to_bare); |
207 -- 3. send_presence_of_available_resources |
207 -- 3. send_presence_of_available_resources |
208 if rostermanager.subscribed(node, host, to_bare) then |
208 if rostermanager.subscribed(node, host, to_bare) then |
209 rostermanager.roster_push(node, host, to_bare); |
209 rostermanager.roster_push(node, host, to_bare); |
210 end |
210 end |
211 core_route_stanza(origin, stanza); |
211 core_route_stanza(origin, stanza); |
212 send_presence_of_available_resources(node, host, to_bare, origin, core_route_stanza); |
212 send_presence_of_available_resources(node, host, to_bare, origin); |
213 elseif stanza.attr.type == "unsubscribed" then |
213 elseif stanza.attr.type == "unsubscribed" then |
214 -- 1. route stanza |
214 -- 1. route stanza |
215 -- 2. roster push (subscription = none or to) |
215 -- 2. roster push (subscription = none or to) |
216 if rostermanager.unsubscribed(node, host, to_bare) then |
216 if rostermanager.unsubscribed(node, host, to_bare) then |
217 rostermanager.roster_push(node, host, to_bare); |
217 rostermanager.roster_push(node, host, to_bare); |
219 core_route_stanza(origin, stanza); |
219 core_route_stanza(origin, stanza); |
220 end |
220 end |
221 stanza.attr.from, stanza.attr.to = st_from, st_to; |
221 stanza.attr.from, stanza.attr.to = st_from, st_to; |
222 end |
222 end |
223 |
223 |
224 function handle_inbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare, core_route_stanza) |
224 function handle_inbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare) |
225 local node, host = jid_split(to_bare); |
225 local node, host = jid_split(to_bare); |
226 local st_from, st_to = stanza.attr.from, stanza.attr.to; |
226 local st_from, st_to = stanza.attr.from, stanza.attr.to; |
227 stanza.attr.from, stanza.attr.to = from_bare, to_bare; |
227 stanza.attr.from, stanza.attr.to = from_bare, to_bare; |
228 log("debug", "inbound presence "..stanza.attr.type.." from "..from_bare.." for "..to_bare); |
228 log("debug", "inbound presence "..stanza.attr.type.." from "..from_bare.." for "..to_bare); |
229 |
229 |
230 if stanza.attr.type == "probe" then |
230 if stanza.attr.type == "probe" then |
231 local result, err = rostermanager.is_contact_subscribed(node, host, from_bare); |
231 local result, err = rostermanager.is_contact_subscribed(node, host, from_bare); |
232 if result then |
232 if result then |
233 if 0 == send_presence_of_available_resources(node, host, st_from, origin, core_route_stanza) then |
233 if 0 == send_presence_of_available_resources(node, host, st_from, origin) then |
234 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"})); -- TODO send last activity |
234 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"})); -- TODO send last activity |
235 end |
235 end |
236 elseif not err then |
236 elseif not err then |
237 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unsubscribed"})); |
237 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unsubscribed"})); |
238 end |
238 end |
239 elseif stanza.attr.type == "subscribe" then |
239 elseif stanza.attr.type == "subscribe" then |
240 if rostermanager.is_contact_subscribed(node, host, from_bare) then |
240 if rostermanager.is_contact_subscribed(node, host, from_bare) then |
241 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="subscribed"})); -- already subscribed |
241 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="subscribed"})); -- already subscribed |
242 -- Sending presence is not clearly stated in the RFC, but it seems appropriate |
242 -- Sending presence is not clearly stated in the RFC, but it seems appropriate |
243 if 0 == send_presence_of_available_resources(node, host, from_bare, origin, core_route_stanza) then |
243 if 0 == send_presence_of_available_resources(node, host, from_bare, origin) then |
244 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"})); -- TODO send last activity |
244 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"})); -- TODO send last activity |
245 end |
245 end |
246 else |
246 else |
247 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"})); -- acknowledging receipt |
247 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"})); -- acknowledging receipt |
248 if not rostermanager.is_contact_pending_in(node, host, from_bare) then |
248 if not rostermanager.is_contact_pending_in(node, host, from_bare) then |
276 |
276 |
277 local to = stanza.attr.to; |
277 local to = stanza.attr.to; |
278 if to then |
278 if to then |
279 local t = stanza.attr.type; |
279 local t = stanza.attr.type; |
280 if t ~= nil and t ~= "unavailable" and t ~= "error" then -- check for subscriptions and probes |
280 if t ~= nil and t ~= "unavailable" and t ~= "error" then -- check for subscriptions and probes |
281 handle_outbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to), core_route_stanza); |
281 handle_outbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to)); |
282 return true; |
282 return true; |
283 end |
283 end |
284 |
284 |
285 local to_bare = jid_bare(to); |
285 local to_bare = jid_bare(to); |
286 if not(origin.roster[to_bare] and (origin.roster[to_bare].subscription == "both" or origin.roster[to_bare].subscription == "from")) then -- directed presence |
286 if not(origin.roster[to_bare] and (origin.roster[to_bare].subscription == "both" or origin.roster[to_bare].subscription == "from")) then -- directed presence |
317 session.send(stanza); |
317 session.send(stanza); |
318 end |
318 end |
319 end |
319 end |
320 end -- no resources not online, discard |
320 end -- no resources not online, discard |
321 elseif not t or t == "unavailable" then |
321 elseif not t or t == "unavailable" then |
322 handle_normal_presence(origin, stanza, core_route_stanza); |
322 handle_normal_presence(origin, stanza); |
323 end |
323 end |
324 return true; |
324 return true; |
325 end); |
325 end); |
326 module:hook("presence/full", function(data) |
326 module:hook("presence/full", function(data) |
327 -- inbound presence to full JID recieved |
327 -- inbound presence to full JID recieved |
328 local origin, stanza = data.origin, data.stanza; |
328 local origin, stanza = data.origin, data.stanza; |
329 |
329 |
330 local t = stanza.attr.type; |
330 local t = stanza.attr.type; |
331 if t ~= nil and t ~= "unavailable" and t ~= "error" then -- check for subscriptions and probes sent to full JID |
331 if t ~= nil and t ~= "unavailable" and t ~= "error" then -- check for subscriptions and probes sent to full JID |
332 handle_inbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to), core_route_stanza); |
332 handle_inbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to)); |
333 return true; |
333 return true; |
334 end |
334 end |
335 |
335 |
336 local session = full_sessions[stanza.attr.to]; |
336 local session = full_sessions[stanza.attr.to]; |
337 if session then |
337 if session then |