diff options
-rw-r--r-- | rebar.config | 2 | ||||
-rw-r--r-- | src/ejabberd_bosh.erl | 38 | ||||
-rw-r--r-- | src/ejabberd_c2s.erl | 21 | ||||
-rw-r--r-- | src/ejabberd_http_ws.erl | 14 | ||||
-rw-r--r-- | src/ejabberd_receiver.erl | 4 | ||||
-rw-r--r-- | src/ejabberd_regexp.erl | 2 | ||||
-rw-r--r-- | src/ejabberd_s2s.erl | 14 | ||||
-rw-r--r-- | src/ejabberd_sql.erl | 30 | ||||
-rw-r--r-- | src/eldap.erl | 30 | ||||
-rw-r--r-- | src/gen_mod.erl | 17 | ||||
-rw-r--r-- | src/mod_echo.erl | 41 | ||||
-rw-r--r-- | src/mod_http_upload.erl | 20 | ||||
-rw-r--r-- | src/mod_irc.erl | 62 | ||||
-rw-r--r-- | src/mod_irc_connection.erl | 10 | ||||
-rw-r--r-- | src/mod_mix.erl | 103 | ||||
-rw-r--r-- | src/mod_muc.erl | 87 | ||||
-rw-r--r-- | src/mod_muc_admin.erl | 20 | ||||
-rw-r--r-- | src/mod_muc_log.erl | 2 | ||||
-rw-r--r-- | src/mod_muc_mnesia.erl | 7 | ||||
-rw-r--r-- | src/mod_muc_room.erl | 12 | ||||
-rw-r--r-- | src/mod_proxy65.erl | 4 | ||||
-rw-r--r-- | src/mod_proxy65_service.erl | 95 | ||||
-rw-r--r-- | src/mod_proxy65_stream.erl | 10 | ||||
-rw-r--r-- | src/mod_pubsub.erl | 141 | ||||
-rw-r--r-- | src/mod_sip_proxy.erl | 7 | ||||
-rw-r--r-- | src/mod_vcard.erl | 82 | ||||
-rw-r--r-- | src/mod_vcard_ldap.erl | 7 | ||||
-rw-r--r-- | test/ejabberd_SUITE.erl | 8 |
28 files changed, 495 insertions, 395 deletions
diff --git a/rebar.config b/rebar.config index 160185511..b8a94611a 100644 --- a/rebar.config +++ b/rebar.config @@ -76,7 +76,7 @@ ezlib, iconv]}}. -{erl_first_files, ["src/ejabberd_config.erl", "src/gen_mod.erl", "src/mod_muc_room.erl"]}. +{erl_first_files, ["src/ejabberd_config.erl", "src/gen_mod.erl", "src/mod_muc_room.erl", "src/mod_push.erl"]}. {erl_opts, [nowarn_deprecated_function, {i, "include"}, diff --git a/src/ejabberd_bosh.erl b/src/ejabberd_bosh.erl index 0755067e7..1df6681ff 100644 --- a/src/ejabberd_bosh.erl +++ b/src/ejabberd_bosh.erl @@ -27,9 +27,7 @@ -protocol({xep, 124, '1.11'}). -protocol({xep, 206, '1.4'}). --define(GEN_FSM, p1_fsm). - --behaviour(?GEN_FSM). +-behaviour(p1_fsm). %% API -export([start/2, start/3, start_link/3]). @@ -137,18 +135,18 @@ start(#body{attrs = Attrs} = Body, IP, SID) -> end. start(StateName, State) -> - (?GEN_FSM):start_link(?MODULE, [StateName, State], + p1_fsm:start_link(?MODULE, [StateName, State], ?FSMOPTS). start_link(Body, IP, SID) -> - (?GEN_FSM):start_link(?MODULE, [Body, IP, SID], + p1_fsm:start_link(?MODULE, [Body, IP, SID], ?FSMOPTS). send({http_bind, FsmRef, IP}, Packet) -> send_xml({http_bind, FsmRef, IP}, Packet). send_xml({http_bind, FsmRef, _IP}, Packet) -> - case catch (?GEN_FSM):sync_send_all_state_event(FsmRef, + case catch p1_fsm:sync_send_all_state_event(FsmRef, {send_xml, Packet}, ?SEND_TIMEOUT) of @@ -160,12 +158,12 @@ send_xml({http_bind, FsmRef, _IP}, Packet) -> setopts({http_bind, FsmRef, _IP}, Opts) -> case lists:member({active, once}, Opts) of true -> - (?GEN_FSM):send_all_state_event(FsmRef, + p1_fsm:send_all_state_event(FsmRef, {activate, self()}); _ -> case lists:member({active, false}, Opts) of true -> - case catch (?GEN_FSM):sync_send_all_state_event(FsmRef, + case catch p1_fsm:sync_send_all_state_event(FsmRef, deactivate_socket) of {'EXIT', _} -> {error, einval}; @@ -181,7 +179,7 @@ custom_receiver({http_bind, FsmRef, _IP}) -> {receiver, ?MODULE, FsmRef}. become_controller(FsmRef, C2SPid) -> - (?GEN_FSM):send_all_state_event(FsmRef, + p1_fsm:send_all_state_event(FsmRef, {become_controller, C2SPid}). change_controller({http_bind, FsmRef, _IP}, C2SPid) -> @@ -190,14 +188,14 @@ change_controller({http_bind, FsmRef, _IP}, C2SPid) -> reset_stream({http_bind, _FsmRef, _IP}) -> ok. change_shaper({http_bind, FsmRef, _IP}, Shaper) -> - (?GEN_FSM):send_all_state_event(FsmRef, + p1_fsm:send_all_state_event(FsmRef, {change_shaper, Shaper}). monitor({http_bind, FsmRef, _IP}) -> erlang:monitor(process, FsmRef). close({http_bind, FsmRef, _IP}) -> - catch (?GEN_FSM):sync_send_all_state_event(FsmRef, + catch p1_fsm:sync_send_all_state_event(FsmRef, close). sockname(_Socket) -> {ok, {{0, 0, 0, 0}, 0}}. @@ -269,7 +267,7 @@ process_request(Data, IP, Type) -> end. process_request(Pid, Req, _IP, Type) -> - case catch (?GEN_FSM):sync_send_event(Pid, Req, + case catch p1_fsm:sync_send_event(Pid, Req, infinity) of #body{} = Resp -> bosh_response(Resp, Type); @@ -571,7 +569,7 @@ handle_sync_event({send_xml, El}, _From, StateName, of {{value, {TRef, From, Body}}, Q} -> cancel_timer(TRef), - (?GEN_FSM):send_event(self(), {Body, From}), + p1_fsm:send_event(self(), {Body, From}), State1#state{shaped_receivers = Q}; _ -> State1 end, @@ -598,7 +596,7 @@ handle_info({timeout, TRef, shaper_timeout}, StateName, State) -> case p1_queue:out(State#state.shaped_receivers) of {{value, {TRef, From, Req}}, Q} -> - (?GEN_FSM):send_event(self(), {Req, From}), + p1_fsm:send_event(self(), {Req, From}), {next_state, StateName, State#state{shaped_receivers = Q}}; {{value, _}, _} -> @@ -630,7 +628,7 @@ terminate(_Reason, _StateName, State) -> mod_bosh:close_session(State#state.sid), case State#state.c2s_pid of C2SPid when is_pid(C2SPid) -> - (?GEN_FSM):send_event(C2SPid, closed); + p1_fsm:send_event(C2SPid, closed); _ -> ok end, bounce_receivers(State, closed), @@ -644,7 +642,7 @@ print_state(State) -> State. route_els(#state{el_ibuf = Buf, c2s_pid = C2SPid} = State) -> NewBuf = p1_queue:dropwhile( fun(El) -> - ?GEN_FSM:send_event(C2SPid, El), + p1_fsm:send_event(C2SPid, El), true end, Buf), State#state{el_ibuf = NewBuf}. @@ -653,7 +651,7 @@ route_els(State, Els) -> case State#state.c2s_pid of C2SPid when is_pid(C2SPid) -> lists:foreach(fun (El) -> - (?GEN_FSM):send_event(C2SPid, El) + p1_fsm:send_event(C2SPid, El) end, Els), State; @@ -676,7 +674,7 @@ reply(State, Body, RID, From) -> case catch gb_trees:take_smallest(Receivers) of {NextRID, {From1, Req}, Receivers1} when NextRID == RID + 1 -> - (?GEN_FSM):send_event(self(), {Req, From1}), + p1_fsm:send_event(self(), {Req, From1}), State2#state{receivers = Receivers1}; _ -> State2#state{receivers = Receivers} end. @@ -715,7 +713,7 @@ do_reply(State, From, Body, RID) -> ?DEBUG("send reply:~n** RequestID: ~p~n** Reply: " "~p~n** To: ~p~n** State: ~p", [RID, Body, From, State]), - (?GEN_FSM):reply(From, Body), + p1_fsm:reply(From, Body), Responses = gb_trees:delete_any(RID, State#state.responses), Responses1 = case gb_trees:size(Responses) of @@ -1053,7 +1051,7 @@ buf_out(Buf, I, Els) -> end. cancel_timer(TRef) when is_reference(TRef) -> - (?GEN_FSM):cancel_timer(TRef); + p1_fsm:cancel_timer(TRef); cancel_timer(_) -> false. restart_timer(TRef, Timeout, Msg) -> diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 4b265d29d..a0be2e118 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -297,14 +297,19 @@ process_terminated(State, _Reason) -> %%%=================================================================== %%% xmpp_stream_in callbacks %%%=================================================================== -tls_options(#{lserver := LServer, tls_options := DefaultOpts}) -> - TLSOpts1 = case ejabberd_config:get_option( - {c2s_certfile, LServer}, - ejabberd_config:get_option( - {domain_certfile, LServer})) of - undefined -> DefaultOpts; - CertFile -> lists:keystore(certfile, 1, DefaultOpts, - {certfile, CertFile}) +tls_options(#{lserver := LServer, tls_options := DefaultOpts, + stream_encrypted := Encrypted}) -> + TLSOpts1 = case {Encrypted, proplists:get_value(certfile, DefaultOpts)} of + {true, CertFile} when CertFile /= undefined -> DefaultOpts; + {_, _} -> + case ejabberd_config:get_option( + {c2s_certfile, LServer}, + ejabberd_config:get_option( + {domain_certfile, LServer})) of + undefined -> DefaultOpts; + CertFile -> lists:keystore(certfile, 1, DefaultOpts, + {certfile, CertFile}) + end end, TLSOpts2 = case ejabberd_config:get_option( {c2s_ciphers, LServer}) of diff --git a/src/ejabberd_http_ws.erl b/src/ejabberd_http_ws.erl index 2c44d6552..f9f7b07e9 100644 --- a/src/ejabberd_http_ws.erl +++ b/src/ejabberd_http_ws.erl @@ -28,7 +28,7 @@ -author('ecestari@process-one.net'). --behaviour(gen_fsm). +-behaviour(p1_fsm). -export([start/1, start_link/1, init/1, handle_event/3, handle_sync_event/4, code_change/4, handle_info/3, @@ -75,13 +75,13 @@ -export_type([ws_socket/0]). start(WS) -> - gen_fsm:start(?MODULE, [WS], ?FSMOPTS). + p1_fsm:start(?MODULE, [WS], ?FSMOPTS). start_link(WS) -> - gen_fsm:start_link(?MODULE, [WS], ?FSMOPTS). + p1_fsm:start_link(?MODULE, [WS], ?FSMOPTS). send_xml({http_ws, FsmRef, _IP}, Packet) -> - case catch gen_fsm:sync_send_all_state_event(FsmRef, + case catch p1_fsm:sync_send_all_state_event(FsmRef, {send_xml, Packet}, 15000) of @@ -93,7 +93,7 @@ send_xml({http_ws, FsmRef, _IP}, Packet) -> setopts({http_ws, FsmRef, _IP}, Opts) -> case lists:member({active, once}, Opts) of true -> - gen_fsm:send_all_state_event(FsmRef, + p1_fsm:send_all_state_event(FsmRef, {activate, self()}); _ -> ok end. @@ -105,11 +105,11 @@ peername({http_ws, _FsmRef, IP}) -> {ok, IP}. controlling_process(_Socket, _Pid) -> ok. become_controller(FsmRef, C2SPid) -> - gen_fsm:send_all_state_event(FsmRef, + p1_fsm:send_all_state_event(FsmRef, {become_controller, C2SPid}). close({http_ws, FsmRef, _IP}) -> - catch gen_fsm:sync_send_all_state_event(FsmRef, close). + catch p1_fsm:sync_send_all_state_event(FsmRef, close). socket_handoff(LocalPath, Request, Socket, SockMod, Buf, Opts) -> ejabberd_websocket:socket_handoff(LocalPath, Request, Socket, SockMod, diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl index 44c29680c..52077ac3c 100644 --- a/src/ejabberd_receiver.erl +++ b/src/ejabberd_receiver.erl @@ -234,7 +234,7 @@ terminate(_Reason, State) -> close_stream(XMLStreamState), if C2SPid /= undefined -> - gen_fsm:send_event(C2SPid, closed); + p1_fsm:send_event(C2SPid, closed); true -> ok end, catch (State#state.sock_mod):close(State#state.socket), @@ -272,7 +272,7 @@ process_data([Element | Els], element(1, Element) == xmlstreamend -> if C2SPid == undefined -> State; true -> - catch gen_fsm:send_event(C2SPid, + catch p1_fsm:send_event(C2SPid, element_wrapper(Element)), process_data(Els, State) end; diff --git a/src/ejabberd_regexp.erl b/src/ejabberd_regexp.erl index b4ef7ac16..10f51aa47 100644 --- a/src/ejabberd_regexp.erl +++ b/src/ejabberd_regexp.erl @@ -25,7 +25,7 @@ -module(ejabberd_regexp). --compile([export_all]). +-export([exec/2, run/2, split/2, replace/3, greplace/3, sh_to_awk/1]). exec({ReM, ReF, ReA}, {RgM, RgF, RgA}) -> try apply(ReM, ReF, ReA) catch diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index a0e9411cf..a614d8c4a 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -39,7 +39,7 @@ remove_connection/2, start_connection/2, start_connection/3, dirty_get_connections/0, allow_host/2, incoming_s2s_number/0, outgoing_s2s_number/0, - stop_all_connections/0, + stop_s2s_connections/0, clean_temporarily_blocked_table/0, list_temporarily_blocked_hosts/0, external_host_overloaded/1, is_temporarly_blocked/1, @@ -558,10 +558,10 @@ get_commands_spec() -> module = ?MODULE, function = outgoing_s2s_number, args = [], result = {s2s_outgoing, integer}}, #ejabberd_commands{ - name = stop_all_connections, tags = [s2s], - desc = "Stop all outgoing and incoming connections", + name = stop_s2s_connections, tags = [s2s], + desc = "Stop all s2s outgoing and incoming connections", policy = admin, - module = ?MODULE, function = stop_all_connections, + module = ?MODULE, function = stop_s2s_connections, args = [], result = {res, rescode}}]. %% TODO Move those stats commands to ejabberd stats command ? @@ -578,8 +578,8 @@ supervisor_count(Supervisor) -> length(Result) end. --spec stop_all_connections() -> ok. -stop_all_connections() -> +-spec stop_s2s_connections() -> ok. +stop_s2s_connections() -> lists:foreach( fun({_Id, Pid, _Type, _Module}) -> supervisor:terminate_child(ejabberd_s2s_in_sup, Pid) @@ -682,7 +682,7 @@ complete_s2s_info([Connection | T], Type, Result) -> -spec get_s2s_state(pid()) -> [{status, open | closed | error} | {s2s_pid, pid()}]. get_s2s_state(S2sPid) -> - Infos = case gen_fsm:sync_send_all_state_event(S2sPid, + Infos = case p1_fsm:sync_send_all_state_event(S2sPid, get_state_infos) of {state_infos, Is} -> [{status, open} | Is]; diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl index 35d970291..cae41da6c 100644 --- a/src/ejabberd_sql.erl +++ b/src/ejabberd_sql.erl @@ -29,9 +29,7 @@ -author('alexey@process-one.net'). --define(GEN_FSM, p1_fsm). - --behaviour(?GEN_FSM). +-behaviour(p1_fsm). %% External exports -export([start/1, start_link/2, @@ -113,11 +111,11 @@ %%% API %%%---------------------------------------------------------------------- start(Host) -> - (?GEN_FSM):start(ejabberd_sql, [Host], + p1_fsm:start(ejabberd_sql, [Host], fsm_limit_opts() ++ (?FSMOPTS)). start_link(Host, StartInterval) -> - (?GEN_FSM):start_link(ejabberd_sql, + p1_fsm:start_link(ejabberd_sql, [Host, StartInterval], fsm_limit_opts() ++ (?FSMOPTS)). @@ -160,7 +158,7 @@ sql_call(Host, Msg) -> case ejabberd_sql_sup:get_random_pid(Host) of none -> {error, <<"Unknown Host">>}; Pid -> - (?GEN_FSM):sync_send_event(Pid,{sql_cmd, Msg, + p1_fsm:sync_send_event(Pid,{sql_cmd, Msg, p1_time_compat:monotonic_time(milli_seconds)}, query_timeout(Host)) end; @@ -168,7 +166,7 @@ sql_call(Host, Msg) -> end. keep_alive(Host, PID) -> - (?GEN_FSM):sync_send_event(PID, + p1_fsm:sync_send_event(PID, {sql_cmd, {sql_query, ?KEEPALIVE_QUERY}, p1_time_compat:monotonic_time(milli_seconds)}, query_timeout(Host)). @@ -280,7 +278,7 @@ init([Host, StartInterval]) -> keep_alive, [Host, self()]) end, [DBType | _] = db_opts(Host), - (?GEN_FSM):send_event(self(), connect), + p1_fsm:send_event(self(), connect), ejabberd_sql_sup:add_pid(Host, self()), QueueType = case ejabberd_config:get_option({sql_queue_type, Host}) of undefined -> @@ -313,7 +311,7 @@ connecting(connect, #state{host = Host} = State) -> PendingRequests = p1_queue:dropwhile( fun(Req) -> - ?GEN_FSM:send_event(self(), Req), + p1_fsm:send_event(self(), Req), true end, State#state.pending_requests), State1 = State#state{db_ref = Ref, @@ -325,7 +323,7 @@ connecting(connect, #state{host = Host} = State) -> "Retry after: ~p seconds", [State#state.db_type, Reason, State#state.start_interval div 1000]), - (?GEN_FSM):send_event_after(State#state.start_interval, + p1_fsm:send_event_after(State#state.start_interval, connect), {next_state, connecting, State} end; @@ -337,7 +335,7 @@ connecting(Event, State) -> connecting({sql_cmd, {sql_query, ?KEEPALIVE_QUERY}, _Timestamp}, From, State) -> - (?GEN_FSM):reply(From, + p1_fsm:reply(From, {error, <<"SQL connection failed">>}), {next_state, connecting, State}; connecting({sql_cmd, Command, Timestamp} = Req, From, @@ -350,7 +348,7 @@ connecting({sql_cmd, Command, Timestamp} = Req, From, catch error:full -> Q = p1_queue:dropwhile( fun({sql_cmd, _, To, _Timestamp}) -> - (?GEN_FSM):reply( + p1_fsm:reply( To, {error, <<"SQL connection failed">>}), true end, State#state.pending_requests), @@ -393,7 +391,7 @@ code_change(_OldVsn, StateName, State, _Extra) -> %% monitoring the connection) handle_info({'DOWN', _MonitorRef, process, _Pid, _Info}, _StateName, State) -> - (?GEN_FSM):send_event(self(), connect), + p1_fsm:send_event(self(), connect), {next_state, connecting, State}; handle_info(Info, StateName, State) -> ?WARNING_MSG("unexpected info in ~p: ~p", @@ -734,16 +732,16 @@ sql_query_to_iolist(SQLQuery) -> abort_on_driver_error({error, <<"query timed out">>} = Reply, From) -> - (?GEN_FSM):reply(From, Reply), + p1_fsm:reply(From, Reply), {stop, timeout, get(?STATE_KEY)}; abort_on_driver_error({error, <<"Failed sending data on socket", _/binary>>} = Reply, From) -> - (?GEN_FSM):reply(From, Reply), + p1_fsm:reply(From, Reply), {stop, closed, get(?STATE_KEY)}; abort_on_driver_error(Reply, From) -> - (?GEN_FSM):reply(From, Reply), + p1_fsm:reply(From, Reply), {next_state, session_established, get(?STATE_KEY)}. %% == pure ODBC code diff --git a/src/eldap.erl b/src/eldap.erl index f47550353..8e6b710b1 100644 --- a/src/eldap.erl +++ b/src/eldap.erl @@ -63,7 +63,7 @@ %%% active_bind - sent bind() request and waiting for response %%%---------------------------------------------------------------------- --behaviour(gen_fsm). +-behaviour(p1_fsm). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -148,7 +148,7 @@ start_link(Name) -> Reg_name = misc:binary_to_atom(<<"eldap_", Name/binary>>), - gen_fsm:start_link({local, Reg_name}, ?MODULE, [], []). + p1_fsm:start_link({local, Reg_name}, ?MODULE, [], []). -spec start_link(binary(), [binary()], inet:port_number(), binary(), binary(), tlsopts()) -> any(). @@ -156,7 +156,7 @@ start_link(Name) -> start_link(Name, Hosts, Port, Rootdn, Passwd, Opts) -> Reg_name = misc:binary_to_atom(<<"eldap_", Name/binary>>), - gen_fsm:start_link({local, Reg_name}, ?MODULE, + p1_fsm:start_link({local, Reg_name}, ?MODULE, [Hosts, Port, Rootdn, Passwd, Opts], []). -spec get_status(handle()) -> any(). @@ -166,7 +166,7 @@ start_link(Name, Hosts, Port, Rootdn, Passwd, Opts) -> %%% -------------------------------------------------------------------- get_status(Handle) -> Handle1 = get_handle(Handle), - gen_fsm:sync_send_all_state_event(Handle1, get_status). + p1_fsm:sync_send_all_state_event(Handle1, get_status). %%% -------------------------------------------------------------------- %%% Shutdown connection (and process) asynchronous. @@ -175,7 +175,7 @@ get_status(Handle) -> close(Handle) -> Handle1 = get_handle(Handle), - gen_fsm:send_all_state_event(Handle1, close). + p1_fsm:send_all_state_event(Handle1, close). %%% -------------------------------------------------------------------- %%% Add an entry. The entry field MUST NOT exist for the AddRequest @@ -192,7 +192,7 @@ close(Handle) -> %%% -------------------------------------------------------------------- add(Handle, Entry, Attributes) -> Handle1 = get_handle(Handle), - gen_fsm:sync_send_event(Handle1, + p1_fsm:sync_send_event(Handle1, {add, Entry, add_attrs(Attributes)}, ?CALL_TIMEOUT). %%% Do sanity check ! @@ -216,7 +216,7 @@ add_attrs(Attrs) -> %%% -------------------------------------------------------------------- delete(Handle, Entry) -> Handle1 = get_handle(Handle), - gen_fsm:sync_send_event(Handle1, {delete, Entry}, + p1_fsm:sync_send_event(Handle1, {delete, Entry}, ?CALL_TIMEOUT). %%% -------------------------------------------------------------------- @@ -234,7 +234,7 @@ delete(Handle, Entry) -> modify(Handle, Object, Mods) -> Handle1 = get_handle(Handle), - gen_fsm:sync_send_event(Handle1, {modify, Object, Mods}, + p1_fsm:sync_send_event(Handle1, {modify, Object, Mods}, ?CALL_TIMEOUT). %%% @@ -274,7 +274,7 @@ m(Operation, Type, Values) -> modify_dn(Handle, Entry, NewRDN, DelOldRDN, NewSup) -> Handle1 = get_handle(Handle), - gen_fsm:sync_send_event(Handle1, + p1_fsm:sync_send_event(Handle1, {modify_dn, Entry, NewRDN, bool_p(DelOldRDN), optional(NewSup)}, ?CALL_TIMEOUT). @@ -283,7 +283,7 @@ modify_dn(Handle, Entry, NewRDN, DelOldRDN, NewSup) -> modify_passwd(Handle, DN, Passwd) -> Handle1 = get_handle(Handle), - gen_fsm:sync_send_event(Handle1, + p1_fsm:sync_send_event(Handle1, {modify_passwd, DN, Passwd}, ?CALL_TIMEOUT). %%% -------------------------------------------------------------------- @@ -298,7 +298,7 @@ modify_passwd(Handle, DN, Passwd) -> bind(Handle, RootDN, Passwd) -> Handle1 = get_handle(Handle), - gen_fsm:sync_send_event(Handle1, {bind, RootDN, Passwd}, + p1_fsm:sync_send_event(Handle1, {bind, RootDN, Passwd}, ?CALL_TIMEOUT). %%% Sanity checks ! @@ -356,7 +356,7 @@ search(Handle, L) when is_list(L) -> call_search(Handle, A) -> Handle1 = get_handle(Handle), - gen_fsm:sync_send_event(Handle1, {search, A}, + p1_fsm:sync_send_event(Handle1, {search, A}, ?CALL_TIMEOUT). -spec parse_search_args(search_args()) -> eldap_search(). @@ -637,7 +637,7 @@ active(Event, From, S) -> %%---------------------------------------------------------------------- %% Func: handle_event/3 -%% Called when gen_fsm:send_all_state_event/2 is invoked. +%% Called when p1_fsm:send_all_state_event/2 is invoked. %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} @@ -680,7 +680,7 @@ handle_info({Tag, _Socket, Data}, StateName, S) case catch recvd_packet(Data, S) of {response, Response, RequestType} -> NewS = case Response of - {reply, Reply, To, S1} -> gen_fsm:reply(To, Reply), S1; + {reply, Reply, To, S1} -> p1_fsm:reply(To, Reply), S1; {ok, S1} -> S1 end, if StateName == active_bind andalso @@ -709,7 +709,7 @@ handle_info({timeout, Timer, {cmd_timeout, Id}}, StateName, S) -> case cmd_timeout(Timer, Id, S) of {reply, To, Reason, NewS} -> - gen_fsm:reply(To, Reason), + p1_fsm:reply(To, Reason), {next_state, StateName, NewS}; {error, _Reason} -> {next_state, StateName, S} end; diff --git a/src/gen_mod.erl b/src/gen_mod.erl index 5bfa3b4d4..e17197dfb 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -34,7 +34,8 @@ stop_child/1, stop_child/2, config_reloaded/0]). -export([start_module/2, start_module/3, 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, loaded_modules/1, loaded_modules_with_opts/1, 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), 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. get_validators(Host, Module, Opts) -> try Module:mod_opt_type('') of diff --git a/src/mod_echo.erl b/src/mod_echo.erl index 861b1a0ef..79dd59962 100644 --- a/src/mod_echo.erl +++ b/src/mod_echo.erl @@ -43,7 +43,7 @@ -include("xmpp.hrl"). --record(state, {host = <<"">> :: binary()}). +-record(state, {hosts = [] :: [binary()]}). %%==================================================================== %% gen_mod API @@ -62,7 +62,9 @@ depends(_Host, _Opts) -> []. 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 @@ -77,10 +79,13 @@ mod_opt_type(_) -> [host]. %%-------------------------------------------------------------------- init([Host, Opts]) -> process_flag(trap_exit, true), - MyHost = gen_mod:get_opt_host(Host, Opts, + Hosts = gen_mod:get_opt_hosts(Host, Opts, <<"echo.@HOST@">>), - ejabberd_router:register_route(MyHost, Host), - {ok, #state{host = MyHost}}. + lists:foreach( + fun(H) -> + ejabberd_router:register_route(H, Host) + end, Hosts), + {ok, #state{hosts = Hosts}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | @@ -101,17 +106,19 @@ handle_call(stop, _From, State) -> %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast({reload, Host, NewOpts, OldOpts}, State) -> - NewMyHost = gen_mod:get_opt_host(Host, NewOpts, - <<"echo.@HOST@">>), - OldMyHost = gen_mod:get_opt_host(Host, OldOpts, - <<"echo.@HOST@">>), - if NewMyHost /= OldMyHost -> - ejabberd_router:register_route(NewMyHost, Host), - ejabberd_router:unregister_route(OldMyHost); - true -> - ok - end, - {noreply, State#state{host = NewMyHost}}; + NewMyHosts = gen_mod:get_opt_hosts(Host, NewOpts, + <<"echo.@HOST@">>), + OldMyHosts = gen_mod:get_opt_hosts(Host, OldOpts, + <<"echo.@HOST@">>), + lists:foreach( + fun(H) -> + ejabberd_router:unregister_route(H) + end, OldMyHosts -- NewMyHosts), + lists:foreach( + fun(H) -> + ejabberd_router:register_route(H, Host) + end, NewMyHosts -- OldMyHosts), + {noreply, State#state{hosts = NewMyHosts}}; handle_cast(Msg, State) -> ?WARNING_MSG("unexpected cast: ~p", [Msg]), {noreply, State}. @@ -147,7 +154,7 @@ handle_info(_Info, State) -> {noreply, State}. %% The return value is ignored. %%-------------------------------------------------------------------- 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} diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index c8cd300f4..6d981e9ec 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -94,7 +94,7 @@ -record(state, {server_host :: binary(), - host :: binary(), + hosts :: [binary()], name :: binary(), access :: atom(), max_size :: pos_integer() | infinity, @@ -151,6 +151,8 @@ stop(ServerHost) -> 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(name) -> fun iolist_to_binary/1; mod_opt_type(access) -> @@ -194,7 +196,7 @@ mod_opt_type(rm_on_unregister) -> mod_opt_type(thumbnail) -> fun(B) when is_boolean(B) -> B end; 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, rm_on_unregister, thumbnail]. @@ -211,7 +213,7 @@ depends(_Host, _Opts) -> init([ServerHost, Opts]) -> 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">>), Access = gen_mod:get_opt(access, Opts, local), MaxSize = gen_mod:get_opt(max_size, Opts, 104857600), @@ -244,8 +246,11 @@ init([ServerHost, Opts]) -> false -> ok end, - ejabberd_router:register_route(Host, ServerHost), - {ok, #state{server_host = ServerHost, host = Host, name = Name, + lists:foreach( + fun(Host) -> + ejabberd_router:register_route(Host, ServerHost) + end, Hosts), + {ok, #state{server_host = ServerHost, hosts = Hosts, name = Name, access = Access, max_size = MaxSize, secret_length = SecretLength, jid_in_url = JIDinURL, file_mode = FileMode, dir_mode = DirMode, @@ -324,10 +329,9 @@ handle_info(Info, State) -> -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]), - ejabberd_router:unregister_route(Host), - ok. + lists:foreach(fun ejabberd_router:unregister_route/1, Hosts). -spec code_change({down, _} | _, state(), _) -> {ok, state()}. diff --git a/src/mod_irc.erl b/src/mod_irc.erl index fc85668e8..04687ea67 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -58,7 +58,7 @@ [<<"koi8-r">>, <<"iso8859-15">>, <<"iso8859-1">>, <<"iso8859-2">>, <<"utf-8">>, <<"utf-8+latin-1">>]). --record(state, {host = <<"">> :: binary(), +-record(state, {hosts = [] :: [binary()], server_host = <<"">> :: binary(), access = all :: atom()}). @@ -99,8 +99,7 @@ depends(_Host, _Opts) -> init([Host, Opts]) -> process_flag(trap_exit, true), ejabberd:start_app(iconv), - MyHost = gen_mod:get_opt_host(Host, Opts, - <<"irc.@HOST@">>), + MyHosts = gen_mod:get_opt_hosts(Host, Opts, <<"irc.@HOST@">>), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), Access = gen_mod:get_opt(access, Opts, all), @@ -108,10 +107,13 @@ init([Host, Opts]) -> [named_table, public, {keypos, #irc_connection.jid_server_host}]), IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), - register_hooks(MyHost, IQDisc), - ejabberd_router:register_route(MyHost, Host), + lists:foreach( + fun(MyHost) -> + register_hooks(MyHost, IQDisc), + ejabberd_router:register_route(MyHost, Host) + end, MyHosts), {ok, - #state{host = MyHost, server_host = Host, + #state{hosts = MyHosts, server_host = Host, access = Access}}. %%-------------------------------------------------------------------- @@ -133,8 +135,8 @@ handle_call(stop, _From, State) -> %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) -> - NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"irc.@HOST@">>), - OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"irc.@HOST@">>), + NewHosts = gen_mod:get_opt_hosts(ServerHost, NewOpts, <<"irc.@HOST@">>), + OldHosts = gen_mod:get_opt_hosts(ServerHost, OldOpts, <<"irc.@HOST@">>), NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, 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), @@ -145,20 +147,26 @@ handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) -> true -> ok end, - if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) -> - register_hooks(NewHost, NewIQDisc); - true -> - ok - end, - if NewHost /= OldHost -> - ejabberd_router:register_route(NewHost, ServerHost), - ejabberd_router:unregister_route(OldHost), - unregister_hooks(OldHost); + if (NewIQDisc /= OldIQDisc) -> + lists:foreach( + fun(NewHost) -> + register_hooks(NewHost, NewIQDisc) + end, NewHosts -- (NewHosts -- OldHosts)); true -> ok 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), - {noreply, State#state{host = NewHost, access = Access}}; + {noreply, State#state{hosts = NewHosts, access = Access}}; handle_cast(Msg, State) -> ?WARNING_MSG("unexpected cast: ~p", [Msg]), {noreply, State}. @@ -170,9 +178,10 @@ handle_cast(Msg, State) -> %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({route, Packet}, - #state{host = Host, server_host = ServerHost, - access = Access} = + #state{server_host = ServerHost, access = Access} = State) -> + To = xmpp:get_to(Packet), + Host = To#jid.lserver, case catch do_route(Host, ServerHost, Access, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok @@ -187,9 +196,12 @@ handle_info(_Info, State) -> {noreply, State}. %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- -terminate(_Reason, #state{host = MyHost}) -> - ejabberd_router:unregister_route(MyHost), - unregister_hooks(MyHost). +terminate(_Reason, #state{hosts = MyHosts}) -> + lists:foreach( + fun(MyHost) -> + ejabberd_router:unregister_route(MyHost), + unregister_hooks(MyHost) + end, MyHosts). %%-------------------------------------------------------------------- %% 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) -> 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(_) -> - [access, db_type, default_encoding, host]. + [access, db_type, default_encoding, host, hosts]. -spec extract_ident(stanza()) -> binary(). extract_ident(Packet) -> diff --git a/src/mod_irc_connection.erl b/src/mod_irc_connection.erl index 1e90c4005..b7b2f8e1d 100644 --- a/src/mod_irc_connection.erl +++ b/src/mod_irc_connection.erl @@ -27,7 +27,7 @@ -author('alexey@process-one.net'). --behaviour(gen_fsm). +-behaviour(p1_fsm). %% External exports -export([start_link/12, start/13, route_chan/4, @@ -91,7 +91,7 @@ start(From, Host, ServerHost, Server, Username, start_link(From, Host, Server, Username, Encoding, Port, Password, Ident, RemoteAddr, RealName, WebircPassword, Mod) -> - gen_fsm:start_link(?MODULE, + p1_fsm:start_link(?MODULE, [From, Host, Server, Username, Encoding, Port, Password, Ident, RemoteAddr, RealName, WebircPassword, Mod], ?FSMOPTS). @@ -109,7 +109,7 @@ start_link(From, Host, Server, Username, Encoding, Port, %%---------------------------------------------------------------------- init([From, Host, Server, Username, Encoding, Port, Password, Ident, RemoteAddr, RealName, WebircPassword, Mod]) -> - gen_fsm:send_event(self(), init), + p1_fsm:send_event(self(), init), {ok, open_socket, #state{mod = Mod, encoding = Encoding, port = Port, password = Password, @@ -628,11 +628,11 @@ handle_info({tcp, _Socket, Data}, StateName, StateData#state{inbuf = NewBuf}}; handle_info({tcp_closed, _Socket}, StateName, StateData) -> - gen_fsm:send_event(self(), closed), + p1_fsm:send_event(self(), closed), {next_state, StateName, StateData}; handle_info({tcp_error, _Socket, _Reason}, StateName, StateData) -> - gen_fsm:send_event(self(), closed), + p1_fsm:send_event(self(), closed), {next_state, StateName, StateData}. %%---------------------------------------------------------------------- diff --git a/src/mod_mix.erl b/src/mod_mix.erl index 4763447f3..90507665b 100644 --- a/src/mod_mix.erl +++ b/src/mod_mix.erl @@ -46,7 +46,7 @@ ?NS_MIX_NODES_CONFIG]). -record(state, {server_host :: binary(), - host :: binary()}). + hosts :: [binary()]}). %%%=================================================================== %%% API @@ -124,36 +124,39 @@ process_iq(#iq{lang = Lang} = IQ) -> %%%=================================================================== init([ServerHost, Opts]) -> process_flag(trap_exit, true), - Host = gen_mod:get_opt_host(ServerHost, Opts, <<"mix.@HOST@">>), - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), - ConfigTab = gen_mod:get_module_proc(Host, config), - ets:new(ConfigTab, [named_table]), - ets:insert(ConfigTab, {plugins, [<<"mix">>]}), - ejabberd_hooks:add(disco_local_items, Host, ?MODULE, disco_items, 100), - ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 100), - ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 100), - ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, disco_items, 100), - ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, disco_features, 100), - ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, disco_identity, 100), - ejabberd_hooks:add(disco_info, Host, ?MODULE, disco_info, 100), - gen_iq_handler:add_iq_handler(ejabberd_local, Host, - ?NS_DISCO_ITEMS, mod_disco, - process_local_iq_items, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_local, Host, - ?NS_DISCO_INFO, mod_disco, - process_local_iq_info, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, - ?NS_DISCO_ITEMS, mod_disco, - process_local_iq_items, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, - ?NS_DISCO_INFO, mod_disco, - process_local_iq_info, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, - ?NS_PUBSUB, mod_pubsub, iq_sm, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, - ?NS_MIX_0, ?MODULE, process_iq, IQDisc), - ejabberd_router:register_route(Host, ServerHost), - {ok, #state{server_host = ServerHost, host = Host}}. + Hosts = gen_mod:get_opt_hosts(ServerHost, Opts, <<"mix.@HOST@">>), + IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(ServerHost)), + lists:foreach( + fun(Host) -> + ConfigTab = gen_mod:get_module_proc(Host, config), + ets:new(ConfigTab, [named_table]), + ets:insert(ConfigTab, {plugins, [<<"mix">>]}), + ejabberd_hooks:add(disco_local_items, Host, ?MODULE, disco_items, 100), + ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 100), + ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 100), + ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, disco_items, 100), + ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, disco_features, 100), + ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, disco_identity, 100), + ejabberd_hooks:add(disco_info, Host, ?MODULE, disco_info, 100), + gen_iq_handler:add_iq_handler(ejabberd_local, Host, + ?NS_DISCO_ITEMS, mod_disco, + process_local_iq_items, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, Host, + ?NS_DISCO_INFO, mod_disco, + process_local_iq_info, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_sm, Host, + ?NS_DISCO_ITEMS, mod_disco, + process_local_iq_items, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_sm, Host, + ?NS_DISCO_INFO, mod_disco, + process_local_iq_info, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_sm, Host, + ?NS_PUBSUB, mod_pubsub, iq_sm, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_sm, 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) -> Reply = ok, @@ -180,22 +183,24 @@ handle_info({route, Packet}, State) -> handle_info(_Info, State) -> {noreply, State}. -terminate(_Reason, #state{host = Host}) -> - ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 100), - ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 100), - ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 100), - ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, disco_items, 100), - ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, disco_features, 100), - ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, disco_identity, 100), - ejabberd_hooks:delete(disco_info, Host, ?MODULE, disco_info, 100), - gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS), - gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO), - gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS), - gen_iq_handler:remove_iq_handler(ejabberd_sm, 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_MIX_0), - ejabberd_router:unregister_route(Host), - ok. +terminate(_Reason, #state{hosts = Hosts}) -> + lists:foreach( + fun(Host) -> + ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 100), + ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 100), + ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 100), + ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, disco_items, 100), + ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, disco_features, 100), + ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, disco_identity, 100), + ejabberd_hooks:delete(disco_info, Host, ?MODULE, disco_info, 100), + gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS), + gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO), + gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS), + gen_iq_handler:remove_iq_handler(ejabberd_sm, 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_MIX_0), + ejabberd_router:unregister_route(Host) + end, Hosts). code_change(_OldVsn, State, _Extra) -> {ok, State}. @@ -316,4 +321,6 @@ depends(_Host, _Opts) -> mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/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]. diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 8b6d7b8b9..db101e4f6 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -75,7 +75,7 @@ -include("mod_muc.hrl"). -record(state, - {host = <<"">> :: binary(), + {hosts = [] :: [binary()], server_host = <<"">> :: binary(), access = {none, none, none, none} :: {atom(), atom(), atom(), atom()}, 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. %% Else use the passed options as defined in mod_muc_room. create_room(Host, Name, From, Nick, Opts) -> - Proc = gen_mod:get_module_proc(Host, ?MODULE), - gen_server:call(Proc, {create, Name, From, Nick, Opts}). + ServerHost = ejabberd_router:host_of_route(Host), + Proc = gen_mod:get_module_proc(ServerHost, ?MODULE), + gen_server:call(Proc, {create, Name, Host, From, Nick, Opts}). store_room(ServerHost, Host, Name, Opts) -> LServer = jid:nameprep(ServerHost), @@ -225,22 +226,26 @@ get_online_rooms_by_user(ServerHost, LUser, LServer) -> init([Host, Opts]) -> process_flag(trap_exit, true), 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, room_shaper = RoomShaper} = State = init_state(Host, Opts), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), RMod = gen_mod:ram_db_mod(Host, Opts, ?MODULE), - Mod:init(Host, [{host, MyHost}|Opts]), - RMod:init(Host, [{host, MyHost}|Opts]), - register_iq_handlers(MyHost, IQDisc), - ejabberd_router:register_route(MyHost, Host), - load_permanent_rooms(MyHost, Host, Access, HistorySize, RoomShaper, QueueType), + Mod:init(Host, [{hosts, MyHosts}|Opts]), + RMod:init(Host, [{hosts, MyHosts}|Opts]), + lists:foreach( + fun(MyHost) -> + register_iq_handlers(MyHost, IQDisc), + ejabberd_router:register_route(MyHost, Host), + load_permanent_rooms(MyHost, Host, Access, HistorySize, + RoomShaper, QueueType) + end, MyHosts), {ok, State}. handle_call(stop, _From, State) -> {stop, normal, ok, State}; -handle_call({create, Room, From, Nick, Opts}, _From, - #state{host = Host, server_host = ServerHost, +handle_call({create, Room, Host, From, Nick, Opts}, _From, + #state{server_host = ServerHost, access = Access, default_room_opts = DefOpts, history_size = HistorySize, queue_type = QueueType, 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]), {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)), OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, gen_iq_handler:iqdisc(ServerHost)), NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE), NewRMod = gen_mod:ram_db_mod(ServerHost, NewOpts, ?MODULE), OldMod = gen_mod: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 -> - NewMod:init(ServerHost, [{host, NewHost}|NewOpts]); + NewMod:init(ServerHost, [{hosts, NewHosts}|NewOpts]); true -> ok end, if NewRMod /= OldRMod -> - NewRMod:init(ServerHost, [{host, NewHost}|NewOpts]); - true -> - ok - end, - if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) -> - register_iq_handlers(NewHost, NewIQDisc); + NewRMod:init(ServerHost, [{hosts, NewHosts}|NewOpts]); true -> ok end, - if NewHost /= OldHost -> - ejabberd_router:register_route(NewHost, ServerHost), - ejabberd_router:unregister_route(OldHost), - unregister_iq_handlers(OldHost); + if (NewIQDisc /= OldIQDisc) -> + lists:foreach( + fun(NewHost) -> + register_iq_handlers(NewHost, NewIQDisc) + end, NewHosts -- (NewHosts -- OldHosts)); true -> ok 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}; handle_cast(Msg, State) -> ?WARNING_MSG("unexpected cast: ~p", [Msg]), {noreply, State}. handle_info({route, Packet}, - #state{host = Host, server_host = ServerHost, + #state{server_host = ServerHost, access = Access, default_room_opts = DefRoomOpts, history_size = HistorySize, queue_type = QueueType, max_rooms_discoitems = MaxRoomsDiscoItems, room_shaper = RoomShaper} = State) -> From = xmpp:get_from(Packet), To = xmpp:get_to(Packet), + Host = To#jid.lserver, case catch do_route(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts, MaxRoomsDiscoItems, QueueType) of @@ -320,9 +332,12 @@ handle_info(Info, State) -> ?ERROR_MSG("unexpected info: ~p", [Info]), {noreply, State}. -terminate(_Reason, #state{host = MyHost}) -> - ejabberd_router:unregister_route(MyHost), - unregister_iq_handlers(MyHost). +terminate(_Reason, #state{hosts = MyHosts}) -> + lists:foreach( + fun(MyHost) -> + ejabberd_router:unregister_route(MyHost), + unregister_iq_handlers(MyHost) + end, MyHosts). code_change(_OldVsn, State, _Extra) -> {ok, State}. @@ -330,8 +345,8 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %%% Internal functions %%-------------------------------------------------------------------- init_state(Host, Opts) -> - MyHost = gen_mod:get_opt_host(Host, Opts, - <<"conference.@HOST@">>), + MyHosts = gen_mod:get_opt_hosts(Host, Opts, + <<"conference.@HOST@">>), Access = gen_mod:get_opt(access, Opts, all), AccessCreate = gen_mod:get_opt(access_create, Opts, all), 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, ejabberd_config:default_queue_type(Host)), RoomShaper = gen_mod:get_opt(room_shaper, Opts, none), - #state{host = MyHost, + #state{hosts = MyHosts, server_host = Host, access = {Access, AccessCreate, AccessAdmin, AccessPersistent}, default_room_opts = DefRoomOpts, @@ -668,7 +683,7 @@ iq_disco_items(_ServerHost, _Host, _From, Lang, _MaxRoomsDiscoItems, _Node, _RSM {error, timeout | notfound}. get_room_disco_item({Name, Host, Pid}, Query) -> RoomJID = jid:make(Name, Host), - try gen_fsm:sync_send_all_state_event(Pid, Query, 100) of + try p1_fsm:sync_send_all_state_event(Pid, Query, 100) of {item, Desc} -> {ok, #disco_item{jid = RoomJID, name = Desc}}; false -> @@ -684,7 +699,7 @@ get_subscribed_rooms(ServerHost, Host, From) -> BareFrom = jid:remove_resource(From), lists:flatmap( fun({Name, _, Pid}) -> - case gen_fsm:sync_send_all_state_event(Pid, {is_subscribed, BareFrom}) of + case p1_fsm:sync_send_all_state_event(Pid, {is_subscribed, BareFrom}) of true -> [jid:make(Name, Host)]; false -> [] end; @@ -766,7 +781,7 @@ process_iq_register_set(ServerHost, Host, From, broadcast_service_message(ServerHost, Host, Msg) -> lists:foreach( fun({_, _, Pid}) -> - gen_fsm:send_all_state_event( + p1_fsm:send_all_state_event( Pid, {service_message, Msg}) end, get_online_rooms(ServerHost, Host)). @@ -851,6 +866,8 @@ mod_opt_type(ram_db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(history_size) -> fun (I) when is_integer(I), I >= 0 -> I end; 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) -> fun (infinity) -> infinity; (I) when is_integer(I), I > 0 -> I @@ -944,7 +961,7 @@ mod_opt_type({default_room_options, presence_broadcast}) -> end; mod_opt_type(_) -> [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_rooms_discoitems, max_user_conferences, max_users, max_users_admin_threshold, max_users_presence, diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 2d1e66ba5..332c83b55 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -597,7 +597,7 @@ muc_create_room(ServerHost, {Name, Host, _}, DefRoomOpts) -> destroy_room(Name, Service) -> case mod_muc:find_online_room(Name, Service) of {ok, Pid} -> - gen_fsm:send_all_state_event(Pid, destroy), + p1_fsm:send_all_state_event(Pid, destroy), ok; error -> error @@ -716,11 +716,11 @@ get_rooms(ServerHost) -> end, Hosts). get_room_config(Room_pid) -> - {ok, R} = gen_fsm:sync_send_all_state_event(Room_pid, get_config), + {ok, R} = p1_fsm:sync_send_all_state_event(Room_pid, get_config), R. get_room_state(Room_pid) -> - {ok, R} = gen_fsm:sync_send_all_state_event(Room_pid, get_state), + {ok, R} = p1_fsm:sync_send_all_state_event(Room_pid, get_state), R. %%--------------- @@ -786,7 +786,7 @@ find_serverhost(Host, ServerHosts) -> ServerHost. act_on_room(destroy, {N, H, Pid}, SH) -> - gen_fsm:send_all_state_event( + p1_fsm:send_all_state_event( Pid, {destroy, <<"Room destroyed by rooms_unused_destroy.">>}), mod_muc:room_destroyed(H, N, Pid, SH), mod_muc:forget_room(SH, H, N); @@ -888,7 +888,7 @@ change_room_option(Name, Service, OptionString, ValueString) -> {Option, Value} = format_room_option(OptionString, ValueString), Config = get_room_config(Pid), Config2 = change_option(Option, Value, Config), - {ok, _} = gen_fsm:sync_send_all_state_event(Pid, {change_config, Config2}), + {ok, _} = p1_fsm:sync_send_all_state_event(Pid, {change_config, Config2}), ok end. @@ -983,7 +983,7 @@ get_room_affiliations(Name, Service) -> case mod_muc:find_online_room(Name, Service) of {ok, Pid} -> %% Get the PID of the online room, then request its state - {ok, StateData} = gen_fsm:sync_send_all_state_event(Pid, get_state), + {ok, StateData} = p1_fsm:sync_send_all_state_event(Pid, get_state), Affiliations = ?DICT:to_list(StateData#state.affiliations), lists:map( fun({{Uname, Domain, _Res}, {Aff, Reason}}) when is_atom(Aff)-> @@ -1012,7 +1012,7 @@ set_room_affiliation(Name, Service, JID, AffiliationString) -> case mod_muc:find_online_room(Name, Service) of {ok, Pid} -> %% Get the PID for the online room so we can get the state of the room - {ok, StateData} = gen_fsm:sync_send_all_state_event(Pid, {process_item_change, {jid:decode(JID), affiliation, Affiliation, <<"">>}, undefined}), + {ok, StateData} = p1_fsm:sync_send_all_state_event(Pid, {process_item_change, {jid:decode(JID), affiliation, Affiliation, <<"">>}, undefined}), mod_muc:store_room(StateData#state.server_host, StateData#state.host, StateData#state.room, make_opts(StateData)), ok; error -> @@ -1035,7 +1035,7 @@ subscribe_room(User, Nick, Room, Nodes) -> UserJID -> case get_room_pid(Name, Host) of Pid when is_pid(Pid) -> - case gen_fsm:sync_send_all_state_event( + case p1_fsm:sync_send_all_state_event( Pid, {muc_subscribe, UserJID, Nick, NodeList}) of {ok, SubscribedNodes} -> @@ -1062,7 +1062,7 @@ unsubscribe_room(User, Room) -> UserJID -> case get_room_pid(Name, Host) of Pid when is_pid(Pid) -> - case gen_fsm:sync_send_all_state_event( + case p1_fsm:sync_send_all_state_event( Pid, {muc_unsubscribe, UserJID}) of ok -> @@ -1085,7 +1085,7 @@ unsubscribe_room(User, Room) -> get_subscribers(Name, Host) -> case get_room_pid(Name, Host) of Pid when is_pid(Pid) -> - {ok, JIDList} = gen_fsm:sync_send_all_state_event(Pid, get_subscribers), + {ok, JIDList} = p1_fsm:sync_send_all_state_event(Pid, get_subscribers), [jid:encode(jid:remove_resource(J)) || J <- JIDList]; _ -> throw({error, "The room does not exist"}) diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl index 3d4c87c0f..61101d1c2 100644 --- a/src/mod_muc_log.erl +++ b/src/mod_muc_log.erl @@ -1142,7 +1142,7 @@ get_room_state(RoomName, MucService) -> -spec get_room_state(pid()) -> mod_muc_room:state(). get_room_state(RoomPid) -> - {ok, R} = gen_fsm:sync_send_all_state_event(RoomPid, + {ok, R} = p1_fsm:sync_send_all_state_event(RoomPid, get_state), R. diff --git a/src/mod_muc_mnesia.erl b/src/mod_muc_mnesia.erl index 53f31cb9f..015c5ec43 100644 --- a/src/mod_muc_mnesia.erl +++ b/src/mod_muc_mnesia.erl @@ -296,7 +296,7 @@ import(_LServer, <<"muc_registered">>, %%% gen_server callbacks %%%=================================================================== 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 ?MODULE -> ejabberd_mnesia:create(?MODULE, muc_room, @@ -318,7 +318,10 @@ init([Host, Opts]) -> {type, ordered_set}, {attributes, record_info(fields, muc_online_room)}]), 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); _ -> ok diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 31dbbbfa7..2a1ca6011 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -27,7 +27,7 @@ -author('alexey@process-one.net'). --behaviour(gen_fsm). +-behaviour(p1_fsm). %% External exports -export([start_link/10, @@ -94,23 +94,23 @@ %%%---------------------------------------------------------------------- start(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, Nick, DefRoomOpts, QueueType) -> - gen_fsm:start(?MODULE, [Host, ServerHost, Access, Room, HistorySize, + p1_fsm:start(?MODULE, [Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, Nick, DefRoomOpts, QueueType], ?FSMOPTS). start(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, QueueType) -> - gen_fsm:start(?MODULE, [Host, ServerHost, Access, Room, HistorySize, + p1_fsm:start(?MODULE, [Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, QueueType], ?FSMOPTS). start_link(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, Nick, DefRoomOpts, QueueType) -> - gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, + p1_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, Nick, DefRoomOpts, QueueType], ?FSMOPTS). start_link(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, QueueType) -> - gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, + p1_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, QueueType], ?FSMOPTS). @@ -703,7 +703,7 @@ terminate(Reason, _StateName, StateData) -> -spec route(pid(), stanza()) -> ok. route(Pid, Packet) -> #jid{lresource = Nick} = xmpp:get_to(Packet), - gen_fsm:send_event(Pid, {route, Nick, Packet}). + p1_fsm:send_event(Pid, {route, Nick, Packet}). -spec process_groupchat_message(message(), state()) -> fsm_next(). process_groupchat_message(#message{from = From, lang = Lang} = Packet, StateData) -> diff --git a/src/mod_proxy65.erl b/src/mod_proxy65.erl index aee324960..671baef9a 100644 --- a/src/mod_proxy65.erl +++ b/src/mod_proxy65.erl @@ -112,6 +112,8 @@ depends(_Host, _Opts) -> mod_opt_type(access) -> fun acl:access_rules_validator/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(ip) -> fun (S) -> @@ -131,7 +133,7 @@ mod_opt_type(ram_db_type) -> mod_opt_type(Opt) -> case mod_proxy65_stream:listen_opt_type(Opt) of Opts when is_list(Opts) -> - [access, host, hostname, ip, name, port, + [access, host, hosts, hostname, ip, name, port, max_connections, ram_db_type] ++ Opts; Fun -> Fun diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl index b27f3bc20..aaece980a 100644 --- a/src/mod_proxy65_service.erl +++ b/src/mod_proxy65_service.erl @@ -43,7 +43,7 @@ -define(PROCNAME, ejabberd_mod_proxy65_service). --record(state, {myhost = <<"">> :: binary()}). +-record(state, {myhosts = [] :: [binary()]}). %%%------------------------ %%% gen_server callbacks @@ -61,24 +61,27 @@ reload(Host, NewOpts, OldOpts) -> init([Host, Opts]) -> process_flag(trap_exit, true), IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), - MyHost = gen_mod:get_opt_host(Host, Opts, <<"proxy.@HOST@">>), - gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO, - ?MODULE, process_disco_info, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS, - ?MODULE, process_disco_items, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_VCARD, - ?MODULE, process_vcard, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS, - ?MODULE, process_bytestreams, IQDisc), - ejabberd_router:register_route(MyHost, Host), - {ok, #state{myhost = MyHost}}. + MyHosts = gen_mod:get_opt_hosts(Host, Opts, <<"proxy.@HOST@">>), + lists:foreach( + fun(MyHost) -> + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO, + ?MODULE, process_disco_info, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS, + ?MODULE, process_disco_items, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_VCARD, + ?MODULE, process_vcard, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS, + ?MODULE, process_bytestreams, IQDisc), + ejabberd_router:register_route(MyHost, Host) + end, MyHosts), + {ok, #state{myhosts = MyHosts}}. -terminate(_Reason, #state{myhost = MyHost}) -> - ejabberd_router:unregister_route(MyHost), - gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO), - gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS), - gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_VCARD), - gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS). +terminate(_Reason, #state{myhosts = MyHosts}) -> + lists:foreach( + fun(MyHost) -> + ejabberd_router:unregister_route(MyHost), + unregister_handlers(MyHost) + end, MyHosts). handle_info({route, #iq{} = Packet}, State) -> ejabberd_router:process_iq(Packet), @@ -89,33 +92,29 @@ handle_call(_Request, _From, State) -> {reply, ok, State}. handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) -> - NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"proxy.@HOST@">>), - OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"proxy.@HOST@">>), + NewHosts = gen_mod:get_opt_hosts(ServerHost, NewOpts, <<"proxy.@HOST@">>), + OldHosts = gen_mod:get_opt_hosts(ServerHost, OldOpts, <<"proxy.@HOST@">>), NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, gen_iq_handler:iqdisc(ServerHost)), OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, gen_iq_handler:iqdisc(ServerHost)), - if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) -> - gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_DISCO_INFO, - ?MODULE, process_disco_info, NewIQDisc), - gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_DISCO_ITEMS, - ?MODULE, process_disco_items, NewIQDisc), - 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 -> - ok - end, - if NewHost /= OldHost -> - ejabberd_router:register_route(NewHost, ServerHost), - ejabberd_router:unregister_route(OldHost), - gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_DISCO_INFO), - gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_DISCO_ITEMS), - gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_VCARD), - gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_BYTESTREAMS); + if (NewIQDisc /= OldIQDisc) -> + lists:foreach( + fun(NewHost) -> + register_handlers(NewHost, NewIQDisc) + end, NewHosts -- (NewHosts -- OldHosts)); true -> ok end, - {noreply, State#state{myhost = NewHost}}; + lists:foreach( + fun(NewHost) -> + ejabberd_router:register_route(NewHost, ServerHost), + register_handlers(NewHost, NewIQDisc) + end, NewHosts -- OldHosts), + lists:foreach( + fun(OldHost) -> + ejabberd_router:unregister_route(OldHost), + unregister_handlers(OldHost) + end, OldHosts -- NewHosts), + {noreply, State#state{myhosts = NewHosts}}; handle_cast(Msg, State) -> ?WARNING_MSG("unexpected cast: ~p", [Msg]), {noreply, State}. @@ -276,3 +275,19 @@ get_my_ip() -> max_connections(ServerHost) -> 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). diff --git a/src/mod_proxy65_stream.erl b/src/mod_proxy65_stream.erl index 899b66727..1fa6ff804 100644 --- a/src/mod_proxy65_stream.erl +++ b/src/mod_proxy65_stream.erl @@ -26,7 +26,7 @@ -author('xram@jabber.ru'). --behaviour(gen_fsm). +-behaviour(p1_fsm). %% gen_fsm callbacks. -export([init/1, handle_event/3, handle_sync_event/4, @@ -75,7 +75,7 @@ start({gen_tcp, Socket}, Opts1) -> [Socket, Host, Opts]). start_link(Socket, Host, Opts) -> - gen_fsm:start_link(?MODULE, [Socket, Host, Opts], []). + p1_fsm:start_link(?MODULE, [Socket, Host, Opts], []). init([Socket, Host, Opts]) -> process_flag(trap_exit, true), @@ -106,9 +106,9 @@ socket_type() -> raw. stop(StreamPid) -> StreamPid ! stop. activate({P1, J1}, {P2, J2}) -> - case catch {gen_fsm:sync_send_all_state_event(P1, + case catch {p1_fsm:sync_send_all_state_event(P1, get_socket), - gen_fsm:sync_send_all_state_event(P2, get_socket)} + p1_fsm:sync_send_all_state_event(P2, get_socket)} of {S1, S2} when is_port(S1), is_port(S2) -> P1 ! {activate, P2, S2, J1, J2}, @@ -197,7 +197,7 @@ handle_info({tcp, _S, Data}, StateName, StateData) when StateName /= wait_for_activation -> erlang:cancel_timer(StateData#state.timer), TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop), - gen_fsm:send_event(self(), Data), + p1_fsm:send_event(self(), Data), {next_state, StateName, StateData#state{timer = TRef}}; %% Activation message. handle_info({activate, PeerPid, PeerSocket, IJid, TJid}, diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index d682eb5f3..0ae68b24b 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -189,7 +189,7 @@ -record(state, { server_host, - host, + hosts, access, pep_mapping = [], ignore_pep_from_offline = true, @@ -205,7 +205,7 @@ -type(state() :: #state{ server_host :: binary(), - host :: mod_pubsub:hostPubsub(), + hosts :: [mod_pubsub:hostPubsub()], access :: atom(), pep_mapping :: [{binary(), binary()}], ignore_pep_from_offline :: boolean(), @@ -243,42 +243,63 @@ stop(Host) -> init([ServerHost, Opts]) -> process_flag(trap_exit, true), ?DEBUG("pubsub init ~p ~p", [ServerHost, Opts]), - Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>), - ejabberd_router:register_route(Host, ServerHost), + Hosts = gen_mod:get_opt_hosts(ServerHost, Opts, <<"pubsub.@HOST@">>), Access = gen_mod:get_opt(access_createnode, Opts, all), 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), MaxItemsNode = gen_mod:get_opt(max_items_node, Opts, ?MAXITEMS), 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, - [{ram_copies, [node()]}, - {attributes, record_info(fields, pubsub_last_item)}]), - lists:foreach( - fun(H) -> - T = gen_mod:get_module_proc(H, config), - 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}) - end, [Host, ServerHost]), + [{ram_copies, [node()]}, + {attributes, record_info(fields, pubsub_last_item)}]), + AllPlugins = + lists:flatmap( + fun(Host) -> + ejabberd_router:register_route(Host, ServerHost), + 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), + 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, ?MODULE, on_user_offline, 75), ejabberd_hooks:add(disco_local_identity, ServerHost, @@ -297,19 +318,7 @@ init([ServerHost, Opts]) -> ?MODULE, remove_user, 50), ejabberd_hooks:add(c2s_handle_info, ServerHost, ?MODULE, c2s_handle_info, 50), - 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), - case lists:member(?PEPNODE, Plugins) of + case lists:member(?PEPNODE, AllPlugins) of true -> ejabberd_hooks:add(caps_add, ServerHost, ?MODULE, caps_add, 80), @@ -328,20 +337,19 @@ init([ServerHost, Opts]) -> false -> ok end, - {_, State} = init_send_loop(ServerHost), + {_, State} = init_send_loop(ServerHost, Hosts), {ok, State}. -init_send_loop(ServerHost) -> +init_send_loop(ServerHost, Hosts) -> NodeTree = config(ServerHost, nodetree), Plugins = config(ServerHost, plugins), LastItemCache = config(ServerHost, last_item_cache), MaxItemsNode = config(ServerHost, max_items_node), PepMapping = config(ServerHost, pep_mapping), PepOffline = config(ServerHost, ignore_pep_from_offline), - Host = config(ServerHost, host), Access = config(ServerHost, access), 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, ignore_pep_from_offline = PepOffline, last_item_cache = LastItemCache, @@ -419,7 +427,7 @@ get_subscribed(User, Server) -> send_loop(State) -> receive {presence, JID, _Pid} -> - Host = State#state.host, + Host = State#state.server_host, ServerHost = State#state.server_host, DBType = State#state.db_type, LJID = jid:tolower(JID), @@ -461,7 +469,7 @@ send_loop(State) -> send_loop(State); {presence, User, Server, Resources, JID} -> spawn(fun() -> - Host = State#state.host, + Host = State#state.server_host, Owner = jid:remove_resource(jid:tolower(JID)), 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 @@ -689,11 +697,7 @@ presence_probe(_From, _To, _Pid) -> ok. presence(ServerHost, Presence) -> - {SendLoop, _} = case whereis(gen_mod:get_module_proc(ServerHost, ?LOOPNAME)) of - undefined -> init_send_loop(ServerHost); - Pid -> {Pid, undefined} - end, - SendLoop ! Presence, + gen_mod:get_module_proc(ServerHost, ?LOOPNAME) ! Presence, ok. %% ------- @@ -859,7 +863,7 @@ handle_info(_Info, State) -> %%-------------------------------------------------------------------- %% @private 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 true -> ejabberd_hooks:delete(caps_add, ServerHost, @@ -897,20 +901,23 @@ terminate(_Reason, ?MODULE, remove_user, 50), ejabberd_hooks:delete(c2s_handle_info, ServerHost, ?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 undefined -> ?ERROR_MSG("~s process is dead, pubsub was broken", [?LOOPNAME]); Pid -> Pid ! stop end, - terminate_plugins(Host, ServerHost, Plugins, TreePlugin), - ejabberd_router:unregister_route(Host). + lists:foreach( + 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} @@ -3877,6 +3884,8 @@ export(Server) -> 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(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) -> fun (A) when is_boolean(A) -> A end; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; @@ -3895,7 +3904,7 @@ mod_opt_type(pep_mapping) -> mod_opt_type(plugins) -> fun (A) when is_list(A) -> A end; mod_opt_type(_) -> - [access_createnode, db_type, host, + [access_createnode, db_type, host, hosts, ignore_pep_from_offline, iqdisc, last_item_cache, max_items_node, nodetree, pep_mapping, plugins, max_subscriptions_node, default_node_config]. diff --git a/src/mod_sip_proxy.erl b/src/mod_sip_proxy.erl index 19a02e8e4..25f035377 100644 --- a/src/mod_sip_proxy.erl +++ b/src/mod_sip_proxy.erl @@ -27,8 +27,7 @@ -ifndef(SIP). -export([]). -else. --define(GEN_FSM, p1_fsm). --behaviour(?GEN_FSM). +-behaviour(p1_fsm). %% API -export([start/2, start_link/2, route/3, route/4]). @@ -58,10 +57,10 @@ start(LServer, Opts) -> supervisor:start_child(mod_sip_proxy_sup, [LServer, Opts]). start_link(LServer, Opts) -> - ?GEN_FSM:start_link(?MODULE, [LServer, Opts], []). + p1_fsm:start_link(?MODULE, [LServer, Opts], []). route(SIPMsg, _SIPSock, TrID, Pid) -> - ?GEN_FSM:send_event(Pid, {SIPMsg, TrID}). + p1_fsm:send_event(Pid, {SIPMsg, TrID}). route(#sip{hdrs = Hdrs} = Req, LServer, Opts) -> case proplists:get_bool(authenticated, Opts) of diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 495393f72..67d01a085 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -67,7 +67,7 @@ -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 @@ -95,37 +95,40 @@ init([Host, Opts]) -> ?NS_VCARD, ?MODULE, process_sm_iq, IQDisc), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, 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), if Search -> - ejabberd_hooks:add( - disco_local_items, MyHost, ?MODULE, disco_items, 100), - ejabberd_hooks:add( - disco_local_features, MyHost, ?MODULE, disco_features, 100), - ejabberd_hooks:add( - disco_local_identity, MyHost, ?MODULE, disco_identity, 100), - gen_iq_handler:add_iq_handler( - ejabberd_local, MyHost, ?NS_SEARCH, ?MODULE, process_search, IQDisc), - gen_iq_handler:add_iq_handler( - ejabberd_local, MyHost, ?NS_VCARD, ?MODULE, process_vcard, IQDisc), - gen_iq_handler:add_iq_handler( - ejabberd_local, MyHost, ?NS_DISCO_ITEMS, mod_disco, - process_local_iq_items, IQDisc), - gen_iq_handler:add_iq_handler( - ejabberd_local, MyHost, ?NS_DISCO_INFO, mod_disco, - process_local_iq_info, IQDisc), - case Mod:is_search_supported(Host) of - false -> - ?WARNING_MSG("vcard search functionality is " - "not implemented for ~s backend", - [gen_mod:db_type(Host, Opts, ?MODULE)]); - true -> - ejabberd_router:register_route(MyHost, Host) - end; + lists:foreach( + fun(MyHost) -> + ejabberd_hooks:add( + disco_local_items, MyHost, ?MODULE, disco_items, 100), + ejabberd_hooks:add( + disco_local_features, MyHost, ?MODULE, disco_features, 100), + ejabberd_hooks:add( + disco_local_identity, MyHost, ?MODULE, disco_identity, 100), + gen_iq_handler:add_iq_handler( + ejabberd_local, MyHost, ?NS_SEARCH, ?MODULE, process_search, IQDisc), + gen_iq_handler:add_iq_handler( + ejabberd_local, MyHost, ?NS_VCARD, ?MODULE, process_vcard, IQDisc), + gen_iq_handler:add_iq_handler( + ejabberd_local, MyHost, ?NS_DISCO_ITEMS, mod_disco, + process_local_iq_items, IQDisc), + gen_iq_handler:add_iq_handler( + ejabberd_local, MyHost, ?NS_DISCO_INFO, mod_disco, + process_local_iq_info, IQDisc), + case Mod:is_search_supported(Host) of + false -> + ?WARNING_MSG("vcard search functionality is " + "not implemented for ~s backend", + [gen_mod:db_type(Host, Opts, ?MODULE)]); + true -> + ejabberd_router:register_route(MyHost, Host) + end + end, MyHosts); true -> ok end, - {ok, #state{host = MyHost, server_host = Host}}. + {ok, #state{hosts = MyHosts, server_host = Host}}. handle_call(_Call, _From, State) -> {noreply, State}. @@ -144,21 +147,24 @@ handle_info(Info, State) -> ?WARNING_MSG("unexpected info: ~p", [Info]), {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), gen_iq_handler:remove_iq_handler(ejabberd_local, 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), Mod = gen_mod:db_mod(Host, ?MODULE), Mod:stop(Host), - ejabberd_router:unregister_route(MyHost), - ejabberd_hooks:delete(disco_local_items, MyHost, ?MODULE, disco_items, 100), - ejabberd_hooks:delete(disco_local_features, MyHost, ?MODULE, disco_features, 100), - ejabberd_hooks:delete(disco_local_identity, MyHost, ?MODULE, disco_identity, 100), - gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_SEARCH), - 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). + lists:foreach( + fun(MyHost) -> + ejabberd_router:unregister_route(MyHost), + ejabberd_hooks:delete(disco_local_items, MyHost, ?MODULE, disco_items, 100), + ejabberd_hooks:delete(disco_local_features, MyHost, ?MODULE, disco_features, 100), + ejabberd_hooks:delete(disco_local_identity, MyHost, ?MODULE, disco_identity, 100), + gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_SEARCH), + 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) -> {ok, State}. @@ -527,6 +533,8 @@ mod_opt_type(allow_return_all) -> 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(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(matches) -> 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 -> fun (B) when is_boolean(B) -> B end; 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, use_cache, cache_missed]. diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index f1f076468..38c4747e6 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -47,7 +47,7 @@ -record(state, {serverhost = <<"">> :: binary(), - myhost = <<"">> :: binary(), + myhosts = [] :: [binary()], eldap_id = <<"">> :: binary(), search = false :: boolean(), servers = [] :: [binary()], @@ -351,8 +351,7 @@ default_search_reported() -> {<<"Organization Unit">>, <<"ORGUNIT">>}]. parse_options(Host, Opts) -> - 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), Matches = gen_mod:get_opt(matches, Opts, 30), Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?PROCNAME)), @@ -394,7 +393,7 @@ parse_options(Host, Opts) -> end, SearchReported) ++ UIDAttrs), - #state{serverhost = Host, myhost = MyHost, + #state{serverhost = Host, myhosts = MyHosts, eldap_id = Eldap_ID, search = Search, servers = Cfg#eldap_config.servers, backups = Cfg#eldap_config.backups, diff --git a/test/ejabberd_SUITE.erl b/test/ejabberd_SUITE.erl index 539d8dc33..97c56159a 100644 --- a/test/ejabberd_SUITE.erl +++ b/test/ejabberd_SUITE.erl @@ -750,25 +750,25 @@ test_component_send(Config) -> disconnect(Config). s2s_dialback(Config) -> - ejabberd_s2s:stop_all_connections(), + ejabberd_s2s:stop_s2s_connections(), ejabberd_config:add_option(s2s_use_starttls, false), ejabberd_config:add_option(domain_certfile, "self-signed-cert.pem"), s2s_ping(Config). s2s_optional(Config) -> - ejabberd_s2s:stop_all_connections(), + ejabberd_s2s:stop_s2s_connections(), ejabberd_config:add_option(s2s_use_starttls, optional), ejabberd_config:add_option(domain_certfile, "self-signed-cert.pem"), s2s_ping(Config). s2s_required(Config) -> - ejabberd_s2s:stop_all_connections(), + ejabberd_s2s:stop_s2s_connections(), ejabberd_config:add_option(s2s_use_starttls, required), ejabberd_config:add_option(domain_certfile, "self-signed-cert.pem"), s2s_ping(Config). s2s_required_trusted(Config) -> - ejabberd_s2s:stop_all_connections(), + ejabberd_s2s:stop_s2s_connections(), ejabberd_config:add_option(s2s_use_starttls, required), ejabberd_config:add_option(domain_certfile, "cert.pem"), s2s_ping(Config). |