25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-28 16:34:13 +01:00

Avoid routing packets through a single process

This commit is contained in:
Evgeny Khramtsov 2019-07-06 12:30:57 +03:00
parent 1663e78cf7
commit fd8e5ffce7
5 changed files with 65 additions and 28 deletions

View File

@ -43,6 +43,7 @@
-include("xmpp.hrl"). -include("xmpp.hrl").
-include("logger.hrl"). -include("logger.hrl").
-include("translate.hrl"). -include("translate.hrl").
-include("ejabberd_stacktrace.hrl").
-callback init(binary(), gen_mod:opts()) -> ok | {error, db_failure}. -callback init(binary(), gen_mod:opts()) -> ok | {error, db_failure}.
-callback set_channel(binary(), binary(), binary(), -callback set_channel(binary(), binary(), binary(),
@ -275,6 +276,15 @@ handle_cast(Request, State) ->
?WARNING_MSG("Unexpected cast: ~p", [Request]), ?WARNING_MSG("Unexpected cast: ~p", [Request]),
{noreply, State}. {noreply, State}.
handle_info({route, Packet}, State) ->
try route(Packet)
catch ?EX_RULE(Class, Reason, St) ->
StackTrace = ?EX_STACK(St),
?ERROR_MSG("Failed to route packet:~n~s~n** ~s",
[xmpp:pp(Packet),
misc:format_exception(2, Class, Reason, StackTrace)])
end,
{noreply, State};
handle_info(Info, State) -> handle_info(Info, State) ->
?WARNING_MSG("Unexpected info: ~p", [Info]), ?WARNING_MSG("Unexpected info: ~p", [Info]),
{noreply, State}. {noreply, State}.

View File

@ -393,10 +393,11 @@ handle_call({create, Room, Host, From, Nick, Opts}, _From,
handle_cast({route_to_room, Packet}, #state{server_host = ServerHost} = State) -> handle_cast({route_to_room, Packet}, #state{server_host = ServerHost} = State) ->
try route_to_room(Packet, ServerHost) try route_to_room(Packet, ServerHost)
catch ?EX_RULE(E, R, St) -> catch ?EX_RULE(Class, Reason, St) ->
StackTrace = ?EX_STACK(St), StackTrace = ?EX_STACK(St),
?ERROR_MSG("Failed to route packet:~n~s~nReason = ~p", ?ERROR_MSG("Failed to route packet:~n~s~n** ~s",
[xmpp:pp(Packet), {E, {R, StackTrace}}]) [xmpp:pp(Packet),
misc:format_exception(2, Class, Reason, StackTrace)])
end, end,
{noreply, State}; {noreply, State};
handle_cast({room_destroyed, {Room, Host}, Pid}, State) -> handle_cast({room_destroyed, {Room, Host}, Pid}, State) ->
@ -420,10 +421,11 @@ handle_info({route, Packet}, State) ->
%% where mod_muc is not loaded. Such configuration %% where mod_muc is not loaded. Such configuration
%% is *highly* discouraged %% is *highly* discouraged
try route(Packet, State#state.server_host) try route(Packet, State#state.server_host)
catch ?EX_RULE(E, R, St) -> catch ?EX_RULE(Class, Reason, St) ->
StackTrace = ?EX_STACK(St), StackTrace = ?EX_STACK(St),
?ERROR_MSG("Failed to route packet:~n~s~nReason = ~p", ?ERROR_MSG("Failed to route packet:~n~s~n** ~s",
[xmpp:pp(Packet), {E, {R, StackTrace}}]) [xmpp:pp(Packet),
misc:format_exception(2, Class, Reason, StackTrace)])
end, end,
{noreply, State}; {noreply, State};
handle_info({room_destroyed, {Room, Host}, Pid}, State) -> handle_info({room_destroyed, {Room, Host}, Pid}, State) ->

View File

@ -35,11 +35,12 @@
-export([start_link/2, reload/3, add_listener/2, process_disco_info/1, -export([start_link/2, reload/3, add_listener/2, process_disco_info/1,
process_disco_items/1, process_vcard/1, process_bytestreams/1, process_disco_items/1, process_vcard/1, process_bytestreams/1,
delete_listener/1]). delete_listener/1, route/1]).
-include("logger.hrl"). -include("logger.hrl").
-include("xmpp.hrl"). -include("xmpp.hrl").
-include("translate.hrl"). -include("translate.hrl").
-include("ejabberd_stacktrace.hrl").
-define(PROCNAME, ejabberd_mod_proxy65_service). -define(PROCNAME, ejabberd_mod_proxy65_service).
@ -71,7 +72,8 @@ init([Host, Opts]) ->
?MODULE, process_vcard), ?MODULE, process_vcard),
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS, gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS,
?MODULE, process_bytestreams), ?MODULE, process_bytestreams),
ejabberd_router:register_route(MyHost, Host) ejabberd_router:register_route(
MyHost, Host, {apply, ?MODULE, route})
end, MyHosts), end, MyHosts),
{ok, #state{myhosts = MyHosts}}. {ok, #state{myhosts = MyHosts}}.
@ -82,8 +84,14 @@ terminate(_Reason, #state{myhosts = MyHosts}) ->
unregister_handlers(MyHost) unregister_handlers(MyHost)
end, MyHosts). end, MyHosts).
handle_info({route, #iq{} = Packet}, State) -> handle_info({route, Packet}, State) ->
ejabberd_router:process_iq(Packet), try route(Packet)
catch ?EX_RULE(Class, Reason, St) ->
StackTrace = ?EX_STACK(St),
?ERROR_MSG("Failed to route packet:~n~s~n** ~s",
[xmpp:pp(Packet),
misc:format_exception(2, Class, Reason, StackTrace)])
end,
{noreply, State}; {noreply, State};
handle_info(_Info, State) -> {noreply, State}. handle_info(_Info, State) -> {noreply, State}.
@ -110,6 +118,12 @@ handle_cast(Msg, State) ->
code_change(_OldVsn, State, _Extra) -> {ok, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}.
-spec route(stanza()) -> ok.
route(#iq{} = IQ) ->
ejabberd_router:process_iq(IQ);
route(_) ->
ok.
%%%------------------------ %%%------------------------
%%% Listener management %%% Listener management
%%%------------------------ %%%------------------------

View File

@ -44,6 +44,7 @@
-include("pubsub.hrl"). -include("pubsub.hrl").
-include("mod_roster.hrl"). -include("mod_roster.hrl").
-include("translate.hrl"). -include("translate.hrl").
-include("ejabberd_stacktrace.hrl").
-define(STDTREE, <<"tree">>). -define(STDTREE, <<"tree">>).
-define(STDNODE, <<"flat">>). -define(STDNODE, <<"flat">>).
@ -92,6 +93,8 @@
handle_call/3, handle_cast/2, handle_info/2, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3, depends/2, mod_opt_type/1, mod_options/1]). terminate/2, code_change/3, depends/2, mod_opt_type/1, mod_options/1]).
-export([route/1]).
%%==================================================================== %%====================================================================
%% API %% API
%%==================================================================== %%====================================================================
@ -254,7 +257,8 @@ init([ServerHost, Opts]) ->
lists:flatmap( lists:flatmap(
fun(Host) -> fun(Host) ->
DBMod:init(Host, ServerHost, Opts), DBMod:init(Host, ServerHost, Opts),
ejabberd_router:register_route(Host, ServerHost), ejabberd_router:register_route(
Host, ServerHost, {apply, ?MODULE, route}),
{Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts), {Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts),
DefaultModule = plugin(Host, hd(Plugins)), DefaultModule = plugin(Host, hd(Plugins)),
DefaultNodeCfg = merge_config( DefaultNodeCfg = merge_config(
@ -727,15 +731,13 @@ handle_cast(_Msg, State) -> {noreply, State}.
%% Description: Handling all non call/cast messages %% Description: Handling all non call/cast messages
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% @private %% @private
handle_info({route, #iq{to = To} = IQ},
State) when To#jid.lresource == <<"">> ->
ejabberd_router:process_iq(IQ),
{noreply, State};
handle_info({route, Packet}, State) -> handle_info({route, Packet}, State) ->
To = xmpp:get_to(Packet), try route(Packet)
case catch do_route(To#jid.lserver, Packet) of catch ?EX_RULE(Class, Reason, St) ->
{'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); StackTrace = ?EX_STACK(St),
_ -> ok ?ERROR_MSG("Failed to route packet:~n~s~n** ~s",
[xmpp:pp(Packet),
misc:format_exception(2, Class, Reason, StackTrace)])
end, end,
{noreply, State}; {noreply, State};
handle_info(_Info, State) -> handle_info(_Info, State) ->
@ -892,8 +894,10 @@ process_commands(#iq{type = get, lang = Lang} = IQ) ->
Txt = ?T("Value 'get' of 'type' attribute is not allowed"), Txt = ?T("Value 'get' of 'type' attribute is not allowed"),
xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)). xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)).
-spec do_route(binary(), stanza()) -> ok. -spec route(stanza()) -> ok.
do_route(Host, Packet) -> route(#iq{to = To} = IQ) when To#jid.lresource == <<"">> ->
ejabberd_router:process_iq(IQ);
route(Packet) ->
To = xmpp:get_to(Packet), To = xmpp:get_to(Packet),
case To of case To of
#jid{luser = <<>>, lresource = <<>>} -> #jid{luser = <<>>, lresource = <<>>} ->
@ -906,7 +910,7 @@ do_route(Host, Packet) ->
ejabberd_router:route_error(Packet, Err); ejabberd_router:route_error(Packet, Err);
AuthResponse -> AuthResponse ->
handle_authorization_response( handle_authorization_response(
Host, Packet, AuthResponse) To#jid.lserver, Packet, AuthResponse)
end; end;
_ -> _ ->
Err = xmpp:err_service_unavailable(), Err = xmpp:err_service_unavailable(),

View File

@ -41,11 +41,13 @@
vcard_iq_set/1, mod_opt_type/1, set_vcard/3, make_vcard_search/4]). vcard_iq_set/1, mod_opt_type/1, set_vcard/3, make_vcard_search/4]).
-export([init/1, handle_call/3, handle_cast/2, -export([init/1, handle_call/3, handle_cast/2,
handle_info/2, terminate/2, code_change/3]). handle_info/2, terminate/2, code_change/3]).
-export([route/1]).
-include("logger.hrl"). -include("logger.hrl").
-include("xmpp.hrl"). -include("xmpp.hrl").
-include("mod_vcard.hrl"). -include("mod_vcard.hrl").
-include("translate.hrl"). -include("translate.hrl").
-include("ejabberd_stacktrace.hrl").
-define(VCARD_CACHE, vcard_cache). -define(VCARD_CACHE, vcard_cache).
@ -121,7 +123,8 @@ init([Host, Opts]) ->
"not implemented for ~s backend", "not implemented for ~s backend",
[mod_vcard_opt:db_type(Opts)]); [mod_vcard_opt:db_type(Opts)]);
true -> true ->
ejabberd_router:register_route(MyHost, Host) ejabberd_router:register_route(
MyHost, Host, {apply, ?MODULE, route})
end end
end, MyHosts); end, MyHosts);
true -> true ->
@ -137,9 +140,12 @@ handle_cast(Cast, State) ->
{noreply, State}. {noreply, State}.
handle_info({route, Packet}, State) -> handle_info({route, Packet}, State) ->
case catch do_route(Packet) of try route(Packet)
{'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); catch ?EX_RULE(Class, Reason, St) ->
_ -> ok StackTrace = ?EX_STACK(St),
?ERROR_MSG("Failed to route packet:~n~s~n** ~s",
[xmpp:pp(Packet),
misc:format_exception(2, Class, Reason, StackTrace)])
end, end,
{noreply, State}; {noreply, State};
handle_info(Info, State) -> handle_info(Info, State) ->
@ -169,9 +175,10 @@ terminate(_Reason, #state{hosts = MyHosts, server_host = Host}) ->
code_change(_OldVsn, State, _Extra) -> code_change(_OldVsn, State, _Extra) ->
{ok, State}. {ok, State}.
do_route(#iq{} = IQ) -> -spec route(stanza()) -> ok.
route(#iq{} = IQ) ->
ejabberd_router:process_iq(IQ); ejabberd_router:process_iq(IQ);
do_route(_) -> route(_) ->
ok. ok.
-spec get_sm_features({error, stanza_error()} | empty | {result, [binary()]}, -spec get_sm_features({error, stanza_error()} | empty | {result, [binary()]},