"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)