diff options
author | Pablo Polvorin <pablo.polvorin@process-one.net> | 2011-12-02 22:30:20 +0400 |
---|---|---|
committer | Pablo Polvorin <pablo.polvorin@process-one.net> | 2011-12-02 22:30:20 +0400 |
commit | cf973f27bb62dbb1e5c89b062eae491a646860db (patch) | |
tree | b695adfc9f5cf9f887b0478f855a69107e060ccc /src/ejabberd_s2s_in.erl | |
parent | 87df27109a18146ba8870a26eece1fbf51cd879b (diff) |
Prevent overload of incomming s2s connections
Three changes were introduced:
1) ejabberd_s2s_in now uses p1_fsm instead of gen_fsm. And uses
the {max_queue, N} option to kill the process if its input
queue grows too much.
2) If a ejabberd_s2s_in process is overload and killed, the server
that originated that connection is not allowed to connect back
to us for X seconds (set to 60seconds on the source)
3) The list of blocked (both statically and dynamically by the above
method) host is now also checked for hosts authenticating by
starttls+sasl. Previusly it was only used during dialback.
Diffstat (limited to 'src/ejabberd_s2s_in.erl')
-rw-r--r-- | src/ejabberd_s2s_in.erl | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index 590b560bd..2cfc1d460 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -27,7 +27,7 @@ -module(ejabberd_s2s_in). -author('alexey@process-one.net'). --behaviour(gen_fsm). +-behaviour(p1_fsm). %% External exports -export([start/2, @@ -92,10 +92,12 @@ -define(FSMOPTS, []). -endif. +-define(FSMLIMITS, [{max_queue, 2000}]). %% if queue grows more than this, we shutdown this connection. + %% Module start with or without supervisor: -ifdef(NO_TRANSIENT_SUPERVISORS). --define(SUPERVISOR_START, gen_fsm:start(ejabberd_s2s_in, [SockData, Opts], - ?FSMOPTS)). +-define(SUPERVISOR_START, p1_fsm:start(ejabberd_s2s_in, [SockData, Opts], + ?FSMOPTS ++ ?FSMLIMITS)). -else. -define(SUPERVISOR_START, supervisor:start_child(ejabberd_s2s_in_sup, [SockData, Opts])). @@ -131,7 +133,7 @@ start(SockData, Opts) -> ?SUPERVISOR_START. start_link(SockData, Opts) -> - gen_fsm:start_link(ejabberd_s2s_in, [SockData, Opts], ?FSMOPTS). + p1_fsm:start_link(ejabberd_s2s_in, [SockData, Opts], ?FSMOPTS ++ ?FSMLIMITS). socket_type() -> xml_stream. @@ -347,8 +349,9 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) -> error -> false end, + AllowRemoteHost = ejabberd_s2s:allow_host("", AuthDomain), if - AuthRes -> + AuthRes andalso AllowRemoteHost -> (StateData#state.sockmod):reset_stream( StateData#state.socket), send_element(StateData, @@ -590,14 +593,7 @@ handle_sync_event(get_state_infos, _From, StateName, StateData) -> catch _:_ -> {unknown,unknown} end, - Domains = case StateData#state.authenticated of - true -> - [StateData#state.auth_domain]; - false -> - Connections = StateData#state.connections, - [D || {{D, _}, established} <- - dict:to_list(Connections)] - end, + Domains = get_external_hosts(StateData), Infos = [ {direction, in}, {statename, StateName}, @@ -656,9 +652,25 @@ handle_info(_, StateName, StateData) -> %%---------------------------------------------------------------------- terminate(Reason, _StateName, StateData) -> ?DEBUG("terminated: ~p", [Reason]), + case Reason of + {process_limit, _} -> + [ejabberd_s2s:external_host_overloaded(Host) || Host <- get_external_hosts(StateData)]; + _ -> + ok + end, (StateData#state.sockmod):close(StateData#state.socket), ok. +get_external_hosts(StateData) -> + case StateData#state.authenticated of + true -> + [StateData#state.auth_domain]; + false -> + Connections = StateData#state.connections, + [D || {{D, _}, established} <- dict:to_list(Connections)] + end. + + %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- |