aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>2018-02-20 11:38:00 +0300
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>2018-02-20 11:38:00 +0300
commitd625e24029221cea30ef7078010f16da526ce257 (patch)
tree62cdc9ca5a944d0d95ff5608431991b929bbe7f8 /src
parentmod_admin_extra: Fix srg_get_info with '@all@' (diff)
Introduce 'negotiation_timeout'
The option can be used to specify a period (in seconds) for a stream negotiation to complete. If the timer fires, the stream is considered as failed and the underlying connection gets closed. This is a global option (you cannot set it per domain) and the default is 30 seconds.
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd_c2s.erl4
-rw-r--r--src/ejabberd_config.erl8
-rw-r--r--src/ejabberd_s2s_in.erl4
-rw-r--r--src/ejabberd_s2s_out.erl4
-rw-r--r--src/ejabberd_service.erl6
5 files changed, 20 insertions, 6 deletions
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 1e81f4d1a..a523083c8 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -519,6 +519,7 @@ init([State, Opts]) ->
TLSRequired = proplists:get_bool(starttls_required, Opts),
TLSVerify = proplists:get_bool(tls_verify, Opts),
Zlib = proplists:get_bool(zlib, Opts),
+ Timeout = ejabberd_config:negotiation_timeout(),
State1 = State#{tls_options => TLSOpts2,
tls_required => TLSRequired,
tls_enabled => TLSEnabled,
@@ -530,7 +531,8 @@ init([State, Opts]) ->
lserver => ?MYNAME,
access => Access,
shaper => Shaper},
- ejabberd_hooks:run_fold(c2s_init, {ok, State1}, [Opts]).
+ State2 = xmpp_stream_in:set_timeout(State1, Timeout),
+ ejabberd_hooks:run_fold(c2s_init, {ok, State2}, [Opts]).
handle_call(get_presence, From, #{jid := JID} = State) ->
Pres = case maps:get(pres_last, State, error) of
diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl
index beb44ddc0..09d433ef6 100644
--- a/src/ejabberd_config.erl
+++ b/src/ejabberd_config.erl
@@ -37,7 +37,7 @@
default_db/1, default_db/2, default_ram_db/1, default_ram_db/2,
default_queue_type/1, queue_dir/0, fsm_limit_opts/1,
use_cache/1, cache_size/1, cache_missed/1, cache_life_time/1,
- codec_options/1, get_plain_terms_file/2]).
+ codec_options/1, get_plain_terms_file/2, negotiation_timeout/0]).
-export([start/2]).
@@ -1415,6 +1415,8 @@ opt_type(cache_life_time) ->
(infinity) -> infinity;
(unlimited) -> infinity
end;
+opt_type(negotiation_timeout) ->
+ fun(T) when T > 0 -> T end;
opt_type(shared_key) ->
fun iolist_to_binary/1;
opt_type(node_start) ->
@@ -1479,3 +1481,7 @@ codec_options(Host) ->
true -> [];
false -> [ignore_els]
end.
+
+-spec negotiation_timeout() -> pos_integer().
+negotiation_timeout() ->
+ timer:seconds(get_option(negotiation_timeout, 30)).
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 5345727a2..31a936c8c 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -259,6 +259,7 @@ init([State, Opts]) ->
false -> [compression_none | TLSOpts1];
true -> TLSOpts1
end,
+ Timeout = ejabberd_config:negotiation_timeout(),
State1 = State#{tls_options => TLSOpts2,
auth_domains => sets:new(),
xmlns => ?NS_SERVER,
@@ -268,7 +269,8 @@ init([State, Opts]) ->
server_host => ?MYNAME,
established => false,
shaper => Shaper},
- ejabberd_hooks:run_fold(s2s_in_init, {ok, State1}, [Opts]).
+ State2 = xmpp_stream_in:set_timeout(State1, Timeout),
+ ejabberd_hooks:run_fold(s2s_in_init, {ok, State2}, [Opts]).
handle_call(Request, From, #{server_host := LServer} = State) ->
ejabberd_hooks:run_fold(s2s_in_handle_call, LServer, State, [Request, From]).
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index 9abc0d017..f82d017ea 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -270,15 +270,17 @@ init([#{server := LServer, remote_server := RServer} = State, Opts]) ->
{_, N} -> N;
false -> unlimited
end,
+ Timeout = ejabberd_config:negotiation_timeout(),
State1 = State#{on_route => queue,
queue => p1_queue:new(QueueType, QueueLimit),
xmlns => ?NS_SERVER,
lang => ?MYLANG,
server_host => ServerHost,
shaper => none},
+ State2 = xmpp_stream_out:set_timeout(State1, Timeout),
?INFO_MSG("Outbound s2s connection started: ~s -> ~s",
[LServer, RServer]),
- ejabberd_hooks:run_fold(s2s_out_init, ServerHost, {ok, State1}, [Opts]).
+ ejabberd_hooks:run_fold(s2s_out_init, ServerHost, {ok, State2}, [Opts]).
handle_call(Request, From, #{server_host := ServerHost} = State) ->
ejabberd_hooks:run_fold(s2s_out_handle_call, ServerHost, State, [Request, From]).
diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl
index de4ab1fd2..816d643eb 100644
--- a/src/ejabberd_service.erl
+++ b/src/ejabberd_service.erl
@@ -101,8 +101,10 @@ init([State, Opts]) ->
true -> TLSOpts1
end,
GlobalRoutes = proplists:get_value(global_routes, Opts, true),
+ Timeout = ejabberd_config:negotiation_timeout(),
State1 = xmpp_stream_in:change_shaper(State, Shaper),
- State2 = State1#{access => Access,
+ State2 = xmpp_stream_in:set_timeout(State1, Timeout),
+ State3 = State2#{access => Access,
xmlns => ?NS_COMPONENT,
lang => ?MYLANG,
server => ?MYNAME,
@@ -111,7 +113,7 @@ init([State, Opts]) ->
tls_options => TLSOpts,
global_routes => GlobalRoutes,
check_from => CheckFrom},
- ejabberd_hooks:run_fold(component_init, {ok, State2}, [Opts]).
+ ejabberd_hooks:run_fold(component_init, {ok, State3}, [Opts]).
handle_stream_start(_StreamStart,
#{remote_server := RemoteServer,