aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFredrik Gustafsson <[email protected]>2012-10-30 11:41:06 +0100
committerFredrik Gustafsson <[email protected]>2012-10-31 10:56:25 +0100
commit600a56059a879a1714cd7f93bcb19f955fe91bca (patch)
treed1e3e37b2aed64aa692c28d0e40fbeafd9a8bb0e
parent0a42a8be1604a29bfefd62e54a2e8453e237fd73 (diff)
downloadotp-600a56059a879a1714cd7f93bcb19f955fe91bca.tar.gz
otp-600a56059a879a1714cd7f93bcb19f955fe91bca.tar.bz2
otp-600a56059a879a1714cd7f93bcb19f955fe91bca.zip
Timeout after 1h of idle on connection, which exits the connection
-rw-r--r--lib/ssh/src/ssh_connection_manager.erl31
1 files changed, 28 insertions, 3 deletions
diff --git a/lib/ssh/src/ssh_connection_manager.erl b/lib/ssh/src/ssh_connection_manager.erl
index 422d9356d5..2d0830857f 100644
--- a/lib/ssh/src/ssh_connection_manager.erl
+++ b/lib/ssh/src/ssh_connection_manager.erl
@@ -62,6 +62,7 @@
latest_channel_id = 0,
opts,
channel_args,
+ timer_ref, % timerref
connected
}).
@@ -203,6 +204,7 @@ 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"}),
{ok, #state{role = client,
client = ChannelPid,
connection_state = #connection{channel_cache = Cache,
@@ -211,6 +213,7 @@ init([client, Opts]) ->
connection_supervisor = Parent,
requests = []},
opts = Opts,
+ timer_ref = TimerRef,
connected = false}}.
%%--------------------------------------------------------------------
@@ -358,7 +361,7 @@ handle_call({open, ChannelPid, Type, InitialWindowSize, MaxPacketSize, Data},
recv_packet_size = MaxPacketSize},
ssh_channel:cache_update(Cache, Channel),
State = add_request(true, ChannelId, From, State1),
- {noreply, State};
+ {noreply, remove_timer_ref(State)};
handle_call({send_window, ChannelId}, _From,
#state{connection_state =
@@ -403,6 +406,7 @@ 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, [], []}),
{reply, ok, State};
undefined ->
{reply, ok, State}
@@ -523,7 +527,10 @@ handle_info({start_connection, client,
Pid ! {self(), not_connected, Reason},
{stop, {shutdown, normal}, State}
end;
-
+handle_info({check_cache, _ , _},
+ #state{connection_state =
+ #connection{channel_cache = Cache}} = State) ->
+ {noreply, check_cache(State, Cache)};
handle_info({ssh_cm, _Sender, Msg}, State0) ->
%% Backwards compatibility!
State = cm_message(Msg, State0),
@@ -580,6 +587,24 @@ code_change(_OldVsn, State, _Extra) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+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};
+ _ ->
+ State
+ end.
+remove_timer_ref(State) ->
+ case State#state.timer_ref of
+ undefined ->
+ State;
+ _ ->
+ TimerRef = State#state.timer_ref,
+ erlang:cancel_timer(TimerRef),
+ State#state{timer_ref = undefined}
+ end.
channel_data(Id, Type, Data, Connection0, ConnectionPid, From, State) ->
case ssh_connection:channel_data(Id, Type, Data, Connection0,
ConnectionPid, From) of
@@ -677,7 +702,7 @@ handle_channel_down(ChannelPid, #state{connection_state =
(_,Acc) ->
Acc
end, [], Cache),
- {{replies, []}, State}.
+ {{replies, []}, check_cache(State, Cache)}.
update_sys(Cache, Channel, Type, ChannelPid) ->
ssh_channel:cache_update(Cache,