|
|
|
|
@ -24,20 +24,6 @@ local rostermanager = require "core.rostermanager"; |
|
|
|
|
local sessionmanager = require "core.sessionmanager"; |
|
|
|
|
local offlinemanager = require "core.offlinemanager"; |
|
|
|
|
|
|
|
|
|
local _core_route_stanza = core_route_stanza; |
|
|
|
|
local core_route_stanza; |
|
|
|
|
function core_route_stanza(origin, stanza) |
|
|
|
|
if stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable" and stanza.attr.type ~= "error" then |
|
|
|
|
local node, host = jid_split(stanza.attr.to); |
|
|
|
|
host = hosts[host]; |
|
|
|
|
if node and host and host.type == "local" then |
|
|
|
|
handle_inbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to)); |
|
|
|
|
return; |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
_core_route_stanza(origin, stanza); |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function select_top_resources(user) |
|
|
|
|
local priority = 0; |
|
|
|
|
local recipients = {}; |
|
|
|
|
@ -82,13 +68,13 @@ function handle_normal_presence(origin, stanza) |
|
|
|
|
for _, res in pairs(user and user.sessions or NULL) do -- broadcast to all resources |
|
|
|
|
if res ~= origin and res.presence then -- to resource |
|
|
|
|
stanza.attr.to = res.full_jid; |
|
|
|
|
core_route_stanza(origin, stanza); |
|
|
|
|
core_post_stanza(origin, stanza, true); |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
for jid, item in pairs(roster) do -- broadcast to all interested contacts |
|
|
|
|
if item.subscription == "both" or item.subscription == "from" then |
|
|
|
|
stanza.attr.to = jid; |
|
|
|
|
core_route_stanza(origin, stanza); |
|
|
|
|
core_post_stanza(origin, stanza, true); |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
if stanza.attr.type == nil and not origin.presence then -- initial presence |
|
|
|
|
@ -103,7 +89,7 @@ function handle_normal_presence(origin, stanza) |
|
|
|
|
for _, res in pairs(user and user.sessions or NULL) do -- broadcast from all available resources |
|
|
|
|
if res ~= origin and res.presence then |
|
|
|
|
res.presence.attr.to = origin.full_jid; |
|
|
|
|
core_route_stanza(res, res.presence); |
|
|
|
|
core_post_stanza(res, res.presence, true); |
|
|
|
|
res.presence.attr.to = nil; |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
@ -116,7 +102,7 @@ function handle_normal_presence(origin, stanza) |
|
|
|
|
for jid, item in pairs(roster) do -- resend outgoing subscription requests |
|
|
|
|
if item.ask then |
|
|
|
|
request.attr.to = jid; |
|
|
|
|
core_route_stanza(origin, request); |
|
|
|
|
core_post_stanza(origin, request, true); |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
local offline = offlinemanager.load(node, host); |
|
|
|
|
@ -136,7 +122,7 @@ function handle_normal_presence(origin, stanza) |
|
|
|
|
if origin.directed then |
|
|
|
|
for jid in pairs(origin.directed) do |
|
|
|
|
stanza.attr.to = jid; |
|
|
|
|
core_route_stanza(origin, stanza); |
|
|
|
|
core_post_stanza(origin, stanza, true); |
|
|
|
|
end |
|
|
|
|
origin.directed = nil; |
|
|
|
|
end |
|
|
|
|
@ -170,7 +156,7 @@ function send_presence_of_available_resources(user, host, jid, recipient_session |
|
|
|
|
if pres then |
|
|
|
|
if stanza then pres = stanza; pres.attr.from = session.full_jid; end |
|
|
|
|
pres.attr.to = jid; |
|
|
|
|
core_route_stanza(session, pres); |
|
|
|
|
core_post_stanza(session, pres, true); |
|
|
|
|
pres.attr.to = nil; |
|
|
|
|
count = count + 1; |
|
|
|
|
end |
|
|
|
|
@ -196,14 +182,14 @@ function handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_ |
|
|
|
|
if rostermanager.set_contact_pending_out(node, host, to_bare) then |
|
|
|
|
rostermanager.roster_push(node, host, to_bare); |
|
|
|
|
end -- else file error |
|
|
|
|
core_route_stanza(origin, stanza); |
|
|
|
|
core_post_stanza(origin, stanza); |
|
|
|
|
elseif stanza.attr.type == "unsubscribe" then |
|
|
|
|
-- 1. route stanza |
|
|
|
|
-- 2. roster push (subscription = none or from) |
|
|
|
|
if rostermanager.unsubscribe(node, host, to_bare) then |
|
|
|
|
rostermanager.roster_push(node, host, to_bare); -- FIXME do roster push when roster has in fact not changed? |
|
|
|
|
end -- else file error |
|
|
|
|
core_route_stanza(origin, stanza); |
|
|
|
|
core_post_stanza(origin, stanza); |
|
|
|
|
elseif stanza.attr.type == "subscribed" then |
|
|
|
|
-- 1. route stanza |
|
|
|
|
-- 2. roster_push () |
|
|
|
|
@ -211,7 +197,7 @@ function handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_ |
|
|
|
|
if rostermanager.subscribed(node, host, to_bare) then |
|
|
|
|
rostermanager.roster_push(node, host, to_bare); |
|
|
|
|
end |
|
|
|
|
core_route_stanza(origin, stanza); |
|
|
|
|
core_post_stanza(origin, stanza); |
|
|
|
|
send_presence_of_available_resources(node, host, to_bare, origin); |
|
|
|
|
elseif stanza.attr.type == "unsubscribed" then |
|
|
|
|
-- 1. route stanza |
|
|
|
|
@ -219,7 +205,7 @@ function handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_ |
|
|
|
|
if rostermanager.unsubscribed(node, host, to_bare) then |
|
|
|
|
rostermanager.roster_push(node, host, to_bare); |
|
|
|
|
end |
|
|
|
|
core_route_stanza(origin, stanza); |
|
|
|
|
core_post_stanza(origin, stanza); |
|
|
|
|
end |
|
|
|
|
stanza.attr.from, stanza.attr.to = st_from, st_to; |
|
|
|
|
return true; |
|
|
|
|
@ -235,20 +221,20 @@ function handle_inbound_presence_subscriptions_and_probes(origin, stanza, from_b |
|
|
|
|
local result, err = rostermanager.is_contact_subscribed(node, host, from_bare); |
|
|
|
|
if result then |
|
|
|
|
if 0 == send_presence_of_available_resources(node, host, st_from, origin) then |
|
|
|
|
core_route_stanza(hosts[host], st.presence({from=to_bare, to=st_from, type="unavailable"})); -- TODO send last activity |
|
|
|
|
core_post_stanza(hosts[host], st.presence({from=to_bare, to=st_from, type="unavailable"}), true); -- TODO send last activity |
|
|
|
|
end |
|
|
|
|
elseif not err then |
|
|
|
|
core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unsubscribed"})); |
|
|
|
|
core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unsubscribed"}), true); |
|
|
|
|
end |
|
|
|
|
elseif stanza.attr.type == "subscribe" then |
|
|
|
|
if rostermanager.is_contact_subscribed(node, host, from_bare) then |
|
|
|
|
core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="subscribed"})); -- already subscribed |
|
|
|
|
core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="subscribed"}), true); -- already subscribed |
|
|
|
|
-- Sending presence is not clearly stated in the RFC, but it seems appropriate |
|
|
|
|
if 0 == send_presence_of_available_resources(node, host, from_bare, origin) then |
|
|
|
|
core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"})); -- TODO send last activity |
|
|
|
|
core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"}), true); -- TODO send last activity |
|
|
|
|
end |
|
|
|
|
else |
|
|
|
|
core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"})); -- acknowledging receipt |
|
|
|
|
core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"}), true); -- acknowledging receipt |
|
|
|
|
if not rostermanager.is_contact_pending_in(node, host, from_bare) then |
|
|
|
|
if rostermanager.set_contact_pending_in(node, host, from_bare) then |
|
|
|
|
sessionmanager.send_to_available_resources(node, host, stanza); |
|
|
|
|
@ -349,10 +335,10 @@ module:hook("presence/host", function(data) |
|
|
|
|
local from_bare = jid_bare(stanza.attr.from); |
|
|
|
|
local t = stanza.attr.type; |
|
|
|
|
if t == "probe" then |
|
|
|
|
core_route_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id })); |
|
|
|
|
core_post_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id })); |
|
|
|
|
elseif t == "subscribe" then |
|
|
|
|
core_route_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id, type = "subscribed" })); |
|
|
|
|
core_route_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id })); |
|
|
|
|
core_post_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id, type = "subscribed" })); |
|
|
|
|
core_post_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id })); |
|
|
|
|
end |
|
|
|
|
return true; |
|
|
|
|
end); |
|
|
|
|
@ -371,7 +357,7 @@ module:hook("resource-unbind", function(event) |
|
|
|
|
pres:tag("status"):text("Disconnected: "..err):up(); |
|
|
|
|
for jid in pairs(session.directed) do |
|
|
|
|
pres.attr.to = jid; |
|
|
|
|
core_route_stanza(session, pres); |
|
|
|
|
core_post_stanza(session, pres, true); |
|
|
|
|
end |
|
|
|
|
session.directed = nil; |
|
|
|
|
end |
|
|
|
|
|