Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge c2s_preprocessing_hook into user_send_packet #3852

Merged
merged 2 commits into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions big_tests/tests/acc_e2e_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -74,26 +74,26 @@ end_per_suite(Config) ->

init_per_group(message, Config) ->
% saves ref, timestamp and some attrs of acc in ets
add_handler(c2s_preprocessing_hook, test_save_acc, 50),
add_handler(user_send_packet, test_save_acc, 5),
% checks it is the same acc
add_handler(filter_local_packet, test_check_acc, 50),
% checks it is the same acc and it has been stripped but keeps persistent props
add_handler(user_receive_packet, test_check_final_acc, 50),
Config;
init_per_group(cache_and_strip, Config) ->
add_handler(c2s_preprocessing_hook, save_my_jid, 50),
add_handler(user_send_packet, save_my_jid, 5),
add_handler(filter_local_packet, drop_if_jid_not_mine, 1),
Config;
init_per_group(_GroupName, Config) ->
Config.

end_per_group(message, _Config) ->
remove_handler(c2s_preprocessing_hook, test_save_acc, 50),
remove_handler(user_send_packet, test_save_acc, 5),
remove_handler(filter_local_packet, test_check_acc, 50),
remove_handler(user_receive_packet, test_check_final_acc, 50),
ok;
end_per_group(cache_and_strip, _Config) ->
remove_handler(c2s_preprocessing_hook, save_my_jid, 50),
remove_handler(user_send_packet, save_my_jid, 5),
remove_handler(filter_local_packet, drop_if_jid_not_mine, 1),
ok;
end_per_group(_GroupName, _Config) ->
Expand Down
1 change: 0 additions & 1 deletion doc/developers-guide/hooks_description.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ This is the perfect place to plug in custom security control.
* auth_failed
* c2s_broadcast_recipients
* c2s_filter_packet
* c2s_preprocessing_hook
* c2s_presence_in
* c2s_remote_hook
* c2s_stream_features
Expand Down
12 changes: 1 addition & 11 deletions src/c2s/mongoose_c2s.erl
Original file line number Diff line number Diff line change
Expand Up @@ -661,17 +661,7 @@ handle_foreign_packet(StateData = #c2s_data{host_type = HostType, lserver = LSer
-spec handle_c2s_packet(c2s_data(), c2s_state(), exml:element()) -> fsm_res().
handle_c2s_packet(StateData = #c2s_data{host_type = HostType}, C2SState, El) ->
HookParams = hook_arg(StateData, C2SState, internal, El, undefined),
Acc0 = element_to_origin_accum(StateData, El),
case mongoose_c2s_hooks:c2s_preprocessing_hook(HostType, Acc0, HookParams) of
{ok, Acc1} ->
do_handle_c2s_packet(StateData, C2SState, Acc1, HookParams);
{stop, _Acc1} ->
{next_state, C2SState, StateData}
end.

-spec do_handle_c2s_packet(c2s_data(), c2s_state(), mongoose_acc:t(), mongoose_c2s_hooks:hook_params()) ->
fsm_res().
do_handle_c2s_packet(StateData = #c2s_data{host_type = HostType}, C2SState, Acc, HookParams) ->
Acc = element_to_origin_accum(StateData, El),
case mongoose_c2s_hooks:user_send_packet(HostType, Acc, HookParams) of
{ok, Acc1} ->
Acc2 = handle_stanza_from_client(StateData, HookParams, Acc1, mongoose_acc:stanza_name(Acc1)),
Expand Down
17 changes: 0 additions & 17 deletions src/c2s/mongoose_c2s_hooks.erl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
-export_type([hook_fn/0, hook_params/0, hook_result/0]).

%% XML handlers
-export([c2s_preprocessing_hook/3]).
-export([user_send_packet/3,
user_receive_packet/3,
user_send_message/3,
Expand All @@ -34,22 +33,6 @@
user_socket_closed/3,
user_socket_error/3]).

%%% @doc Event triggered after a user sends _any_ packet to the server.
%%% The purpose is to modify, or reject, packets, before they are further processed.
%%% TODO: this can really be merged into `user_send_packet' with early priority.
-spec c2s_preprocessing_hook(HostType, Acc, Params) -> Result when
HostType :: mongooseim:host_type(),
Acc :: mongoose_acc:t(),
Params :: hook_params(),
Result :: hook_result().
c2s_preprocessing_hook(HostType, Acc, #{c2s_data := StateData} = Params) ->
ParamsWithLegacyArgs = ejabberd_hooks:add_args(Params, [StateData]),
{Tag, Acc1} = gen_hook:run_fold(c2s_preprocessing_hook, HostType, Acc, ParamsWithLegacyArgs),
case mongoose_acc:get(hook, result, undefined, Acc1) of
drop -> {stop, Acc1};
_ -> {Tag, Acc1}
end.

%%% @doc Event triggered after a user sends _any_ packet to the server.
%%% Examples of handlers can be metrics, archives, and any other subsystem
%%% that wants to see all stanzas the user delivers.
Expand Down
59 changes: 18 additions & 41 deletions src/jingle_sip/mod_jingle_sip.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,14 @@
-include("jlib.hrl").
-include("mongoose.hrl").
-include("mongoose_config_spec.hrl").
-include_lib("nklib/include/nklib.hrl").
-include_lib("nksip/include/nksip.hrl").
-include_lib("nksip/include/nksip_call.hrl").

-define(SERVICE, "mim_sip").

%% gen_mod callbacks
-export([start/2, stop/1, config_spec/0]).

-export([intercept_jingle_stanza/3]).
-export([user_send_iq/3]).

-export([content_to_nksip_media/1]).

Expand Down Expand Up @@ -121,60 +119,40 @@ process_u2p(#{username := U, phone := P}) ->
{U, P}.

hooks(Host) ->
[{c2s_preprocessing_hook, Host, fun ?MODULE:intercept_jingle_stanza/3, #{}, 75}].

-spec intercept_jingle_stanza(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mongoose_acc:t(),
Params :: map(),
Extra :: map().
intercept_jingle_stanza(Acc, _, _) ->
NewAcc = case mongoose_acc:get(hook, result, undefined, Acc) of
drop ->
Acc;
_ ->
maybe_iq_stanza(Acc)
end,
{ok, NewAcc}.

maybe_iq_stanza(Acc) ->
case mongoose_acc:stanza_name(Acc) of
<<"iq">> ->
maybe_iq_to_other_user(Acc);
_ ->
Acc
end.
[{user_send_iq, Host, fun ?MODULE:user_send_iq/3, #{}, 10}].

maybe_iq_to_other_user(Acc) ->
#jid{luser = StanzaTo} = mongoose_acc:to_jid(Acc),
-spec user_send_iq(mongoose_acc:t(), mongoose_c2s_hooks:hook_params(), gen_hook:extra()) ->
mongoose_c2s_hooks:hook_result().
user_send_iq(Acc, _, _) ->
{From, To, Packet} = mongoose_acc:packet(Acc),
#jid{luser = StanzaTo} = To,
#jid{luser = LUser} = mongoose_acc:get(c2s, origin_jid, Acc),
case LUser of
StanzaTo ->
QueryInfo = jlib:iq_query_info(mongoose_acc:element(Acc)),
QueryInfo = jlib:iq_query_info(Packet),
maybe_jingle_get_stanza_to_self(QueryInfo, Acc);
_ ->
QueryInfo = jlib:iq_query_info(mongoose_acc:element(Acc)),
maybe_jingle_stanza(QueryInfo, Acc)
QueryInfo = jlib:iq_query_info(Packet),
maybe_jingle_stanza(QueryInfo, From, To, Acc)
end.

maybe_jingle_stanza(#iq{xmlns = ?JINGLE_NS, sub_el = Jingle, type = set} = IQ, Acc) ->
maybe_jingle_stanza(#iq{xmlns = ?JINGLE_NS, sub_el = Jingle, type = set} = IQ, From, To, Acc) ->
JingleAction = exml_query:attr(Jingle, <<"action">>),
From = mongoose_acc:from_jid(Acc),
To = mongoose_acc:to_jid(Acc),
maybe_translate_to_sip(JingleAction, From, To, IQ, Acc);
maybe_jingle_stanza(_, Acc) ->
Acc.
maybe_jingle_stanza(_, _, _, Acc) ->
{ok, Acc}.

maybe_jingle_get_stanza_to_self(#iq{xmlns = ?JINGLE_NS, sub_el = Jingle, type = get} = IQ, Acc) ->
JingleAction = exml_query:attr(Jingle, <<"action">>),
case JingleAction of
<<"existing-session-initiate">> ->
resend_session_initiate(IQ, Acc),
mongoose_acc:set(hook, result, drop, Acc);
{stop, Acc};
_ ->
Acc
{ok, Acc}
end;
maybe_jingle_get_stanza_to_self(_, Acc) ->
Acc.
{ok, Acc}.

maybe_translate_to_sip(JingleAction, From, To, IQ, Acc)
when JingleAction =:= <<"session-initiate">>;
Expand All @@ -193,12 +171,12 @@ maybe_translate_to_sip(JingleAction, From, To, IQ, Acc)
?LOG_ERROR(#{what => sip_translate_failed, acc => Acc,
class => Class, reason => Error, stacktrace => StackTrace})
end,
mongoose_acc:set(hook, result, drop, Acc);
{stop, Acc};
maybe_translate_to_sip(JingleAction, _, _, _, Acc) ->
?LOG_WARNING(#{what => sip_unknown_action,
text => <<"Forwarding unknown action to SIP">>,
jingle_action => JingleAction, acc => Acc}),
Acc.
{ok, Acc}.

route_result(ok, From, To, IQ) ->
route_ok_result(From, To, IQ);
Expand Down Expand Up @@ -610,4 +588,3 @@ nksip_uac_bye(Node, DialogHandle, Args) ->
_ ->
rpc:call(Node, nksip_uac, bye, [DialogHandle, Args], timer:seconds(5))
end.

26 changes: 11 additions & 15 deletions src/mod_amp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
-behaviour(mongoose_module_metrics).
-xep([{xep, 79}, {version, "1.2"}, {comment, "partially implemented."}]).
-export([start/2, stop/1, supported_features/0]).
-export([run_initial_check/3,
-export([user_send_message/3,
check_packet/2,
disco_local_features/3,
c2s_stream_features/3,
Expand All @@ -35,7 +35,7 @@ supported_features() -> [dynamic_domains].

-spec c2s_hooks(mongooseim:host_type()) -> gen_hook:hook_list(mongoose_c2s_hooks:hook_fn()).
c2s_hooks(HostType) ->
[{c2s_preprocessing_hook, HostType, fun ?MODULE:run_initial_check/3, #{}, 10}].
[{user_send_message, HostType, fun ?MODULE:user_send_message/3, #{}, 5}].

hooks(HostType) ->
[
Expand All @@ -49,13 +49,11 @@ hooks(HostType) ->

%% API

-spec run_initial_check(mongoose_acc:t(), mongoose_c2s_hooks:hook_params(), gen_hook:extra()) ->
gen_hook:hook_fn_ret(mongoose_acc:t()).
run_initial_check(Acc, _, _) ->
case mongoose_acc:stanza_name(Acc) of
<<"message">> -> run_initial_check(Acc);
_ -> {ok, Acc}
end.
-spec user_send_message(mongoose_acc:t(), mongoose_c2s_hooks:hook_params(), gen_hook:extra()) ->
mongoose_c2s_hooks:hook_result().
user_send_message(Acc, _, _) ->
{From, To, Element} = mongoose_acc:packet(Acc),
run_initial_check(Acc, From, To, Element).

-spec check_packet(mongoose_acc:t(), amp_event()) -> mongoose_acc:t().
check_packet(Acc, Event) ->
Expand Down Expand Up @@ -89,13 +87,11 @@ xmpp_send_element(Acc, _Params, _Extra) ->
_ -> delivery_failed
end,
{ok, check_packet(Acc, Event)}.
%% Internal

-spec run_initial_check(mongoose_acc:t()) -> gen_hook:hook_fn_ret(mongoose_acc:t()).
run_initial_check(Acc) ->
Packet = mongoose_acc:element(Acc),
From = mongoose_acc:from_jid(Acc),
To = mongoose_acc:to_jid(Acc),
%% Internal
-spec run_initial_check(mongoose_acc:t(), jid:jid(), jid:jid(), exml:element()) ->
mongoose_c2s_hooks:hook_result().
run_initial_check(Acc, From, To, Packet) ->
Result = case amp:extract_requested_rules(Packet) of
none -> nothing_to_do;
{rules, Rules} -> validate_and_process_rules(Packet, From, Rules, Acc);
Expand Down
2 changes: 1 addition & 1 deletion src/stream_management/mod_stream_management.erl
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ hooks(HostType) ->
-spec c2s_hooks(mongooseim:host_type()) -> gen_hook:hook_list(mongoose_c2s_hooks:hook_fn()).
c2s_hooks(HostType) ->
[
{user_send_packet, HostType, fun ?MODULE:user_send_packet/3, #{}, 10},
{user_send_packet, HostType, fun ?MODULE:user_send_packet/3, #{}, 20},
{user_receive_packet, HostType, fun ?MODULE:user_receive_packet/3, #{}, 100},
{user_send_xmlel, HostType, fun ?MODULE:user_send_xmlel/3, #{}, 50},
{foreign_event, HostType, fun ?MODULE:foreign_event/3, #{}, 50},
Expand Down