diff options
author | Evgeniy Khramtsov <ekhramtsov@process-one.net> | 2015-08-12 16:58:56 +0300 |
---|---|---|
committer | Christophe Romain <christophe.romain@process-one.net> | 2015-10-02 16:09:55 +0200 |
commit | 6378c673df75ad05932e9029d3ccc965df43c810 (patch) | |
tree | aba1fcb77e78c5033aced089d5b8f30312f1d2f1 /src/mod_mam.erl | |
parent | Fix force_update_presence (diff) |
Avoid MAM dups when routing to multiple resources
Diffstat (limited to 'src/mod_mam.erl')
-rw-r--r-- | src/mod_mam.erl | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 3e3e0873..0c85e701 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -157,11 +157,12 @@ remove_user(LUser, LServer, odbc) -> LServer, [<<"delete from archive_prefs where username='">>, SUser, <<"';">>]). -user_receive_packet(Pkt, C2SState, JID, Peer, _To) -> +user_receive_packet(Pkt, C2SState, JID, Peer, To) -> LUser = JID#jid.luser, LServer = JID#jid.lserver, + IsBareCopy = is_bare_copy(JID, To), case should_archive(Pkt) of - true -> + true when not IsBareCopy -> NewPkt = strip_my_archived_tag(Pkt, LServer), case store_msg(C2SState, NewPkt, LUser, LServer, Peer, recv) of {ok, ID} -> @@ -178,7 +179,7 @@ user_receive_packet(Pkt, C2SState, JID, Peer, _To) -> _ -> NewPkt end; - false -> + _ -> Pkt end. @@ -726,6 +727,38 @@ maybe_update_from_to(#xmlel{children = Els} = Pkt, JidRequestor, Pkt2 = jlib:replace_from(jlib:jid_replace_resource(JidRequestor, Nick), Pkt1), jlib:remove_attr(<<"to">>, Pkt2). +is_bare_copy(#jid{luser = U, lserver = S, lresource = R}, To) -> + PrioRes = ejabberd_sm:get_user_present_resources(U, S), + MaxRes = case catch lists:max(PrioRes) of + {_Prio, Res} when is_binary(Res) -> + Res; + _ -> + undefined + end, + IsBareTo = case To of + #jid{lresource = <<"">>} -> + true; + #jid{lresource = LRes} -> + %% Unavailable resources are handled like bare JIDs. + lists:keyfind(LRes, 2, PrioRes) =:= false + end, + case {IsBareTo, R} of + {true, MaxRes} -> + ?DEBUG("Recipient of message to bare JID has top priority: ~s@~s/~s", + [U, S, R]), + false; + {true, _R} -> + %% 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 store the message + %% only from the resource where R equals MaxRes. + ?DEBUG("Additional recipient of message to bare JID: ~s@~s/~s", + [U, S, R]), + true; + {false, _R} -> + false + end. + send(From, To, Msgs, RSM, Count, IsComplete, #iq{sub_el = SubEl} = IQ) -> QID = xml:get_tag_attr_s(<<"queryid">>, SubEl), NS = xml:get_tag_attr_s(<<"xmlns">>, SubEl), |