aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2015-05-29 10:15:51 +0200
committerIngela Anderton Andin <[email protected]>2015-05-29 14:59:52 +0200
commit92a9ddf4c4169c486c1b3bfe958464a90b553289 (patch)
tree3bbdc161a96426baae206470a8e1441b4ffbe516
parentf3fefbae24a2569a13b538d80d0e99129963ebef (diff)
downloadotp-92a9ddf4c4169c486c1b3bfe958464a90b553289.tar.gz
otp-92a9ddf4c4169c486c1b3bfe958464a90b553289.tar.bz2
otp-92a9ddf4c4169c486c1b3bfe958464a90b553289.zip
ssh: handle that inet:getopts(Socket, [recbuf]) may return {ok, []}
If something bad happens and the socket is closed the call inet:getopts(Socket, [recbuf]) may return {ok, []}. We want to treat this as a fatal error and terminate gracefully. The same goes for the case that inet:getopts returns {error, Reason} that was not handled either.
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl19
1 files changed, 16 insertions, 3 deletions
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 0f6162db60..d4bbb0b32e 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -326,9 +326,13 @@ info(ConnectionHandler, ChannelProcess) ->
hello(socket_control, #state{socket = Socket, ssh_params = Ssh} = State) ->
VsnMsg = ssh_transport:hello_version_msg(string_version(Ssh)),
send_msg(VsnMsg, State),
- {ok, [{recbuf, Size}]} = inet:getopts(Socket, [recbuf]),
- inet:setopts(Socket, [{packet, line}, {active, once}, {recbuf, ?MAX_PROTO_VERSION}]),
- {next_state, hello, State#state{recbuf = Size}};
+ case getopt(recbuf, Socket) of
+ {ok, Size} ->
+ inet:setopts(Socket, [{packet, line}, {active, once}, {recbuf, ?MAX_PROTO_VERSION}]),
+ {next_state, hello, State#state{recbuf = Size}};
+ {error, Reason} ->
+ {stop, {shutdown, Reason}, State}
+ end;
hello({info_line, _Line},#state{role = client, socket = Socket} = State) ->
%% The server may send info lines before the version_exchange
@@ -1719,3 +1723,12 @@ start_timeout(_,_, infinity) ->
ok;
start_timeout(Channel, From, Time) ->
erlang:send_after(Time, self(), {timeout, {Channel, From}}).
+
+getopt(Opt, Socket) ->
+ case inet:getopts(Socket, [Opt]) of
+ {ok, [{Opt, Value}]} ->
+ {ok, Value};
+ Other ->
+ {error, {unexpected_getopts_return, Other}}
+ end.
+