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("logger.hrl").
-include("translate.hrl").
-include("ejabberd_stacktrace.hrl").
-callback init(binary(), gen_mod:opts()) -> ok | {error, db_failure}.
-callback set_channel(binary(), binary(), binary(),
@ -275,6 +276,15 @@ handle_cast(Request, State) ->
?WARNING_MSG("Unexpected cast: ~p", [Request]),
{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) ->
?WARNING_MSG("Unexpected info: ~p", [Info]),
{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) ->
try route_to_room(Packet, ServerHost)
catch ?EX_RULE(E, R, St) ->
catch ?EX_RULE(Class, Reason, St) ->
StackTrace = ?EX_STACK(St),
?ERROR_MSG("Failed to route packet:~n~s~nReason = ~p",
[xmpp:pp(Packet), {E, {R, StackTrace}}])
?ERROR_MSG("Failed to route packet:~n~s~n** ~s",
[xmpp:pp(Packet),
misc:format_exception(2, Class, Reason, StackTrace)])
end,
{noreply, 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
%% is *highly* discouraged
try route(Packet, State#state.server_host)
catch ?EX_RULE(E, R, St) ->
catch ?EX_RULE(Class, Reason, St) ->
StackTrace = ?EX_STACK(St),
?ERROR_MSG("Failed to route packet:~n~s~nReason = ~p",
[xmpp:pp(Packet), {E, {R, StackTrace}}])
?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({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,
process_disco_items/1, process_vcard/1, process_bytestreams/1,
delete_listener/1]).
delete_listener/1, route/1]).
-include("logger.hrl").
-include("xmpp.hrl").
-include("translate.hrl").
-include("ejabberd_stacktrace.hrl").
-define(PROCNAME, ejabberd_mod_proxy65_service).
@ -71,7 +72,8 @@ init([Host, Opts]) ->
?MODULE, process_vcard),
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS,
?MODULE, process_bytestreams),
ejabberd_router:register_route(MyHost, Host)
ejabberd_router:register_route(
MyHost, Host, {apply, ?MODULE, route})
end, MyHosts),
{ok, #state{myhosts = MyHosts}}.
@ -82,8 +84,14 @@ terminate(_Reason, #state{myhosts = MyHosts}) ->
unregister_handlers(MyHost)
end, MyHosts).
handle_info({route, #iq{} = Packet}, State) ->
ejabberd_router:process_iq(Packet),
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) -> {noreply, State}.
@ -110,6 +118,12 @@ handle_cast(Msg, State) ->
code_change(_OldVsn, State, _Extra) -> {ok, State}.
-spec route(stanza()) -> ok.
route(#iq{} = IQ) ->
ejabberd_router:process_iq(IQ);
route(_) ->
ok.
%%%------------------------
%%% Listener management
%%%------------------------

View File

@ -44,6 +44,7 @@
-include("pubsub.hrl").
-include("mod_roster.hrl").
-include("translate.hrl").
-include("ejabberd_stacktrace.hrl").
-define(STDTREE, <<"tree">>).
-define(STDNODE, <<"flat">>).
@ -92,6 +93,8 @@
handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3, depends/2, mod_opt_type/1, mod_options/1]).
-export([route/1]).
%%====================================================================
%% API
%%====================================================================
@ -254,7 +257,8 @@ init([ServerHost, Opts]) ->
lists:flatmap(
fun(Host) ->
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),
DefaultModule = plugin(Host, hd(Plugins)),
DefaultNodeCfg = merge_config(
@ -727,15 +731,13 @@ handle_cast(_Msg, State) -> {noreply, State}.
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
%% @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) ->
To = xmpp:get_to(Packet),
case catch do_route(To#jid.lserver, Packet) of
{'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
_ -> ok
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) ->
@ -892,8 +894,10 @@ process_commands(#iq{type = get, lang = Lang} = IQ) ->
Txt = ?T("Value 'get' of 'type' attribute is not allowed"),
xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)).
-spec do_route(binary(), stanza()) -> ok.
do_route(Host, Packet) ->
-spec route(stanza()) -> ok.
route(#iq{to = To} = IQ) when To#jid.lresource == <<"">> ->
ejabberd_router:process_iq(IQ);
route(Packet) ->
To = xmpp:get_to(Packet),
case To of
#jid{luser = <<>>, lresource = <<>>} ->
@ -906,7 +910,7 @@ do_route(Host, Packet) ->
ejabberd_router:route_error(Packet, Err);
AuthResponse ->
handle_authorization_response(
Host, Packet, AuthResponse)
To#jid.lserver, Packet, AuthResponse)
end;
_ ->
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]).
-export([init/1, handle_call/3, handle_cast/2,
handle_info/2, terminate/2, code_change/3]).
-export([route/1]).
-include("logger.hrl").
-include("xmpp.hrl").
-include("mod_vcard.hrl").
-include("translate.hrl").
-include("ejabberd_stacktrace.hrl").
-define(VCARD_CACHE, vcard_cache).
@ -121,7 +123,8 @@ init([Host, Opts]) ->
"not implemented for ~s backend",
[mod_vcard_opt:db_type(Opts)]);
true ->
ejabberd_router:register_route(MyHost, Host)
ejabberd_router:register_route(
MyHost, Host, {apply, ?MODULE, route})
end
end, MyHosts);
true ->
@ -137,9 +140,12 @@ handle_cast(Cast, State) ->
{noreply, State}.
handle_info({route, Packet}, State) ->
case catch do_route(Packet) of
{'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
_ -> ok
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) ->
@ -169,9 +175,10 @@ terminate(_Reason, #state{hosts = MyHosts, server_host = Host}) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
do_route(#iq{} = IQ) ->
-spec route(stanza()) -> ok.
route(#iq{} = IQ) ->
ejabberd_router:process_iq(IQ);
do_route(_) ->
route(_) ->
ok.
-spec get_sm_features({error, stanza_error()} | empty | {result, [binary()]},