25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-26 17:38:45 +01:00

Introduce 'hosts' option

The option can be used as a replacement of 'host' option
when several (sub)domains are needed to be registered for the module.
Note that you cannot combine both 'host' and 'hosts' in the config
because 'host' option is of a higher priority. Example:

mod_pubsub:
   ...
   hosts:
     - "pubsub1.@HOST@"
     - "pubsub2.@HOST@"

Fixes #1883
This commit is contained in:
Evgeniy Khramtsov 2017-08-08 17:46:26 +03:00
parent 52525eb76d
commit 3fec782494
12 changed files with 380 additions and 280 deletions

View File

@ -34,7 +34,8 @@
stop_child/1, stop_child/2, config_reloaded/0]). stop_child/1, stop_child/2, config_reloaded/0]).
-export([start_module/2, start_module/3, -export([start_module/2, start_module/3,
stop_module/2, stop_module_keep_config/2, stop_module/2, stop_module_keep_config/2,
get_opt/2, get_opt/3, get_opt_host/3, opt_type/1, is_equal_opt/4, get_opt/2, get_opt/3, get_opt_host/3,
get_opt_hosts/3, opt_type/1, is_equal_opt/4,
get_module_opt/3, get_module_opt/4, get_module_opt_host/3, get_module_opt/3, get_module_opt/4, get_module_opt_host/3,
loaded_modules/1, loaded_modules_with_opts/1, loaded_modules/1, loaded_modules_with_opts/1,
get_hosts/2, get_module_proc/2, is_loaded/2, is_loaded_elsewhere/2, get_hosts/2, get_module_proc/2, is_loaded/2, is_loaded_elsewhere/2,
@ -441,6 +442,20 @@ get_opt_host(Host, Opts, Default) ->
Val = get_opt(host, Opts, Default), Val = get_opt(host, Opts, Default),
ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host). ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host).
-spec get_opt_hosts(binary(), opts(), binary()) -> [binary()].
get_opt_hosts(Host, Opts, Default) ->
Vals = case get_opt(host, Opts, undefined) of
undefined ->
case get_opt(hosts, Opts, []) of
[] -> [Default];
L -> L
end;
Val ->
[Val]
end,
[ejabberd_regexp:greplace(V, <<"@HOST@">>, Host) || V <- Vals].
-spec get_validators(binary(), module(), opts()) -> dict:dict() | undef. -spec get_validators(binary(), module(), opts()) -> dict:dict() | undef.
get_validators(Host, Module, Opts) -> get_validators(Host, Module, Opts) ->
try Module:mod_opt_type('') of try Module:mod_opt_type('') of

View File

@ -43,7 +43,7 @@
-include("xmpp.hrl"). -include("xmpp.hrl").
-record(state, {host = <<"">> :: binary()}). -record(state, {hosts = [] :: [binary()]}).
%%==================================================================== %%====================================================================
%% gen_mod API %% gen_mod API
@ -62,7 +62,9 @@ depends(_Host, _Opts) ->
[]. [].
mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(host) -> fun iolist_to_binary/1;
mod_opt_type(_) -> [host]. mod_opt_type(hosts) ->
fun(L) -> lists:map(fun iolist_to_binary/1, L) end;
mod_opt_type(_) -> [host, hosts].
%%==================================================================== %%====================================================================
%% gen_server callbacks %% gen_server callbacks
@ -77,10 +79,13 @@ mod_opt_type(_) -> [host].
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
init([Host, Opts]) -> init([Host, Opts]) ->
process_flag(trap_exit, true), process_flag(trap_exit, true),
MyHost = gen_mod:get_opt_host(Host, Opts, Hosts = gen_mod:get_opt_hosts(Host, Opts,
<<"echo.@HOST@">>), <<"echo.@HOST@">>),
ejabberd_router:register_route(MyHost, Host), lists:foreach(
{ok, #state{host = MyHost}}. fun(H) ->
ejabberd_router:register_route(H, Host)
end, Hosts),
{ok, #state{hosts = Hosts}}.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
@ -101,17 +106,19 @@ handle_call(stop, _From, State) ->
%% Description: Handling cast messages %% Description: Handling cast messages
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
handle_cast({reload, Host, NewOpts, OldOpts}, State) -> handle_cast({reload, Host, NewOpts, OldOpts}, State) ->
NewMyHost = gen_mod:get_opt_host(Host, NewOpts, NewMyHosts = gen_mod:get_opt_hosts(Host, NewOpts,
<<"echo.@HOST@">>), <<"echo.@HOST@">>),
OldMyHost = gen_mod:get_opt_host(Host, OldOpts, OldMyHosts = gen_mod:get_opt_hosts(Host, OldOpts,
<<"echo.@HOST@">>), <<"echo.@HOST@">>),
if NewMyHost /= OldMyHost -> lists:foreach(
ejabberd_router:register_route(NewMyHost, Host), fun(H) ->
ejabberd_router:unregister_route(OldMyHost); ejabberd_router:unregister_route(H)
true -> end, OldMyHosts -- NewMyHosts),
ok lists:foreach(
end, fun(H) ->
{noreply, State#state{host = NewMyHost}}; ejabberd_router:register_route(H, Host)
end, NewMyHosts -- OldMyHosts),
{noreply, State#state{hosts = NewMyHosts}};
handle_cast(Msg, State) -> handle_cast(Msg, State) ->
?WARNING_MSG("unexpected cast: ~p", [Msg]), ?WARNING_MSG("unexpected cast: ~p", [Msg]),
{noreply, State}. {noreply, State}.
@ -147,7 +154,7 @@ handle_info(_Info, State) -> {noreply, State}.
%% The return value is ignored. %% The return value is ignored.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
terminate(_Reason, State) -> terminate(_Reason, State) ->
ejabberd_router:unregister_route(State#state.host), ok. lists:foreach(fun ejabberd_router:unregister_route/1, State#state.hosts).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}

View File

@ -94,7 +94,7 @@
-record(state, -record(state,
{server_host :: binary(), {server_host :: binary(),
host :: binary(), hosts :: [binary()],
name :: binary(), name :: binary(),
access :: atom(), access :: atom(),
max_size :: pos_integer() | infinity, max_size :: pos_integer() | infinity,
@ -151,6 +151,8 @@ stop(ServerHost) ->
mod_opt_type(host) -> mod_opt_type(host) ->
fun iolist_to_binary/1; fun iolist_to_binary/1;
mod_opt_type(hosts) ->
fun (L) -> lists:map(fun iolist_to_binary/1, L) end;
mod_opt_type(name) -> mod_opt_type(name) ->
fun iolist_to_binary/1; fun iolist_to_binary/1;
mod_opt_type(access) -> mod_opt_type(access) ->
@ -194,7 +196,7 @@ mod_opt_type(rm_on_unregister) ->
mod_opt_type(thumbnail) -> mod_opt_type(thumbnail) ->
fun(B) when is_boolean(B) -> B end; fun(B) when is_boolean(B) -> B end;
mod_opt_type(_) -> mod_opt_type(_) ->
[host, name, access, max_size, secret_length, jid_in_url, file_mode, [host, hosts, name, access, max_size, secret_length, jid_in_url, file_mode,
dir_mode, docroot, put_url, get_url, service_url, custom_headers, dir_mode, docroot, put_url, get_url, service_url, custom_headers,
rm_on_unregister, thumbnail]. rm_on_unregister, thumbnail].
@ -211,7 +213,7 @@ depends(_Host, _Opts) ->
init([ServerHost, Opts]) -> init([ServerHost, Opts]) ->
process_flag(trap_exit, true), process_flag(trap_exit, true),
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"upload.@HOST@">>), Hosts = gen_mod:get_opt_hosts(ServerHost, Opts, <<"upload.@HOST@">>),
Name = gen_mod:get_opt(name, Opts, <<"HTTP File Upload">>), Name = gen_mod:get_opt(name, Opts, <<"HTTP File Upload">>),
Access = gen_mod:get_opt(access, Opts, local), Access = gen_mod:get_opt(access, Opts, local),
MaxSize = gen_mod:get_opt(max_size, Opts, 104857600), MaxSize = gen_mod:get_opt(max_size, Opts, 104857600),
@ -244,8 +246,11 @@ init([ServerHost, Opts]) ->
false -> false ->
ok ok
end, end,
ejabberd_router:register_route(Host, ServerHost), lists:foreach(
{ok, #state{server_host = ServerHost, host = Host, name = Name, fun(Host) ->
ejabberd_router:register_route(Host, ServerHost)
end, Hosts),
{ok, #state{server_host = ServerHost, hosts = Hosts, name = Name,
access = Access, max_size = MaxSize, access = Access, max_size = MaxSize,
secret_length = SecretLength, jid_in_url = JIDinURL, secret_length = SecretLength, jid_in_url = JIDinURL,
file_mode = FileMode, dir_mode = DirMode, file_mode = FileMode, dir_mode = DirMode,
@ -324,10 +329,9 @@ handle_info(Info, State) ->
-spec terminate(normal | shutdown | {shutdown, _} | _, state()) -> ok. -spec terminate(normal | shutdown | {shutdown, _} | _, state()) -> ok.
terminate(Reason, #state{server_host = ServerHost, host = Host}) -> terminate(Reason, #state{server_host = ServerHost, hosts = Hosts}) ->
?DEBUG("Stopping HTTP upload process for ~s: ~p", [ServerHost, Reason]), ?DEBUG("Stopping HTTP upload process for ~s: ~p", [ServerHost, Reason]),
ejabberd_router:unregister_route(Host), lists:foreach(fun ejabberd_router:unregister_route/1, Hosts).
ok.
-spec code_change({down, _} | _, state(), _) -> {ok, state()}. -spec code_change({down, _} | _, state(), _) -> {ok, state()}.

View File

@ -58,7 +58,7 @@
[<<"koi8-r">>, <<"iso8859-15">>, <<"iso8859-1">>, <<"iso8859-2">>, [<<"koi8-r">>, <<"iso8859-15">>, <<"iso8859-1">>, <<"iso8859-2">>,
<<"utf-8">>, <<"utf-8+latin-1">>]). <<"utf-8">>, <<"utf-8+latin-1">>]).
-record(state, {host = <<"">> :: binary(), -record(state, {hosts = [] :: [binary()],
server_host = <<"">> :: binary(), server_host = <<"">> :: binary(),
access = all :: atom()}). access = all :: atom()}).
@ -99,8 +99,7 @@ depends(_Host, _Opts) ->
init([Host, Opts]) -> init([Host, Opts]) ->
process_flag(trap_exit, true), process_flag(trap_exit, true),
ejabberd:start_app(iconv), ejabberd:start_app(iconv),
MyHost = gen_mod:get_opt_host(Host, Opts, MyHosts = gen_mod:get_opt_hosts(Host, Opts, <<"irc.@HOST@">>),
<<"irc.@HOST@">>),
Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
Mod:init(Host, Opts), Mod:init(Host, Opts),
Access = gen_mod:get_opt(access, Opts, all), Access = gen_mod:get_opt(access, Opts, all),
@ -108,10 +107,13 @@ init([Host, Opts]) ->
[named_table, public, [named_table, public,
{keypos, #irc_connection.jid_server_host}]), {keypos, #irc_connection.jid_server_host}]),
IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)),
register_hooks(MyHost, IQDisc), lists:foreach(
ejabberd_router:register_route(MyHost, Host), fun(MyHost) ->
register_hooks(MyHost, IQDisc),
ejabberd_router:register_route(MyHost, Host)
end, MyHosts),
{ok, {ok,
#state{host = MyHost, server_host = Host, #state{hosts = MyHosts, server_host = Host,
access = Access}}. access = Access}}.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
@ -133,8 +135,8 @@ handle_call(stop, _From, State) ->
%% Description: Handling cast messages %% Description: Handling cast messages
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) -> handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) ->
NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"irc.@HOST@">>), NewHosts = gen_mod:get_opt_hosts(ServerHost, NewOpts, <<"irc.@HOST@">>),
OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"irc.@HOST@">>), OldHosts = gen_mod:get_opt_hosts(ServerHost, OldOpts, <<"irc.@HOST@">>),
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, gen_iq_handler:iqdisc(ServerHost)), NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, gen_iq_handler:iqdisc(ServerHost)),
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, gen_iq_handler:iqdisc(ServerHost)), OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, gen_iq_handler:iqdisc(ServerHost)),
NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE), NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE),
@ -145,20 +147,26 @@ handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) ->
true -> true ->
ok ok
end, end,
if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) -> if (NewIQDisc /= OldIQDisc) ->
register_hooks(NewHost, NewIQDisc); lists:foreach(
true -> fun(NewHost) ->
ok register_hooks(NewHost, NewIQDisc)
end, end, NewHosts -- (NewHosts -- OldHosts));
if NewHost /= OldHost ->
ejabberd_router:register_route(NewHost, ServerHost),
ejabberd_router:unregister_route(OldHost),
unregister_hooks(OldHost);
true -> true ->
ok ok
end, end,
lists:foreach(
fun(NewHost) ->
ejabberd_router:register_route(NewHost, ServerHost),
register_hooks(NewHost, NewIQDisc)
end, NewHosts -- OldHosts),
lists:foreach(
fun(OldHost) ->
ejabberd_router:unregister_route(OldHost),
unregister_hooks(OldHost)
end, OldHosts -- NewHosts),
Access = gen_mod:get_opt(access, NewOpts, all), Access = gen_mod:get_opt(access, NewOpts, all),
{noreply, State#state{host = NewHost, access = Access}}; {noreply, State#state{hosts = NewHosts, access = Access}};
handle_cast(Msg, State) -> handle_cast(Msg, State) ->
?WARNING_MSG("unexpected cast: ~p", [Msg]), ?WARNING_MSG("unexpected cast: ~p", [Msg]),
{noreply, State}. {noreply, State}.
@ -170,9 +178,10 @@ handle_cast(Msg, State) ->
%% Description: Handling all non call/cast messages %% Description: Handling all non call/cast messages
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
handle_info({route, Packet}, handle_info({route, Packet},
#state{host = Host, server_host = ServerHost, #state{server_host = ServerHost, access = Access} =
access = Access} =
State) -> State) ->
To = xmpp:get_to(Packet),
Host = To#jid.lserver,
case catch do_route(Host, ServerHost, Access, Packet) of case catch do_route(Host, ServerHost, Access, Packet) of
{'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
_ -> ok _ -> ok
@ -187,9 +196,12 @@ handle_info(_Info, State) -> {noreply, State}.
%% cleaning up. When it returns, the gen_server terminates with Reason. %% cleaning up. When it returns, the gen_server terminates with Reason.
%% The return value is ignored. %% The return value is ignored.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
terminate(_Reason, #state{host = MyHost}) -> terminate(_Reason, #state{hosts = MyHosts}) ->
ejabberd_router:unregister_route(MyHost), lists:foreach(
unregister_hooks(MyHost). fun(MyHost) ->
ejabberd_router:unregister_route(MyHost),
unregister_hooks(MyHost)
end, MyHosts).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
@ -975,8 +987,10 @@ mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
mod_opt_type(default_encoding) -> mod_opt_type(default_encoding) ->
fun iolist_to_binary/1; fun iolist_to_binary/1;
mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(host) -> fun iolist_to_binary/1;
mod_opt_type(hosts) ->
fun (L) -> lists:map(fun iolist_to_binary/1, L) end;
mod_opt_type(_) -> mod_opt_type(_) ->
[access, db_type, default_encoding, host]. [access, db_type, default_encoding, host, hosts].
-spec extract_ident(stanza()) -> binary(). -spec extract_ident(stanza()) -> binary().
extract_ident(Packet) -> extract_ident(Packet) ->

View File

@ -46,7 +46,7 @@
?NS_MIX_NODES_CONFIG]). ?NS_MIX_NODES_CONFIG]).
-record(state, {server_host :: binary(), -record(state, {server_host :: binary(),
host :: binary()}). hosts :: [binary()]}).
%%%=================================================================== %%%===================================================================
%%% API %%% API
@ -124,36 +124,39 @@ process_iq(#iq{lang = Lang} = IQ) ->
%%%=================================================================== %%%===================================================================
init([ServerHost, Opts]) -> init([ServerHost, Opts]) ->
process_flag(trap_exit, true), process_flag(trap_exit, true),
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"mix.@HOST@">>), Hosts = gen_mod:get_opt_hosts(ServerHost, Opts, <<"mix.@HOST@">>),
IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(ServerHost)),
ConfigTab = gen_mod:get_module_proc(Host, config), lists:foreach(
ets:new(ConfigTab, [named_table]), fun(Host) ->
ets:insert(ConfigTab, {plugins, [<<"mix">>]}), ConfigTab = gen_mod:get_module_proc(Host, config),
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, disco_items, 100), ets:new(ConfigTab, [named_table]),
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 100), ets:insert(ConfigTab, {plugins, [<<"mix">>]}),
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 100), ejabberd_hooks:add(disco_local_items, Host, ?MODULE, disco_items, 100),
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, disco_items, 100), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 100),
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, disco_features, 100), ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 100),
ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, disco_identity, 100), ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, disco_items, 100),
ejabberd_hooks:add(disco_info, Host, ?MODULE, disco_info, 100), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, disco_features, 100),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, disco_identity, 100),
?NS_DISCO_ITEMS, mod_disco, ejabberd_hooks:add(disco_info, Host, ?MODULE, disco_info, 100),
process_local_iq_items, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_local, Host,
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS, mod_disco,
?NS_DISCO_INFO, mod_disco, process_local_iq_items, IQDisc),
process_local_iq_info, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_local, Host,
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO, mod_disco,
?NS_DISCO_ITEMS, mod_disco, process_local_iq_info, IQDisc),
process_local_iq_items, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS, mod_disco,
?NS_DISCO_INFO, mod_disco, process_local_iq_items, IQDisc),
process_local_iq_info, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO, mod_disco,
?NS_PUBSUB, mod_pubsub, iq_sm, IQDisc), process_local_iq_info, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
?NS_MIX_0, ?MODULE, process_iq, IQDisc), ?NS_PUBSUB, mod_pubsub, iq_sm, IQDisc),
ejabberd_router:register_route(Host, ServerHost), gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
{ok, #state{server_host = ServerHost, host = Host}}. ?NS_MIX_0, ?MODULE, process_iq, IQDisc),
ejabberd_router:register_route(Host, ServerHost)
end, Hosts),
{ok, #state{server_host = ServerHost, hosts = Hosts}}.
handle_call(_Request, _From, State) -> handle_call(_Request, _From, State) ->
Reply = ok, Reply = ok,
@ -180,22 +183,24 @@ handle_info({route, Packet}, State) ->
handle_info(_Info, State) -> handle_info(_Info, State) ->
{noreply, State}. {noreply, State}.
terminate(_Reason, #state{host = Host}) -> terminate(_Reason, #state{hosts = Hosts}) ->
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 100), lists:foreach(
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 100), fun(Host) ->
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 100), ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 100),
ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, disco_items, 100), ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 100),
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, disco_features, 100), ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 100),
ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, disco_identity, 100), ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, disco_items, 100),
ejabberd_hooks:delete(disco_info, Host, ?MODULE, disco_info, 100), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, disco_features, 100),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS), ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, disco_identity, 100),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO), ejabberd_hooks:delete(disco_info, Host, ?MODULE, disco_info, 100),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PUBSUB), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_MIX_0), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO),
ejabberd_router:unregister_route(Host), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PUBSUB),
ok. gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_MIX_0),
ejabberd_router:unregister_route(Host)
end, Hosts).
code_change(_OldVsn, State, _Extra) -> code_change(_OldVsn, State, _Extra) ->
{ok, State}. {ok, State}.
@ -316,4 +321,6 @@ depends(_Host, _Opts) ->
mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(host) -> fun iolist_to_binary/1;
mod_opt_type(_) -> [host, iqdisc]. mod_opt_type(hosts) ->
fun (L) -> lists:map(fun iolist_to_binary/1, L) end;
mod_opt_type(_) -> [host, hosts, iqdisc].

View File

@ -75,7 +75,7 @@
-include("mod_muc.hrl"). -include("mod_muc.hrl").
-record(state, -record(state,
{host = <<"">> :: binary(), {hosts = [] :: [binary()],
server_host = <<"">> :: binary(), server_host = <<"">> :: binary(),
access = {none, none, none, none} :: {atom(), atom(), atom(), atom()}, access = {none, none, none, none} :: {atom(), atom(), atom(), atom()},
history_size = 20 :: non_neg_integer(), history_size = 20 :: non_neg_integer(),
@ -151,8 +151,9 @@ room_destroyed(Host, Room, Pid, ServerHost) ->
%% If Opts = default, the default room options are used. %% If Opts = default, the default room options are used.
%% Else use the passed options as defined in mod_muc_room. %% Else use the passed options as defined in mod_muc_room.
create_room(Host, Name, From, Nick, Opts) -> create_room(Host, Name, From, Nick, Opts) ->
Proc = gen_mod:get_module_proc(Host, ?MODULE), ServerHost = ejabberd_router:host_of_route(Host),
gen_server:call(Proc, {create, Name, From, Nick, Opts}). Proc = gen_mod:get_module_proc(ServerHost, ?MODULE),
gen_server:call(Proc, {create, Name, Host, From, Nick, Opts}).
store_room(ServerHost, Host, Name, Opts) -> store_room(ServerHost, Host, Name, Opts) ->
LServer = jid:nameprep(ServerHost), LServer = jid:nameprep(ServerHost),
@ -225,22 +226,26 @@ get_online_rooms_by_user(ServerHost, LUser, LServer) ->
init([Host, Opts]) -> init([Host, Opts]) ->
process_flag(trap_exit, true), process_flag(trap_exit, true),
IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)),
#state{access = Access, host = MyHost, #state{access = Access, hosts = MyHosts,
history_size = HistorySize, queue_type = QueueType, history_size = HistorySize, queue_type = QueueType,
room_shaper = RoomShaper} = State = init_state(Host, Opts), room_shaper = RoomShaper} = State = init_state(Host, Opts),
Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
RMod = gen_mod:ram_db_mod(Host, Opts, ?MODULE), RMod = gen_mod:ram_db_mod(Host, Opts, ?MODULE),
Mod:init(Host, [{host, MyHost}|Opts]), Mod:init(Host, [{hosts, MyHosts}|Opts]),
RMod:init(Host, [{host, MyHost}|Opts]), RMod:init(Host, [{hosts, MyHosts}|Opts]),
register_iq_handlers(MyHost, IQDisc), lists:foreach(
ejabberd_router:register_route(MyHost, Host), fun(MyHost) ->
load_permanent_rooms(MyHost, Host, Access, HistorySize, RoomShaper, QueueType), register_iq_handlers(MyHost, IQDisc),
ejabberd_router:register_route(MyHost, Host),
load_permanent_rooms(MyHost, Host, Access, HistorySize,
RoomShaper, QueueType)
end, MyHosts),
{ok, State}. {ok, State}.
handle_call(stop, _From, State) -> handle_call(stop, _From, State) ->
{stop, normal, ok, State}; {stop, normal, ok, State};
handle_call({create, Room, From, Nick, Opts}, _From, handle_call({create, Room, Host, From, Nick, Opts}, _From,
#state{host = Host, server_host = ServerHost, #state{server_host = ServerHost,
access = Access, default_room_opts = DefOpts, access = Access, default_room_opts = DefOpts,
history_size = HistorySize, queue_type = QueueType, history_size = HistorySize, queue_type = QueueType,
room_shaper = RoomShaper} = State) -> room_shaper = RoomShaper} = State) ->
@ -259,49 +264,56 @@ handle_call({create, Room, From, Nick, Opts}, _From,
ejabberd_hooks:run(create_room, ServerHost, [ServerHost, Room, Host]), ejabberd_hooks:run(create_room, ServerHost, [ServerHost, Room, Host]),
{reply, ok, State}. {reply, ok, State}.
handle_cast({reload, ServerHost, NewOpts, OldOpts}, #state{host = OldHost}) -> handle_cast({reload, ServerHost, NewOpts, OldOpts}, #state{hosts = OldHosts}) ->
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, gen_iq_handler:iqdisc(ServerHost)), NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, gen_iq_handler:iqdisc(ServerHost)),
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, gen_iq_handler:iqdisc(ServerHost)), OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, gen_iq_handler:iqdisc(ServerHost)),
NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE), NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE),
NewRMod = gen_mod:ram_db_mod(ServerHost, NewOpts, ?MODULE), NewRMod = gen_mod:ram_db_mod(ServerHost, NewOpts, ?MODULE),
OldMod = gen_mod:db_mod(ServerHost, OldOpts, ?MODULE), OldMod = gen_mod:db_mod(ServerHost, OldOpts, ?MODULE),
OldRMod = gen_mod:ram_db_mod(ServerHost, OldOpts, ?MODULE), OldRMod = gen_mod:ram_db_mod(ServerHost, OldOpts, ?MODULE),
#state{host = NewHost} = NewState = init_state(ServerHost, NewOpts), #state{hosts = NewHosts} = NewState = init_state(ServerHost, NewOpts),
if NewMod /= OldMod -> if NewMod /= OldMod ->
NewMod:init(ServerHost, [{host, NewHost}|NewOpts]); NewMod:init(ServerHost, [{hosts, NewHosts}|NewOpts]);
true -> true ->
ok ok
end, end,
if NewRMod /= OldRMod -> if NewRMod /= OldRMod ->
NewRMod:init(ServerHost, [{host, NewHost}|NewOpts]); NewRMod:init(ServerHost, [{hosts, NewHosts}|NewOpts]);
true -> true ->
ok ok
end, end,
if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) -> if (NewIQDisc /= OldIQDisc) ->
register_iq_handlers(NewHost, NewIQDisc); lists:foreach(
true -> fun(NewHost) ->
ok register_iq_handlers(NewHost, NewIQDisc)
end, end, NewHosts -- (NewHosts -- OldHosts));
if NewHost /= OldHost ->
ejabberd_router:register_route(NewHost, ServerHost),
ejabberd_router:unregister_route(OldHost),
unregister_iq_handlers(OldHost);
true -> true ->
ok ok
end, end,
lists:foreach(
fun(NewHost) ->
ejabberd_router:register_route(NewHost, ServerHost),
register_iq_handlers(NewHost, NewIQDisc)
end, NewHosts -- OldHosts),
lists:foreach(
fun(OldHost) ->
ejabberd_router:unregister_route(OldHost),
unregister_iq_handlers(OldHost)
end, OldHosts -- NewHosts),
{noreply, NewState}; {noreply, NewState};
handle_cast(Msg, State) -> handle_cast(Msg, State) ->
?WARNING_MSG("unexpected cast: ~p", [Msg]), ?WARNING_MSG("unexpected cast: ~p", [Msg]),
{noreply, State}. {noreply, State}.
handle_info({route, Packet}, handle_info({route, Packet},
#state{host = Host, server_host = ServerHost, #state{server_host = ServerHost,
access = Access, default_room_opts = DefRoomOpts, access = Access, default_room_opts = DefRoomOpts,
history_size = HistorySize, queue_type = QueueType, history_size = HistorySize, queue_type = QueueType,
max_rooms_discoitems = MaxRoomsDiscoItems, max_rooms_discoitems = MaxRoomsDiscoItems,
room_shaper = RoomShaper} = State) -> room_shaper = RoomShaper} = State) ->
From = xmpp:get_from(Packet), From = xmpp:get_from(Packet),
To = xmpp:get_to(Packet), To = xmpp:get_to(Packet),
Host = To#jid.lserver,
case catch do_route(Host, ServerHost, Access, HistorySize, RoomShaper, case catch do_route(Host, ServerHost, Access, HistorySize, RoomShaper,
From, To, Packet, DefRoomOpts, MaxRoomsDiscoItems, From, To, Packet, DefRoomOpts, MaxRoomsDiscoItems,
QueueType) of QueueType) of
@ -320,9 +332,12 @@ handle_info(Info, State) ->
?ERROR_MSG("unexpected info: ~p", [Info]), ?ERROR_MSG("unexpected info: ~p", [Info]),
{noreply, State}. {noreply, State}.
terminate(_Reason, #state{host = MyHost}) -> terminate(_Reason, #state{hosts = MyHosts}) ->
ejabberd_router:unregister_route(MyHost), lists:foreach(
unregister_iq_handlers(MyHost). fun(MyHost) ->
ejabberd_router:unregister_route(MyHost),
unregister_iq_handlers(MyHost)
end, MyHosts).
code_change(_OldVsn, State, _Extra) -> {ok, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}.
@ -330,8 +345,8 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
%%% Internal functions %%% Internal functions
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
init_state(Host, Opts) -> init_state(Host, Opts) ->
MyHost = gen_mod:get_opt_host(Host, Opts, MyHosts = gen_mod:get_opt_hosts(Host, Opts,
<<"conference.@HOST@">>), <<"conference.@HOST@">>),
Access = gen_mod:get_opt(access, Opts, all), Access = gen_mod:get_opt(access, Opts, all),
AccessCreate = gen_mod:get_opt(access_create, Opts, all), AccessCreate = gen_mod:get_opt(access_create, Opts, all),
AccessAdmin = gen_mod:get_opt(access_admin, Opts, none), AccessAdmin = gen_mod:get_opt(access_admin, Opts, none),
@ -342,7 +357,7 @@ init_state(Host, Opts) ->
QueueType = gen_mod:get_opt(queue_type, Opts, QueueType = gen_mod:get_opt(queue_type, Opts,
ejabberd_config:default_queue_type(Host)), ejabberd_config:default_queue_type(Host)),
RoomShaper = gen_mod:get_opt(room_shaper, Opts, none), RoomShaper = gen_mod:get_opt(room_shaper, Opts, none),
#state{host = MyHost, #state{hosts = MyHosts,
server_host = Host, server_host = Host,
access = {Access, AccessCreate, AccessAdmin, AccessPersistent}, access = {Access, AccessCreate, AccessAdmin, AccessPersistent},
default_room_opts = DefRoomOpts, default_room_opts = DefRoomOpts,
@ -851,6 +866,8 @@ mod_opt_type(ram_db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
mod_opt_type(history_size) -> mod_opt_type(history_size) ->
fun (I) when is_integer(I), I >= 0 -> I end; fun (I) when is_integer(I), I >= 0 -> I end;
mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(host) -> fun iolist_to_binary/1;
mod_opt_type(hosts) ->
fun (L) -> lists:map(fun iolist_to_binary/1, L) end;
mod_opt_type(max_room_desc) -> mod_opt_type(max_room_desc) ->
fun (infinity) -> infinity; fun (infinity) -> infinity;
(I) when is_integer(I), I > 0 -> I (I) when is_integer(I), I > 0 -> I
@ -944,7 +961,7 @@ mod_opt_type({default_room_options, presence_broadcast}) ->
end; end;
mod_opt_type(_) -> mod_opt_type(_) ->
[access, access_admin, access_create, access_persistent, [access, access_admin, access_create, access_persistent,
db_type, ram_db_type, history_size, host, db_type, ram_db_type, history_size, host, hosts,
max_room_desc, max_room_id, max_room_name, max_room_desc, max_room_id, max_room_name,
max_rooms_discoitems, max_user_conferences, max_users, max_rooms_discoitems, max_user_conferences, max_users,
max_users_admin_threshold, max_users_presence, max_users_admin_threshold, max_users_presence,

View File

@ -296,7 +296,7 @@ import(_LServer, <<"muc_registered">>,
%%% gen_server callbacks %%% gen_server callbacks
%%%=================================================================== %%%===================================================================
init([Host, Opts]) -> init([Host, Opts]) ->
MyHost = proplists:get_value(host, Opts), MyHosts = proplists:get_value(hosts, Opts),
case gen_mod:db_mod(Host, Opts, mod_muc) of case gen_mod:db_mod(Host, Opts, mod_muc) of
?MODULE -> ?MODULE ->
ejabberd_mnesia:create(?MODULE, muc_room, ejabberd_mnesia:create(?MODULE, muc_room,
@ -318,7 +318,10 @@ init([Host, Opts]) ->
{type, ordered_set}, {type, ordered_set},
{attributes, record_info(fields, muc_online_room)}]), {attributes, record_info(fields, muc_online_room)}]),
catch ets:new(muc_online_users, [bag, named_table, public, {keypos, 2}]), catch ets:new(muc_online_users, [bag, named_table, public, {keypos, 2}]),
clean_table_from_bad_node(node(), MyHost), lists:foreach(
fun(MyHost) ->
clean_table_from_bad_node(node(), MyHost)
end, MyHosts),
mnesia:subscribe(system); mnesia:subscribe(system);
_ -> _ ->
ok ok

View File

@ -112,6 +112,8 @@ depends(_Host, _Opts) ->
mod_opt_type(access) -> fun acl:access_rules_validator/1; mod_opt_type(access) -> fun acl:access_rules_validator/1;
mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(host) -> fun iolist_to_binary/1;
mod_opt_type(hosts) ->
fun(L) -> lists:map(fun iolist_to_binary/1, L) end;
mod_opt_type(hostname) -> fun iolist_to_binary/1; mod_opt_type(hostname) -> fun iolist_to_binary/1;
mod_opt_type(ip) -> mod_opt_type(ip) ->
fun (S) -> fun (S) ->
@ -131,7 +133,7 @@ mod_opt_type(ram_db_type) ->
mod_opt_type(Opt) -> mod_opt_type(Opt) ->
case mod_proxy65_stream:listen_opt_type(Opt) of case mod_proxy65_stream:listen_opt_type(Opt) of
Opts when is_list(Opts) -> Opts when is_list(Opts) ->
[access, host, hostname, ip, name, port, [access, host, hosts, hostname, ip, name, port,
max_connections, ram_db_type] ++ Opts; max_connections, ram_db_type] ++ Opts;
Fun -> Fun ->
Fun Fun

View File

@ -43,7 +43,7 @@
-define(PROCNAME, ejabberd_mod_proxy65_service). -define(PROCNAME, ejabberd_mod_proxy65_service).
-record(state, {myhost = <<"">> :: binary()}). -record(state, {myhosts = [] :: [binary()]}).
%%%------------------------ %%%------------------------
%%% gen_server callbacks %%% gen_server callbacks
@ -61,24 +61,27 @@ reload(Host, NewOpts, OldOpts) ->
init([Host, Opts]) -> init([Host, Opts]) ->
process_flag(trap_exit, true), process_flag(trap_exit, true),
IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)),
MyHost = gen_mod:get_opt_host(Host, Opts, <<"proxy.@HOST@">>), MyHosts = gen_mod:get_opt_hosts(Host, Opts, <<"proxy.@HOST@">>),
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO, lists:foreach(
?MODULE, process_disco_info, IQDisc), fun(MyHost) ->
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS, gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO,
?MODULE, process_disco_items, IQDisc), ?MODULE, process_disco_info, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_VCARD, gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS,
?MODULE, process_vcard, IQDisc), ?MODULE, process_disco_items, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS, gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_VCARD,
?MODULE, process_bytestreams, IQDisc), ?MODULE, process_vcard, IQDisc),
ejabberd_router:register_route(MyHost, Host), gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS,
{ok, #state{myhost = MyHost}}. ?MODULE, process_bytestreams, IQDisc),
ejabberd_router:register_route(MyHost, Host)
end, MyHosts),
{ok, #state{myhosts = MyHosts}}.
terminate(_Reason, #state{myhost = MyHost}) -> terminate(_Reason, #state{myhosts = MyHosts}) ->
ejabberd_router:unregister_route(MyHost), lists:foreach(
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO), fun(MyHost) ->
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS), ejabberd_router:unregister_route(MyHost),
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_VCARD), unregister_handlers(MyHost)
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS). end, MyHosts).
handle_info({route, #iq{} = Packet}, State) -> handle_info({route, #iq{} = Packet}, State) ->
ejabberd_router:process_iq(Packet), ejabberd_router:process_iq(Packet),
@ -89,33 +92,29 @@ handle_call(_Request, _From, State) ->
{reply, ok, State}. {reply, ok, State}.
handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) -> handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) ->
NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"proxy.@HOST@">>), NewHosts = gen_mod:get_opt_hosts(ServerHost, NewOpts, <<"proxy.@HOST@">>),
OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"proxy.@HOST@">>), OldHosts = gen_mod:get_opt_hosts(ServerHost, OldOpts, <<"proxy.@HOST@">>),
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, gen_iq_handler:iqdisc(ServerHost)), NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, gen_iq_handler:iqdisc(ServerHost)),
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, gen_iq_handler:iqdisc(ServerHost)), OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, gen_iq_handler:iqdisc(ServerHost)),
if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) -> if (NewIQDisc /= OldIQDisc) ->
gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_DISCO_INFO, lists:foreach(
?MODULE, process_disco_info, NewIQDisc), fun(NewHost) ->
gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_DISCO_ITEMS, register_handlers(NewHost, NewIQDisc)
?MODULE, process_disco_items, NewIQDisc), end, NewHosts -- (NewHosts -- OldHosts));
gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_VCARD,
?MODULE, process_vcard, NewIQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_BYTESTREAMS,
?MODULE, process_bytestreams, NewIQDisc);
true -> true ->
ok ok
end, end,
if NewHost /= OldHost -> lists:foreach(
ejabberd_router:register_route(NewHost, ServerHost), fun(NewHost) ->
ejabberd_router:unregister_route(OldHost), ejabberd_router:register_route(NewHost, ServerHost),
gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_DISCO_INFO), register_handlers(NewHost, NewIQDisc)
gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_DISCO_ITEMS), end, NewHosts -- OldHosts),
gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_VCARD), lists:foreach(
gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_BYTESTREAMS); fun(OldHost) ->
true -> ejabberd_router:unregister_route(OldHost),
ok unregister_handlers(OldHost)
end, end, OldHosts -- NewHosts),
{noreply, State#state{myhost = NewHost}}; {noreply, State#state{myhosts = NewHosts}};
handle_cast(Msg, State) -> handle_cast(Msg, State) ->
?WARNING_MSG("unexpected cast: ~p", [Msg]), ?WARNING_MSG("unexpected cast: ~p", [Msg]),
{noreply, State}. {noreply, State}.
@ -276,3 +275,19 @@ get_my_ip() ->
max_connections(ServerHost) -> max_connections(ServerHost) ->
gen_mod:get_module_opt(ServerHost, mod_proxy65, max_connections, infinity). gen_mod:get_module_opt(ServerHost, mod_proxy65, max_connections, infinity).
register_handlers(Host, IQDisc) ->
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO,
?MODULE, process_disco_info, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS,
?MODULE, process_disco_items, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
?MODULE, process_vcard, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_BYTESTREAMS,
?MODULE, process_bytestreams, IQDisc).
unregister_handlers(Host) ->
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_BYTESTREAMS).

View File

@ -189,7 +189,7 @@
-record(state, -record(state,
{ {
server_host, server_host,
host, hosts,
access, access,
pep_mapping = [], pep_mapping = [],
ignore_pep_from_offline = true, ignore_pep_from_offline = true,
@ -205,7 +205,7 @@
-type(state() :: -type(state() ::
#state{ #state{
server_host :: binary(), server_host :: binary(),
host :: mod_pubsub:hostPubsub(), hosts :: [mod_pubsub:hostPubsub()],
access :: atom(), access :: atom(),
pep_mapping :: [{binary(), binary()}], pep_mapping :: [{binary(), binary()}],
ignore_pep_from_offline :: boolean(), ignore_pep_from_offline :: boolean(),
@ -243,42 +243,63 @@ stop(Host) ->
init([ServerHost, Opts]) -> init([ServerHost, Opts]) ->
process_flag(trap_exit, true), process_flag(trap_exit, true),
?DEBUG("pubsub init ~p ~p", [ServerHost, Opts]), ?DEBUG("pubsub init ~p ~p", [ServerHost, Opts]),
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>), Hosts = gen_mod:get_opt_hosts(ServerHost, Opts, <<"pubsub.@HOST@">>),
ejabberd_router:register_route(Host, ServerHost),
Access = gen_mod:get_opt(access_createnode, Opts, all), Access = gen_mod:get_opt(access_createnode, Opts, all),
PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts, true), PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts, true),
IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(ServerHost)),
LastItemCache = gen_mod:get_opt(last_item_cache, Opts, false), LastItemCache = gen_mod:get_opt(last_item_cache, Opts, false),
MaxItemsNode = gen_mod:get_opt(max_items_node, Opts, ?MAXITEMS), MaxItemsNode = gen_mod:get_opt(max_items_node, Opts, ?MAXITEMS),
MaxSubsNode = gen_mod:get_opt(max_subscriptions_node, Opts), MaxSubsNode = gen_mod:get_opt(max_subscriptions_node, Opts),
case gen_mod:db_type(ServerHost, ?MODULE) of
mnesia -> pubsub_index:init(Host, ServerHost, Opts);
_ -> ok
end,
{Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts),
DefaultModule = plugin(Host, hd(Plugins)),
BaseOptions = DefaultModule:options(),
DefaultNodeCfg = filter_node_options(
gen_mod:get_opt(default_node_config, Opts, []),
BaseOptions),
ejabberd_mnesia:create(?MODULE, pubsub_last_item, ejabberd_mnesia:create(?MODULE, pubsub_last_item,
[{ram_copies, [node()]}, [{ram_copies, [node()]},
{attributes, record_info(fields, pubsub_last_item)}]), {attributes, record_info(fields, pubsub_last_item)}]),
lists:foreach( AllPlugins =
fun(H) -> lists:flatmap(
T = gen_mod:get_module_proc(H, config), fun(Host) ->
ets:new(T, [set, named_table]), ejabberd_router:register_route(Host, ServerHost),
ets:insert(T, {nodetree, NodeTree}), case gen_mod:db_type(ServerHost, ?MODULE) of
ets:insert(T, {plugins, Plugins}), mnesia -> pubsub_index:init(Host, ServerHost, Opts);
ets:insert(T, {last_item_cache, LastItemCache}), _ -> ok
ets:insert(T, {max_items_node, MaxItemsNode}), end,
ets:insert(T, {max_subscriptions_node, MaxSubsNode}), {Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts),
ets:insert(T, {default_node_config, DefaultNodeCfg}), DefaultModule = plugin(Host, hd(Plugins)),
ets:insert(T, {pep_mapping, PepMapping}), BaseOptions = DefaultModule:options(),
ets:insert(T, {ignore_pep_from_offline, PepOffline}), DefaultNodeCfg = filter_node_options(
ets:insert(T, {host, Host}), gen_mod:get_opt(default_node_config, Opts, []),
ets:insert(T, {access, Access}) BaseOptions),
end, [Host, ServerHost]), lists:foreach(
fun(H) ->
T = gen_mod:get_module_proc(H, config),
try
ets:new(T, [set, named_table]),
ets:insert(T, {nodetree, NodeTree}),
ets:insert(T, {plugins, Plugins}),
ets:insert(T, {last_item_cache, LastItemCache}),
ets:insert(T, {max_items_node, MaxItemsNode}),
ets:insert(T, {max_subscriptions_node, MaxSubsNode}),
ets:insert(T, {default_node_config, DefaultNodeCfg}),
ets:insert(T, {pep_mapping, PepMapping}),
ets:insert(T, {ignore_pep_from_offline, PepOffline}),
ets:insert(T, {host, Host}),
ets:insert(T, {access, Access})
catch error:badarg when H == ServerHost ->
ok
end
end, [Host, ServerHost]),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO,
?MODULE, process_disco_info, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS,
?MODULE, process_disco_items, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_PUBSUB,
?MODULE, process_pubsub, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_PUBSUB_OWNER,
?MODULE, process_pubsub_owner, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
?MODULE, process_vcard, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS,
?MODULE, process_commands, IQDisc),
Plugins
end, Hosts),
ejabberd_hooks:add(sm_remove_connection_hook, ServerHost, ejabberd_hooks:add(sm_remove_connection_hook, ServerHost,
?MODULE, on_user_offline, 75), ?MODULE, on_user_offline, 75),
ejabberd_hooks:add(disco_local_identity, ServerHost, ejabberd_hooks:add(disco_local_identity, ServerHost,
@ -297,19 +318,7 @@ init([ServerHost, Opts]) ->
?MODULE, remove_user, 50), ?MODULE, remove_user, 50),
ejabberd_hooks:add(c2s_handle_info, ServerHost, ejabberd_hooks:add(c2s_handle_info, ServerHost,
?MODULE, c2s_handle_info, 50), ?MODULE, c2s_handle_info, 50),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO, case lists:member(?PEPNODE, AllPlugins) of
?MODULE, process_disco_info, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS,
?MODULE, process_disco_items, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_PUBSUB,
?MODULE, process_pubsub, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_PUBSUB_OWNER,
?MODULE, process_pubsub_owner, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
?MODULE, process_vcard, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS,
?MODULE, process_commands, IQDisc),
case lists:member(?PEPNODE, Plugins) of
true -> true ->
ejabberd_hooks:add(caps_add, ServerHost, ejabberd_hooks:add(caps_add, ServerHost,
?MODULE, caps_add, 80), ?MODULE, caps_add, 80),
@ -328,20 +337,19 @@ init([ServerHost, Opts]) ->
false -> false ->
ok ok
end, end,
{_, State} = init_send_loop(ServerHost), {_, State} = init_send_loop(ServerHost, Hosts),
{ok, State}. {ok, State}.
init_send_loop(ServerHost) -> init_send_loop(ServerHost, Hosts) ->
NodeTree = config(ServerHost, nodetree), NodeTree = config(ServerHost, nodetree),
Plugins = config(ServerHost, plugins), Plugins = config(ServerHost, plugins),
LastItemCache = config(ServerHost, last_item_cache), LastItemCache = config(ServerHost, last_item_cache),
MaxItemsNode = config(ServerHost, max_items_node), MaxItemsNode = config(ServerHost, max_items_node),
PepMapping = config(ServerHost, pep_mapping), PepMapping = config(ServerHost, pep_mapping),
PepOffline = config(ServerHost, ignore_pep_from_offline), PepOffline = config(ServerHost, ignore_pep_from_offline),
Host = config(ServerHost, host),
Access = config(ServerHost, access), Access = config(ServerHost, access),
DBType = gen_mod:db_type(ServerHost, ?MODULE), DBType = gen_mod:db_type(ServerHost, ?MODULE),
State = #state{host = Host, server_host = ServerHost, State = #state{hosts = Hosts, server_host = ServerHost,
access = Access, pep_mapping = PepMapping, access = Access, pep_mapping = PepMapping,
ignore_pep_from_offline = PepOffline, ignore_pep_from_offline = PepOffline,
last_item_cache = LastItemCache, last_item_cache = LastItemCache,
@ -419,7 +427,7 @@ get_subscribed(User, Server) ->
send_loop(State) -> send_loop(State) ->
receive receive
{presence, JID, _Pid} -> {presence, JID, _Pid} ->
Host = State#state.host, Host = State#state.server_host,
ServerHost = State#state.server_host, ServerHost = State#state.server_host,
DBType = State#state.db_type, DBType = State#state.db_type,
LJID = jid:tolower(JID), LJID = jid:tolower(JID),
@ -461,7 +469,7 @@ send_loop(State) ->
send_loop(State); send_loop(State);
{presence, User, Server, Resources, JID} -> {presence, User, Server, Resources, JID} ->
spawn(fun() -> spawn(fun() ->
Host = State#state.host, Host = State#state.server_host,
Owner = jid:remove_resource(jid:tolower(JID)), Owner = jid:remove_resource(jid:tolower(JID)),
lists:foreach(fun(#pubsub_node{nodeid = {_, Node}, type = Type, id = Nidx, options = Options}) -> lists:foreach(fun(#pubsub_node{nodeid = {_, Node}, type = Type, id = Nidx, options = Options}) ->
case match_option(Options, send_last_published_item, on_sub_and_presence) of case match_option(Options, send_last_published_item, on_sub_and_presence) of
@ -689,11 +697,7 @@ presence_probe(_From, _To, _Pid) ->
ok. ok.
presence(ServerHost, Presence) -> presence(ServerHost, Presence) ->
{SendLoop, _} = case whereis(gen_mod:get_module_proc(ServerHost, ?LOOPNAME)) of gen_mod:get_module_proc(ServerHost, ?LOOPNAME) ! Presence,
undefined -> init_send_loop(ServerHost);
Pid -> {Pid, undefined}
end,
SendLoop ! Presence,
ok. ok.
%% ------- %% -------
@ -859,7 +863,7 @@ handle_info(_Info, State) ->
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% @private %% @private
terminate(_Reason, terminate(_Reason,
#state{host = Host, server_host = ServerHost, nodetree = TreePlugin, plugins = Plugins}) -> #state{hosts = Hosts, server_host = ServerHost, nodetree = TreePlugin, plugins = Plugins}) ->
case lists:member(?PEPNODE, Plugins) of case lists:member(?PEPNODE, Plugins) of
true -> true ->
ejabberd_hooks:delete(caps_add, ServerHost, ejabberd_hooks:delete(caps_add, ServerHost,
@ -897,20 +901,23 @@ terminate(_Reason,
?MODULE, remove_user, 50), ?MODULE, remove_user, 50),
ejabberd_hooks:delete(c2s_handle_info, ServerHost, ejabberd_hooks:delete(c2s_handle_info, ServerHost,
?MODULE, c2s_handle_info, 50), ?MODULE, c2s_handle_info, 50),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_PUBSUB),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_PUBSUB_OWNER),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS),
case whereis(gen_mod:get_module_proc(ServerHost, ?LOOPNAME)) of case whereis(gen_mod:get_module_proc(ServerHost, ?LOOPNAME)) of
undefined -> undefined ->
?ERROR_MSG("~s process is dead, pubsub was broken", [?LOOPNAME]); ?ERROR_MSG("~s process is dead, pubsub was broken", [?LOOPNAME]);
Pid -> Pid ->
Pid ! stop Pid ! stop
end, end,
terminate_plugins(Host, ServerHost, Plugins, TreePlugin), lists:foreach(
ejabberd_router:unregister_route(Host). fun(Host) ->
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_PUBSUB),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_PUBSUB_OWNER),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS),
terminate_plugins(Host, ServerHost, Plugins, TreePlugin),
ejabberd_router:unregister_route(Host)
end, Hosts).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
@ -3877,6 +3884,8 @@ export(Server) ->
mod_opt_type(access_createnode) -> fun acl:access_rules_validator/1; mod_opt_type(access_createnode) -> fun acl:access_rules_validator/1;
mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(host) -> fun iolist_to_binary/1;
mod_opt_type(hosts) ->
fun (L) -> lists:map(fun iolist_to_binary/1, L) end;
mod_opt_type(ignore_pep_from_offline) -> mod_opt_type(ignore_pep_from_offline) ->
fun (A) when is_boolean(A) -> A end; fun (A) when is_boolean(A) -> A end;
mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
@ -3895,7 +3904,7 @@ mod_opt_type(pep_mapping) ->
mod_opt_type(plugins) -> mod_opt_type(plugins) ->
fun (A) when is_list(A) -> A end; fun (A) when is_list(A) -> A end;
mod_opt_type(_) -> mod_opt_type(_) ->
[access_createnode, db_type, host, [access_createnode, db_type, host, hosts,
ignore_pep_from_offline, iqdisc, last_item_cache, ignore_pep_from_offline, iqdisc, last_item_cache,
max_items_node, nodetree, pep_mapping, plugins, max_items_node, nodetree, pep_mapping, plugins,
max_subscriptions_node, default_node_config]. max_subscriptions_node, default_node_config].

View File

@ -67,7 +67,7 @@
-optional_callbacks([use_cache/1, cache_nodes/1]). -optional_callbacks([use_cache/1, cache_nodes/1]).
-record(state, {host :: binary(), server_host :: binary()}). -record(state, {hosts :: [binary()], server_host :: binary()}).
%%==================================================================== %%====================================================================
%% gen_mod callbacks %% gen_mod callbacks
@ -95,37 +95,40 @@ init([Host, Opts]) ->
?NS_VCARD, ?MODULE, process_sm_iq, IQDisc), ?NS_VCARD, ?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, ejabberd_hooks:add(disco_sm_features, Host, ?MODULE,
get_sm_features, 50), get_sm_features, 50),
MyHost = gen_mod:get_opt_host(Host, Opts, <<"vjud.@HOST@">>), MyHosts = gen_mod:get_opt_hosts(Host, Opts, <<"vjud.@HOST@">>),
Search = gen_mod:get_opt(search, Opts, false), Search = gen_mod:get_opt(search, Opts, false),
if Search -> if Search ->
ejabberd_hooks:add( lists:foreach(
disco_local_items, MyHost, ?MODULE, disco_items, 100), fun(MyHost) ->
ejabberd_hooks:add( ejabberd_hooks:add(
disco_local_features, MyHost, ?MODULE, disco_features, 100), disco_local_items, MyHost, ?MODULE, disco_items, 100),
ejabberd_hooks:add( ejabberd_hooks:add(
disco_local_identity, MyHost, ?MODULE, disco_identity, 100), disco_local_features, MyHost, ?MODULE, disco_features, 100),
gen_iq_handler:add_iq_handler( ejabberd_hooks:add(
ejabberd_local, MyHost, ?NS_SEARCH, ?MODULE, process_search, IQDisc), disco_local_identity, MyHost, ?MODULE, disco_identity, 100),
gen_iq_handler:add_iq_handler( gen_iq_handler:add_iq_handler(
ejabberd_local, MyHost, ?NS_VCARD, ?MODULE, process_vcard, IQDisc), ejabberd_local, MyHost, ?NS_SEARCH, ?MODULE, process_search, IQDisc),
gen_iq_handler:add_iq_handler( gen_iq_handler:add_iq_handler(
ejabberd_local, MyHost, ?NS_DISCO_ITEMS, mod_disco, ejabberd_local, MyHost, ?NS_VCARD, ?MODULE, process_vcard, IQDisc),
process_local_iq_items, IQDisc), gen_iq_handler:add_iq_handler(
gen_iq_handler:add_iq_handler( ejabberd_local, MyHost, ?NS_DISCO_ITEMS, mod_disco,
ejabberd_local, MyHost, ?NS_DISCO_INFO, mod_disco, process_local_iq_items, IQDisc),
process_local_iq_info, IQDisc), gen_iq_handler:add_iq_handler(
case Mod:is_search_supported(Host) of ejabberd_local, MyHost, ?NS_DISCO_INFO, mod_disco,
false -> process_local_iq_info, IQDisc),
?WARNING_MSG("vcard search functionality is " case Mod:is_search_supported(Host) of
"not implemented for ~s backend", false ->
[gen_mod:db_type(Host, Opts, ?MODULE)]); ?WARNING_MSG("vcard search functionality is "
true -> "not implemented for ~s backend",
ejabberd_router:register_route(MyHost, Host) [gen_mod:db_type(Host, Opts, ?MODULE)]);
end; true ->
ejabberd_router:register_route(MyHost, Host)
end
end, MyHosts);
true -> true ->
ok ok
end, end,
{ok, #state{host = MyHost, server_host = Host}}. {ok, #state{hosts = MyHosts, server_host = Host}}.
handle_call(_Call, _From, State) -> handle_call(_Call, _From, State) ->
{noreply, State}. {noreply, State}.
@ -144,21 +147,24 @@ handle_info(Info, State) ->
?WARNING_MSG("unexpected info: ~p", [Info]), ?WARNING_MSG("unexpected info: ~p", [Info]),
{noreply, State}. {noreply, State}.
terminate(_Reason, #state{host = MyHost, server_host = Host}) -> terminate(_Reason, #state{hosts = MyHosts, server_host = Host}) ->
ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
Mod = gen_mod:db_mod(Host, ?MODULE), Mod = gen_mod:db_mod(Host, ?MODULE),
Mod:stop(Host), Mod:stop(Host),
ejabberd_router:unregister_route(MyHost), lists:foreach(
ejabberd_hooks:delete(disco_local_items, MyHost, ?MODULE, disco_items, 100), fun(MyHost) ->
ejabberd_hooks:delete(disco_local_features, MyHost, ?MODULE, disco_features, 100), ejabberd_router:unregister_route(MyHost),
ejabberd_hooks:delete(disco_local_identity, MyHost, ?MODULE, disco_identity, 100), ejabberd_hooks:delete(disco_local_items, MyHost, ?MODULE, disco_items, 100),
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_SEARCH), ejabberd_hooks:delete(disco_local_features, MyHost, ?MODULE, disco_features, 100),
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_VCARD), ejabberd_hooks:delete(disco_local_identity, MyHost, ?MODULE, disco_identity, 100),
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS), gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_SEARCH),
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO). gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_VCARD),
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS),
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO)
end, MyHosts).
code_change(_OldVsn, State, _Extra) -> code_change(_OldVsn, State, _Extra) ->
{ok, State}. {ok, State}.
@ -527,6 +533,8 @@ mod_opt_type(allow_return_all) ->
fun (B) when is_boolean(B) -> B end; fun (B) when is_boolean(B) -> B end;
mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(host) -> fun iolist_to_binary/1;
mod_opt_type(hosts) ->
fun (L) -> lists:map(fun iolist_to_binary/1, L) end;
mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
mod_opt_type(matches) -> mod_opt_type(matches) ->
fun (infinity) -> infinity; fun (infinity) -> infinity;
@ -543,6 +551,6 @@ mod_opt_type(O) when O == cache_life_time; O == cache_size ->
mod_opt_type(O) when O == use_cache; O == cache_missed -> mod_opt_type(O) when O == use_cache; O == cache_missed ->
fun (B) when is_boolean(B) -> B end; fun (B) when is_boolean(B) -> B end;
mod_opt_type(_) -> mod_opt_type(_) ->
[allow_return_all, db_type, host, iqdisc, matches, [allow_return_all, db_type, host, hosts, iqdisc, matches,
search, search_all_hosts, cache_life_time, cache_size, search, search_all_hosts, cache_life_time, cache_size,
use_cache, cache_missed]. use_cache, cache_missed].

View File

@ -47,7 +47,7 @@
-record(state, -record(state,
{serverhost = <<"">> :: binary(), {serverhost = <<"">> :: binary(),
myhost = <<"">> :: binary(), myhosts = [] :: [binary()],
eldap_id = <<"">> :: binary(), eldap_id = <<"">> :: binary(),
search = false :: boolean(), search = false :: boolean(),
servers = [] :: [binary()], servers = [] :: [binary()],
@ -351,8 +351,7 @@ default_search_reported() ->
{<<"Organization Unit">>, <<"ORGUNIT">>}]. {<<"Organization Unit">>, <<"ORGUNIT">>}].
parse_options(Host, Opts) -> parse_options(Host, Opts) ->
MyHost = gen_mod:get_opt_host(Host, Opts, MyHosts = gen_mod:get_opt_hosts(Host, Opts, <<"vjud.@HOST@">>),
<<"vjud.@HOST@">>),
Search = gen_mod:get_opt(search, Opts, false), Search = gen_mod:get_opt(search, Opts, false),
Matches = gen_mod:get_opt(matches, Opts, 30), Matches = gen_mod:get_opt(matches, Opts, 30),
Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?PROCNAME)), Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?PROCNAME)),
@ -394,7 +393,7 @@ parse_options(Host, Opts) ->
end, end,
SearchReported) SearchReported)
++ UIDAttrs), ++ UIDAttrs),
#state{serverhost = Host, myhost = MyHost, #state{serverhost = Host, myhosts = MyHosts,
eldap_id = Eldap_ID, search = Search, eldap_id = Eldap_ID, search = Search,
servers = Cfg#eldap_config.servers, servers = Cfg#eldap_config.servers,
backups = Cfg#eldap_config.backups, backups = Cfg#eldap_config.backups,