aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/ssh/src/ssh.erl13
-rw-r--r--lib/ssh/src/ssh_connection_manager.erl36
2 files changed, 38 insertions, 11 deletions
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 3395f73884..db753e0e4e 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -79,7 +79,7 @@ connect(Host, Port, Options, Timeout) ->
DisableIpv6 = proplists:get_value(ip_v6_disabled, SshOptions, false),
Inet = inetopt(DisableIpv6),
do_connect(Host, Port, [Inet | SocketOptions],
- [{host, Host} | SshOptions], Timeout, DisableIpv6)
+ [{host, Host} | fix_idle_time(SshOptions)], Timeout, DisableIpv6)
end.
do_connect(Host, Port, SocketOptions, SshOptions, Timeout, DisableIpv6) ->
@@ -237,6 +237,13 @@ shell(Host, Port, Options) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+fix_idle_time(SshOptions) ->
+ case proplists:get_value(idle_time, SshOptions) of
+ undefined ->
+ [{idle_time, infinity}|SshOptions];
+ _ ->
+ SshOptions
+ end.
start_daemon(Host, Port, Options, Inet) ->
case handle_options(Options) of
{error, _Reason} = Error ->
@@ -342,6 +349,8 @@ handle_option([{exec, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{auth_methods, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{idle_time, _} = Opt | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, [handle_inet_option(Opt) | SocketOptions], SshOptions).
@@ -407,6 +416,8 @@ handle_ssh_option({shell, {Module, Function, _}} = Opt) when is_atom(Module),
Opt;
handle_ssh_option({shell, Value} = Opt) when is_function(Value) ->
Opt;
+handle_ssh_option({idle_time, Value} = Opt) when is_integer(Value), Value > 0 ->
+ Opt;
handle_ssh_option(Opt) ->
throw({error, {eoptions, Opt}}).
diff --git a/lib/ssh/src/ssh_connection_manager.erl b/lib/ssh/src/ssh_connection_manager.erl
index 2d0830857f..2e62312423 100644
--- a/lib/ssh/src/ssh_connection_manager.erl
+++ b/lib/ssh/src/ssh_connection_manager.erl
@@ -62,7 +62,7 @@
latest_channel_id = 0,
opts,
channel_args,
- timer_ref, % timerref
+ idle_timer_ref, % timerref
connected
}).
@@ -204,7 +204,8 @@ init([client, Opts]) ->
ChannelPid = proplists:get_value(channel_pid, Opts),
self() !
{start_connection, client, [Parent, Address, Port, SocketOpts, Options]},
- TimerRef = erlang:send_after(3600000, self(), {'EXIT', [], "Timeout"}),
+ TimerRef = get_idle_time(Options),
+
{ok, #state{role = client,
client = ChannelPid,
connection_state = #connection{channel_cache = Cache,
@@ -213,7 +214,7 @@ init([client, Opts]) ->
connection_supervisor = Parent,
requests = []},
opts = Opts,
- timer_ref = TimerRef,
+ idle_timer_ref = TimerRef,
connected = false}}.
%%--------------------------------------------------------------------
@@ -406,7 +407,13 @@ handle_call({close, ChannelId}, _,
send_msg({connection_reply, Pid,
ssh_connection:channel_close_msg(Id)}),
ssh_channel:cache_update(Cache, Channel#channel{sent_close = true}),
- erlang:send_after(3600000, self(), {check_cache, [], []}),
+ SshOpts = proplists:get_value(ssh_opts, State#state.opts),
+ case proplists:get_value(idle_time, SshOpts) of
+ infinity ->
+ ok;
+ _IdleTime ->
+ erlang:send_after(5000, self(), {check_cache, [], []})
+ end,
{reply, ok, State};
undefined ->
{reply, ok, State}
@@ -587,23 +594,32 @@ code_change(_OldVsn, State, _Extra) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+get_idle_time(SshOptions) ->
+ case proplists:get_value(idle_time, SshOptions) of
+ infinity ->
+ infinity;
+ IdleTime ->
+ TimerRef = erlang:send_after(IdleTime, self(), {'EXIT', [], "Timeout"}),
+ TimerRef
+ end.
check_cache(State, Cache) ->
%% Check the number of entries in Cache
case proplists:get_value(size, ets:info(Cache)) of
0 ->
- TimerRef = erlang:send_after(3600000, self(), {'EXIT', [], "Timeout"}),
- State#state{timer_ref=TimerRef};
+ Opts = proplists:get_value(ssh_opts, State#state.opts),
+ TimerRef = erlang:send_after(proplists:get_value(idle_time, Opts), self(), {'EXIT', [], "Timeout"}),
+ State#state{idle_timer_ref=TimerRef};
_ ->
State
end.
remove_timer_ref(State) ->
- case State#state.timer_ref of
- undefined ->
+ case State#state.idle_timer_ref of
+ infinity ->
State;
_ ->
- TimerRef = State#state.timer_ref,
+ TimerRef = State#state.idle_timer_ref,
erlang:cancel_timer(TimerRef),
- State#state{timer_ref = undefined}
+ State#state{idle_timer_ref = undefined}
end.
channel_data(Id, Type, Data, Connection0, ConnectionPid, From, State) ->
case ssh_connection:channel_data(Id, Type, Data, Connection0,