View Source net_kernel (kernel v9.3)
Erlang networking kernel.
The net kernel is a system process, registered as net_kernel
, which must be
operational for distributed Erlang to work. The purpose of this process is to
implement parts of the BIFs spawn/4
and
spawn_link/4
, and to provide monitoring of the network.
An Erlang node is started using command-line flag -name
or -sname
:
$ erl -sname foobar
It is also possible to call net_kernel:start(foobar, #{})
directly from the normal Erlang shell prompt:
1> net_kernel:start(foobar, #{name_domain => shortnames}).
{ok,<0.64.0>}
(foobar@gringotts)2>
If the node is started with command-line flag -sname
, the node name is
foobar@Host
, where Host
is the short name of the host (not the fully
qualified domain name). If started with flag -name
, the node name is
foobar@Host
, where Host
is the fully qualified domain name. For more
information, see erl
.
Normally, connections are established automatically when another node is
referenced. This functionality can be disabled by setting Kernel configuration
parameter dist_auto_connect
to never
, see kernel(6)
. In
this case, connections must be established explicitly by calling
connect_node/1
.
Which nodes that are allowed to communicate with each other is handled by the magic cookie system, see section Distributed Erlang in the Erlang Reference Manual.
Warning
Starting a distributed node without also specifying
-proto_dist inet_tls
will expose the node to attacks that may give the attacker complete access to the node and in extension the cluster. When using un-secure distributed nodes, make sure that the network is configured to keep potential attackers out. See the Using SSL for Erlang Distribution User's Guide for details on how to setup a secure distributed node.
Summary
Functions
Permits access to the specified set of nodes.
Establishes a connection to Node
. Returns true
if a connection was
established or was already established or if Node
is the local node itself.
Returns false
if the connection attempt failed, and ignored
if the local
node is not alive.
Returns currently used net tick time in seconds. For more information see the
net_ticktime
kernel(6)
parameter.
Get the current state of the distribution for the local node.
Get one or more options for the distribution socket connected to Node
.
Equivalent to monitor_nodes/2
.
The calling process subscribes or unsubscribes to node status change messages. A
nodeup
message is delivered to all subscribing processes when a new node is
connected, and a nodedown
message is delivered when a node is disconnected.
Equivalent to set_net_ticktime/2
.
Sets net_ticktime
(see kernel(6)
) to NetTicktime
seconds.
TransitionPeriod
defaults to 60
.
Set one or more options for distribution sockets. Argument Node
can be either
one node name or the atom new
to affect the distribution sockets of all future
connected nodes.
Turns a non-distributed node into a distributed node by starting net_kernel
and other necessary processes.
Types
-type connection_state() :: pending | up | up_pending.
-type connection_type() :: normal | hidden.
Functions
-spec allow(Nodes) -> ok | error when Nodes :: [node()].
Permits access to the specified set of nodes.
Before the first call to allow/1
, any node with the correct
cookie can be connected. When allow/1
is called, a list of
allowed nodes is established. Any access attempts made from (or to) nodes not in
that list will be rejected.
Subsequent calls to allow/1
will add the specified nodes to the
list of allowed nodes. It is not possible to remove nodes from the list.
Returns error
if any element in Nodes
is not an atom.
Establishes a connection to Node
. Returns true
if a connection was
established or was already established or if Node
is the local node itself.
Returns false
if the connection attempt failed, and ignored
if the local
node is not alive.
-spec get_net_ticktime() -> Res when Res :: NetTicktime | {ongoing_change_to, NetTicktime} | ignored, NetTicktime :: pos_integer().
Returns currently used net tick time in seconds. For more information see the
net_ticktime
kernel(6)
parameter.
Defined return values (Res
):
NetTicktime
-net_ticktime
isNetTicktime
seconds.{ongoing_change_to, NetTicktime}
-net_kernel
is currently changingnet_ticktime
toNetTicktime
seconds.ignored
- The local node is not alive.
-spec get_state() -> #{started => no | static | dynamic, name => atom(), name_type => static | dynamic, name_domain => shortnames | longnames}.
Get the current state of the distribution for the local node.
Returns a map with (at least) the following key-value pairs:
started => Started
- Valid values forStarted
:no
- The distribution is not started. In this state none of the other keys below are present in the map.static
- The distribution was started with command line arguments-name
or-sname
.dynamic
- The distribution was started withnet_kernel:start/1
and can be stopped withnet_kernel:stop/0
.
name => Name
- The name of the node. Same as returned byerlang:node/0
except whenname_type
isdynamic
in which caseName
may beundefined
(instead ofnonode@nohost
).name_type => NameType
- Valid values forNameType
:static
- The node has a static node name set by the node itself.dynamic
- The distribution was started in dynamic node name mode, and will get its node name assigned from the first node it connects to. If keyname
has valueundefined
that has not happened yet.
name_domain => NameDomain
- Valid values forNameDomain
:shortnames
- The distribution was started to use node names with a short host portion (not fully qualified).longnames
- The distribution was started to use node names with a long fully qualified host portion.
-spec getopts(Node, Options) -> {ok, OptionValues} | {error, Reason} | ignored when Node :: node(), Options :: [inet:socket_getopt()], OptionValues :: [inet:socket_setopt()], Reason :: inet:posix() | noconnection.
Get one or more options for the distribution socket connected to Node
.
If Node
is a connected node the return value is the same as from
inet:getopts(Sock, Options)
where Sock
is the
distribution socket for Node
.
Returns ignored
if the local node is not alive or {error, noconnection}
if
Node
is not connected.
Equivalent to monitor_nodes/2
.
-spec monitor_nodes(Flag, Options) -> ok | Error when Flag :: boolean(), Options :: OptionsList | OptionsMap, OptionsList :: [ListOption], ListOption :: connection_id | {node_type, NodeType} | nodedown_reason, OptionsMap :: #{connection_id => boolean(), node_type => NodeType, nodedown_reason => boolean()}, NodeType :: visible | hidden | all, Error :: error | {error, term()}.
The calling process subscribes or unsubscribes to node status change messages. A
nodeup
message is delivered to all subscribing processes when a new node is
connected, and a nodedown
message is delivered when a node is disconnected.
If Flag
is true
, a new subscription is started. If Flag
is false
, all
previous subscriptions started with the same Options
are stopped. Two option
lists are considered the same if they contain the same set of options.
Delivery guarantees of nodeup
/nodedown
messages:
nodeup
messages are delivered before delivery of any signals from the remote node through the newly established connection.nodedown
messages are delivered after all the signals from the remote node over the connection have been delivered.nodeup
messages are delivered after the corresponding node appears in results fromerlang:nodes()
.nodedown
messages are delivered after the corresponding node has disappeared in results fromerlang:nodes()
.- As of OTP 23.0, a
nodedown
message for a connection being taken down will be delivered before anodeup
message due to a new connection to the same node. Prior to OTP 23.0, this was not guaranteed to be the case.
The format of the node status change messages depends on Options
. If Options
is the empty list or if net_kernel:monitor_nodes/1
is called, the format is as
follows:
{nodeup, Node} | {nodedown, Node}
Node = node()
When Options
is the empty map or empty list, the caller will only subscribe
for status change messages for visible nodes. That is, only nodes that appear in
the result of erlang:nodes/0
.
If Options
equals anything other than the empty list, the format of the status
change messages is as follows:
{nodeup, Node, Info} | {nodedown, Node, Info}
Node = node()
Info = #{Tag => Val} | [{Tag, Val}]
Info
is either a map or a list of 2-tuples. Its content depends on Options
.
If Options
is a map, Info
will also be a map. If Options
is a list, Info
will also be a list.
When Options
is a map, currently the following associations are allowed:
connection_id => boolean()
- If the value of the association equalstrue
, aconnection_id => ConnectionId
association will be included in theInfo
map whereConnectionId
is the connection identifier of the connection coming up or going down. For more info about this connection identifier see the documentation of erlang:nodes/2.node_type => NodeType
- Valid values forNodeType
:visible
- Subscribe to node status change messages for visible nodes only. The associationnode_type => visible
will be included in theInfo
map.hidden
- Subscribe to node status change messages for hidden nodes only. The associationnode_type => hidden
will be included in theInfo
map.all
- Subscribe to node status change messages for both visible and hidden nodes. The associationnode_type => visible | hidden
will be included in theInfo
map.
If no
node_type => NodeType
association is included in theOptions
map, the caller will subscribe for status change messages for visible nodes only, but nonode_type => visible
association will be included in theInfo
map.nodedown_reason => boolean()
- If the value of the association equalstrue
, anodedown_reason => Reason
association will be included in theInfo
map fornodedown
messages.Reason
can, depending on which distribution module or process that is used, be any term, but for the standard TCP distribution module it is one of the following:connection_setup_failed
- The connection setup failed (afternodeup
messages were sent).no_network
- No network is available.net_kernel_terminated
- Thenet_kernel
process terminated.shutdown
- Unspecified connection shutdown.connection_closed
- The connection was closed.disconnect
- The connection was disconnected (forced from the current node).net_tick_timeout
- Net tick time-out.send_net_tick_failed
- Failed to send net tick over the connection.get_status_failed
- Status information retrieval from thePort
holding the connection failed.
When Options
is a list, currently ListOption
can be one of the following:
connection_id
- A{connection_id, ConnectionId}
tuple will be included inInfo
whereConnectionId
is the connection identifier of the connection coming up or going down. For more info about this connection identifier see the documentation of erlang:nodes/2.{node_type, NodeType}
- Valid values forNodeType
:visible
- Subscribe to node status change messages for visible nodes only. The tuple{node_type, visible}
will be included in theInfo
list.hidden
- Subscribe to node status change messages for hidden nodes only. The tuple{node_type, hidden}
will be included in theInfo
list.all
- Subscribe to node status change messages for both visible and hidden nodes. The tuple{node_type, visible | hidden}
will be included in theInfo
list.
If no
{node_type, NodeType}
option has been given. The caller will subscribe for status change messages for visible nodes only, but no{node_type, visible}
tuple will be included in theInfo
list.nodedown_reason
- The tuple{nodedown_reason, Reason}
will be included in theInfo
list fornodedown
messages.See the documentation of the
nodedown_reason => boolean()
association above for information about possibleReason
values.
Example:
(a@localhost)1> net_kernel:monitor_nodes(true, #{connection_id=>true, node_type=>all, nodedown_reason=>true}).
ok
(a@localhost)2> flush().
Shell got {nodeup,b@localhost,
#{connection_id => 3067552,node_type => visible}}
Shell got {nodeup,c@localhost,
#{connection_id => 13892107,node_type => hidden}}
Shell got {nodedown,b@localhost,
#{connection_id => 3067552,node_type => visible,
nodedown_reason => connection_closed}}
Shell got {nodedown,c@localhost,
#{connection_id => 13892107,node_type => hidden,
nodedown_reason => net_tick_timeout}}
Shell got {nodeup,b@localhost,
#{connection_id => 3067553,node_type => visible}}
ok
(a@localhost)3>
-spec set_net_ticktime(NetTicktime) -> Res when NetTicktime :: pos_integer(), Res :: unchanged | change_initiated | {ongoing_change_to, NewNetTicktime}, NewNetTicktime :: pos_integer().
Equivalent to set_net_ticktime/2
.
-spec set_net_ticktime(NetTicktime, TransitionPeriod) -> Res when NetTicktime :: pos_integer(), TransitionPeriod :: non_neg_integer(), Res :: unchanged | change_initiated | {ongoing_change_to, NewNetTicktime}, NewNetTicktime :: pos_integer().
Sets net_ticktime
(see kernel(6)
) to NetTicktime
seconds.
TransitionPeriod
defaults to 60
.
Some definitions:
Minimum transition traffic interval (
MTTI
) -minimum(NetTicktime, PreviousNetTicktime)*1000 div 4
milliseconds.Transition period - The time of the least number of consecutive
MTTI
s to coverTransitionPeriod
seconds following the call toset_net_ticktime/2
(that is, ((TransitionPeriod*1000 - 1) div MTTI + 1)*MTTI
milliseconds).
If NetTicktime < PreviousNetTicktime
, the net_ticktime
change is done at the
end of the transition period; otherwise at the beginning. During the transition
period, net_kernel
ensures that there is outgoing traffic on all connections
at least every MTTI
millisecond.
Note
The
net_ticktime
changes must be initiated on all nodes in the network (with the sameNetTicktime
) before the end of any transition period on any node; otherwise connections can erroneously be disconnected.
Returns one of the following:
unchanged
-net_ticktime
already has the value ofNetTicktime
and is left unchanged.change_initiated
-net_kernel
initiated the change ofnet_ticktime
toNetTicktime
seconds.{ongoing_change_to, NewNetTicktime}
- The request is ignored becausenet_kernel
is busy changingnet_ticktime
toNewNetTicktime
seconds.
-spec setopts(Node, Options) -> ok | {error, Reason} | ignored when Node :: node() | new, Options :: [inet:socket_setopt()], Reason :: inet:posix() | noconnection.
Set one or more options for distribution sockets. Argument Node
can be either
one node name or the atom new
to affect the distribution sockets of all future
connected nodes.
The return value is the same as from inet:setopts/2
or {error, noconnection}
if Node
is not a connected node or new
.
If Node
is new
the Options
will then also be added to kernel configuration
parameters inet_dist_listen_options
and inet_dist_connect_options.
Returns ignored
if the local node is not alive.
-spec start(Options) -> {ok, pid()} | {error, Reason} when Options :: [Name | NameDomain | TickTime, ...], Name :: atom(), NameDomain :: shortnames | longnames, TickTime :: pos_integer(), Reason :: {already_started, pid()} | term().
Warning
Turns a non-distributed node into a distributed node by starting net_kernel
and other necessary processes.
Options
list can only be exactly one of the following lists (order is
imporant):
[Name]
- The same asnet_kernel:start([Name, longnames, 15000])
.[Name, NameDomain]
- The same asnet_kernel:start([Name, NameDomain, 15000])
.[Name, NameDomain, TickTime]
- The same asnet_kernel:start(Name, #{name_domain => NameDomain, net_ticktime => ((TickTime*4-1) div 1000) + 1, net_tickintensity => 4})
. Note thatTickTime
is not the same as net tick time expressed in milliseconds.TickTime
is the time between ticks when net tick intensity equals4
.
-spec start(Name, Options) -> {ok, pid()} | {error, Reason} when Options :: #{name_domain => NameDomain, net_ticktime => NetTickTime, net_tickintensity => NetTickIntensity, dist_listen => boolean(), hidden => boolean()}, Name :: atom(), NameDomain :: shortnames | longnames, NetTickTime :: pos_integer(), NetTickIntensity :: 4..1000, Reason :: {already_started, pid()} | term().
Turns a non-distributed node into a distributed node by starting net_kernel
and other necessary processes.
If Name
is set to undefined
the distribution will be started to request a
dynamic node name from the first node it connects to. See
Dynamic Node Name. Setting Name
to
undefined
implies options dist_listen => false
and hidden => true
.
Currently supported options:
name_domain => NameDomain
- Determines the host name part of the node name. IfNameDomain
equalslongnames
, fully qualified domain names will be used which also is the default. IfNameDomain
equalsshortnames
, only the short name of the host will be used.net_ticktime => NetTickTime
- Net tick time to use in seconds. Defaults to the value of thenet_ticktime
kernel(6)
parameter. For more information about net tick time, see thekernel
parameter. However, note that if the value of thekernel
parameter is invalid, it will silently be replaced by a valid value, but if an invalidNetTickTime
value is passed as option value to this function, the call will fail.net_tickintensity => NetTickIntensity
- Net tick intensity to use. Defaults to the value of thenet_tickintensity
kernel(6)
parameter. For more information about net tick intensity, see thekernel
parameter. However, note that if the value of thekernel
parameter is invalid, it will silently be replaced by a valid value, but if an invalidNetTickIntensity
value is passed as option value to this function, the call will fail.dist_listen => boolean()
- Enable or disable listening for incoming connections. Defaults to the value of the-dist_listen
erl
command line argument. Note thatdist_listen => false
implieshidden => true
.If
undefined
has been passed asName
, thedist_listen
option will be overridden withdist_listen => false
.hidden => boolean()
- Enable or disable hidden node. Defaults totrue
if the-hidden
erl
command line argument has been passed; otherwisefalse
.If
undefined
has been passed asName
, or the optiondist_listen
equalsfalse
, thehidden
option will be overridden withhidden => true
.
-spec stop() -> ok | {error, Reason} when Reason :: not_allowed | not_found.
Turns a distributed node into a non-distributed node. For other nodes in the
network, this is the same as the node going down. Only possible when the net
kernel was started using start/2
, otherwise {error, not_allowed}
is
returned. Returns {error, not_found}
if the local node is not alive.