mirror of
https://git.lapiole.org/dani/ansible-roles.git
synced 2025-08-03 23:26:58 +02:00
Update to 2024-07-22 23:00
This commit is contained in:
202
roles/jitsi/files/prosody/modules/mod_client_proxy.lua
Normal file
202
roles/jitsi/files/prosody/modules/mod_client_proxy.lua
Normal file
@@ -0,0 +1,202 @@
|
||||
if module:get_host_type() ~= "component" then
|
||||
error("proxy_component should be loaded as component", 0);
|
||||
end
|
||||
|
||||
local jid_split = require "util.jid".split;
|
||||
local jid_bare = require "util.jid".bare;
|
||||
local jid_prep = require "util.jid".prep;
|
||||
local st = require "util.stanza";
|
||||
local array = require "util.array";
|
||||
|
||||
local target_address = module:get_option_string("target_address");
|
||||
|
||||
sessions = array{};
|
||||
local sessions = sessions;
|
||||
|
||||
local function handle_target_presence(stanza)
|
||||
local type = stanza.attr.type;
|
||||
module:log("debug", "received presence from destination: %s", type)
|
||||
local _, _, resource = jid_split(stanza.attr.from);
|
||||
if type == "error" then
|
||||
-- drop all known sessions
|
||||
for k in pairs(sessions) do
|
||||
sessions[k] = nil
|
||||
end
|
||||
module:log(
|
||||
"debug",
|
||||
"received error presence, dropping all target sessions",
|
||||
resource
|
||||
)
|
||||
elseif type == "unavailable" then
|
||||
for k in pairs(sessions) do
|
||||
if sessions[k] == resource then
|
||||
sessions[k] = nil
|
||||
module:log(
|
||||
"debug",
|
||||
"dropped target session: %s",
|
||||
resource
|
||||
)
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif not type then
|
||||
-- available
|
||||
local found = false;
|
||||
for k in pairs(sessions) do
|
||||
if sessions[k] == resource then
|
||||
found = true;
|
||||
break
|
||||
end
|
||||
end
|
||||
if not found then
|
||||
module:log(
|
||||
"debug",
|
||||
"registered new target session: %s",
|
||||
resource
|
||||
)
|
||||
sessions:push(resource)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_from_target(stanza)
|
||||
local type = stanza.attr.type
|
||||
module:log(
|
||||
"debug",
|
||||
"non-presence stanza from target: name = %s, type = %s",
|
||||
stanza.name,
|
||||
type
|
||||
)
|
||||
if stanza.name == "iq" then
|
||||
if type == "error" or type == "result" then
|
||||
-- de-NAT message
|
||||
local _, _, denatted_to_unprepped = jid_split(stanza.attr.to);
|
||||
local denatted_to = jid_prep(denatted_to_unprepped);
|
||||
if not denatted_to then
|
||||
module:log(
|
||||
"debug",
|
||||
"cannot de-NAT stanza, invalid to: %s",
|
||||
denatted_to_unprepped
|
||||
)
|
||||
return
|
||||
end
|
||||
local denatted_from = module:get_host();
|
||||
|
||||
module:log(
|
||||
"debug",
|
||||
"de-NAT-ed stanza: from: %s -> %s, to: %s -> %s",
|
||||
stanza.attr.from,
|
||||
denatted_from,
|
||||
stanza.attr.to,
|
||||
denatted_to
|
||||
)
|
||||
|
||||
stanza.attr.from = denatted_from
|
||||
stanza.attr.to = denatted_to
|
||||
|
||||
module:send(stanza)
|
||||
else
|
||||
-- FIXME: we don’t support NATing outbund requests atm.
|
||||
module:send(st.error_reply(stanza, "cancel", "feature-not-implemented"))
|
||||
end
|
||||
elseif stanza.name == "message" then
|
||||
-- not implemented yet, we need a way to ensure that routing doesn’t
|
||||
-- break
|
||||
module:send(st.error_reply(stanza, "cancel", "feature-not-implemented"))
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_to_target(stanza)
|
||||
local type = stanza.attr.type;
|
||||
module:log(
|
||||
"debug",
|
||||
"stanza to target: name = %s, type = %s",
|
||||
stanza.name, type
|
||||
)
|
||||
if stanza.name == "presence" then
|
||||
if type ~= "error" then
|
||||
module:send(st.error_reply(stanza, "cancel", "bad-request"))
|
||||
return
|
||||
end
|
||||
elseif stanza.name == "iq" then
|
||||
if type == "get" or type == "set" then
|
||||
if #sessions == 0 then
|
||||
-- no sessions available to send to
|
||||
module:log("debug", "no sessions to send to!")
|
||||
module:send(st.error_reply(stanza, "cancel", "service-unavailable"))
|
||||
return
|
||||
end
|
||||
|
||||
-- find a target session
|
||||
local target_session = sessions:random()
|
||||
local target = target_address .. "/" .. target_session
|
||||
|
||||
-- encode sender JID in resource
|
||||
local natted_from = module:get_host() .. "/" .. stanza.attr.from;
|
||||
|
||||
module:log(
|
||||
"debug",
|
||||
"NAT-ed stanza: from: %s -> %s, to: %s -> %s",
|
||||
stanza.attr.from,
|
||||
natted_from,
|
||||
stanza.attr.to,
|
||||
target
|
||||
)
|
||||
|
||||
stanza.attr.from = natted_from
|
||||
stanza.attr.to = target
|
||||
|
||||
module:send(stanza)
|
||||
end
|
||||
-- FIXME: handle and forward result/error correctly
|
||||
elseif stanza.name == "message" then
|
||||
-- not implemented yet, we need a way to ensure that routing doesn’t
|
||||
-- break
|
||||
module:send(st.error_reply(stanza, "cancel", "feature-not-implemented"))
|
||||
end
|
||||
end
|
||||
|
||||
local function stanza_handler(event)
|
||||
local origin, stanza = event.origin, event.stanza
|
||||
module:log("debug", "received stanza from %s session", origin.type)
|
||||
|
||||
local bare_from = jid_bare(stanza.attr.from);
|
||||
local _, _, to = jid_split(stanza.attr.to);
|
||||
if bare_from == target_address then
|
||||
-- from our target, to whom?
|
||||
if not to then
|
||||
-- directly to component
|
||||
if stanza.name == "presence" then
|
||||
handle_target_presence(stanza)
|
||||
else
|
||||
module:send(st.error_reply(stanza, "cancel", "bad-request"))
|
||||
return true
|
||||
end
|
||||
else
|
||||
-- to someone else
|
||||
handle_from_target(stanza)
|
||||
end
|
||||
else
|
||||
handle_to_target(stanza)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
module:hook("iq/bare", stanza_handler, -1);
|
||||
module:hook("message/bare", stanza_handler, -1);
|
||||
module:hook("presence/bare", stanza_handler, -1);
|
||||
module:hook("iq/full", stanza_handler, -1);
|
||||
module:hook("message/full", stanza_handler, -1);
|
||||
module:hook("presence/full", stanza_handler, -1);
|
||||
module:hook("iq/host", stanza_handler, -1);
|
||||
module:hook("message/host", stanza_handler, -1);
|
||||
module:hook("presence/host", stanza_handler, -1);
|
||||
|
||||
module:log("debug", "loaded proxy on %s", module:get_host())
|
||||
|
||||
subscription_request = st.presence({
|
||||
type = "subscribe",
|
||||
to = target_address,
|
||||
from = module:get_host()}
|
||||
)
|
||||
module:send(subscription_request)
|
Reference in New Issue
Block a user