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

openSUSE Build Service is sponsored by