mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2025-12-30 11:22:31 +00:00
fix(visitors): Fixes s2s multiple connections.
We cannot use filters with s2s as not sending a stanza will result skipping existing connection and creating a new one. This also clears some of the "No hosts[from_host] (please report)" errors, but there is still one (easy to repro is we disable the jicofo locking) on join we see a presence trying to be routed using the wrong from (virtual tenant jid).
This commit is contained in:
@@ -20,6 +20,7 @@ local room_jid_match_rewrite = util.room_jid_match_rewrite;
|
||||
local get_room_from_jid = util.get_room_from_jid;
|
||||
local get_focus_occupant = util.get_focus_occupant;
|
||||
local internal_room_jid_match_rewrite = util.internal_room_jid_match_rewrite;
|
||||
local presence_check_status = util.presence_check_status;
|
||||
|
||||
-- this is the main virtual host of this vnode
|
||||
local local_domain = module:get_option_string('muc_mapper_domain_base');
|
||||
@@ -325,6 +326,8 @@ module:hook('muc-occupant-groupchat', function(event)
|
||||
if occupant and occupant_host ~= main_domain then
|
||||
local main_message = st.clone(stanza);
|
||||
main_message.attr.to = jid.join(jid.node(room.jid), muc_domain_prefix..'.'..main_domain);
|
||||
-- make sure we fix the from to be the real jid
|
||||
main_message.attr.from = room_jid_match_rewrite(stanza.attr.from);
|
||||
module:send(main_message);
|
||||
end
|
||||
stanza.attr.from = from; -- something prosody does internally
|
||||
@@ -461,15 +464,24 @@ end
|
||||
module:hook('iq/host', iq_from_main_handler, 10);
|
||||
|
||||
-- Filters presences (if detected) that are with destination the main prosody
|
||||
function filter_stanza(stanza)
|
||||
if not stanza.attr or not stanza.attr.to or stanza.name ~= 'presence' then
|
||||
return stanza;
|
||||
end
|
||||
function filter_stanza(stanza, session)
|
||||
if (stanza.name == 'presence' or stanza.name == 'message') and session.type ~= 'c2s' then
|
||||
-- we clone it so we do not affect broadcast using same stanza, sending it to clients
|
||||
local f_st = st.clone(stanza);
|
||||
f_st.skipMapping = true;
|
||||
return f_st;
|
||||
elseif stanza.name == 'presence' and session.type == 'c2s' and jid.node(stanza.attr.to) == 'focus' then
|
||||
local x = stanza:get_child('x', 'http://jabber.org/protocol/muc#user');
|
||||
if presence_check_status(x, '110') then
|
||||
return stanza; -- no filter
|
||||
end
|
||||
|
||||
if jid.host(stanza.attr.to) == main_domain then
|
||||
-- we want to filter presences to jicofo for the main participants
|
||||
-- no point of having them, but if it is the one of the first to be sent
|
||||
-- when first visitor is joining can produce the 'No hosts[from_host]' error as we
|
||||
-- rewrite the from, but we need to not do it to be able to filter it later for the s2s
|
||||
return nil; -- returning nil filters the stanza
|
||||
end
|
||||
|
||||
return stanza; -- no filter
|
||||
end
|
||||
function filter_session(session)
|
||||
@@ -478,3 +490,34 @@ function filter_session(session)
|
||||
end
|
||||
|
||||
filters.add_filter_hook(filter_session);
|
||||
|
||||
|
||||
function route_s2s_stanza(event)
|
||||
local from_host, to_host, stanza = event.from_host, event.to_host, event.stanza;
|
||||
|
||||
if to_host ~= main_domain then
|
||||
return; -- continue with hook listeners
|
||||
end
|
||||
|
||||
if stanza.name == 'message' then
|
||||
if jid.resource(stanza.to) then
|
||||
-- there is no point of delivering messages to main participants individually
|
||||
return true; -- drop it
|
||||
end
|
||||
return;
|
||||
end
|
||||
|
||||
if stanza.name == 'presence' then
|
||||
-- we want to leave only unavailable presences to go to main node
|
||||
-- all other presences from jicofo or the main participants there is no point to go to the main node
|
||||
-- they are anyway not handled
|
||||
if stanza.attr.type ~= 'unavailable' then
|
||||
return true; -- drop it
|
||||
end
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
-- routing to sessions in mod_s2s is -1 and -10, we want to hook before that to make sure to is correct
|
||||
-- or if we want to filter that stanza
|
||||
module:hook("route/remote", route_s2s_stanza, 10);
|
||||
|
||||
@@ -17,6 +17,10 @@ local internal_room_jid_match_rewrite = util.internal_room_jid_match_rewrite;
|
||||
|
||||
-- We must filter stanzas in order to hook in to all incoming and outgoing messaging which skips the stanza routers
|
||||
function filter_stanza(stanza)
|
||||
if stanza.skipMapping then
|
||||
return stanza;
|
||||
end
|
||||
|
||||
if stanza.name == "message" or stanza.name == "iq" or stanza.name == "presence" then
|
||||
-- module:log("debug", "Filtering stanza type %s to %s from %s",stanza.name,stanza.attr.to,stanza.attr.from);
|
||||
if stanza.name == "iq" then
|
||||
|
||||
@@ -115,8 +115,6 @@ function handle_jicofo_unlock(event)
|
||||
|
||||
-- and now let's handle all pre_join_queue events
|
||||
for _, ev in room.pre_join_queue:items() do
|
||||
-- we see wrong from on some stanzas when using tenants with visitor nodes
|
||||
ev.stanza.attr.from = internal_room_jid_match_rewrite(ev.stanza.attr.from, ev.stanza)
|
||||
module:log('info', 'Occupant processed from queue %s', ev.occupant.nick);
|
||||
room:handle_normal_presence(ev.origin, ev.stanza);
|
||||
end
|
||||
|
||||
@@ -129,7 +129,8 @@ local function stanza_handler(event)
|
||||
return;
|
||||
end
|
||||
|
||||
if stanza.attr.type == 'result' and sent_iq_cache:get(stanza.attr.id) then
|
||||
-- we receive error from vnode for our disconnect message as the room was already destroyed (all visitors left)
|
||||
if (stanza.attr.type == 'result' or stanza.attr.type == 'error') and sent_iq_cache:get(stanza.attr.id) then
|
||||
sent_iq_cache:set(stanza.attr.id, nil);
|
||||
return true;
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user