"Fossies" - the Fresh Open Source Software Archive

Member "jitsi-meet-7316/resources/prosody-plugins/mod_client_proxy.lua" (5 Jun 2023, 5214 Bytes) of package /linux/misc/jitsi-meet-7316.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Lua source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 if module:get_host_type() ~= "component" then
    2     error("proxy_component should be loaded as component", 0);
    3 end
    4 
    5 local jid_split = require "util.jid".split;
    6 local jid_bare = require "util.jid".bare;
    7 local jid_prep = require "util.jid".prep;
    8 local st = require "util.stanza";
    9 local array = require "util.array";
   10 
   11 local target_address = module:get_option_string("target_address");
   12 
   13 sessions = array{};
   14 local sessions = sessions;
   15 
   16 local function handle_target_presence(stanza)
   17     local type = stanza.attr.type;
   18     module:log("debug", "received presence from destination: %s", type)
   19     local _, _, resource = jid_split(stanza.attr.from);
   20     if type == "error" then
   21         -- drop all known sessions
   22         for k in pairs(sessions) do
   23             sessions[k] = nil
   24         end
   25         module:log(
   26             "debug",
   27             "received error presence, dropping all target sessions",
   28             resource
   29         )
   30     elseif type == "unavailable" then
   31         for k in pairs(sessions) do
   32             if sessions[k] == resource then
   33                 sessions[k] = nil
   34                 module:log(
   35                     "debug",
   36                     "dropped target session: %s",
   37                     resource
   38                 )
   39                 break
   40             end
   41         end
   42     elseif not type then
   43         -- available
   44         local found = false;
   45         for k in pairs(sessions) do
   46             if sessions[k] == resource then
   47                 found = true;
   48                 break
   49             end
   50         end
   51         if not found then
   52             module:log(
   53                 "debug",
   54                 "registered new target session: %s",
   55                 resource
   56             )
   57             sessions:push(resource)
   58         end
   59     end
   60 end
   61 
   62 local function handle_from_target(stanza)
   63     local type = stanza.attr.type
   64     module:log(
   65         "debug",
   66         "non-presence stanza from target: name = %s, type = %s",
   67         stanza.name,
   68         type
   69     )
   70     if stanza.name == "iq" then
   71         if type == "error" or type == "result" then
   72             -- de-NAT message
   73             local _, _, denatted_to_unprepped = jid_split(stanza.attr.to);
   74             local denatted_to = jid_prep(denatted_to_unprepped);
   75             if not denatted_to then
   76                 module:log(
   77                     "debug",
   78                     "cannot de-NAT stanza, invalid to: %s",
   79                     denatted_to_unprepped
   80                 )
   81                 return
   82             end
   83             local denatted_from = module:get_host();
   84 
   85             module:log(
   86                 "debug",
   87                 "de-NAT-ed stanza: from: %s -> %s, to: %s -> %s",
   88                 stanza.attr.from,
   89                 denatted_from,
   90                 stanza.attr.to,
   91                 denatted_to
   92             )
   93 
   94             stanza.attr.from = denatted_from
   95             stanza.attr.to = denatted_to
   96 
   97             module:send(stanza)
   98         else
   99             -- FIXME: we don’t support NATing outbund requests atm.
  100             module:send(st.error_reply(stanza, "cancel", "feature-not-implemented"))
  101         end
  102     elseif stanza.name == "message" then
  103         -- not implemented yet, we need a way to ensure that routing doesn’t
  104         -- break
  105         module:send(st.error_reply(stanza, "cancel", "feature-not-implemented"))
  106     end
  107 end
  108 
  109 local function handle_to_target(stanza)
  110     local type = stanza.attr.type;
  111     module:log(
  112         "debug",
  113         "stanza to target: name = %s, type = %s",
  114         stanza.name, type
  115     )
  116     if stanza.name == "presence" then
  117         if type ~= "error" then
  118             module:send(st.error_reply(stanza, "cancel", "bad-request"))
  119             return
  120         end
  121     elseif stanza.name == "iq" then
  122         if type == "get" or type == "set" then
  123             if #sessions == 0 then
  124                 -- no sessions available to send to
  125                 module:log("debug", "no sessions to send to!")
  126                 module:send(st.error_reply(stanza, "cancel", "service-unavailable"))
  127                 return
  128             end
  129 
  130             -- find a target session
  131             local target_session = sessions:random()
  132             local target = target_address .. "/" .. target_session
  133 
  134             -- encode sender JID in resource
  135             local natted_from = module:get_host() .. "/" .. stanza.attr.from;
  136 
  137             module:log(
  138                 "debug",
  139                 "NAT-ed stanza: from: %s -> %s, to: %s -> %s",
  140                 stanza.attr.from,
  141                 natted_from,
  142                 stanza.attr.to,
  143                 target
  144             )
  145 
  146             stanza.attr.from = natted_from
  147             stanza.attr.to = target
  148 
  149             module:send(stanza)
  150         end
  151         -- FIXME: handle and forward result/error correctly
  152     elseif stanza.name == "message" then
  153         -- not implemented yet, we need a way to ensure that routing doesn’t
  154         -- break
  155         module:send(st.error_reply(stanza, "cancel", "feature-not-implemented"))
  156     end
  157 end
  158 
  159 local function stanza_handler(event)
  160     local origin, stanza = event.origin, event.stanza
  161     module:log("debug", "received stanza from %s session", origin.type)
  162 
  163     local bare_from = jid_bare(stanza.attr.from);
  164     local _, _, to = jid_split(stanza.attr.to);
  165     if bare_from == target_address then
  166         -- from our target, to whom?
  167         if not to then
  168             -- directly to component
  169             if stanza.name == "presence" then
  170                 handle_target_presence(stanza)
  171             else
  172                 module:send(st.error_reply(stanza, "cancel", "bad-request"))
  173                 return true
  174             end
  175         else
  176             -- to someone else
  177             handle_from_target(stanza)
  178         end
  179     else
  180         handle_to_target(stanza)
  181     end
  182     return true
  183 end
  184 
  185 module:hook("iq/bare", stanza_handler, -1);
  186 module:hook("message/bare", stanza_handler, -1);
  187 module:hook("presence/bare", stanza_handler, -1);
  188 module:hook("iq/full", stanza_handler, -1);
  189 module:hook("message/full", stanza_handler, -1);
  190 module:hook("presence/full", stanza_handler, -1);
  191 module:hook("iq/host", stanza_handler, -1);
  192 module:hook("message/host", stanza_handler, -1);
  193 module:hook("presence/host", stanza_handler, -1);
  194 
  195 module:log("debug", "loaded proxy on %s", module:get_host())
  196 
  197 subscription_request = st.presence({
  198     type = "subscribe",
  199     to = target_address,
  200     from = module:get_host()}
  201 )
  202 module:send(subscription_request)