From c08c4a88a73453bd60fb93d0462482a6afc50544 Mon Sep 17 00:00:00 2001 From: Simon Cornish Date: Thu, 16 Apr 2015 15:45:20 -0700 Subject: Fix ssh_sftp wait_for_version_negotiation timeout This patch fixes a bug that causes an SFTP connection to always fail when {timeout, Timeout} option is used with ssh_sftp:start_channel. The bug is that the version negotiation timer is not cancelled upon reception of SSH_FXP_VERSION. --- lib/ssh/src/ssh_sftp.erl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl index c264eabc78..bab688f226 100644 --- a/lib/ssh/src/ssh_sftp.erl +++ b/lib/ssh/src/ssh_sftp.erl @@ -508,12 +508,12 @@ init([Cm, ChannelId, Options]) -> %%-------------------------------------------------------------------- handle_call({{timeout, infinity}, wait_for_version_negotiation}, From, #state{xf = #ssh_xfer{vsn = undefined} = Xf} = State) -> - {noreply, State#state{xf = Xf#ssh_xfer{vsn = From}}}; + {noreply, State#state{xf = Xf#ssh_xfer{vsn = {wait, From, undefined}}}}; handle_call({{timeout, Timeout}, wait_for_version_negotiation}, From, #state{xf = #ssh_xfer{vsn = undefined} = Xf} = State) -> - timer:send_after(Timeout, {timeout, undefined, From}), - {noreply, State#state{xf = Xf#ssh_xfer{vsn = From}}}; + TRef = erlang:send_after(Timeout, self(), {timeout, undefined, From}), + {noreply, State#state{xf = Xf#ssh_xfer{vsn = {wait, From, TRef}}}}; handle_call({_, wait_for_version_negotiation}, _, State) -> {reply, ok, State}; @@ -865,7 +865,12 @@ do_handle_reply(#state{xf = Xf} = State, case Xf#ssh_xfer.vsn of undefined -> ok; - From -> + {wait, From, TRef} -> + if is_reference(TRef) -> + erlang:cancel_timer(TRef); + true -> + ok + end, ssh_channel:reply(From, ok) end, State#state{xf = Xf#ssh_xfer{vsn = Version, ext = Ext}, rep_buf = Rest}; -- cgit v1.2.3