aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_sm.erl
diff options
context:
space:
mode:
authorHolger Weiss <holger@zedat.fu-berlin.de>2016-11-22 19:25:20 +0100
committerHolger Weiss <holger@zedat.fu-berlin.de>2016-11-22 19:25:20 +0100
commit114ca786ee051b68c6ddc88b012af2226b07601e (patch)
treea2ceeeedfbf2705f7ab78384d0a682a23c037741 /src/ejabberd_sm.erl
parentFix xref issue injected by fbfbb96 (diff)
Let ejabberd_sm mark copied messages
When multiple resources have the same (highest) priority, ejabberd_sm dispatches messages addressed to the bare JID (or to an unavailable resource) to each of these resources. Such messages are now marked with an 'sm_copy' flag for all but one of the resources. This makes it easier for other modules to identify those duplicates. Resolves #1356.
Diffstat (limited to 'src/ejabberd_sm.erl')
-rw-r--r--src/ejabberd_sm.erl23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index 18703dc9c..b3953ec49 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -570,9 +570,9 @@ route_message(From, To, Packet, Type) ->
LServer = To#jid.lserver,
PrioRes = get_user_present_resources(LUser, LServer),
case catch lists:max(PrioRes) of
- {Priority, _R}
- when is_integer(Priority), Priority >= 0 ->
- lists:foreach(fun ({P, R}) when P == Priority;
+ {MaxPrio, MaxRes}
+ when is_integer(MaxPrio), MaxPrio >= 0 ->
+ lists:foreach(fun ({P, R}) when P == MaxPrio;
(P >= 0) and (Type == headline) ->
LResource = jid:resourceprep(R),
Mod = get_sm_backend(LServer),
@@ -584,7 +584,12 @@ route_message(From, To, Packet, Type) ->
Session = lists:max(Ss),
Pid = element(2, Session#session.sid),
?DEBUG("sending to process ~p~n", [Pid]),
- Pid ! {route, From, To, Packet}
+ LMaxRes = jid:resourceprep(MaxRes),
+ Packet1 = maybe_mark_as_copy(Packet,
+ LResource,
+ LMaxRes,
+ P, MaxPrio),
+ Pid ! {route, From, To, Packet1}
end;
%% Ignore other priority:
({_Prio, _Res}) -> ok
@@ -603,6 +608,16 @@ route_message(From, To, Packet, Type) ->
end
end.
+-spec maybe_mark_as_copy(message(), binary(), binary(), integer(), integer())
+ -> message().
+maybe_mark_as_copy(Packet, R, R, P, P) ->
+ Packet;
+maybe_mark_as_copy(Packet, _, _, P, P) ->
+ Meta = Packet#message.meta,
+ Packet#message{meta = Meta#{sm_copy => true}};
+maybe_mark_as_copy(Packet, _, _, _, _) ->
+ Packet.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec clean_session_list([#session{}]) -> [#session{}].
clean_session_list(Ss) ->