mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-28 16:34:13 +01:00
Merge pull request #161 from weiss/fix-carbons
Let mod_carboncopy take care of messages sent to bare/unavailable JIDs
This commit is contained in:
commit
37d4109e8a
@ -37,6 +37,7 @@
|
|||||||
bounce_offline_message/3,
|
bounce_offline_message/3,
|
||||||
disconnect_removed_user/2,
|
disconnect_removed_user/2,
|
||||||
get_user_resources/2,
|
get_user_resources/2,
|
||||||
|
get_user_present_resources/2,
|
||||||
set_presence/7,
|
set_presence/7,
|
||||||
unset_presence/6,
|
unset_presence/6,
|
||||||
close_session_unset_presence/5,
|
close_session_unset_presence/5,
|
||||||
@ -166,6 +167,20 @@ get_user_resources(User, Server) ->
|
|||||||
[element(3, S#session.usr) || S <- clean_session_list(Ss)]
|
[element(3, S#session.usr) || S <- clean_session_list(Ss)]
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec get_user_present_resources(binary(), binary()) -> [tuple()].
|
||||||
|
|
||||||
|
get_user_present_resources(LUser, LServer) ->
|
||||||
|
US = {LUser, LServer},
|
||||||
|
case catch mnesia:dirty_index_read(session, US,
|
||||||
|
#session.us)
|
||||||
|
of
|
||||||
|
{'EXIT', _Reason} -> [];
|
||||||
|
Ss ->
|
||||||
|
[{S#session.priority, element(3, S#session.usr)}
|
||||||
|
|| S <- clean_session_list(Ss),
|
||||||
|
is_integer(S#session.priority)]
|
||||||
|
end.
|
||||||
|
|
||||||
-spec get_user_ip(binary(), binary(), binary()) -> ip().
|
-spec get_user_ip(binary(), binary(), binary()) -> ip().
|
||||||
|
|
||||||
get_user_ip(User, Server, Resource) ->
|
get_user_ip(User, Server, Resource) ->
|
||||||
@ -669,20 +684,6 @@ clean_session_list([S1, S2 | Rest], Res) ->
|
|||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
get_user_present_resources(LUser, LServer) ->
|
|
||||||
US = {LUser, LServer},
|
|
||||||
case catch mnesia:dirty_index_read(session, US,
|
|
||||||
#session.us)
|
|
||||||
of
|
|
||||||
{'EXIT', _Reason} -> [];
|
|
||||||
Ss ->
|
|
||||||
[{S#session.priority, element(3, S#session.usr)}
|
|
||||||
|| S <- clean_session_list(Ss),
|
|
||||||
is_integer(S#session.priority)]
|
|
||||||
end.
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
%% On new session, check if some existing connections need to be replace
|
%% On new session, check if some existing connections need to be replace
|
||||||
check_for_sessions_to_replace(User, Server, Resource) ->
|
check_for_sessions_to_replace(User, Server, Resource) ->
|
||||||
LUser = jlib:nodeprep(User),
|
LUser = jlib:nodeprep(User),
|
||||||
|
@ -127,23 +127,18 @@ iq_handler(From, _To, #iq{type=set, sub_el = #xmlel{name = Operation, children
|
|||||||
iq_handler(_From, _To, IQ, _CC)->
|
iq_handler(_From, _To, IQ, _CC)->
|
||||||
IQ#iq{type=error, sub_el = [?ERR_NOT_ALLOWED]}.
|
IQ#iq{type=error, sub_el = [?ERR_NOT_ALLOWED]}.
|
||||||
|
|
||||||
user_send_packet(From, _To, Packet) ->
|
user_send_packet(From, To, Packet) ->
|
||||||
check_and_forward(From, Packet, sent).
|
check_and_forward(From, To, Packet, sent).
|
||||||
|
|
||||||
%% Only make carbon copies if the original destination was not a bare jid.
|
user_receive_packet(JID, _From, To, Packet) ->
|
||||||
%% If the original destination was a bare jid, the message is going to be delivered to all
|
check_and_forward(JID, To, Packet, received).
|
||||||
%% connected resources anyway. Avoid duplicate delivery. "XEP-0280 : 3.5 Receiving Messages"
|
|
||||||
user_receive_packet(JID, _From, #jid{resource=Resource} = _To, Packet) when Resource /= <<>> ->
|
|
||||||
check_and_forward(JID, Packet, received);
|
|
||||||
user_receive_packet(_JID, _From, _To, _Packet) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
% verifier si le trafic est local
|
% verifier si le trafic est local
|
||||||
% Modified from original version:
|
% Modified from original version:
|
||||||
% - registered to the user_send_packet hook, to be called only once even for multicast
|
% - registered to the user_send_packet hook, to be called only once even for multicast
|
||||||
% - do not support "private" message mode, and do not modify the original packet in any way
|
% - do not support "private" message mode, and do not modify the original packet in any way
|
||||||
% - we also replicate "read" notifications
|
% - we also replicate "read" notifications
|
||||||
check_and_forward(JID, #xmlel{name = <<"message">>, attrs = Attrs} = Packet, Direction)->
|
check_and_forward(JID, To, #xmlel{name = <<"message">>, attrs = Attrs} = Packet, Direction)->
|
||||||
case xml:get_attr_s(<<"type">>, Attrs) of
|
case xml:get_attr_s(<<"type">>, Attrs) of
|
||||||
<<"chat">> ->
|
<<"chat">> ->
|
||||||
case xml:get_subtag(Packet, <<"private">>) of
|
case xml:get_subtag(Packet, <<"private">>) of
|
||||||
@ -154,11 +149,11 @@ check_and_forward(JID, #xmlel{name = <<"message">>, attrs = Attrs} = Packet, Dir
|
|||||||
%% receiving message back to original sender.
|
%% receiving message back to original sender.
|
||||||
SubTag = xml:get_subtag(Packet,<<"sent">>),
|
SubTag = xml:get_subtag(Packet,<<"sent">>),
|
||||||
if SubTag == false ->
|
if SubTag == false ->
|
||||||
send_copies(JID, Packet, Direction);
|
send_copies(JID, To, Packet, Direction);
|
||||||
true ->
|
true ->
|
||||||
case xml:get_subtag(SubTag,<<"forwarded">>) of
|
case xml:get_subtag(SubTag,<<"forwarded">>) of
|
||||||
false->
|
false->
|
||||||
send_copies(JID, Packet, Direction);
|
send_copies(JID, To, Packet, Direction);
|
||||||
_ ->
|
_ ->
|
||||||
stop
|
stop
|
||||||
end
|
end
|
||||||
@ -174,7 +169,7 @@ check_and_forward(JID, #xmlel{name = <<"message">>, attrs = Attrs} = Packet, Dir
|
|||||||
ok
|
ok
|
||||||
end;
|
end;
|
||||||
|
|
||||||
check_and_forward(_JID, _Packet, _)-> ok.
|
check_and_forward(_JID, _To, _Packet, _)-> ok.
|
||||||
|
|
||||||
remove_connection(User, Server, Resource, _Status)->
|
remove_connection(User, Server, Resource, _Status)->
|
||||||
disable(Server, User, Resource),
|
disable(Server, User, Resource),
|
||||||
@ -183,14 +178,35 @@ remove_connection(User, Server, Resource, _Status)->
|
|||||||
|
|
||||||
%%% Internal
|
%%% Internal
|
||||||
%% Direction = received | sent <received xmlns='urn:xmpp:carbons:1'/>
|
%% Direction = received | sent <received xmlns='urn:xmpp:carbons:1'/>
|
||||||
send_copies(JID, 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),
|
||||||
|
|
||||||
|
IsBareTo = case {Direction, To} of
|
||||||
|
{received, #jid{lresource = <<>>}} -> true;
|
||||||
|
{received, #jid{lresource = LRes}} ->
|
||||||
|
%% unavailable resources are handled like bare JIDs
|
||||||
|
case lists:keyfind(LRes, 2, PrioRes) of
|
||||||
|
false -> true;
|
||||||
|
_ -> false
|
||||||
|
end;
|
||||||
|
_ -> false
|
||||||
|
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 of the original message
|
%% receiver(s) of the original message
|
||||||
TargetJIDs = [ {jlib:make_jid({U, S, CCRes}), CC_Version} || {CCRes, CC_Version} <- list(U, S), CCRes /= R ],
|
TargetJIDs = if IsBareTo ->
|
||||||
|
MaxPrio = case catch lists:max(PrioRes) of
|
||||||
|
{Prio, _Res} -> Prio;
|
||||||
|
_ -> 0
|
||||||
|
end,
|
||||||
|
OrigTo = fun(Res) -> lists:member({MaxPrio, Res}, PrioRes) end,
|
||||||
|
[ {jlib:make_jid({U, S, CCRes}), CC_Version}
|
||||||
|
|| {CCRes, CC_Version} <- list(U, S), not OrigTo(CCRes) ];
|
||||||
|
true ->
|
||||||
|
[ {jlib:make_jid({U, S, CCRes}), CC_Version}
|
||||||
|
|| {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) ]),
|
||||||
|
end,
|
||||||
|
|
||||||
lists:map(fun({Dest,Version}) ->
|
lists:map(fun({Dest,Version}) ->
|
||||||
{_, _, Resource} = jlib:jid_tolower(Dest),
|
{_, _, Resource} = jlib:jid_tolower(Dest),
|
||||||
|
Loading…
Reference in New Issue
Block a user