summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Larsson <lukas@erlang.org>2019-12-12 16:01:06 +0100
committerSverker Eriksson <sverker@erlang.org>2020-03-19 15:58:12 +0100
commit7a7c90be0e87cb3b4920de5aaf215c4b9cebcb30 (patch)
tree722a7463479ac39de41c26cb508abe0446bf6eaa
parenta8cac323f014c4b6f7160b6dbd71a19c81cd255b (diff)
downloaderlang-7a7c90be0e87cb3b4920de5aaf215c4b9cebcb30.tar.gz
kernel: Add -dist_listen false option
This option makes it so that the distribution no longer listens for incoming connections. This way the node does not need to occupy a tcp port, but it also cannot be part of any global groups.
-rw-r--r--erts/doc/src/alt_dist.xml13
-rw-r--r--lib/crypto/src/crypto.erl2
-rw-r--r--lib/kernel/src/global_group.erl20
-rw-r--r--lib/kernel/src/inet6_tcp_dist.erl10
-rw-r--r--lib/kernel/src/inet_tcp_dist.erl16
-rw-r--r--lib/kernel/src/net_kernel.erl54
6 files changed, 99 insertions, 16 deletions
diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml
index 66b22a7a1c..82ff47f3d4 100644
--- a/erts/doc/src/alt_dist.xml
+++ b/erts/doc/src/alt_dist.xml
@@ -231,6 +231,19 @@
</p>
</item>
+ <tag><marker id="address"/><c>address() -></c><br/>&nbsp;&nbsp;<c>Address</c></tag>
+ <item>
+ <p><c>address/0</c> is called in order to get the <c>Address</c> part of the
+ <seealso marker="#listen"><c>listen/2</c></seealso> function without creating
+ a listen socket. All fields except <c>address</c> have to be set in the returned
+ record</p>
+ <p>Example:</p>
+ <code type="erl">address() ->
+ {ok, Host} = inet:gethostname(),
+ #net_address{ host = Host, protocol = tcp, family = inet6 }.
+ </code>
+ </item>
+
<tag><marker id="accept"/><c>accept(Listen) -></c><br/>&nbsp;&nbsp;<c>AcceptorPid</c></tag>
<item>
<p>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 2632db4f18..898a139768 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -2517,7 +2517,7 @@ on_load() ->
filename:join([PrivDir, "lib",
erlang:system_info(system_architecture)]),
Candidate =
- filelib:wildcard(filename:join([ArchLibDir,LibName ++ "*" ])),
+ filelib:wildcard(filename:join([ArchLibDir,LibName ++ "*" ]),erl_prim_loader),
case Candidate of
[] -> Error1;
_ ->
diff --git a/lib/kernel/src/global_group.erl b/lib/kernel/src/global_group.erl
index f5ead2a4c5..09b058af2f 100644
--- a/lib/kernel/src/global_group.erl
+++ b/lib/kernel/src/global_group.erl
@@ -1312,16 +1312,20 @@ get_own_nodes() ->
%%% -hidden command line argument
%%%====================================================================================
publish_arg() ->
- case init:get_argument(hidden) of
- {ok,[[]]} ->
- hidden;
- {ok,[["true"]]} ->
- hidden;
- _ ->
- normal
+ case net_kernel:dist_listen() of
+ false ->
+ hidden;
+ _ ->
+ case init:get_argument(hidden) of
+ {ok,[[]]} ->
+ hidden;
+ {ok,[["true"]]} ->
+ hidden;
+ _ ->
+ normal
+ end
end.
-
%%%====================================================================================
%%% Own group publication type and nodes
%%%====================================================================================
diff --git a/lib/kernel/src/inet6_tcp_dist.erl b/lib/kernel/src/inet6_tcp_dist.erl
index 9b6c2745d5..79f69bfa4c 100644
--- a/lib/kernel/src/inet6_tcp_dist.erl
+++ b/lib/kernel/src/inet6_tcp_dist.erl
@@ -22,7 +22,7 @@
%% Handles the connection setup phase with other Erlang nodes.
-export([listen/1, accept/1, accept_connection/5,
- setup/5, close/1, select/1, is_node_name/1]).
+ setup/5, close/1, select/1, address/0, is_node_name/1]).
-export([setopts/2, getopts/2]).
@@ -35,6 +35,14 @@ select(Node) ->
inet_tcp_dist:gen_select(inet6_tcp, Node).
%% ------------------------------------------------------------
+%% Get address family
+%% address() => #net_address{}
+%% ------------------------------------------------------------
+
+address() ->
+ inet_tcp_dist:gen_address(inet6_tcp).
+
+%% ------------------------------------------------------------
%% Create the listen socket, i.e. the port that this erlang
%% node is accessible through.
%% ------------------------------------------------------------
diff --git a/lib/kernel/src/inet_tcp_dist.erl b/lib/kernel/src/inet_tcp_dist.erl
index c5a114a9ef..2ce7e4f474 100644
--- a/lib/kernel/src/inet_tcp_dist.erl
+++ b/lib/kernel/src/inet_tcp_dist.erl
@@ -22,14 +22,14 @@
%% Handles the connection setup phase with other Erlang nodes.
-export([listen/1, accept/1, accept_connection/5,
- setup/5, close/1, select/1, is_node_name/1]).
+ setup/5, close/1, select/1, address/0, is_node_name/1]).
%% Optional
-export([setopts/2, getopts/2]).
%% Generalized dist API
-export([gen_listen/2, gen_accept/2, gen_accept_connection/6,
- gen_setup/6, gen_select/2]).
+ gen_setup/6, gen_select/2, gen_address/1]).
%% internal exports
@@ -64,6 +64,14 @@ gen_select(Driver, Node) ->
end.
%% ------------------------------------------------------------
+%% Get the address family that this distribution uses
+%% ------------------------------------------------------------
+address() ->
+ gen_address(inet_tcp).
+gen_address(Driver) ->
+ get_tcp_address(Driver).
+
+%% ------------------------------------------------------------
%% Create the listen socket, i.e. the port that this erlang
%% node is accessible through.
%% ------------------------------------------------------------
@@ -436,9 +444,11 @@ split_node([], _, Ack) -> [lists:reverse(Ack)].
%% ------------------------------------------------------------
get_tcp_address(Driver, Socket) ->
{ok, Address} = inet:sockname(Socket),
+ NetAddr = get_tcp_address(Driver),
+ NetAddr#net_address{ address = Address }.
+get_tcp_address(Driver) ->
{ok, Host} = inet:gethostname(),
#net_address {
- address = Address,
host = Host,
protocol = tcp,
family = Driver:family()
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index b857000a80..ce4966684a 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.erl
@@ -68,7 +68,8 @@
kernel_apply/3,
longnames/0,
protocol_childspecs/0,
- epmd_module/0]).
+ epmd_module/0,
+ dist_listen/0]).
-export([disconnect/1, passive_cnct/1]).
-export([hidden_connect_node/1]).
@@ -693,7 +694,10 @@ terminate(no_network, State) ->
terminate(_Reason, State) ->
lists:foreach(
fun(#listen {listen = Listen,module = Mod}) ->
- Mod:close(Listen)
+ case Listen of
+ undefined -> ignore;
+ _ -> Mod:close(Listen)
+ end
end, State#state.listen),
lists:foreach(
fun(Node) -> ?nodedown(Node, State)
@@ -1542,6 +1546,18 @@ epmd_module() ->
end.
%%
+%% dist_listen() -> whether the erlang distribution should listen for connections
+%%
+dist_listen() ->
+ case init:get_argument(dist_listen) of
+ {ok,[[DoListen]]} ->
+ list_to_atom(DoListen) =/= false;
+ _ ->
+ true
+ end.
+
+
+%%
%% Start all protocols
%%
@@ -1553,8 +1569,13 @@ start_protos(Name, Node, CleanHalt) ->
start_protos(Name, ["inet_tcp"], Node, CleanHalt)
end.
+
+
start_protos(Name, Ps, Node, CleanHalt) ->
- case start_protos(Name, Ps, Node, [], CleanHalt) of
+ case case dist_listen() of
+ false -> start_protos_no_listen(Name, Ps, Node, [], CleanHalt);
+ _ -> start_protos(Name, Ps, Node, [], CleanHalt)
+ end of
[] ->
case CleanHalt of
true -> halt(1);
@@ -1564,6 +1585,33 @@ start_protos(Name, Ps, Node, CleanHalt) ->
{ok, Ls}
end.
+start_protos_no_listen(Name, [Proto | Ps], Node, Ls, CleanHalt) ->
+ Mod = list_to_atom(Proto ++ "_dist"),
+ case set_node(Node, create_creation()) of
+ ok ->
+ auth:sync_cookie(),
+ L = #listen {
+ listen = undefined,
+ address = Mod:address(),
+ accept = undefined,
+ module = Mod },
+ start_protos_no_listen(Name, Ps, Node, [L|Ls], CleanHalt);
+ _ ->
+ S = "invalid node name: " ++ atom_to_list(Node),
+ proto_error(CleanHalt, Proto, S),
+ start_protos_no_listen(Name, Ps, Node, Ls, CleanHalt)
+ end;
+start_protos_no_listen(_Name, [], _Node, Ls, _CleanHalt) ->
+ Ls.
+
+create_creation() ->
+ try binary:decode_unsigned(crypto:strong_rand_bytes(4)) of
+ Creation ->
+ Creation
+ catch _:_ ->
+ rand:uniform((1 bsl 32)-1)
+ end.
+
start_protos(Name, [Proto | Ps], Node, Ls, CleanHalt) ->
Mod = list_to_atom(Proto ++ "_dist"),
case catch Mod:listen(Name) of