diff options
author | Simon Cornish <simon@cali.local> | 2015-04-16 15:45:20 -0700 |
---|---|---|
committer | Zandra Hird <zandra@erlang.org> | 2015-04-23 16:41:14 +0200 |
commit | c08c4a88a73453bd60fb93d0462482a6afc50544 (patch) | |
tree | e99e940116eeb7388609a9ac6bd6d482d5f6ee9d | |
parent | 1756ef6ea4af36e061cdde92d1a87b3b225edea7 (diff) | |
download | otp-c08c4a88a73453bd60fb93d0462482a6afc50544.tar.gz otp-c08c4a88a73453bd60fb93d0462482a6afc50544.tar.bz2 otp-c08c4a88a73453bd60fb93d0462482a6afc50544.zip |
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.
-rw-r--r-- | lib/ssh/src/ssh_sftp.erl | 13 |
1 files 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}; |