diff options
-rw-r--r-- | lib/ssh/src/ssh.erl | 13 | ||||
-rw-r--r-- | lib/ssh/src/ssh_connection_manager.erl | 36 |
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, |