aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh/src')
-rw-r--r--lib/ssh/src/ssh.erl6
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl50
2 files changed, 46 insertions, 10 deletions
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 826c585d65..86c042781c 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -345,6 +345,8 @@ handle_option([{connectfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{disconnectfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{unexpectedfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{failfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{ssh_msg_debug_fun, _} = Opt | Rest], SocketOptions, SshOptions) ->
@@ -450,7 +452,9 @@ handle_ssh_option({infofun, Value} = Opt) when is_function(Value) ->
Opt;
handle_ssh_option({connectfun, Value} = Opt) when is_function(Value) ->
Opt;
-handle_ssh_option({disconnectfun , Value} = Opt) when is_function(Value) ->
+handle_ssh_option({disconnectfun, Value} = Opt) when is_function(Value) ->
+ Opt;
+handle_ssh_option({unexpectedfun, Value} = Opt) when is_function(Value,2) ->
Opt;
handle_ssh_option({failfun, Value} = Opt) when is_function(Value) ->
Opt;
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index ab1fc93a1b..e303f02922 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -984,15 +984,38 @@ handle_info({check_cache, _ , _},
#connection{channel_cache = Cache}} = State) ->
{next_state, StateName, check_cache(State, Cache)};
-handle_info(UnexpectedMessage, StateName, #state{ssh_params = SshParams} = State) ->
- Msg = lists:flatten(io_lib:format(
- "Unexpected message '~p' received in state '~p'\n"
- "Role: ~p\n"
- "Peer: ~p\n"
- "Local Address: ~p\n", [UnexpectedMessage, StateName,
- SshParams#ssh.role, SshParams#ssh.peer,
- proplists:get_value(address, SshParams#ssh.opts)])),
- error_logger:info_report(Msg),
+handle_info(UnexpectedMessage, StateName, #state{opts = Opts,
+ ssh_params = SshParams} = State) ->
+ case unexpected_fun(UnexpectedMessage, Opts, SshParams) of
+ report ->
+ Msg = lists:flatten(
+ io_lib:format(
+ "Unexpected message '~p' received in state '~p'\n"
+ "Role: ~p\n"
+ "Peer: ~p\n"
+ "Local Address: ~p\n", [UnexpectedMessage, StateName,
+ SshParams#ssh.role, SshParams#ssh.peer,
+ proplists:get_value(address, SshParams#ssh.opts)])),
+ error_logger:info_report(Msg);
+
+ skip ->
+ ok;
+
+ Other ->
+ Msg = lists:flatten(
+ io_lib:format("Call to fun in 'unexpectedfun' failed:~n"
+ "Return: ~p\n"
+ "Message: ~p\n"
+ "Role: ~p\n"
+ "Peer: ~p\n"
+ "Local Address: ~p\n", [Other, UnexpectedMessage,
+ SshParams#ssh.role,
+ element(2,SshParams#ssh.peer),
+ proplists:get_value(address, SshParams#ssh.opts)]
+ )),
+
+ error_logger:error_report(Msg)
+ end,
{next_state, StateName, State}.
%%--------------------------------------------------------------------
@@ -1706,6 +1729,15 @@ disconnect_fun(Reason, Opts) ->
catch Fun(Reason)
end.
+unexpected_fun(UnexpectedMessage, Opts, #ssh{peer={_,Peer}}) ->
+ case proplists:get_value(unexpectedfun, Opts) of
+ undefined ->
+ report;
+ Fun ->
+ catch Fun(UnexpectedMessage, Peer)
+ end.
+
+
check_cache(#state{opts = Opts} = State, Cache) ->
%% Check the number of entries in Cache
case proplists:get_value(size, ets:info(Cache)) of