aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_router_multicast.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/ejabberd_router_multicast.erl')
-rw-r--r--src/ejabberd_router_multicast.erl51
1 files changed, 42 insertions, 9 deletions
diff --git a/src/ejabberd_router_multicast.erl b/src/ejabberd_router_multicast.erl
index 0d9d6b1d4..e97ccb837 100644
--- a/src/ejabberd_router_multicast.erl
+++ b/src/ejabberd_router_multicast.erl
@@ -30,7 +30,7 @@
-behaviour(gen_server).
%% API
--export([route_multicast/4,
+-export([route_multicast/5,
register_route/1,
unregister_route/1
]).
@@ -39,7 +39,7 @@
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
+ terminate/2, code_change/3, update_to_in_wrapped/2]).
-include("logger.hrl").
-include_lib("xmpp/include/xmpp.hrl").
@@ -58,9 +58,11 @@
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
--spec route_multicast(jid(), binary(), [jid()], stanza()) -> ok.
-route_multicast(From, Domain, Destinations, Packet) ->
- case catch do_route(Domain, Destinations, xmpp:set_from(Packet, From)) of
+-spec route_multicast(jid(), binary(), [jid()], stanza(), boolean()) -> ok.
+route_multicast(From0, Domain0, Destinations0, Packet0, Wrapped0) ->
+ {From, Domain, Destinations, Packet, Wrapped} =
+ ejabberd_hooks:run_fold(multicast_route, Domain0, {From0, Domain0, Destinations0, Packet0, Wrapped0}, []),
+ case catch do_route(Domain, Destinations, xmpp:set_from(Packet, From), Wrapped) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
[Reason, {From, Domain, Destinations, Packet}]);
@@ -157,7 +159,7 @@ handle_cast(Msg, State) ->
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info({route_multicast, Domain, Destinations, Packet}, State) ->
- case catch do_route(Domain, Destinations, Packet) of
+ case catch do_route(Domain, Destinations, Packet, false) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
[Reason, {Domain, Destinations, Packet}]);
@@ -204,13 +206,41 @@ terminate(_Reason, _State) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+-spec update_to_in_wrapped(stanza(), jid()) -> stanza().
+update_to_in_wrapped(Packet, To) ->
+ case Packet of
+ #message{sub_els = [#ps_event{
+ items = #ps_items{
+ items = [#ps_item{
+ sub_els = [Internal]
+ } = PSItem]
+ } = PSItems
+ } = PSEvent]} ->
+ Internal2 = xmpp:set_to(Internal, To),
+ PSItem2 = PSItem#ps_item{sub_els = [Internal2]},
+ PSItems2 = PSItems#ps_items{items = [PSItem2]},
+ PSEvent2 = PSEvent#ps_event{items = PSItems2},
+ xmpp:set_to(Packet#message{sub_els = [PSEvent2]}, To);
+ _ ->
+ xmpp:set_to(Packet, To)
+ end.
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
%% From = #jid
%% Destinations = [#jid]
--spec do_route(binary(), [jid()], stanza()) -> any().
-do_route(Domain, Destinations, Packet) ->
+-spec do_route(binary(), [jid()], stanza(), boolean()) -> any().
+do_route(Domain, Destinations, Packet, true) ->
+ ?DEBUG("Route multicast:~n~ts~nDomain: ~ts~nDestinations: ~ts~n",
+ [xmpp:pp(Packet), Domain,
+ str:join([jid:encode(To) || To <- Destinations], <<", ">>)]),
+ lists:foreach(
+ fun(To) ->
+ Packet2 = update_to_in_wrapped(Packet, To),
+ ejabberd_router:route(Packet2)
+ end, Destinations);
+do_route(Domain, Destinations, Packet, false) ->
?DEBUG("Route multicast:~n~ts~nDomain: ~ts~nDestinations: ~ts~n",
[xmpp:pp(Packet), Domain,
str:join([jid:encode(To) || To <- Destinations], <<", ">>)]),
@@ -236,4 +266,7 @@ pick_multicast_pid(Rs) ->
-spec do_route_normal([jid()], stanza()) -> any().
do_route_normal(Destinations, Packet) ->
- [ejabberd_router:route(xmpp:set_to(Packet, To)) || To <- Destinations].
+ lists:foreach(
+ fun(To) ->
+ ejabberd_router:route(xmpp:set_to(Packet, To))
+ end, Destinations).