diff options
Diffstat (limited to 'src/ejabberd_options.erl')
-rw-r--r-- | src/ejabberd_options.erl | 757 |
1 files changed, 757 insertions, 0 deletions
diff --git a/src/ejabberd_options.erl b/src/ejabberd_options.erl new file mode 100644 index 000000000..16d3f7ba5 --- /dev/null +++ b/src/ejabberd_options.erl @@ -0,0 +1,757 @@ +%%%---------------------------------------------------------------------- +%%% ejabberd, Copyright (C) 2002-2019 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License along +%%% with this program; if not, write to the Free Software Foundation, Inc., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +%%% +%%%---------------------------------------------------------------------- +-module(ejabberd_options). +-behaviour(ejabberd_config). + +-export([opt_type/1, options/0, globals/0]). + +-ifdef(NEW_SQL_SCHEMA). +-define(USE_NEW_SQL_SCHEMA_DEFAULT, true). +-else. +-define(USE_NEW_SQL_SCHEMA_DEFAULT, false). +-endif. + +-include_lib("kernel/include/inet.hrl"). + +%%%=================================================================== +%%% API +%%%=================================================================== +-spec opt_type(atom()) -> econf:validator(). +opt_type(access_rules) -> + acl:validator(access_rules); +opt_type(acl) -> + acl:validator(acl); +opt_type(acme) -> + econf:options( + #{ca_url => econf:url(), + contact => econf:binary("^[a-zA-Z]+:[^:]+$")}, + [unique, {return, map}]); +opt_type(allow_contrib_modules) -> + econf:bool(); +opt_type(allow_multiple_connections) -> + econf:bool(); +opt_type(anonymous_protocol) -> + econf:enum([sasl_anon, login_anon, both]); +opt_type(api_permissions) -> + ejabberd_access_permissions:validator(); +opt_type(append_host_config) -> + econf:map( + econf:and_then( + econf:domain(), + econf:enum(ejabberd_config:get_option(hosts))), + validator(), + [unique]); +opt_type(auth_cache_life_time) -> + econf:timeout(second, infinity); +opt_type(auth_cache_missed) -> + econf:bool(); +opt_type(auth_cache_size) -> + econf:pos_int(infinity); +opt_type(auth_method) -> + econf:list_or_single(econf:db_type(ejabberd_auth)); +opt_type(auth_password_format) -> + econf:enum([plain, scram]); +opt_type(auth_use_cache) -> + econf:bool(); +opt_type(c2s_cafile) -> + econf:file(); +opt_type(c2s_ciphers) -> + econf:binary(); +opt_type(c2s_dhfile) -> + econf:file(); +opt_type(c2s_protocol_options) -> + econf:and_then( + econf:list(econf:binary(), [unique]), + fun concat_tls_protocol_options/1); +opt_type(c2s_tls_compression) -> + econf:bool(); +opt_type(ca_file) -> + econf:pem(); +opt_type(cache_life_time) -> + econf:timeout(second, infinity); +opt_type(cache_missed) -> + econf:bool(); +opt_type(cache_size) -> + econf:pos_int(infinity); +opt_type(captcha_cmd) -> + econf:file(); +opt_type(captcha_host) -> + econf:binary(); +opt_type(captcha_limit) -> + econf:pos_int(infinity); +opt_type(captcha_url) -> + econf:url(); +opt_type(certfiles) -> + econf:list(econf:binary()); +opt_type(cluster_backend) -> + econf:db_type(ejabberd_cluster); +opt_type(cluster_nodes) -> + econf:list(econf:atom(), [unique]); +opt_type(default_db) -> + econf:enum([mnesia, riak, sql]); +opt_type(default_ram_db) -> + econf:enum([mnesia, riak, sql, redis]); +opt_type(define_macro) -> + econf:any(); +opt_type(disable_sasl_mechanisms) -> + econf:list_or_single( + econf:and_then( + econf:binary(), + fun str:to_upper/1)); +opt_type(domain_balancing) -> + econf:map( + econf:domain(), + econf:options( + #{component_number => econf:int(2, 1000), + type => econf:enum([random, source, destination, + bare_source, bare_destination])}, + [{required, [component_number]}, {return, map}, unique]), + [{return, map}]); +opt_type(ext_api_path_oauth) -> + econf:binary(); +opt_type(ext_api_http_pool_size) -> + econf:pos_int(); +opt_type(ext_api_url) -> + econf:url(); +opt_type(ext_api_headers) -> + econf:binary(); +opt_type(extauth_pool_name) -> + econf:binary(); +opt_type(extauth_pool_size) -> + econf:pos_int(); +opt_type(extauth_program) -> + econf:string(); +opt_type(fqdn) -> + econf:list_or_single(econf:domain()); +opt_type(hide_sensitive_log_data) -> + econf:bool(); +opt_type(host_config) -> + econf:map( + econf:and_then( + econf:domain(), + econf:enum(ejabberd_config:get_option(hosts))), + validator(), + [unique]); +opt_type(hosts) -> + econf:non_empty(econf:list(econf:domain(), [unique])); +opt_type(include_config_file) -> + econf:any(); +opt_type(language) -> + econf:lang(); +opt_type(ldap_backups) -> + econf:list(econf:domain(), [unique]); +opt_type(ldap_base) -> + econf:binary(); +opt_type(ldap_deref_aliases) -> + econf:enum([never, searching, finding, always]); +opt_type(ldap_dn_filter) -> + econf:and_then( + econf:non_empty( + econf:map( + econf:ldap_filter(), + econf:list(econf:binary()))), + fun hd/1); +opt_type(ldap_encrypt) -> + econf:enum([tls, starttls, none]); +opt_type(ldap_filter) -> + econf:ldap_filter(); +opt_type(ldap_password) -> + econf:binary(); +opt_type(ldap_port) -> + econf:port(); +opt_type(ldap_rootdn) -> + econf:binary(); +opt_type(ldap_servers) -> + econf:list(econf:domain(), [unique]); +opt_type(ldap_tls_cacertfile) -> + econf:pem(); +opt_type(ldap_tls_certfile) -> + econf:pem(); +opt_type(ldap_tls_depth) -> + econf:non_neg_int(); +opt_type(ldap_tls_verify) -> + econf:enum([hard, soft, false]); +opt_type(ldap_uids) -> + econf:either( + econf:list( + econf:and_then( + econf:binary(), + fun(U) -> {U, <<"%u">>} end)), + econf:map(econf:binary(), econf:binary(), [unique])); +opt_type(listen) -> + ejabberd_listener:validator(); +opt_type(log_rate_limit) -> + econf:non_neg_int(); +opt_type(log_rotate_count) -> + econf:non_neg_int(); +opt_type(log_rotate_date) -> + econf:string("^(\\$((D(([0-9])|(1[0-9])|(2[0-3])))|" + "(((W[0-6])|(M(([1-2][0-9])|(3[0-1])|([1-9]))))" + "(D(([0-9])|(1[0-9])|(2[0-3])))?)))?$"); +opt_type(log_rotate_size) -> + econf:non_neg_int(); +opt_type(loglevel) -> + econf:int(0, 5); +opt_type(max_fsm_queue) -> + econf:pos_int(); +opt_type(modules) -> + econf:map(econf:atom(), econf:any()); +opt_type(negotiation_timeout) -> + econf:timeout(second); +opt_type(net_ticktime) -> + econf:pos_int(); +opt_type(new_sql_schema) -> + econf:bool(); +opt_type(oauth_access) -> + econf:acl(); +opt_type(oauth_cache_life_time) -> + econf:timeout(second, infinity); +opt_type(oauth_cache_missed) -> + econf:bool(); +opt_type(oauth_cache_size) -> + econf:pos_int(infinity); +opt_type(oauth_db_type) -> + econf:db_type(ejabberd_oauth); +opt_type(oauth_expire) -> + econf:non_neg_int(); +opt_type(oauth_use_cache) -> + econf:bool(); +opt_type(oom_killer) -> + econf:bool(); +opt_type(oom_queue) -> + econf:pos_int(); +opt_type(oom_watermark) -> + econf:int(1, 99); +opt_type(outgoing_s2s_families) -> + econf:and_then( + econf:non_empty( + econf:list(econf:enum([ipv4, ipv6]), [unique])), + fun(L) -> + lists:map( + fun(ipv4) -> inet; + (ipv6) -> inet6 + end, L) + end); +opt_type(outgoing_s2s_port) -> + econf:port(); +opt_type(outgoing_s2s_timeout) -> + econf:timeout(second, infinity); +opt_type(pam_service) -> + econf:binary(); +opt_type(pam_userinfotype) -> + econf:enum([username, jid]); +opt_type(pgsql_users_number_estimate) -> + econf:bool(); +opt_type(queue_dir) -> + econf:directory(write); +opt_type(queue_type) -> + econf:enum([ram, file]); +opt_type(redis_connect_timeout) -> + econf:timeout(second); +opt_type(redis_db) -> + econf:non_neg_int(); +opt_type(redis_password) -> + econf:string(); +opt_type(redis_pool_size) -> + econf:pos_int(); +opt_type(redis_port) -> + econf:port(); +opt_type(redis_queue_type) -> + econf:enum([ram, file]); +opt_type(redis_server) -> + econf:string(); +opt_type(registration_timeout) -> + econf:pos_int(infinity); +opt_type(resource_conflict) -> + econf:enum([setresource, closeold, closenew, acceptnew]); +opt_type(riak_cacertfile) -> + econf:and_then(econf:pem(), econf:string()); +opt_type(riak_password) -> + econf:string(); +opt_type(riak_pool_size) -> + econf:pos_int(); +opt_type(riak_port) -> + econf:port(); +opt_type(riak_server) -> + econf:string(); +opt_type(riak_start_interval) -> + econf:timeout(second); +opt_type(riak_username) -> + econf:string(); +opt_type(router_cache_life_time) -> + econf:timeout(second, infinity); +opt_type(router_cache_missed) -> + econf:bool(); +opt_type(router_cache_size) -> + econf:pos_int(infinity); +opt_type(router_db_type) -> + econf:db_type(ejabberd_router); +opt_type(router_use_cache) -> + econf:bool(); +opt_type(rpc_timeout) -> + econf:timeout(second); +opt_type(s2s_access) -> + econf:acl(); +opt_type(s2s_cafile) -> + econf:pem(); +opt_type(s2s_ciphers) -> + econf:binary(); +opt_type(s2s_dhfile) -> + econf:file(); +opt_type(s2s_dns_retries) -> + econf:non_neg_int(); +opt_type(s2s_dns_timeout) -> + econf:timeout(second, infinity); +opt_type(s2s_max_retry_delay) -> + econf:pos_int(); +opt_type(s2s_protocol_options) -> + econf:and_then( + econf:list(econf:binary(), [unique]), + fun concat_tls_protocol_options/1); +opt_type(s2s_queue_type) -> + econf:enum([ram, file]); +opt_type(s2s_timeout) -> + econf:timeout(second, infinity); +opt_type(s2s_tls_compression) -> + econf:bool(); +opt_type(s2s_use_starttls) -> + econf:either( + econf:bool(), + econf:enum([optional, required])); +opt_type(s2s_zlib) -> + econf:and_then( + econf:bool(), + fun(false) -> false; + (true) -> + ejabberd:start_app(ezlib), + true + end); +opt_type(shaper) -> + ejabberd_shaper:validator(shaper); +opt_type(shaper_rules) -> + ejabberd_shaper:validator(shaper_rules); +opt_type(sm_cache_life_time) -> + econf:timeout(second, infinity); +opt_type(sm_cache_missed) -> + econf:bool(); +opt_type(sm_cache_size) -> + econf:pos_int(infinity); +opt_type(sm_db_type) -> + econf:db_type(ejabberd_sm); +opt_type(sm_use_cache) -> + econf:bool(); +opt_type(sql_connect_timeout) -> + econf:timeout(second); +opt_type(sql_database) -> + econf:binary(); +opt_type(sql_keepalive_interval) -> + econf:timeout(second); +opt_type(sql_password) -> + econf:binary(); +opt_type(sql_pool_size) -> + econf:pos_int(); +opt_type(sql_port) -> + econf:port(); +opt_type(sql_query_timeout) -> + econf:timeout(second); +opt_type(sql_queue_type) -> + econf:enum([ram, file]); +opt_type(sql_server) -> + econf:binary(); +opt_type(sql_ssl) -> + econf:bool(); +opt_type(sql_ssl_cafile) -> + econf:pem(); +opt_type(sql_ssl_certfile) -> + econf:pem(); +opt_type(sql_ssl_verify) -> + econf:bool(); +opt_type(sql_start_interval) -> + econf:timeout(second); +opt_type(sql_type) -> + econf:enum([mysql, pgsql, sqlite, mssql, odbc]); +opt_type(sql_username) -> + econf:binary(); +opt_type(trusted_proxies) -> + econf:either(all, econf:list(econf:ip_mask())); +opt_type(use_cache) -> + econf:bool(); +opt_type(validate_stream) -> + econf:bool(); +opt_type(version) -> + econf:binary(); +opt_type(websocket_origin) -> + econf:list( + econf:and_then( + econf:and_then( + econf:binary_sep("\\s+"), + econf:list(econf:url(), [unique])), + fun(L) -> str:join(L, <<" ">>) end), + [unique]); +opt_type(websocket_ping_interval) -> + econf:timeout(second); +opt_type(websocket_timeout) -> + econf:timeout(second); +opt_type(jwt_key) -> + econf:and_then( + econf:file(), + fun(Path) -> + case file:read_file(Path) of + {ok, Binary} -> Binary; + {error, Reason} -> + econf:fail({read_file, Reason, Path}) + end + end). + +%% We only define the types of options that cannot be derived +%% automatically by tools/opt_type.sh script +-spec options() -> [{s2s_protocol_options, undefined | binary()} | + {c2s_protocol_options, undefined | binary()} | + {websocket_origin, [binary()]} | + {disable_sasl_mechanisms, [binary()]} | + {s2s_zlib, boolean()} | + {listen, [ejabberd_listener:listener()]} | + {modules, [{module(), gen_mod:opts(), integer()}]} | + {ldap_uids, [{binary(), binary()}]} | + {ldap_dn_filter, {binary(), [binary()]}} | + {outgoing_s2s_families, [inet | inet6, ...]} | + {acl, [{atom(), [acl:acl_rule()]}]} | + {access_rules, [{atom(), acl:access()}]} | + {shaper, #{atom() => ejabberd_shaper:shaper_rate()}} | + {shaper_rules, [{atom(), [ejabberd_shaper:shaper_rule()]}]} | + {api_permissions, [ejabberd_access_permissions:permission()]} | + {jwt_key, binary()} | + {append_host_config, [{binary(), any()}]} | + {host_config, [{binary(), any()}]} | + {define_macro, any()} | + {include_config_file, any()} | + {atom(), any()}]. +options() -> + [%% Top-priority options + hosts, + {loglevel, 4}, + {cache_life_time, timer:seconds(3600)}, + {cache_missed, true}, + {cache_size, 1000}, + {use_cache, true}, + {default_db, mnesia}, + {default_ram_db, mnesia}, + {queue_type, ram}, + {version, ejabberd_config:version()}, + %% Other options + {acl, []}, + {access_rules, []}, + {acme, #{}}, + {allow_contrib_modules, true}, + {allow_multiple_connections, false}, + {anonymous_protocol, sasl_anon}, + {api_permissions, + [{<<"admin access">>, + {[], + [{acl, admin}, + {oauth, {[<<"ejabberd:admin">>], [{acl, admin}]}}], + {all, [start, stop]}}}]}, + {append_host_config, []}, + {auth_cache_life_time, + fun(Host) -> ejabberd_config:get_option({cache_life_time, Host}) end}, + {auth_cache_missed, + fun(Host) -> ejabberd_config:get_option({cache_missed, Host}) end}, + {auth_cache_size, + fun(Host) -> ejabberd_config:get_option({cache_size, Host}) end}, + {auth_method, + fun(Host) -> [ejabberd_config:default_db(Host, ejabberd_auth)] end}, + {auth_password_format, plain}, + {auth_use_cache, + fun(Host) -> ejabberd_config:get_option({use_cache, Host}) end}, + {c2s_cafile, undefined}, + {c2s_ciphers, undefined}, + {c2s_dhfile, undefined}, + {c2s_protocol_options, undefined}, + {c2s_tls_compression, undefined}, + {ca_file, iolist_to_binary(pkix:get_cafile())}, + {captcha_cmd, undefined}, + {captcha_host, <<"">>}, + {captcha_limit, infinity}, + {captcha_url, undefined}, + {certfiles, undefined}, + {cluster_backend, mnesia}, + {cluster_nodes, []}, + {define_macro, []}, + {disable_sasl_mechanisms, []}, + {domain_balancing, #{}}, + {ext_api_headers, <<>>}, + {ext_api_http_pool_size, 100}, + {ext_api_path_oauth, <<"/oauth">>}, + {ext_api_url, <<"http://localhost/api">>}, + {extauth_pool_name, undefined}, + {extauth_pool_size, undefined}, + {extauth_program, undefined}, + {fqdn, fun fqdn/1}, + {hide_sensitive_log_data, false}, + {host_config, []}, + {include_config_file, []}, + {language, <<"en">>}, + {ldap_backups, []}, + {ldap_base, <<"">>}, + {ldap_deref_aliases, never}, + {ldap_dn_filter, {undefined, []}}, + {ldap_encrypt, none}, + {ldap_filter, <<"">>}, + {ldap_password, <<"">>}, + {ldap_port, + fun(Host) -> + case ejabberd_config:get_option({ldap_encrypt, Host}) of + tls -> 636; + _ -> 389 + end + end}, + {ldap_rootdn, <<"">>}, + {ldap_servers, [<<"localhost">>]}, + {ldap_tls_cacertfile, undefined}, + {ldap_tls_certfile, undefined}, + {ldap_tls_depth, undefined}, + {ldap_tls_verify, false}, + {ldap_uids, [{<<"uid">>, <<"%u">>}]}, + {listen, []}, + {log_rate_limit, undefined}, + {log_rotate_count, undefined}, + {log_rotate_date, undefined}, + {log_rotate_size, undefined}, + {max_fsm_queue, undefined}, + {modules, []}, + {negotiation_timeout, timer:seconds(30)}, + {net_ticktime, 60}, + {new_sql_schema, ?USE_NEW_SQL_SCHEMA_DEFAULT}, + {oauth_access, none}, + {oauth_cache_life_time, + fun(Host) -> ejabberd_config:get_option({cache_life_time, Host}) end}, + {oauth_cache_missed, + fun(Host) -> ejabberd_config:get_option({cache_missed, Host}) end}, + {oauth_cache_size, + fun(Host) -> ejabberd_config:get_option({cache_size, Host}) end}, + {oauth_db_type, + fun(Host) -> ejabberd_config:default_db(Host, ejabberd_oauth) end}, + {oauth_expire, 4294967}, + {oauth_use_cache, + fun(Host) -> ejabberd_config:get_option({use_cache, Host}) end}, + {oom_killer, true}, + {oom_queue, 10000}, + {oom_watermark, 80}, + {outgoing_s2s_families, [inet, inet6]}, + {outgoing_s2s_port, 5269}, + {outgoing_s2s_timeout, timer:seconds(10)}, + {pam_service, <<"ejabberd">>}, + {pam_userinfotype, username}, + {pgsql_users_number_estimate, false}, + {queue_dir, undefined}, + {redis_connect_timeout, timer:seconds(1)}, + {redis_db, 0}, + {redis_password, ""}, + {redis_pool_size, 10}, + {redis_port, 6379}, + {redis_queue_type, + fun(Host) -> ejabberd_config:get_option({queue_type, Host}) end}, + {redis_server, "localhost"}, + {registration_timeout, 600}, + {resource_conflict, acceptnew}, + {riak_cacertfile, nil}, + {riak_password, nil}, + {riak_pool_size, 10}, + {riak_port, 8087}, + {riak_server, "127.0.0.1"}, + {riak_start_interval, timer:seconds(30)}, + {riak_username, nil}, + {router_cache_life_time, + fun(Host) -> ejabberd_config:get_option({cache_life_time, Host}) end}, + {router_cache_missed, + fun(Host) -> ejabberd_config:get_option({cache_missed, Host}) end}, + {router_cache_size, + fun(Host) -> ejabberd_config:get_option({cache_size, Host}) end}, + {router_db_type, + fun(Host) -> ejabberd_config:default_ram_db(Host, ejabberd_router) end}, + {router_use_cache, + fun(Host) -> ejabberd_config:get_option({use_cache, Host}) end}, + {rpc_timeout, timer:seconds(5)}, + {s2s_access, all}, + {s2s_cafile, undefined}, + {s2s_ciphers, undefined}, + {s2s_dhfile, undefined}, + {s2s_dns_retries, 2}, + {s2s_dns_timeout, timer:seconds(10)}, + {s2s_max_retry_delay, 300}, + {s2s_protocol_options, undefined}, + {s2s_queue_type, + fun(Host) -> ejabberd_config:get_option({queue_type, Host}) end}, + {s2s_timeout, timer:minutes(10)}, + {s2s_tls_compression, undefined}, + {s2s_use_starttls, false}, + {s2s_zlib, false}, + {shaper, #{}}, + {shaper_rules, []}, + {sm_cache_life_time, + fun(Host) -> ejabberd_config:get_option({cache_life_time, Host}) end}, + {sm_cache_missed, + fun(Host) -> ejabberd_config:get_option({cache_missed, Host}) end}, + {sm_cache_size, + fun(Host) -> ejabberd_config:get_option({cache_size, Host}) end}, + {sm_db_type, + fun(Host) -> ejabberd_config:default_ram_db(Host, ejabberd_sm) end}, + {sm_use_cache, + fun(Host) -> ejabberd_config:get_option({use_cache, Host}) end}, + {sql_type, undefined}, + {sql_connect_timeout, timer:seconds(5)}, + {sql_database, undefined}, + {sql_keepalive_interval, undefined}, + {sql_password, <<"">>}, + {sql_pool_size, + fun(Host) -> + case ejabberd_config:get_option({sql_type, Host}) of + sqlite -> 1; + _ -> 10 + end + end}, + {sql_port, + fun(Host) -> + case ejabberd_config:get_option({sql_type, Host}) of + mssql -> 1433; + mysql -> 3306; + pgsql -> 5432; + _ -> undefined + end + end}, + {sql_query_timeout, timer:seconds(60)}, + {sql_queue_type, + fun(Host) -> ejabberd_config:get_option({queue_type, Host}) end}, + {sql_server, <<"localhost">>}, + {sql_ssl, false}, + {sql_ssl_cafile, undefined}, + {sql_ssl_certfile, undefined}, + {sql_ssl_verify, false}, + {sql_start_interval, timer:seconds(30)}, + {sql_username, <<"ejabberd">>}, + {trusted_proxies, []}, + {validate_stream, false}, + {websocket_origin, []}, + {websocket_ping_interval, timer:seconds(60)}, + {websocket_timeout, timer:minutes(5)}, + {jwt_key, <<"">>}]. + +-spec globals() -> [atom()]. +globals() -> + [acme, + allow_contrib_modules, + api_permissions, + append_host_config, + auth_cache_life_time, + auth_cache_missed, + auth_cache_size, + ca_file, + captcha_cmd, + captcha_host, + captcha_limit, + captcha_url, + certfiles, + cluster_backend, + cluster_nodes, + domain_balancing, + ext_api_path_oauth, + fqdn, + hosts, + host_config, + listen, + loglevel, + log_rate_limit, + log_rotate_count, + log_rotate_date, + log_rotate_size, + negotiation_timeout, + net_ticktime, + new_sql_schema, + node_start, + oauth_cache_life_time, + oauth_cache_missed, + oauth_cache_size, + oauth_db_type, + oauth_expire, + oauth_use_cache, + oom_killer, + oom_queue, + oom_watermark, + queue_dir, + redis_connect_timeout, + redis_db, + redis_password, + redis_pool_size, + redis_port, + redis_queue_type, + redis_server, + registration_timeout, + riak_cacertfile, + riak_password, + riak_pool_size, + riak_port, + riak_server, + riak_start_interval, + riak_username, + router_cache_life_time, + router_cache_missed, + router_cache_size, + router_db_type, + router_use_cache, + rpc_timeout, + s2s_max_retry_delay, + shaper, + sm_cache_life_time, + sm_cache_missed, + sm_cache_size, + validate_stream, + version, + websocket_origin, + websocket_ping_interval, + websocket_timeout]. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== +-spec validator() -> econf:validator(). +validator() -> + Disallowed = ejabberd_config:globals(), + {Validators, Required} = ejabberd_config:validators(Disallowed), + econf:options( + Validators, + [{disallowed, Required ++ Disallowed}, unique]). + +-spec fqdn(global | binary()) -> [binary()]. +fqdn(global) -> + {ok, Hostname} = inet:gethostname(), + case inet:gethostbyname(Hostname) of + {ok, #hostent{h_name = FQDN}} -> + case jid:nameprep(iolist_to_binary(FQDN)) of + error -> []; + Domain -> [Domain] + end; + {error, _} -> + [] + end; +fqdn(_) -> + ejabberd_config:get_option(fqdn). + +-spec concat_tls_protocol_options([binary()]) -> binary(). +concat_tls_protocol_options(Opts) -> + str:join(Opts, <<"|">>). |