diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index e25566d75..835f4db4a 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -46,6 +46,8 @@ %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). +%% ejabberd API +-export([get_info_s2s_connections/1]). -include_lib("exmpp/include/exmpp.hrl"). @@ -520,3 +522,32 @@ allow_host(MyServer, S2SHost) -> _ -> true %% The default s2s policy is allow end end. + +%% Get information about S2S connections of the specified type. +%% @spec (Type) -> [Info] +%% where Type = in | out +%% Info = [{InfoName::atom(), InfoValue::any()}] +get_info_s2s_connections(Type) -> + ChildType = case Type of + in -> ejabberd_s2s_in_sup; + out -> ejabberd_s2s_out_sup + end, + Connections = supervisor:which_children(ChildType), + get_s2s_info(Connections,Type). + +get_s2s_info(Connections,Type)-> + complete_s2s_info(Connections,Type,[]). +complete_s2s_info([],_,Result)-> + Result; +complete_s2s_info([Connection|T],Type,Result)-> + {_,PID,_,_}=Connection, + State = get_s2s_state(PID), + complete_s2s_info(T,Type,[State|Result]). + +get_s2s_state(S2sPid)-> + Infos = case gen_fsm:sync_send_all_state_event(S2sPid,get_state_infos) of + {state_infos, Is} -> [{status, open} | Is]; + {noproc,_} -> [{status, closed}]; %% Connection closed + {badrpc,_} -> [{status, error}] + end, + [{s2s_pid, S2sPid} | Infos]. diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index ea1f3e597..0676abbcc 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -500,6 +500,35 @@ stream_established(closed, StateData) -> %%---------------------------------------------------------------------- handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. +%%---------------------------------------------------------------------- +%% Func: handle_sync_event/4 +%% Returns: The associated StateData for this connection +%% {reply, Reply, NextStateName, NextStateData} +%% Reply = {state_infos, [{InfoName::atom(), InfoValue::any()] +%%---------------------------------------------------------------------- +handle_sync_event(get_state_infos, _From, StateName, StateData) -> + SockMod = StateData#state.sockmod, + {Addr,Port} = try SockMod:peername(StateData#state.socket) of + {ok, {A,P}} -> {A,P}; + {error, _} -> {unknown,unknown} + catch + _:_ -> {unknown,unknown} + end, + Infos = [ + {direction, in}, + {statename, StateName}, + {addr, Addr}, + {port, Port}, + {streamid, StateData#state.streamid}, + {tls, StateData#state.tls}, + {tls_enabled, StateData#state.tls_enabled}, + {tls_options, StateData#state.tls_options}, + {authenticated, StateData#state.authenticated}, + {shaper, StateData#state.shaper}, + {sockmod, SockMod} + ], + Reply = {state_infos, Infos}, + {reply,Reply,StateName,StateData}; %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index 029e3e631..9641e5c11 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -700,6 +700,42 @@ stream_established(closed, StateData) -> handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData, get_timeout_interval(StateName)}. +%%---------------------------------------------------------------------- +%% Func: handle_sync_event/4 +%% Returns: The associated StateData for this connection +%% {reply, Reply, NextStateName, NextStateData} +%% Reply = {state_infos, [{InfoName::atom(), InfoValue::any()] +%%---------------------------------------------------------------------- +handle_sync_event(get_state_infos, _From, StateName, StateData) -> + {Addr,Port} = try ejabberd_socket:peername(StateData#state.socket) of + {ok, {A,P}} -> {A,P}; + {error, _} -> {unknown,unknown} + catch + _:_ -> + {unknown,unknown} + end, + Infos = [ + {direction, out}, + {statename, StateName}, + {addr, Addr}, + {port, Port}, + {streamid, StateData#state.streamid}, + {use_v10, StateData#state.use_v10}, + {tls, StateData#state.tls}, + {tls_required, StateData#state.tls_required}, + {tls_enabled, StateData#state.tls_enabled}, + {tls_options, StateData#state.tls_options}, + {authenticated, StateData#state.authenticated}, + {db_enabled, StateData#state.db_enabled}, + {try_auth, StateData#state.try_auth}, + {myname, StateData#state.myname}, + {server, StateData#state.server}, + {delay_to_retry, StateData#state.delay_to_retry}, + {verify, StateData#state.verify} + ], + Reply = {state_infos, Infos}, + {reply,Reply,StateName,StateData}; + %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Returns: {next_state, NextStateName, NextStateData} |