Skip to content

Commit

Permalink
Merge pull request #3628 from esl/listener-config-rework
Browse files Browse the repository at this point in the history
Listener configuration rework
  • Loading branch information
arcusfelis authored Apr 20, 2022
2 parents 3cf9f22 + 01ed2ab commit 6d1c24b
Show file tree
Hide file tree
Showing 33 changed files with 1,040 additions and 1,350 deletions.
15 changes: 9 additions & 6 deletions big_tests/tests/connect_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ init_per_group(feature_order, Config) ->
configure_c2s_listener(Config, #{zlib => 10000,
tls => [starttls_required | common_tls_opts(Config)]}),
Config;
init_per_group(just_tls,Config)->
init_per_group(just_tls, Config)->
[{tls_module, just_tls} | Config];
init_per_group(fast_tls,Config)->
init_per_group(fast_tls, Config)->
[{tls_module, fast_tls} | Config];
init_per_group(proxy_protocol, Config) ->
configure_c2s_listener(Config, #{proxy_protocol => true}),
Expand Down Expand Up @@ -765,10 +765,13 @@ configure_c2s_listener(Config, ExtraC2SOpts) ->
mongoose_helper:restart_listener(mim(), NewC2SListener).

common_tls_opts(Config) ->
TLSModule = ?config(tls_module, Config),
[{tls_module, TLSModule},
{certfile, ?CERT_FILE},
{dhfile, ?DH_FILE}].
tls_module_opts(Config) ++ [{certfile, ?CERT_FILE}, {dhfile, ?DH_FILE}].

tls_module_opts(Config) ->
case ?config(tls_module, Config) of
undefined -> [];
Module -> [{tls_module, Module}]
end.

set_secure_connection_protocol(UserSpec, Version) ->
[{ssl_opts, [{versions, [Version]}]} | UserSpec].
Expand Down
23 changes: 10 additions & 13 deletions big_tests/tests/domain_rest_helper.erl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
stop_listener/1]).

-import(distributed_helper, [mim/0, mim2/0, require_rpc_nodes/1, rpc/4]).
-import(config_parser_helper, [default_config/1, config/2]).

-define(TEST_PORT, 8866).

Expand Down Expand Up @@ -98,23 +99,19 @@ patch_custom(Config, Role, Path, Body) ->

%% REST handler setup
start_listener(Params) ->
rpc(mim(), ejabberd_listener, start_listener, [listener_opts(Params)]).
rpc(mim(), mongoose_listener, start_listener, [listener_opts(Params)]).

stop_listener(Params) ->
rpc(mim(), ejabberd_listener, stop_listener, [listener_opts(Params)]).
rpc(mim(), mongoose_listener, stop_listener, [listener_opts(Params)]).

listener_opts(Params) ->
#{port => ?TEST_PORT,
ip_tuple => {127, 0, 0, 1},
ip_address => "127.0.0.1",
ip_version => 4,
proto => tcp,
module => ejabberd_cowboy,
modules => [domain_handler(Params)],
transport_options => transport_options()}.

transport_options() ->
[{max_connections, 1024}, {num_acceptors, 10}].
config([listen, http],
#{port => ?TEST_PORT,
ip_tuple => {127, 0, 0, 1},
ip_address => "127.0.0.1",
module => ejabberd_cowboy,
handlers => [domain_handler(Params)],
transport => config([listen, http, transport], #{num_acceptors => 10})}).

domain_handler(Params) ->
{"localhost", "/api", mongoose_domain_handler, handler_opts(Params)}.
Expand Down
4 changes: 2 additions & 2 deletions big_tests/tests/mongoose_helper.erl
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,8 @@ get_listeners(#{} = Spec, Pattern) ->

%% 'port', 'ip_tuple' and 'proto' options need to stay unchanged for a successful restart
restart_listener(Spec, Listener) ->
rpc(Spec, ejabberd_listener, stop_listener, [Listener]),
rpc(Spec, ejabberd_listener, start_listener, [Listener]).
rpc(Spec, mongoose_listener, stop_listener, [Listener]),
rpc(Spec, mongoose_listener, start_listener, [Listener]).

should_minio_be_running(Config) ->
case proplists:get_value(preset, Config, undefined) of
Expand Down
16 changes: 8 additions & 8 deletions big_tests/tests/rest_helper.erl
Original file line number Diff line number Diff line change
Expand Up @@ -255,34 +255,34 @@ get_port(Role, Node, _Params) ->
get_ssl_status(Role, Node) ->
Listeners = rpc(Node, mongoose_config, get_opt, [listen]),
[Opts] = lists:filter(fun (Opts) -> is_roles_config(Opts, Role) end, Listeners),
maps:is_key(ssl, Opts).
maps:is_key(tls, Opts).

% @doc Changes the control credentials for admin by restarting the listener
% with new options.
-spec change_admin_creds({User :: binary(), Password :: binary()}) -> 'ok' | 'error'.
change_admin_creds(Creds) ->
stop_admin_listener(),
{ok, _} = start_admin_listener(Creds).
ok = start_admin_listener(Creds).

-spec stop_admin_listener() -> 'ok' | {'error', 'not_found' | 'restarting' | 'running' | 'simple_one_for_one'}.
stop_admin_listener() ->
Listeners = rpc(mim(), mongoose_config, get_opt, [listen]),
[Opts] = lists:filter(fun (Opts) -> is_roles_config(Opts, admin) end, Listeners),
rpc(mim(), ejabberd_listener, stop_listener, [Opts]).
rpc(mim(), mongoose_listener, stop_listener, [Opts]).

-spec start_admin_listener(Creds :: {binary(), binary()}) -> {'error', pid()} | {'ok', _}.
start_admin_listener(Creds) ->
Listeners = rpc(mim(), mongoose_config, get_opt, [listen]),
[Opts] = lists:filter(fun (Opts) -> is_roles_config(Opts, admin) end, Listeners),
NewOpts = insert_creds(Opts, Creds),
rpc(mim(), ejabberd_listener, start_listener, [NewOpts]).
rpc(mim(), mongoose_listener, start_listener, [NewOpts]).

insert_creds(Opts = #{modules := Modules}, Creds) ->
insert_creds(Opts = #{handlers := Modules}, Creds) ->
{Host, Path, mongoose_api_admin, PathOpts} = lists:keyfind(mongoose_api_admin, 3, Modules),
NewPathOpts = inject_creds_to_opts(PathOpts, Creds),
NewModules = lists:keyreplace(mongoose_api_admin, 3, Modules,
{Host, Path, mongoose_api_admin, NewPathOpts}),
Opts#{modules := NewModules}.
Opts#{handlers := NewModules}.

inject_creds_to_opts(PathOpts, any) ->
lists:keydelete(auth, 1, PathOpts);
Expand All @@ -298,9 +298,9 @@ inject_creds_to_opts(PathOpts, Creds) ->
% This is determined based on modules used. If there is any mongoose_api_admin module used,
% it is admin config. If not and there is at least one mongoose_api_client* module used,
% it's clients.
is_roles_config(#{module := ejabberd_cowboy, modules := Modules}, admin) ->
is_roles_config(#{module := ejabberd_cowboy, handlers := Modules}, admin) ->
lists:any(fun({_, _Path, Mod, _Args}) -> Mod == mongoose_api_admin; (_) -> false end, Modules);
is_roles_config(#{module := ejabberd_cowboy, modules := Modules}, client) ->
is_roles_config(#{module := ejabberd_cowboy, handlers := Modules}, client) ->
ModulesTokens = lists:map(fun({_, _Path, Mod, _}) -> string:tokens(atom_to_list(Mod), "_");
(_) -> []
end, Modules),
Expand Down
12 changes: 6 additions & 6 deletions doc/configuration/listen.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ The port number to which the listening socket is bound.
The IP address to which the listening socket is bound.

### `listen.*.proto`
* **Syntax:** string, `"udp"` or `"tcp"`
* **Syntax:** string, only `"tcp"` is accepted
* **Default:** `"tcp"`
* **Example:** `proto = "udp"`
* **Example:** `proto = "tcp"`

The protocol, which is TCP by default. There is no reason to change this for XMPP or HTTP listeners.
The protocol, which is TCP by default. Currently this is the only valid option.

### `listen.*.ip_version`
* **Syntax:** integer, `4` or `6`
Expand Down Expand Up @@ -78,11 +78,11 @@ Hibernation greatly reduces memory consumption of client processes, but *may* re
The default, recommended value of 0 means that the client processes will hibernate at every opportunity.

### `listen.*.max_stanza_size`
* **Syntax:** positive integer
* **Default:** not set, unlimited size
* **Syntax:** positive integer or the string `"infinity"`
* **Default:** `"infinity"`
* **Example:** `max_stanza_size = 10_000`

Maximum allowed incoming stanza size in bytes.
Maximum allowed incoming stanza size in bytes.
!!! Warning
This limit is checked **after** the input data parsing, so it does not apply to the input data size itself.

Expand Down
Loading

0 comments on commit 6d1c24b

Please sign in to comment.