25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-26 17:38:45 +01:00

Avoid duplicates of carbon copies

When multiple resources have the same (highest) priority, the session
manager routes messages sent to their bare JID to each of these
resources.  When another resource has a lower priority but receives
carbon copies, make sure it won't receive multiple copies of such
messages.
This commit is contained in:
Holger Weiss 2014-11-05 19:04:02 +01:00
parent 1d2efcc168
commit 41dc1efde4

View File

@ -167,6 +167,10 @@ remove_connection(User, Server, Resource, _Status)->
send_copies(JID, To, Packet, Direction)-> send_copies(JID, To, Packet, Direction)->
{U, S, R} = jlib:jid_tolower(JID), {U, S, R} = jlib:jid_tolower(JID),
PrioRes = ejabberd_sm:get_user_present_resources(U, S), PrioRes = ejabberd_sm:get_user_present_resources(U, S),
{MaxPrio, MaxRes} = case catch lists:max(PrioRes) of
{Prio, Res} -> {Prio, Res};
_ -> {0, undefined}
end,
IsBareTo = case {Direction, To} of IsBareTo = case {Direction, To} of
{received, #jid{lresource = <<>>}} -> true; {received, #jid{lresource = <<>>}} -> true;
@ -180,15 +184,19 @@ send_copies(JID, To, Packet, Direction)->
end, end,
%% list of JIDs that should receive a carbon copy of this message (excluding the %% list of JIDs that should receive a carbon copy of this message (excluding the
%% receiver(s) of the original message %% receiver(s) of the original message
TargetJIDs = if IsBareTo -> TargetJIDs = case {IsBareTo, R} of
MaxPrio = case catch lists:max(PrioRes) of {true, MaxRes} ->
{Prio, _Res} -> Prio;
_ -> 0
end,
OrigTo = fun(Res) -> lists:member({MaxPrio, Res}, PrioRes) end, OrigTo = fun(Res) -> lists:member({MaxPrio, Res}, PrioRes) end,
[ {jlib:make_jid({U, S, CCRes}), CC_Version} [ {jlib:make_jid({U, S, CCRes}), CC_Version}
|| {CCRes, CC_Version} <- list(U, S), not OrigTo(CCRes) ]; || {CCRes, CC_Version} <- list(U, S), not OrigTo(CCRes) ];
true -> {true, _} ->
%% The message was sent to our bare JID, and we currently have
%% multiple resources with the same highest priority, so the session
%% manager routes the message to each of them. We create carbon
%% copies only from one of those resources (the one where R equals
%% MaxRes) in order to avoid duplicates.
[];
{false, _} ->
[ {jlib:make_jid({U, S, CCRes}), CC_Version} [ {jlib:make_jid({U, S, CCRes}), CC_Version}
|| {CCRes, CC_Version} <- list(U, S), CCRes /= R ] || {CCRes, CC_Version} <- list(U, S), CCRes /= R ]
%TargetJIDs = lists:delete(JID, [ jlib:make_jid({U, S, CCRes}) || CCRes <- list(U, S) ]), %TargetJIDs = lists:delete(JID, [ jlib:make_jid({U, S, CCRes}) || CCRes <- list(U, S) ]),