Skip to content

Commit

Permalink
rabbit_peer_discovery: Pass inetrc config file to temporary hidden node
Browse files Browse the repository at this point in the history
[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.
  • Loading branch information
dumbbell committed Mar 16, 2024
1 parent 07242c2 commit 22c1e5e
Showing 1 changed file with 41 additions and 27 deletions.
68 changes: 41 additions & 27 deletions deps/rabbit/src/rabbit_peer_discovery.erl
Expand Up @@ -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]),
Expand All @@ -423,27 +425,39 @@ 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]]} ->
Mod = list_to_existing_atom(Val),
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("~p", [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:
%%
Expand Down Expand Up @@ -494,14 +508,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:
Expand All @@ -511,13 +525,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
Expand Down

0 comments on commit 22c1e5e

Please sign in to comment.