]> granicus.if.org Git - ejabberd/commitdiff
Introduce 'negotiation_timeout'
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Tue, 20 Feb 2018 08:38:00 +0000 (11:38 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Tue, 20 Feb 2018 08:38:00 +0000 (11:38 +0300)
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.

src/ejabberd_c2s.erl
src/ejabberd_config.erl
src/ejabberd_s2s_in.erl
src/ejabberd_s2s_out.erl
src/ejabberd_service.erl

index 1e81f4d1aa9a163a3244f64cb6eed1b18f9582df..a523083c86403ae41109eee4654451122d56b507 100644 (file)
@@ -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
index beb44ddc024257c90704858ca2310b2db536234b..09d433ef673838936d37768a8908913625bd5901 100644 (file)
@@ -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)).
index 5345727a298cd90bf12d3d2223003d073c2a94cf..31a936c8cd76e400e21740fa6b85c96f7d9264d0 100644 (file)
@@ -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]).
index 9abc0d0171da6739656c8a65e5bc94c4d0305e8a..f82d017eaae11687438845f21d8a1d502fe30fd3 100644 (file)
@@ -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]).
index de4ab1fd2c47254c3fef59e01511b0e7672a8754..816d643ebc86a756f3a382957331c915b62222e1 100644 (file)
@@ -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,