File 3061-ssh-implemented-get_sock_opts-2-and-get_sock_opts-2.patch of Package erlang
From a616bcfa7c0af0bd555a98193d2d37f3c9d9d9df Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Wed, 19 Feb 2020 16:39:55 +0100
Subject: [PATCH 1/2] ssh: implemented get_sock_opts/2 and get_sock_opts/2
---
lib/ssh/doc/src/ssh.xml | 35 ++++++++++++++++++++++++++++
lib/ssh/src/ssh.erl | 20 ++++++++++++++++
lib/ssh/src/ssh_connection_handler.erl | 42 +++++++++++++++++++++++++++++++++-
3 files changed, 96 insertions(+), 1 deletion(-)
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index aa0fbe376c..862f79ac56 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -1107,6 +1107,41 @@
</desc>
</func>
+<!-- SET_SOCK_OPTS/2 -->
+ <func>
+ <name name="set_sock_opts" arity="2" since=""/>
+ <fsummary>Set tcp socket options on connections</fsummary>
+ <desc>
+ <p>Sets tcp socket options on the tcp-socket below an ssh connection.</p>
+ <p>This function calls the
+ <seealso marker="kernel:inet#setopts/2">inet:setopts/2</seealso>, read that documentation and
+ for <seealso marker="kernel:gen_tcp#type-option">gen_tcp:option()</seealso>.
+ All gen_tcp socket options except <c>active</c>, <c>deliver</c>, <c>mode</c> and <c>packet</c>
+ are allowed. The excluded options are reserved by the SSH application.
+ </p>
+ <warning>
+ <p>This is an extremly dangerous function. You use it on your own risk.</p>
+ <p>Some options are OS and OS version dependent.
+ Do not use it unless you know what effect your option values will have
+ on an TCP stream.</p>
+ <p>Some values may destroy the functionality of the SSH protocol.
+ </p>
+ </warning>
+ </desc>
+ </func>
+
+<!-- GET_SOCK_OPTS/2 -->
+ <func>
+ <name name="get_sock_opts" arity="2" since=""/>
+ <fsummary>Get tcp socket options on connections</fsummary>
+ <desc>
+ <p>Get tcp socket option values of the tcp-socket below an ssh connection.</p>
+ <p>This function calls the
+ <seealso marker="kernel:inet#getopts/2">inet:getopts/2</seealso>, read that documentation.
+ </p>
+ </desc>
+ </func>
+
<!-- DAEMON/1,2,3 -->
<func>
<name since="">daemon(Port | TcpSocket) -> Result</name>
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index c93b796078..355b40eea8 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -34,6 +34,7 @@
channel_info/3,
daemon/1, daemon/2, daemon/3,
daemon_info/1,
+ set_sock_opts/2, get_sock_opts/2,
default_algorithms/0,
chk_algos_opts/1,
stop_listener/1, stop_listener/2, stop_listener/3,
@@ -480,6 +481,25 @@ chk_algos_opts(Opts) ->
{error, {non_algo_opts_found,OtherOps}}
end.
+
+%%--------------------------------------------------------------------
+-spec set_sock_opts(ConnectionRef, SocketOptions) ->
+ ok | {error, inet:posix()} when
+ ConnectionRef :: connection_ref(),
+ SocketOptions :: [gen_tcp:option()] .
+%%--------------------------------------------------------------------
+set_sock_opts(ConnectionRef, SocketOptions) ->
+ ssh_connection_handler:set_sock_opts(ConnectionRef, SocketOptions).
+
+%%--------------------------------------------------------------------
+-spec get_sock_opts(ConnectionRef, SocketGetOptions) ->
+ ok | {error, inet:posix()} when
+ ConnectionRef :: connection_ref(),
+ SocketGetOptions :: [gen_tcp:option_name()] .
+%%--------------------------------------------------------------------
+get_sock_opts(ConnectionRef, SocketGetOptions) ->
+ ssh_connection_handler:get_sock_opts(ConnectionRef, SocketGetOptions).
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index d200dac33c..e8c0d88e59 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -57,7 +57,8 @@
channel_info/3,
adjust_window/3, close/2,
disconnect/4,
- get_print_info/1
+ get_print_info/1,
+ set_sock_opts/2, get_sock_opts/2
]).
-type connection_ref() :: ssh:connection_ref().
@@ -321,6 +322,31 @@ close(ConnectionHandler, ChannelId) ->
ok
end.
+
+%%--------------------------------------------------------------------
+%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+set_sock_opts(ConnectionRef, SocketOptions) ->
+ try lists:foldr(fun({Name,_Val}, Acc) ->
+ case lists:member(Name, [active, deliver, mode, packet]) of
+ true -> [Name|Acc];
+ false -> Acc
+ end
+ end, [], SocketOptions)
+ of
+ [] ->
+ call(ConnectionRef, {set_sock_opts,SocketOptions});
+ Bad ->
+ {error, {not_allowed,Bad}}
+ catch
+ _:_ ->
+ {error, badarg}
+ end.
+
+%%--------------------------------------------------------------------
+%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+get_sock_opts(ConnectionRef, SocketGetOptions) ->
+ call(ConnectionRef, {get_sock_opts,SocketGetOptions}).
+
%%====================================================================
%% Test support
%%====================================================================
@@ -1205,6 +1231,20 @@ handle_event({call,From}, {info, ChannelPid}, _, D) ->
end, [], cache(D)),
{keep_state_and_data, [{reply, From, {ok,Result}}]};
+handle_event({call,From}, {set_sock_opts,SocketOptions}, _StateName, D) ->
+ Result = try inet:setopts(D#data.socket, SocketOptions)
+ catch
+ _:_ -> {error, badarg}
+ end,
+ {keep_state_and_data, [{reply,From,Result}]};
+
+handle_event({call,From}, {get_sock_opts,SocketGetOptions}, _StateName, D) ->
+ Result = try inet:getopts(D#data.socket, SocketGetOptions)
+ catch
+ _:_ -> {error, badarg}
+ end,
+ {keep_state_and_data, [{reply,From,Result}]};
+
handle_event({call,From}, stop, _StateName, D0) ->
{Repls,D} = send_replies(ssh_connection:handle_stop(D0#data.connection_state), D0),
{stop_and_reply, normal, [{reply,From,ok}|Repls], D};
--
2.16.4