Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Improved subdomain handling with dedicated registry #1116

Merged
merged 3 commits into from
Dec 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion apps/ejabberd/include/mod_muc_light.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
-define(DEFAULT_MAX_OCCUPANTS, infinity).
-define(DEFAULT_ROOMS_PER_PAGE, 10).
-define(DEFAULT_ROOMS_IN_ROSTERS, false).
-define(DEFAULT_HOST, <<"muclight.@HOST@">>).

-type schema_value_type() :: binary | integer | float.
-type schema_item() :: {FormFieldName :: binary(), OptionName :: atom(),
Expand Down
5 changes: 2 additions & 3 deletions apps/ejabberd/src/ejabberd_admin.erl
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,8 @@ status() ->
send_service_message_all_mucs(Subject, AnnouncementText) ->
Message = io_lib:format("~s~n~s", [Subject, AnnouncementText]),
lists:foreach(
fun(ServerHost) ->
MUCHost = gen_mod:get_module_opt_host(
ServerHost, mod_muc, "conference.@HOST@"),
fun(Host) ->
MUCHost = gen_mod:get_module_opt_subhost(Host, mod_muc, mod_muc:default_host()),
mod_muc:broadcast_service_message(MUCHost, Message)
end,
?MYHOSTS).
Expand Down
2 changes: 2 additions & 0 deletions apps/ejabberd/src/ejabberd_app.erl
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ start(normal, _Args) ->
ejabberd_ctl:init(),
ejabberd_commands:init(),
mongoose_commands:init(),
mongoose_subhosts:init(),
gen_mod:start(),
ejabberd_config:start(),
ejabberd_check:config(),
Expand Down Expand Up @@ -80,6 +81,7 @@ start(_, _) ->
prep_stop(State) ->
ejabberd_listener:stop_listeners(),
stop_modules(),
mongoose_subhosts:stop(),
broadcast_c2s_shutdown(),
timer:sleep(5000),
mongoose_metrics:remove_all_metrics(),
Expand Down
2 changes: 1 addition & 1 deletion apps/ejabberd/src/ejabberd_receiver.erl
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ handle_call({starttls, TLSSocket}, _From, #state{parser = Parser} = State) ->
NewState = State#state{socket = TLSSocket,
sock_mod = fast_tls,
parser = NewParser},
case fast_tls:recv_data(TLSSocket, "") of
case fast_tls:recv_data(TLSSocket, <<"">>) of
{ok, TLSData} ->
{reply, ok, process_data(TLSData, NewState), ?HIBERNATE_TIMEOUT};
{error, _Reason} ->
Expand Down
72 changes: 39 additions & 33 deletions apps/ejabberd/src/gen_mod.erl
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,41 @@
-module(gen_mod).
-author('alexey@process-one.net').

-export([start/0,
-export([
% Modules start & stop
start/0,
start_module/3,
start_backend_module/2,
start_backend_module/3,
stop_module/2,
stop_module_keep_config/2,
reload_module/3,
% Get/set opts by host or from a list
get_opt/2,
get_opt/3,
get_opt/4,
get_opt_host/3,
set_opt/3,
get_module_opt/4,
get_module_opt_host/3,
set_module_opt/4,
get_opt_subhost/3,
get_module_opt_subhost/3,
% Get/set opts by subhost
get_module_opt_by_subhost/4,
set_module_opt_by_subhost/4,

loaded_modules/1,
loaded_modules_with_opts/1,
get_hosts/2,
get_module_proc/2,
backend_code/3,
is_loaded/2,
get_deps/3]).

-include("ejabberd.hrl").

-record(ejabberd_module, {module_host, opts}).
-record(ejabberd_module, {
module_host, % {module(), ejabberd:server()},
opts % list()
}).

%% -export([behaviour_info/1]).
%% behaviour_info(callbacks) ->
Expand All @@ -77,10 +86,8 @@

-spec start() -> 'ok'.
start() ->
ets:new(ejabberd_modules,
[named_table,
public,
{keypos, #ejabberd_module.module_host}]),
ets:new(ejabberd_modules, [named_table, public, {keypos, #ejabberd_module.module_host},
{read_concurrency, true}]),
ok.


Expand All @@ -90,9 +97,7 @@ start() ->
start_module(Host, Module, Opts0) ->
Opts = clear_opts(Module, Opts0),
set_module_opts_mnesia(Host, Module, Opts),
ets:insert(ejabberd_modules,
#ejabberd_module{module_host = {Module, Host},
opts = Opts}),
ets:insert(ejabberd_modules, #ejabberd_module{module_host = {Module, Host}, opts = Opts}),
try
Res = Module:start(Host, Opts),
?DEBUG("Module ~p started for ~p.", [Module, Host]),
Expand Down Expand Up @@ -307,6 +312,14 @@ get_module_opt(Host, Module, Opt, Default) ->
get_opt(Opt, Opts, Default)
end.

-spec get_module_opt_by_subhost(
SubHost :: ejabberd:server(),
Module :: module(),
Opt :: term(),
Default :: term()) -> term().
get_module_opt_by_subhost(SubHost, Module, Opt, Default) ->
{ok, Host} = mongoose_subhosts:get_host(SubHost),
get_module_opt(Host, Module, Opt, Default).

%% @doc Non-atomic! You have been warned.
-spec set_module_opt(ejabberd:server(), module(), _Opt, _Value) -> boolean().
Expand All @@ -322,18 +335,25 @@ set_module_opt(Host, Module, Opt, Value) ->
{#ejabberd_module.opts, Updated})
end.


-spec get_module_opt_host(ejabberd:server(), module(), _) -> ejabberd:server().
get_module_opt_host(Host, Module, Default) ->
Val = get_module_opt(Host, Module, host, Default),
re:replace(Val, "@HOST@", Host, [global, {return, binary}]).
-spec set_module_opt_by_subhost(
SubHost :: ejabberd:server(),
Module :: module(),
Opt :: term(),
Value :: term()) -> boolean().
set_module_opt_by_subhost(SubHost, Module, Opt, Value) ->
{ok, Host} = mongoose_subhosts:get_host(SubHost),
set_module_opt(Host, Module, Opt, Value).


-spec get_opt_host(ejabberd:server(), list(), _) -> ejabberd:server().
get_opt_host(Host, Opts, Default) ->
-spec get_opt_subhost(ejabberd:server(), list(), list() | binary()) -> ejabberd:server().
get_opt_subhost(Host, Opts, Default) ->
Val = get_opt(host, Opts, Default),
re:replace(Val, "@HOST@", Host, [global, {return, binary}]).

-spec get_module_opt_subhost(ejabberd:server(), module(), list() | binary()) -> ejabberd:server().
get_module_opt_subhost(Host, Module, Default) ->
Subject = get_module_opt(Host, Module, host, Default),
re:replace(Subject, "@HOST@", Host, [global, {return, binary}]).

-spec loaded_modules(ejabberd:server()) -> [module()].
loaded_modules(Host) ->
Expand Down Expand Up @@ -381,20 +401,6 @@ del_module_mnesia(Host, Module) ->
ejabberd_config:add_local_option({modules, Host}, OtherModules)
end.

get_hosts(Opts, Prefix) ->
case catch gen_mod:get_opt(hosts, Opts) of
{'EXIT', _Error1} ->
case catch gen_mod:get_opt(host, Opts) of
{'EXIT', _Error2} ->
[Prefix ++ Host || Host <- ?MYHOSTS];
Host ->
[Host]
end;
Hosts ->
Hosts
end.


-spec get_module_proc(binary() | string(), module()) -> atom().
get_module_proc(Host, Base) when is_binary(Host) ->
get_module_proc(binary_to_list(Host), Base);
Expand Down
112 changes: 37 additions & 75 deletions apps/ejabberd/src/mod_mam_muc.erl
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@
room_process_mam_iq/3,
forget_room/2]).

-export([server_host/1]).

%% private
-export([archive_message/8]).
-export([lookup_messages/13]).
Expand Down Expand Up @@ -140,104 +138,68 @@ max_result_limit() -> 50.
%% API

-spec delete_archive(ejabberd:server(), ejabberd:user()) -> 'ok'.
delete_archive(Server, User)
when is_binary(Server), is_binary(User) ->
?DEBUG("Remove user ~p from ~p.", [User, Server]),
ArcJID = jid:make(User, Server, <<>>),
Host = server_host(ArcJID),
delete_archive(SubHost, RoomName) when is_binary(SubHost), is_binary(RoomName) ->
?DEBUG("Remove room ~p from ~p.", [RoomName, SubHost]),
ArcJID = jid:make(RoomName, SubHost, <<>>),
{ok, Host} = mongoose_subhosts:get_host(SubHost),
ArcID = archive_id_int(Host, ArcJID),
remove_archive(Host, ArcID, ArcJID),
ok.


-spec archive_size(ejabberd:server(), ejabberd:user()) -> integer().
archive_size(Server, User)
when is_binary(Server), is_binary(User) ->
ArcJID = jid:make(User, Server, <<>>),
Host = server_host(ArcJID),
archive_size(SubHost, RoomName) when is_binary(SubHost), is_binary(RoomName) ->
ArcJID = jid:make(RoomName, SubHost, <<>>),
{ok, Host} = mongoose_subhosts:get_host(SubHost),
ArcID = archive_id_int(Host, ArcJID),
archive_size(Host, ArcID, ArcJID).


-spec archive_id(ejabberd:server(), ejabberd:user()) -> integer().
archive_id(Server, User)
when is_binary(Server), is_binary(User) ->
ArcJID = jid:make(User, Server, <<>>),
Host = server_host(ArcJID),
archive_id(SubHost, RoomName) when is_binary(SubHost), is_binary(RoomName) ->
ArcJID = jid:make(RoomName, SubHost, <<>>),
{ok, Host} = mongoose_subhosts:get_host(SubHost),
archive_id_int(Host, ArcJID).

%% ----------------------------------------------------------------------
%% gen_mod callbacks
%% Starting and stopping functions for MUC archives

-spec start(Host :: ejabberd:server(), Opts :: list()) -> any().
start(ServerHost, Opts) ->
start(Host, Opts) ->
?DEBUG("mod_mam_muc starting", []),
compile_params_module(Opts),
%% MUC host.
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"conference.@HOST@">>),
start_host_mapping(Host, ServerHost),
MUCHost = gen_mod:get_opt_subhost(Host, Opts, mod_muc:default_host()),
IQDisc = gen_mod:get_opt(iqdisc, Opts, parallel), %% Type
mod_disco:register_feature(Host, ?NS_MAM),
mod_disco:register_feature(Host, ?NS_MAM_03),
mod_disco:register_feature(Host, ?NS_MAM_04),
gen_iq_handler:add_iq_handler(mod_muc_iq, Host, ?NS_MAM,
mod_disco:register_feature(MUCHost, ?NS_MAM),
mod_disco:register_feature(MUCHost, ?NS_MAM_03),
mod_disco:register_feature(MUCHost, ?NS_MAM_04),
gen_iq_handler:add_iq_handler(mod_muc_iq, MUCHost, ?NS_MAM,
?MODULE, room_process_mam_iq, IQDisc),
gen_iq_handler:add_iq_handler(mod_muc_iq, Host, ?NS_MAM_03,
gen_iq_handler:add_iq_handler(mod_muc_iq, MUCHost, ?NS_MAM_03,
?MODULE, room_process_mam_iq, IQDisc),
gen_iq_handler:add_iq_handler(mod_muc_iq, Host, ?NS_MAM_04,
gen_iq_handler:add_iq_handler(mod_muc_iq, MUCHost, ?NS_MAM_04,
?MODULE, room_process_mam_iq, IQDisc),
ejabberd_hooks:add(filter_room_packet, Host, ?MODULE,
ejabberd_hooks:add(filter_room_packet, MUCHost, ?MODULE,
filter_room_packet, 90),
ejabberd_hooks:add(forget_room, Host, ?MODULE, forget_room, 90),
ejabberd_hooks:add(forget_room, MUCHost, ?MODULE, forget_room, 90),
ok.

-spec stop(Host :: ejabberd:server()) -> any().
stop(ServerHost) ->
%% MUC host.
Host = gen_mod:get_module_opt_host(
ServerHost, ?MODULE, <<"conference.@HOST@">>),
stop(Host) ->
MUCHost = gen_mod:get_module_opt_subhost(Host, mod_mam_muc, mod_muc:default_host()),
?DEBUG("mod_mam stopping", []),
ejabberd_hooks:delete(filter_room_packet, Host, ?MODULE, filter_room_packet, 90),
ejabberd_hooks:delete(forget_room, Host, ?MODULE, forget_room, 90),
gen_iq_handler:remove_iq_handler(mod_muc_iq, Host, ?NS_MAM),
gen_iq_handler:remove_iq_handler(mod_muc_iq, Host, ?NS_MAM_03),
gen_iq_handler:remove_iq_handler(mod_muc_iq, Host, ?NS_MAM_04),
mod_disco:unregister_feature(Host, ?NS_MAM),
mod_disco:unregister_feature(Host, ?NS_MAM_03),
mod_disco:unregister_feature(Host, ?NS_MAM_04),
stop_host_mapping(Host, ServerHost),
ejabberd_hooks:delete(filter_room_packet, MUCHost, ?MODULE, filter_room_packet, 90),
ejabberd_hooks:delete(forget_room, MUCHost, ?MODULE, forget_room, 90),
gen_iq_handler:remove_iq_handler(mod_muc_iq, MUCHost, ?NS_MAM),
gen_iq_handler:remove_iq_handler(mod_muc_iq, MUCHost, ?NS_MAM_03),
gen_iq_handler:remove_iq_handler(mod_muc_iq, MUCHost, ?NS_MAM_04),
mod_disco:unregister_feature(MUCHost, ?NS_MAM),
mod_disco:unregister_feature(MUCHost, ?NS_MAM_03),
mod_disco:unregister_feature(MUCHost, ?NS_MAM_04),
ok.

%% ----------------------------------------------------------------------
%% Host to ServerHost mapping

-record(mam_host, {host :: ejabberd:server(),
server_host :: ejabberd:server()}).

-spec start_host_mapping(ejabberd:server(), ejabberd:server()) -> any().
start_host_mapping(Host, ServerHost) ->
mnesia:create_table(mam_host,
[{ram_copies, [node()]},
{type, set},
{attributes, record_info(fields, mam_host)}]),
mnesia:add_table_copy(mam_host, node(), ram_copies),
mnesia:dirty_write(#mam_host{host = Host, server_host = ServerHost}).


-spec stop_host_mapping(ejabberd:server(), ejabberd:server()) -> any().
stop_host_mapping(Host, ServerHost) ->
mnesia:dirty_delete_object(
#mam_host{host = Host, server_host = ServerHost}).


-spec server_host(ejabberd:jid()) -> ejabberd:server().
server_host(#jid{lserver=Host}) ->
server_host_1(Host, mnesia:dirty_read(mam_host, Host)).

server_host_1(_Host, [#mam_host{ server_host = ServerHost }]) ->
ServerHost.

%% ----------------------------------------------------------------------
%% hooks and handlers for MUC

Expand All @@ -263,7 +225,7 @@ filter_room_packet(Packet, EventData) ->
FromJID :: ejabberd:jid(), RoomJID :: ejabberd:jid(),
Role :: mod_muc:role(), Affiliation :: mod_muc:affiliation()) -> packet().
archive_room_packet(Packet, FromNick, FromJID=#jid{}, RoomJID=#jid{}, Role, Affiliation) ->
Host = server_host(RoomJID),
{ok, Host} = mongoose_subhosts:get_host(RoomJID#jid.lserver),
ArcID = archive_id_int(Host, RoomJID),
%% Occupant JID <room@service/nick>
SrcJID = jid:replace_resource(RoomJID, FromNick),
Expand Down Expand Up @@ -445,7 +407,7 @@ handle_set_prefs(ArcJID=#jid{},
{DefaultMode, AlwaysJIDs, NeverJIDs} = parse_prefs(PrefsEl),
?DEBUG("Parsed data~n\tDefaultMode ~p~n\tAlwaysJIDs ~p~n\tNeverJIDS ~p~n",
[DefaultMode, AlwaysJIDs, NeverJIDs]),
Host = server_host(ArcJID),
{ok, Host} = mongoose_subhosts:get_host(ArcJID#jid.lserver),
ArcID = archive_id_int(Host, ArcJID),
Res = set_prefs(Host, ArcID, ArcJID, DefaultMode, AlwaysJIDs, NeverJIDs),
handle_set_prefs_result(Res, DefaultMode, AlwaysJIDs, NeverJIDs, IQ).
Expand All @@ -461,7 +423,7 @@ handle_set_prefs_result({error, Reason},
-spec handle_get_prefs(ejabberd:jid(), ejabberd:iq()) ->
ejabberd:iq() | {error, any(), ejabberd:iq()}.
handle_get_prefs(ArcJID=#jid{}, IQ=#iq{}) ->
Host = server_host(ArcJID),
{ok, Host} = mongoose_subhosts:get_host(ArcJID#jid.lserver),
ArcID = archive_id_int(Host, ArcJID),
Res = get_prefs(Host, ArcID, ArcJID, always),
handle_get_prefs_result(Res, IQ).
Expand All @@ -482,7 +444,7 @@ handle_lookup_messages(
ArcJID=#jid{},
IQ=#iq{xmlns = MamNs, sub_el = QueryEl}) ->
Now = mod_mam_utils:now_to_microseconds(now()),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to Compiler:

Warning: erlang:now/0: Deprecated BIF. See the "Time and Time Correction in Erlang" chapter of the ERTS User's Guide for more information.

Host = server_host(ArcJID),
{ok, Host} = mongoose_subhosts:get_host(ArcJID#jid.lserver),
ArcID = archive_id_int(Host, ArcJID),
QueryID = xml:get_tag_attr_s(<<"queryid">>, QueryEl),
%% Filtering by date.
Expand Down Expand Up @@ -537,7 +499,7 @@ handle_set_message_form(
ArcJID=#jid{},
IQ=#iq{xmlns=MamNs, sub_el = QueryEl}) ->
Now = mod_mam_utils:now_to_microseconds(now()),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to Compiler:

Warning: erlang:now/0: Deprecated BIF. See the "Time and Time Correction in Erlang" chapter of the ERTS User's Guide for more information.

Host = server_host(ArcJID),
{ok, Host} = mongoose_subhosts:get_host(ArcJID#jid.lserver),
ArcID = archive_id_int(Host, ArcJID),
QueryID = xml:get_tag_attr_s(<<"queryid">>, QueryEl),
%% Filtering by date.
Expand Down Expand Up @@ -623,7 +585,7 @@ handle_get_message_form(_From=#jid{}, _ArcJID=#jid{}, IQ=#iq{}) ->
handle_purge_multiple_messages(ArcJID=#jid{},
IQ=#iq{sub_el = PurgeEl}) ->
Now = mod_mam_utils:now_to_microseconds(now()),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to Compiler:

Warning: erlang:now/0: Deprecated BIF. See the "Time and Time Correction in Erlang" chapter of the ERTS User's Guide for more information.

Host = server_host(ArcJID),
{ok, Host} = mongoose_subhosts:get_host(ArcJID#jid.lserver),
ArcID = archive_id_int(Host, ArcJID),
%% Filtering by date.
%% Start :: integer() | undefined
Expand All @@ -643,7 +605,7 @@ handle_purge_multiple_messages(ArcJID=#jid{},
handle_purge_single_message(ArcJID=#jid{},
IQ=#iq{sub_el = PurgeEl}) ->
Now = mod_mam_utils:now_to_microseconds(now()),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to Compiler:

Warning: erlang:now/0: Deprecated BIF. See the "Time and Time Correction in Erlang" chapter of the ERTS User's Guide for more information.

Host = server_host(ArcJID),
{ok, Host} = mongoose_subhosts:get_host(ArcJID#jid.lserver),
ArcID = archive_id_int(Host, ArcJID),
BExtMessID = xml:get_tag_attr_s(<<"id">>, PurgeEl),
MessID = mod_mam_utils:external_binary_to_mess_id(BExtMessID),
Expand Down
Loading