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:
parent
52525eb76d
commit
3fec782494
@ -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
|
||||||
|
@ -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}
|
||||||
|
@ -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()}.
|
||||||
|
|
||||||
|
@ -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) ->
|
||||||
|
103
src/mod_mix.erl
103
src/mod_mix.erl
@ -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].
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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).
|
||||||
|
@ -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].
|
||||||
|
@ -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].
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user