From 10d14e41327605490f2773316ba1f9c85b067f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?= Date: Sat, 16 Mar 2024 18:06:18 +0100 Subject: [PATCH] rabbit_peer_discovery: Pass inetrc config file to temporary hidden node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Why] As shown in #10728, in an IPv6-only environment, `kernel` name resolution must be configured through an inetrc file. The temporary hidden node must be configured exactly like the main node (and all nodes in the cluster in fact) to allow communication. Thus we must pass the same inetrc file to that temporary hidden node. This wasn’t the case before this patch. [How] We query the main node’s kernel to see if there is any inetrc file set and we use the same on the temporary hidden node’s command line. While here, extract the handling of the `proto_dist` module from the TLS code. This parameter may be used outside of TLS like this IPv6-only environment. Fixes #10728. (cherry picked from commit 1bcfa473147ea1958990f217e6ce2b13fdc4225d) --- deps/rabbit/src/rabbit_peer_discovery.erl | 69 ++++++++++++++--------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/deps/rabbit/src/rabbit_peer_discovery.erl b/deps/rabbit/src/rabbit_peer_discovery.erl index a53ffe6083b3..b3f8123f40cd 100644 --- a/deps/rabbit/src/rabbit_peer_discovery.erl +++ b/deps/rabbit/src/rabbit_peer_discovery.erl @@ -388,16 +388,18 @@ query_node_props(Nodes) when Nodes =/= [] -> _ -> VMArgs1 end, - VMArgs3 = maybe_add_tls_arguments(VMArgs2), + VMArgs3 = maybe_add_proto_dist_arguments(VMArgs2), + VMArgs4 = maybe_add_inetrc_arguments(VMArgs3), + VMArgs5 = maybe_add_tls_arguments(VMArgs4), PeerStartArg = case Context of #{nodename_type := longnames} -> #{name => PeerName, host => Suffix, longnames => true, - args => VMArgs3}; + args => VMArgs5}; _ -> #{name => PeerName, - args => VMArgs3} + args => VMArgs5} end, ?LOG_DEBUG("Peer discovery: peer node arguments: ~tp", [PeerStartArg]), @@ -423,27 +425,40 @@ query_node_props(Nodes) when Nodes =/= [] -> query_node_props([]) -> []. -maybe_add_tls_arguments(VMArgs0) -> +maybe_add_proto_dist_arguments(VMArgs) -> case init:get_argument(proto_dist) of - {ok, [["inet_tls"]]} -> - add_tls_arguments(inet_tls, VMArgs0); - {ok, [["inet6_tls"]]} -> - add_tls_arguments(inet6_tls, VMArgs0); + {ok, [[Val]]} -> + %% See net_kernel.erl / protocol_childspecs/1 + Mod = list_to_existing_atom(Val ++ "_dist"), + ModDir = filename:dirname(code:which(Mod)), + ["-proto_dist", Val, "-pa", ModDir | VMArgs]; _ -> - VMArgs0 + VMArgs end. -add_tls_arguments(InetDistModule, VMArgs0) -> - VMArgs1 = case InetDistModule of - inet_tls -> - ProtoDistArg = ["-proto_dist", "inet_tls" | VMArgs0], - ["-pa", filename:dirname(code:which(inet_tls_dist)) - | ProtoDistArg]; - inet6_tls -> - ProtoDistArg = ["-proto_dist", "inet6_tls" | VMArgs0], - ["-pa", filename:dirname(code:which(inet6_tls_dist)) - | ProtoDistArg] - end, +maybe_add_inetrc_arguments(VMArgs) -> + %% If an inetrc file is configured, we need to use it for the temporary + %% hidden node too. + case application:get_env(kernel, inetrc) of + {ok, Val} when is_list(Val) -> + maybe_add_inetrc_arguments1(VMArgs, Val); + undefined -> + case os:getenv("ERL_INETRC") of + Val when is_list(Val) -> + maybe_add_inetrc_arguments1(VMArgs, Val); + false -> + VMArgs + end + end. + +maybe_add_inetrc_arguments1(VMArgs, Val) -> + %% The filename argument must be passed as a quoted string so that the + %% command line is correctly parsed as an Erlang string by the temporary + %% hidden node. + ValString = rabbit_misc:format("~0p", [Val]), + ["-kernel", "inetrc", ValString | VMArgs]. + +maybe_add_tls_arguments(VMArgs) -> %% In the next case, RabbitMQ has been configured with additional Erlang VM %% arguments such as this: %% @@ -494,14 +509,14 @@ add_tls_arguments(InetDistModule, VMArgs0) -> %% "/usr/local/lib/erlang/lib/ssl-11.0.3/ebin", %% "-proto_dist","inet_tls","-boot", %% "no_dot_erlang","-hidden"], - VMArgs2 = case init:get_argument(ssl_dist_opt) of + VMArgs1 = case init:get_argument(ssl_dist_opt) of {ok, SslDistOpts0} -> SslDistOpts1 = [["-ssl_dist_opt" | SslDistOpt] || SslDistOpt <- SslDistOpts0], SslDistOpts2 = lists:concat(SslDistOpts1), - SslDistOpts2 ++ VMArgs1; + SslDistOpts2 ++ VMArgs; _ -> - VMArgs1 + VMArgs end, %% In the next case, RabbitMQ has been configured with additional Erlang VM %% arguments such as this: @@ -511,13 +526,13 @@ add_tls_arguments(InetDistModule, VMArgs0) -> %% %% This code adds the `ssl_dist_optfile' argument to the peer node's %% argument list. - VMArgs3 = case init:get_argument(ssl_dist_optfile) of + VMArgs2 = case init:get_argument(ssl_dist_optfile) of {ok, [[SslDistOptfileArg]]} -> - ["-ssl_dist_optfile", SslDistOptfileArg | VMArgs2]; + ["-ssl_dist_optfile", SslDistOptfileArg | VMArgs1]; _ -> - VMArgs2 + VMArgs1 end, - VMArgs3. + VMArgs2. do_query_node_props(Nodes) when Nodes =/= [] -> %% Make sure all log messages are forwarded from this temporary hidden