Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Polvorin <pablo.polvorin@process-one.net>2011-12-02 22:30:20 +0400
committerPablo Polvorin <pablo.polvorin@process-one.net>2011-12-02 22:30:20 +0400
commitcf973f27bb62dbb1e5c89b062eae491a646860db (patch)
treeb695adfc9f5cf9f887b0478f855a69107e060ccc /src/ejabberd_s2s_in.erl
parent87df27109a18146ba8870a26eece1fbf51cd879b (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.erl38
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
%%%----------------------------------------------------------------------