diff options
Diffstat (limited to 'src/ejabberd_router.erl')
-rw-r--r-- | src/ejabberd_router.erl | 144 |
1 files changed, 88 insertions, 56 deletions
diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index 6a56a22ea..e29d6acfb 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -5,7 +5,7 @@ %%% Created : 27 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2015 ProcessOne +%%% ejabberd, Copyright (C) 2002-2016 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -36,7 +36,9 @@ route_error/4, register_route/1, register_route/2, + register_route/3, register_routes/1, + host_of_route/1, unregister_route/1, unregister_routes/1, dirty_get_all_routes/0, @@ -55,7 +57,7 @@ -type local_hint() :: undefined | integer() | {apply, atom(), atom()}. --record(route, {domain, pid, local_hint}). +-record(route, {domain, server_host, pid, local_hint}). -record(state, {}). @@ -86,7 +88,7 @@ route(From, To, Packet) -> route_error(From, To, ErrPacket, OrigPacket) -> #xmlel{attrs = Attrs} = OrigPacket, - case <<"error">> == xml:get_attr_s(<<"type">>, Attrs) of + case <<"error">> == fxml:get_attr_s(<<"type">>, Attrs) of false -> route(From, To, ErrPacket); true -> ok end. @@ -94,19 +96,29 @@ route_error(From, To, ErrPacket, OrigPacket) -> -spec register_route(binary()) -> term(). 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) -> - case jlib:nameprep(Domain) of - error -> erlang:error({invalid_domain, Domain}); - LDomain -> +register_route(Domain, ServerHost) -> + register_route(Domain, ServerHost, undefined). + +-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(), case get_component_number(LDomain) of undefined -> F = fun () -> mnesia:write(#route{domain = LDomain, pid = Pid, + server_host = LServerHost, local_hint = LocalHint}) end, mnesia:transaction(F); @@ -115,53 +127,49 @@ register_route(Domain, LocalHint) -> case mnesia:wread({route, LDomain}) of [] -> mnesia:write(#route{domain = LDomain, + server_host = LServerHost, pid = Pid, local_hint = 1}), - lists:foreach(fun (I) -> - mnesia:write(#route{domain - = - LDomain, - pid - = - undefined, - local_hint - = - I}) - end, - lists:seq(2, N)); + lists:foreach( + fun (I) -> + mnesia:write( + #route{domain = LDomain, + pid = undefined, + server_host = LServerHost, + local_hint = I}) + end, + lists:seq(2, N)); Rs -> - lists:any(fun (#route{pid = undefined, - local_hint = I} = - R) -> - mnesia:write(#route{domain = - LDomain, - pid = - Pid, - local_hint - = - I}), - mnesia:delete_object(R), - true; - (_) -> false - end, - Rs) + lists:any( + fun (#route{pid = undefined, + local_hint = I} = R) -> + mnesia:write( + #route{domain = LDomain, + pid = Pid, + server_host = LServerHost, + local_hint = I}), + mnesia:delete_object(R), + true; + (_) -> false + end, + Rs) end end, mnesia:transaction(F) end end. --spec register_routes([binary()]) -> ok. +-spec register_routes([{binary(), binary()}]) -> ok. register_routes(Domains) -> - lists:foreach(fun (Domain) -> register_route(Domain) + lists:foreach(fun ({Domain, ServerHost}) -> register_route(Domain, ServerHost) end, Domains). -spec unregister_route(binary()) -> term(). unregister_route(Domain) -> - case jlib:nameprep(Domain) of + case jid:nameprep(Domain) of error -> erlang:error({invalid_domain, Domain}); LDomain -> Pid = self(), @@ -183,7 +191,9 @@ unregister_route(Domain) -> of [R] -> I = R#route.local_hint, + ServerHost = R#route.server_host, mnesia:write(#route{domain = LDomain, + server_host = ServerHost, pid = undefined, local_hint = I}), mnesia:delete_object(R); @@ -211,6 +221,20 @@ dirty_get_all_routes() -> dirty_get_all_domains() -> 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 @@ -226,7 +250,8 @@ dirty_get_all_domains() -> init([]) -> update_tables(), mnesia:create_table(route, - [{ram_copies, [node()]}, {type, bag}, + [{ram_copies, [node()]}, + {type, bag}, {attributes, record_info(fields, route)}]), mnesia:add_table_copy(route, node(), ram_copies), mnesia:subscribe({table, route, simple}), @@ -282,8 +307,11 @@ handle_info({'DOWN', _Ref, _Type, Pid, _Info}, State) -> if is_integer(E#route.local_hint) -> LDomain = E#route.domain, I = E#route.local_hint, + ServerHost = E#route.server_host, mnesia:write(#route{domain = LDomain, + server_host = + ServerHost, pid = undefined, local_hint = @@ -343,17 +371,17 @@ do_route(OrigFrom, OrigTo, OrigPacket) -> end; Rs -> Value = case - ejabberd_config:get_local_option({domain_balancing, - LDstDomain}, fun(D) when is_atom(D) -> D end) + ejabberd_config:get_option({domain_balancing, + LDstDomain}, fun(D) when is_atom(D) -> D end) of - undefined -> now(); - random -> now(); - source -> jlib:jid_tolower(From); - destination -> jlib:jid_tolower(To); + undefined -> p1_time_compat:monotonic_time(); + random -> p1_time_compat:monotonic_time(); + source -> jid:tolower(From); + destination -> jid:tolower(To); bare_source -> - jlib:jid_remove_resource(jlib:jid_tolower(From)); + jid:remove_resource(jid:tolower(From)); bare_destination -> - jlib:jid_remove_resource(jlib:jid_tolower(To)) + jid:remove_resource(jid:tolower(To)) end, case get_component_number(LDstDomain) of undefined -> @@ -393,12 +421,10 @@ get_component_number(LDomain) -> undefined). update_tables() -> - case catch mnesia:table_info(route, attributes) of - [domain, node, pid] -> mnesia:delete_table(route); - [domain, pid] -> mnesia:delete_table(route); - [domain, pid, local_hint] -> ok; - [domain, pid, local_hint|_] -> mnesia:delete_table(route); - {'EXIT', _} -> ok + try + mnesia:transform_table(route, ignore, record_info(fields, route)) + catch exit:{aborted, {no_exists, _}} -> + ok end, case lists:member(local_route, mnesia:system_info(tables)) @@ -407,7 +433,13 @@ update_tables() -> false -> ok end. - +opt_type(domain_balancing) -> + fun (random) -> random; + (source) -> source; + (destination) -> destination; + (bare_source) -> bare_source; + (bare_destination) -> bare_destination + end; opt_type(domain_balancing_component_number) -> fun (N) when is_integer(N), N > 1 -> N end; -opt_type(_) -> [domain_balancing_component_number]. +opt_type(_) -> [domain_balancing, domain_balancing_component_number]. |