Make it possible to get virtual host of a registered route

This commit is contained in:
Evgeniy Khramtsov 2016-03-13 11:38:40 +03:00
parent 9ceeaf213b
commit 357e48fb6b
13 changed files with 79 additions and 53 deletions

View File

@ -178,6 +178,7 @@ bounce_resource_packet(From, To, Packet) ->
init([]) -> init([]) ->
lists:foreach(fun (Host) -> lists:foreach(fun (Host) ->
ejabberd_router:register_route(Host, ejabberd_router:register_route(Host,
Host,
{apply, ?MODULE, {apply, ?MODULE,
route}), route}),
ejabberd_hooks:add(local_send_to_resource_hook, Host, ejabberd_hooks:add(local_send_to_resource_hook, Host,

View File

@ -36,7 +36,9 @@
route_error/4, route_error/4,
register_route/1, register_route/1,
register_route/2, register_route/2,
register_route/3,
register_routes/1, register_routes/1,
host_of_route/1,
unregister_route/1, unregister_route/1,
unregister_routes/1, unregister_routes/1,
dirty_get_all_routes/0, dirty_get_all_routes/0,
@ -55,7 +57,7 @@
-type local_hint() :: undefined | integer() | {apply, atom(), atom()}. -type local_hint() :: undefined | integer() | {apply, atom(), atom()}.
-record(route, {domain, pid, local_hint}). -record(route, {domain, server_host, pid, local_hint}).
-record(state, {}). -record(state, {}).
@ -94,19 +96,29 @@ route_error(From, To, ErrPacket, OrigPacket) ->
-spec register_route(binary()) -> term(). -spec register_route(binary()) -> term().
register_route(Domain) -> register_route(Domain) ->
register_route(Domain, undefined). ?WARNING_MSG("~s:register_route/1 is deprected, "
"use ~s:register_route/2 instead",
[?MODULE, ?MODULE]),
register_route(Domain, ?MYNAME).
-spec register_route(binary(), local_hint()) -> term(). -spec register_route(binary(), binary()) -> term().
register_route(Domain, LocalHint) -> register_route(Domain, ServerHost) ->
case jid:nameprep(Domain) of register_route(Domain, ServerHost, undefined).
error -> erlang:error({invalid_domain, Domain});
LDomain -> -spec register_route(binary(), binary(), local_hint()) -> term().
register_route(Domain, ServerHost, LocalHint) ->
case {jid:nameprep(Domain), jid:nameprep(ServerHost)} of
{error, _} -> erlang:error({invalid_domain, Domain});
{_, error} -> erlang:error({invalid_domain, ServerHost});
{LDomain, LServerHost} ->
Pid = self(), Pid = self(),
case get_component_number(LDomain) of case get_component_number(LDomain) of
undefined -> undefined ->
F = fun () -> F = fun () ->
mnesia:write(#route{domain = LDomain, pid = Pid, mnesia:write(#route{domain = LDomain, pid = Pid,
server_host = LServerHost,
local_hint = LocalHint}) local_hint = LocalHint})
end, end,
mnesia:transaction(F); mnesia:transaction(F);
@ -115,46 +127,42 @@ register_route(Domain, LocalHint) ->
case mnesia:wread({route, LDomain}) of case mnesia:wread({route, LDomain}) of
[] -> [] ->
mnesia:write(#route{domain = LDomain, mnesia:write(#route{domain = LDomain,
server_host = LServerHost,
pid = Pid, pid = Pid,
local_hint = 1}), local_hint = 1}),
lists:foreach(fun (I) -> lists:foreach(
mnesia:write(#route{domain fun (I) ->
= mnesia:write(
LDomain, #route{domain = LDomain,
pid pid = undefined,
= server_host = LServerHost,
undefined, local_hint = I})
local_hint end,
= lists:seq(2, N));
I})
end,
lists:seq(2, N));
Rs -> Rs ->
lists:any(fun (#route{pid = undefined, lists:any(
local_hint = I} = fun (#route{pid = undefined,
R) -> local_hint = I} = R) ->
mnesia:write(#route{domain = mnesia:write(
LDomain, #route{domain = LDomain,
pid = pid = Pid,
Pid, server_host = LServerHost,
local_hint local_hint = I}),
= mnesia:delete_object(R),
I}), true;
mnesia:delete_object(R), (_) -> false
true; end,
(_) -> false Rs)
end,
Rs)
end end
end, end,
mnesia:transaction(F) mnesia:transaction(F)
end end
end. end.
-spec register_routes([binary()]) -> ok. -spec register_routes([{binary(), binary()}]) -> ok.
register_routes(Domains) -> register_routes(Domains) ->
lists:foreach(fun (Domain) -> register_route(Domain) lists:foreach(fun ({Domain, ServerHost}) -> register_route(Domain, ServerHost)
end, end,
Domains). Domains).
@ -183,7 +191,9 @@ unregister_route(Domain) ->
of of
[R] -> [R] ->
I = R#route.local_hint, I = R#route.local_hint,
ServerHost = R#route.server_host,
mnesia:write(#route{domain = LDomain, mnesia:write(#route{domain = LDomain,
server_host = ServerHost,
pid = undefined, pid = undefined,
local_hint = I}), local_hint = I}),
mnesia:delete_object(R); mnesia:delete_object(R);
@ -211,6 +221,20 @@ dirty_get_all_routes() ->
dirty_get_all_domains() -> dirty_get_all_domains() ->
lists:usort(mnesia:dirty_all_keys(route)). lists:usort(mnesia:dirty_all_keys(route)).
-spec host_of_route(binary()) -> binary().
host_of_route(Domain) ->
case jid:nameprep(Domain) of
error ->
erlang:error({invalid_domain, Domain});
LDomain ->
case mnesia:dirty_read(route, LDomain) of
[#route{server_host = ServerHost}|_] ->
ServerHost;
[] ->
erlang:error({unregistered_route, Domain})
end
end.
%%==================================================================== %%====================================================================
%% gen_server callbacks %% gen_server callbacks
@ -283,8 +307,11 @@ handle_info({'DOWN', _Ref, _Type, Pid, _Info}, State) ->
if is_integer(E#route.local_hint) -> if is_integer(E#route.local_hint) ->
LDomain = E#route.domain, LDomain = E#route.domain,
I = E#route.local_hint, I = E#route.local_hint,
ServerHost = E#route.server_host,
mnesia:write(#route{domain = mnesia:write(#route{domain =
LDomain, LDomain,
server_host =
ServerHost,
pid = pid =
undefined, undefined,
local_hint = local_hint =
@ -394,12 +421,10 @@ get_component_number(LDomain) ->
undefined). undefined).
update_tables() -> update_tables() ->
case catch mnesia:table_info(route, attributes) of try
[domain, node, pid] -> mnesia:delete_table(route); mnesia:transform_table(route, ignore, record_info(fields, route))
[domain, pid] -> mnesia:delete_table(route); catch exit:{aborted, {no_exists, _}} ->
[domain, pid, local_hint] -> ok; ok
[domain, pid, local_hint|_] -> mnesia:delete_table(route);
{'EXIT', _} -> ok
end, end,
case lists:member(local_route, case lists:member(local_route,
mnesia:system_info(tables)) mnesia:system_info(tables))

View File

@ -222,7 +222,7 @@ wait_for_handshake({xmlstreamelement, El}, StateData) ->
send_text(StateData, <<"<handshake/>">>), send_text(StateData, <<"<handshake/>">>),
lists:foreach( lists:foreach(
fun (H) -> fun (H) ->
ejabberd_router:register_route(H), ejabberd_router:register_route(H, ?MYNAME),
?INFO_MSG("Route registered for service ~p~n", ?INFO_MSG("Route registered for service ~p~n",
[H]) [H])
end, dict:fetch_keys(StateData#state.host_opts)), end, dict:fetch_keys(StateData#state.host_opts)),

View File

@ -86,7 +86,7 @@ stop(Host) ->
init([Host, Opts]) -> init([Host, Opts]) ->
MyHost = gen_mod:get_opt_host(Host, Opts, MyHost = gen_mod:get_opt_host(Host, Opts,
<<"echo.@HOST@">>), <<"echo.@HOST@">>),
ejabberd_router:register_route(MyHost), ejabberd_router:register_route(MyHost, Host),
{ok, #state{host = MyHost}}. {ok, #state{host = MyHost}}.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------

View File

@ -306,7 +306,7 @@ init({ServerHost, Opts}) ->
false -> false ->
ok ok
end, end,
ejabberd_router:register_route(Host), ejabberd_router:register_route(Host, ServerHost),
{ok, #state{server_host = ServerHost, host = Host, name = Name, {ok, #state{server_host = ServerHost, host = Host, name = Name,
access = Access, max_size = MaxSize, access = Access, max_size = MaxSize,
secret_length = SecretLength, jid_in_url = JIDinURL, secret_length = SecretLength, jid_in_url = JIDinURL,

View File

@ -133,7 +133,7 @@ init([Host, Opts]) ->
catch ets:new(irc_connection, catch ets:new(irc_connection,
[named_table, public, [named_table, public,
{keypos, #irc_connection.jid_server_host}]), {keypos, #irc_connection.jid_server_host}]),
ejabberd_router:register_route(MyHost), ejabberd_router:register_route(MyHost, Host),
{ok, {ok,
#state{host = MyHost, server_host = Host, #state{host = MyHost, server_host = Host,
access = Access}}. access = Access}}.

View File

@ -168,7 +168,7 @@ init([ServerHost, Opts]) ->
?NS_PUBSUB, mod_pubsub, iq_sm, IQDisc), ?NS_PUBSUB, mod_pubsub, iq_sm, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
?NS_MIX_0, ?MODULE, process_iq, IQDisc), ?NS_MIX_0, ?MODULE, process_iq, IQDisc),
ejabberd_router:register_route(Host), ejabberd_router:register_route(Host, ServerHost),
{ok, #state{server_host = ServerHost, host = Host}}. {ok, #state{server_host = ServerHost, host = Host}}.
handle_call(_Request, _From, State) -> handle_call(_Request, _From, State) ->

View File

@ -373,7 +373,7 @@ init([Host, Opts]) ->
RoomShaper = gen_mod:get_opt(room_shaper, Opts, RoomShaper = gen_mod:get_opt(room_shaper, Opts,
fun(A) when is_atom(A) -> A end, fun(A) when is_atom(A) -> A end,
none), none),
ejabberd_router:register_route(MyHost), ejabberd_router:register_route(MyHost, Host),
load_permanent_rooms(MyHost, Host, load_permanent_rooms(MyHost, Host,
{Access, AccessCreate, AccessAdmin, AccessPersistent}, {Access, AccessCreate, AccessAdmin, AccessPersistent},
HistorySize, RoomShaper), HistorySize, RoomShaper),

View File

@ -151,7 +151,7 @@ init([LServerS, Opts]) ->
try_start_loop(), try_start_loop(),
create_pool(), create_pool(),
ejabberd_router_multicast:register_route(LServerS), ejabberd_router_multicast:register_route(LServerS),
ejabberd_router:register_route(LServiceS), ejabberd_router:register_route(LServiceS, LServerS),
{ok, {ok,
#state{lservice = LServiceS, lserver = LServerS, #state{lservice = LServiceS, lserver = LServerS,
access = Access, service_limits = SLimits}}. access = Access, service_limits = SLimits}}.

View File

@ -63,7 +63,7 @@ start_link(Host, Opts) ->
init([Host, Opts]) -> init([Host, Opts]) ->
State = parse_options(Host, Opts), State = parse_options(Host, Opts),
ejabberd_router:register_route(State#state.myhost), ejabberd_router:register_route(State#state.myhost, Host),
{ok, State}. {ok, State}.
terminate(_Reason, #state{myhost = MyHost}) -> terminate(_Reason, #state{myhost = MyHost}) ->

View File

@ -241,6 +241,7 @@ stop(Host) ->
init([ServerHost, Opts]) -> init([ServerHost, Opts]) ->
?DEBUG("pubsub init ~p ~p", [ServerHost, Opts]), ?DEBUG("pubsub init ~p ~p", [ServerHost, Opts]),
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>), Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>),
ejabberd_router:register_route(Host, ServerHost),
Access = gen_mod:get_opt(access_createnode, Opts, Access = gen_mod:get_opt(access_createnode, Opts,
fun(A) when is_atom(A) -> A end, all), fun(A) when is_atom(A) -> A end, all),
PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts, PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts,
@ -309,7 +310,6 @@ init([ServerHost, Opts]) ->
false -> false ->
ok ok
end, end,
ejabberd_router:register_route(Host),
pubsub_migrate:update_node_database(Host, ServerHost), pubsub_migrate:update_node_database(Host, ServerHost),
pubsub_migrate:update_state_database(Host, ServerHost), pubsub_migrate:update_state_database(Host, ServerHost),
pubsub_migrate:update_lastitem_database(Host, ServerHost), pubsub_migrate:update_lastitem_database(Host, ServerHost),

View File

@ -105,7 +105,7 @@ init(Host, ServerHost, Search) ->
case Search of case Search of
false -> loop(Host, ServerHost); false -> loop(Host, ServerHost);
_ -> _ ->
ejabberd_router:register_route(Host), ejabberd_router:register_route(Host, ServerHost),
loop(Host, ServerHost) loop(Host, ServerHost)
end. end.

View File

@ -173,7 +173,7 @@ init([Host, Opts]) ->
State#state.password, State#state.tls_options), State#state.password, State#state.tls_options),
case State#state.search of case State#state.search of
true -> true ->
ejabberd_router:register_route(State#state.myhost); ejabberd_router:register_route(State#state.myhost, Host);
_ -> ok _ -> ok
end, end,
{ok, State}. {ok, State}.