File 0742-ssl-Fix-erl_epmd-address_please-callback.patch of Package erlang

From 9437f3ebfd3416a55efa28f853e3c4eee9f54a5d Mon Sep 17 00:00:00 2001
From: Lukas Larsson <lukas@erlang.org>
Date: Fri, 26 Nov 2021 10:07:37 +0100
Subject: [PATCH] ssl: Fix erl_epmd address_please callback

The selection of which ip version to use used DNS to
do the lookup when it should use erl_epmd. Also, the
ip address gotten from erl_epmd:address_please was not
used when doing the actual connect.

Closes #5334
---
 lib/ssl/src/inet_tls_dist.erl      | 14 ++----
 lib/ssl/test/ssl_dist_SUITE.erl    | 68 ++++++++++++++++++++++++++++--
 lib/ssl/test/ssl_dist_test_lib.erl | 48 +++++++++++----------
 3 files changed, 94 insertions(+), 36 deletions(-)

diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl
index 5cfbeff387..cddc4f90bf 100644
--- a/lib/ssl/src/inet_tls_dist.erl
+++ b/lib/ssl/src/inet_tls_dist.erl
@@ -53,15 +53,7 @@ select(Node) ->
     gen_select(inet_tcp, Node).
 
 gen_select(Driver, Node) ->
-    case dist_util:split_node(Node) of
-        {node,_,Host} ->
-	    case Driver:getaddr(Host) of
-		{ok, _} -> true;
-		_ -> false
-	    end;
-        _ ->
-            false
-    end.
+    inet_tcp_dist:gen_select(Driver, Node).
 
 %% ------------------------------------------------------------
 %% Get the address family that this distribution uses
@@ -582,8 +574,8 @@ do_setup_connect(Driver, Kernel, Node, Address, Ip, TcpPort, Version, Type, MyNo
     Opts =  trace(connect_options(get_ssl_options(client))),
     dist_util:reset_timer(Timer),
     case ssl:connect(
-        Address, TcpPort,
-        [binary, {active, false}, {packet, 4},
+        Ip, TcpPort,
+        [binary, {active, false}, {packet, 4}, {server_name_indication, Address},
             Driver:family(), {nodelay, true}] ++ Opts,
         net_kernel:connecttime()) of
     {ok, #sslsocket{pid = [_, DistCtrl| _]} = SslSocket} ->
diff --git a/lib/ssl/test/ssl_dist_SUITE.erl b/lib/ssl/test/ssl_dist_SUITE.erl
index 67be91196f..5c8a8d9138 100644
--- a/lib/ssl/test/ssl_dist_SUITE.erl
+++ b/lib/ssl/test/ssl_dist_SUITE.erl
@@ -58,7 +58,9 @@
          verify_fun_fail/0,
          verify_fun_fail/1,
          verify_fun_pass/0,
-         verify_fun_pass/1
+         verify_fun_pass/1,
+         epmd_module/0,
+         epmd_module/1
          ]).
 
 %% Apply export
@@ -75,6 +77,12 @@
          verify_pass_always/3,
          verify_fail_always/3]).
 
+%% Epmd module export
+-export([start_link/0,
+         register_node/2,
+         register_node/3,
+         port_please/2,
+         address_please/3]).
 
 -define(DEFAULT_TIMETRAP_SECS, 240).
 -define(AWAIT_SSL_NODE_UP_TIMEOUT, 30000).
@@ -102,7 +110,8 @@ all() ->
      connect_options,
      use_interface,
      verify_fun_fail,
-     verify_fun_pass
+     verify_fun_pass,
+     epmd_module
     ].
 
 init_per_suite(Config0) ->
@@ -381,6 +390,53 @@ verify_fun_pass(Config) when is_list(Config) ->
 	"\"{ssl_dist_SUITE,verify_pass_always,{}}\" ",
     gen_dist_test(verify_fun_pass_test, [{tls_verify_opts, AddTLSVerifyOpts} | Config]).
 
+%%--------------------------------------------------------------------
+epmd_module() ->
+    [{doc,"Test that custom epmd_modules work"}].
+epmd_module(Config0) when is_list(Config0) ->
+    Config = [{hostname, "dummy"} | Config0],
+    NH1 = start_ssl_node(Config, "-epmd_module " ++ atom_to_list(?MODULE)),
+    NH2 = start_ssl_node(Config, "-epmd_module " ++ atom_to_list(?MODULE)),
+
+    {ok, Port1} = apply_on_ssl_node(NH1, fun() -> application:get_env(kernel, dist_listen_port) end),
+    {ok, Port2} = apply_on_ssl_node(NH2, fun() -> application:get_env(kernel, dist_listen_port) end),
+    apply_on_ssl_node(NH1, fun() -> application:set_env(kernel, dist_connect_port, Port2) end),
+    apply_on_ssl_node(NH2, fun() -> application:set_env(kernel, dist_connect_port, Port1) end),
+
+    try
+        basic_test(NH1, NH2, Config)
+    catch
+	_:Reason ->
+	    stop_ssl_node(NH1),
+	    stop_ssl_node(NH2),
+	    ct:fail(Reason)
+    end,
+    stop_ssl_node(NH1),
+    stop_ssl_node(NH2),	
+    success(Config).
+
+start_link() ->
+    ignore.
+
+register_node(Name, Port) ->
+    register_node(Name, Port, inet_tcp).
+register_node(_Name, Port, _Driver) ->
+    %% Save the port number we're listening on.
+    application:set_env(kernel, dist_listen_port, Port),
+    Creation = rand:uniform(3),
+    {ok, Creation}.
+
+port_please(_Name, _Ip) ->
+    {ok, Port} = application:get_env(kernel, dist_connect_port),
+    {port, Port, 5}.
+
+address_please(_Name, "dummy", AddressFamily) ->
+    %% Use localhost.
+    {ok,Host} = inet:gethostname(),
+    inet:getaddr(Host, AddressFamily);
+address_please(_, _, _) ->
+    {error, nxdomain}.
+
 %%--------------------------------------------------------------------
 %%% Internal functions -----------------------------------------------
 %%--------------------------------------------------------------------
@@ -653,11 +709,17 @@ start_ssl_node(Config, XArgs) ->
 mk_node_name(Config) ->
     N = erlang:unique_integer([positive]),
     Case = proplists:get_value(testcase, Config),
+    Hostname =
+        case proplists:get_value(hostname, Config) of
+            undefined -> "";
+            Host -> "@" ++ Host
+        end,
     atom_to_list(?MODULE)
 	++ "_"
 	++ atom_to_list(Case)
 	++ "_"
-	++ integer_to_list(N).
+	++ integer_to_list(N) ++ Hostname.
+
 
 setup_certs(Config) ->
     PrivDir = proplists:get_value(priv_dir, Config),
diff --git a/lib/ssl/test/ssl_dist_test_lib.erl b/lib/ssl/test/ssl_dist_test_lib.erl
index e85eddaf08..5ecc4e5b90 100644
--- a/lib/ssl/test/ssl_dist_test_lib.erl
+++ b/lib/ssl/test/ssl_dist_test_lib.erl
@@ -108,8 +108,7 @@ start_ssl_node(Name, Args) ->
 	    case await_ssl_node_up(Name, LSock) of
 		#node_handle{} = NodeHandle ->
 		    ?t:format("Ssl node ~s started.~n", [Name]),
-		    NodeName = list_to_atom(Name ++ "@" ++ host_name()),
-		    NodeHandle#node_handle{nodename = NodeName};
+		    NodeHandle;
 		Error ->
 		    exit({failed_to_start_node, Name, Error})
 	    end;
@@ -173,31 +172,36 @@ await_ssl_node_up(Name, LSock) ->
     end.
 
 check_ssl_node_up(Socket, Name, Bin) ->
+    NodeName =
+        case string:find(Name,"@") of
+            nomatch ->
+                list_to_atom(Name++"@"++host_name());
+            _ ->
+                list_to_atom(Name)
+        end,
     case catch binary_to_term(Bin) of
 	{'EXIT', _} ->
 	    gen_tcp:close(Socket),
 	    exit({bad_data_received_from_ssl_node, Name, Bin});
 	{ssl_node_up, NodeName} ->
-	    case list_to_atom(Name++"@"++host_name()) of
-		NodeName ->
-		    Parent = self(),
-		    Go = make_ref(),
-		    %% Spawn connection handler on test server side
-		    Pid = spawn(
-			    fun () ->
-                                    link(group_leader()),
-				    receive Go -> ok end,
-                                    process_flag(trap_exit, true),
-				    tstsrvr_con_loop(Name, Socket, Parent)
-			    end),
-		    ok = gen_tcp:controlling_process(Socket, Pid),
-		    Pid ! Go,
-		    #node_handle{connection_handler = Pid,
-				 socket = Socket,
-				 name = Name};
-		_ ->
-		    exit({unexpected_ssl_node_connected, NodeName})
-	    end;
+            Parent = self(),
+            Go = make_ref(),
+            %% Spawn connection handler on test server side
+            Pid = spawn(
+                    fun () ->
+                            link(group_leader()),
+                            receive Go -> ok end,
+                            process_flag(trap_exit, true),
+                            tstsrvr_con_loop(Name, Socket, Parent)
+                    end),
+            ok = gen_tcp:controlling_process(Socket, Pid),
+            Pid ! Go,
+            #node_handle{connection_handler = Pid,
+                         socket = Socket,
+                         nodename = NodeName,
+                         name = Name};
+        {ssl_node_up, OtherNodeName} ->
+            exit({unexpected_ssl_node_connected, OtherNodeName});
 	Msg ->
 	    exit({unexpected_msg_instead_of_ssl_node_up, Name, Msg})
     end.
-- 
2.31.1

openSUSE Build Service is sponsored by