.TH net_kernel 3erl "kernel 8.5.4.3" "Ericsson AB" "Erlang Module Definition" .SH NAME net_kernel \- Erlang networking kernel. .SH DESCRIPTION .LP The net kernel is a system process, registered as \fInet_kernel\fR\&, which must be operational for distributed Erlang to work\&. The purpose of this process is to implement parts of the BIFs \fIspawn/4\fR\& and \fIspawn_link/4\fR\&, and to provide monitoring of the network\&. .LP An Erlang node is started using command-line flag \fI-name\fR\& or \fI-sname\fR\&: .LP .nf $ erl -sname foobar .fi .LP It is also possible to call \fInet_kernel:start(foobar, #{})\fR\& directly from the normal Erlang shell prompt: .LP .nf 1> net_kernel:start(foobar, #{name_domain => shortnames})\&. {ok,<0.64.0>} (foobar@gringotts)2> .fi .LP If the node is started with command-line flag \fI-sname\fR\&, the node name is \fIfoobar@Host\fR\&, where \fIHost\fR\& is the short name of the host (not the fully qualified domain name)\&. If started with flag \fI-name\fR\&, the node name is \fIfoobar@Host\fR\&, where \fIHost\fR\& is the fully qualified domain name\&. For more information, see \fIerl\fR\&\&. .LP Normally, connections are established automatically when another node is referenced\&. This functionality can be disabled by setting Kernel configuration parameter \fIdist_auto_connect\fR\& to \fInever\fR\&, see \fIkernel(7)\fR\&\&. In this case, connections must be established explicitly by calling \fIconnect_node/1\fR\&\&. .LP 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\&. .LP .RS -4 .B Warning: .RE Starting a distributed node without also specifying \fI-proto_dist inet_tls\fR\& 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\&. .SH EXPORTS .LP .nf .B allow(Nodes) -> ok | error .br .fi .br .RS .LP Types: .RS 3 Nodes = [node()] .br .RE .RE .RS .LP Permits access to the specified set of nodes\&. .LP Before the first call to \fIallow/1\fR\&, any node with the correct cookie can be connected\&. When \fIallow/1\fR\& is called, a list of allowed nodes is established\&. Any access attempts made from (or to) nodes not in that list will be rejected\&. .LP Subsequent calls to \fIallow/1\fR\& will add the specified nodes to the list of allowed nodes\&. It is not possible to remove nodes from the list\&. .LP Returns \fIerror\fR\& if any element in \fINodes\fR\& is not an atom\&. .RE .LP .nf .B connect_node(Node) -> boolean() | ignored .br .fi .br .RS .LP Types: .RS 3 Node = node() .br .RE .RE .RS .LP Establishes a connection to \fINode\fR\&\&. Returns \fItrue\fR\& if a connection was established or was already established or if \fINode\fR\& is the local node itself\&. Returns \fIfalse\fR\& if the connection attempt failed, and \fIignored\fR\& if the local node is not alive\&. .RE .LP .nf .B get_net_ticktime() -> Res .br .fi .br .RS .LP Types: .RS 3 Res = NetTicktime | {ongoing_change_to, NetTicktime} | ignored .br NetTicktime = integer() >= 1 .br .RE .RE .RS .LP Returns currently used net tick time in seconds\&. For more information see the \fInet_ticktime\fR\& \fIkernel(7)\fR\& parameter\&. .LP Defined return values (\fIRes\fR\&): .RS 2 .TP 2 .B \fINetTicktime\fR\&: \fInet_ticktime\fR\& is \fINetTicktime\fR\& seconds\&. .TP 2 .B \fI{ongoing_change_to, NetTicktime}\fR\&: \fInet_kernel\fR\& is currently changing \fInet_ticktime\fR\& to \fINetTicktime\fR\& seconds\&. .TP 2 .B \fIignored\fR\&: The local node is not alive\&. .RE .RE .LP .nf .B getopts(Node, Options) -> .B {ok, OptionValues} | {error, Reason} | ignored .br .fi .br .RS .LP Types: .RS 3 Node = node() .br Options = [inet:socket_getopt()] .br OptionValues = [inet:socket_setopt()] .br Reason = inet:posix() | noconnection .br .RE .RE .RS .LP Get one or more options for the distribution socket connected to \fINode\fR\&\&. .LP If \fINode\fR\& is a connected node the return value is the same as from \fIinet:getopts(Sock, Options)\fR\& where \fISock\fR\& is the distribution socket for \fINode\fR\&\&. .LP Returns \fIignored\fR\& if the local node is not alive or \fI{error, noconnection}\fR\& if \fINode\fR\& is not connected\&. .RE .LP .nf .B get_state() -> .B #{started => no | static | dynamic, .B name => atom(), .B name_type => static | dynamic, .B name_domain => shortnames | longnames} .br .fi .br .RS .LP Get the current state of the distribution for the local node\&. .LP Returns a map with (at least) the following key-value pairs: .RS 2 .TP 2 .B \fIstarted => Started\fR\&: Valid values for \fIStarted\fR\&: .RS 2 .TP 2 .B \fIno\fR\&: The distribution is not started\&. In this state none of the other keys below are present in the map\&. .TP 2 .B \fIstatic\fR\&: The distribution was started with command line arguments \fI-name\fR\& or \fI-sname\fR\&\&. .TP 2 .B \fIdynamic\fR\&: The distribution was started with \fInet_kernel:start/1\fR\& and can be stopped with \fInet_kernel:stop/0\fR\&\&. .RE .TP 2 .B \fIname => Name\fR\&: The name of the node\&. Same as returned by \fIerlang:node/0\fR\& except when \fIname_type\fR\& is \fIdynamic\fR\& in which case \fIName\fR\& may be \fIundefined\fR\& (instead of \fInonode@nohost\fR\&)\&. .TP 2 .B \fIname_type => NameType\fR\&: Valid values for \fINameType\fR\&: .RS 2 .TP 2 .B \fIstatic\fR\&: The node has a static node name set by the node itself\&. .TP 2 .B \fIdynamic\fR\&: The distribution was started in dynamic node name mode, and will get its node name assigned from the first node it connects to\&. If key \fIname\fR\& has value \fIundefined\fR\& that has not happened yet\&. .RE .TP 2 .B \fIname_domain => NameDomain\fR\&: Valid values for \fINameDomain\fR\&: .RS 2 .TP 2 .B \fIshortnames\fR\&: The distribution was started to use node names with a short host portion (not fully qualified)\&. .TP 2 .B \fIlongnames\fR\&: The distribution was started to use node names with a long fully qualified host portion\&. .RE .RE .RE .LP .nf .B monitor_nodes(Flag) -> ok | Error .br .fi .br .nf .B monitor_nodes(Flag, Options) -> ok | Error .br .fi .br .RS .LP Types: .RS 3 Flag = boolean() .br Options = OptionsList | OptionsMap .br OptionsList = [ListOption] .br ListOption = .br connection_id | {node_type, NodeType} | nodedown_reason .br OptionsMap = .br #{connection_id => boolean(), .br node_type => NodeType, .br nodedown_reason => boolean()} .br NodeType = visible | hidden | all .br Error = error | {error, term()} .br .RE .RE .RS .LP The calling process subscribes or unsubscribes to node status change messages\&. A \fInodeup\fR\& message is delivered to all subscribing processes when a new node is connected, and a \fInodedown\fR\& message is delivered when a node is disconnected\&. .LP If \fIFlag\fR\& is \fItrue\fR\&, a new subscription is started\&. If \fIFlag\fR\& is \fIfalse\fR\&, all previous subscriptions started with the same \fIOptions\fR\& are stopped\&. Two option lists are considered the same if they contain the same set of options\&. .LP Delivery guarantees of \fInodeup\fR\&/\fInodedown\fR\& messages: .RS 2 .TP 2 * \fInodeup\fR\& messages are delivered before delivery of any signals from the remote node through the newly established connection\&. .LP .TP 2 * \fInodedown\fR\& messages are delivered after all the signals from the remote node over the connection have been delivered\&. .LP .TP 2 * \fInodeup\fR\& messages are delivered after the corresponding node appears in results from \fIerlang:nodes()\fR\&\&. .LP .TP 2 * \fInodedown\fR\& messages are delivered after the corresponding node has disappeared in results from \fIerlang:nodes()\fR\&\&. .LP .TP 2 * As of OTP 23\&.0, a \fInodedown\fR\& message for a connection being taken down will be delivered before a \fInodeup\fR\& message due to a new connection to the same node\&. Prior to OTP 23\&.0, this was not guaranteed to be the case\&. .LP .RE .LP The format of the node status change messages depends on \fIOptions\fR\&\&. If \fIOptions\fR\& is the empty list or if \fInet_kernel:monitor_nodes/1\fR\& is called, the format is as follows: .LP .nf {nodeup, Node} | {nodedown, Node} Node = node() .fi .LP When \fIOptions\fR\& 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 \fIerlang:nodes/0\fR\&\&. .LP If \fIOptions\fR\& equals anything other than the empty list, the format of the status change messages is as follows: .LP .nf {nodeup, Node, Info} | {nodedown, Node, Info} Node = node() Info = #{Tag => Val} | [{Tag, Val}] .fi .LP \fIInfo\fR\& is either a map or a list of 2-tuples\&. Its content depends on \fIOptions\fR\&\&. If \fIOptions\fR\& is a map, \fIInfo\fR\& will also be a map\&. If \fIOptions\fR\& is a list, \fIInfo\fR\& will also be a list\&. .LP When \fIOptions\fR\& is a map, currently the following associations are allowed: .RS 2 .TP 2 .B \fIconnection_id => boolean()\fR\&: If the value of the association equals \fItrue\fR\&, a \fIconnection_id => ConnectionId\fR\& association will be included in the \fIInfo\fR\& map where \fIConnectionId\fR\& 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\&. .TP 2 .B \fInode_type => NodeType\fR\&: Valid values for \fINodeType\fR\&: .RS 2 .TP 2 .B \fIvisible\fR\&: Subscribe to node status change messages for visible nodes only\&. The association \fInode_type => visible\fR\& will be included in the \fIInfo\fR\& map\&. .TP 2 .B \fIhidden\fR\&: Subscribe to node status change messages for hidden nodes only\&. The association \fInode_type => hidden\fR\& will be included in the \fIInfo\fR\& map\&. .TP 2 .B \fIall\fR\&: Subscribe to node status change messages for both visible and hidden nodes\&. The association \fInode_type => visible | hidden\fR\& will be included in the \fIInfo\fR\& map\&. .RE .RS 2 .LP If no \fInode_type => NodeType\fR\& association is included in the \fIOptions\fR\& map, the caller will subscribe for status change messages for visible nodes only, but \fIno\fR\& \fInode_type => visible\fR\& association will be included in the \fIInfo\fR\& map\&. .RE .TP 2 .B \fInodedown_reason => boolean()\fR\&: If the value of the association equals \fItrue\fR\&, a \fInodedown_reason => Reason\fR\& association will be included in the \fIInfo\fR\& map for \fInodedown\fR\& messages\&. .RS 2 .LP \fIReason\fR\& 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: .RE .RS 2 .TP 2 .B \fIconnection_setup_failed\fR\&: The connection setup failed (after \fInodeup\fR\& messages were sent)\&. .TP 2 .B \fIno_network\fR\&: No network is available\&. .TP 2 .B \fInet_kernel_terminated\fR\&: The \fInet_kernel\fR\& process terminated\&. .TP 2 .B \fIshutdown\fR\&: Unspecified connection shutdown\&. .TP 2 .B \fIconnection_closed\fR\&: The connection was closed\&. .TP 2 .B \fIdisconnect\fR\&: The connection was disconnected (forced from the current node)\&. .TP 2 .B \fInet_tick_timeout\fR\&: Net tick time-out\&. .TP 2 .B \fIsend_net_tick_failed\fR\&: Failed to send net tick over the connection\&. .TP 2 .B \fIget_status_failed\fR\&: Status information retrieval from the \fIPort\fR\& holding the connection failed\&. .RE .RE .LP When \fIOptions\fR\& is a list, currently \fIListOption\fR\& can be one of the following: .RS 2 .TP 2 .B \fIconnection_id\fR\&: A \fI{connection_id, ConnectionId}\fR\& tuple will be included in \fIInfo\fR\& where \fIConnectionId\fR\& 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\&. .TP 2 .B \fI{node_type, NodeType}\fR\&: Valid values for \fINodeType\fR\&: .RS 2 .TP 2 .B \fIvisible\fR\&: Subscribe to node status change messages for visible nodes only\&. The tuple \fI{node_type, visible}\fR\& will be included in the \fIInfo\fR\& list\&. .TP 2 .B \fIhidden\fR\&: Subscribe to node status change messages for hidden nodes only\&. The tuple \fI{node_type, hidden}\fR\& will be included in the \fIInfo\fR\& list\&. .TP 2 .B \fIall\fR\&: Subscribe to node status change messages for both visible and hidden nodes\&. The tuple \fI{node_type, visible | hidden}\fR\& will be included in the \fIInfo\fR\& list\&. .RE .RS 2 .LP If no \fI{node_type, NodeType}\fR\& option has been given\&. The caller will subscribe for status change messages for visible nodes only, but \fIno\fR\& \fI{node_type, visible}\fR\& tuple will be included in the \fIInfo\fR\& list\&. .RE .TP 2 .B \fInodedown_reason\fR\&: The tuple \fI{nodedown_reason, Reason}\fR\& will be included in the \fIInfo\fR\& list for \fInodedown\fR\& messages\&. .RS 2 .LP See the documentation of the \fInodedown_reason => boolean()\fR\& association above for information about possible \fIReason\fR\& values\&. .RE .RE .LP Example: .LP .nf (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> .fi .RE .LP .nf .B set_net_ticktime(NetTicktime) -> Res .br .fi .br .nf .B set_net_ticktime(NetTicktime, TransitionPeriod) -> Res .br .fi .br .RS .LP Types: .RS 3 NetTicktime = integer() >= 1 .br TransitionPeriod = integer() >= 0 .br Res = .br unchanged | change_initiated | .br {ongoing_change_to, NewNetTicktime} .br NewNetTicktime = integer() >= 1 .br .RE .RE .RS .LP Sets \fInet_ticktime\fR\& (see \fIkernel(7)\fR\&) to \fINetTicktime\fR\& seconds\&. \fITransitionPeriod\fR\& defaults to \fI60\fR\&\&. .LP Some definitions: .RS 2 .TP 2 .B Minimum transition traffic interval (\fIMTTI\fR\&): \fIminimum(NetTicktime, PreviousNetTicktime)*1000 div 4\fR\& milliseconds\&. .TP 2 .B Transition period: The time of the least number of consecutive \fIMTTI\fR\&s to cover \fITransitionPeriod\fR\& seconds following the call to \fIset_net_ticktime/2\fR\& (that is, ((\fITransitionPeriod*1000 - 1) div MTTI + 1)*MTTI\fR\& milliseconds)\&. .RE .LP If \fINetTicktime < PreviousNetTicktime\fR\&, the \fInet_ticktime\fR\& change is done at the end of the transition period; otherwise at the beginning\&. During the transition period, \fInet_kernel\fR\& ensures that there is outgoing traffic on all connections at least every \fIMTTI\fR\& millisecond\&. .LP .RS -4 .B Note: .RE The \fInet_ticktime\fR\& changes must be initiated on all nodes in the network (with the same \fINetTicktime\fR\&) before the end of any transition period on any node; otherwise connections can erroneously be disconnected\&. .LP Returns one of the following: .RS 2 .TP 2 .B \fIunchanged\fR\&: \fInet_ticktime\fR\& already has the value of \fINetTicktime\fR\& and is left unchanged\&. .TP 2 .B \fIchange_initiated\fR\&: \fInet_kernel\fR\& initiated the change of \fInet_ticktime\fR\& to \fINetTicktime\fR\& seconds\&. .TP 2 .B \fI{ongoing_change_to, NewNetTicktime}\fR\&: The request is \fIignored\fR\& because \fInet_kernel\fR\& is busy changing \fInet_ticktime\fR\& to \fINewNetTicktime\fR\& seconds\&. .RE .RE .LP .nf .B setopts(Node, Options) -> ok | {error, Reason} | ignored .br .fi .br .RS .LP Types: .RS 3 Node = node() | new .br Options = [inet:socket_setopt()] .br Reason = inet:posix() | noconnection .br .RE .RE .RS .LP Set one or more options for distribution sockets\&. Argument \fINode\fR\& can be either one node name or the atom \fInew\fR\& to affect the distribution sockets of all future connected nodes\&. .LP The return value is the same as from \fIinet:setopts/2\fR\& or \fI{error, noconnection}\fR\& if \fINode\fR\& is not a connected node or \fInew\fR\&\&. .LP If \fINode\fR\& is \fInew\fR\& the \fIOptions\fR\& will then also be added to kernel configuration parameters inet_dist_listen_options and inet_dist_connect_options\&. .LP Returns \fIignored\fR\& if the local node is not alive\&. .RE .LP .nf .B start(Name, Options) -> {ok, pid()} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Options = .br #{name_domain => NameDomain, .br net_ticktime => NetTickTime, .br net_tickintensity => NetTickIntensity, .br dist_listen => boolean(), .br hidden => boolean()} .br Name = atom() .br NameDomain = shortnames | longnames .br NetTickTime = integer() >= 1 .br NetTickIntensity = 4\&.\&.1000 .br Reason = {already_started, pid()} | term() .br .RE .RE .RS .LP Turns a non-distributed node into a distributed node by starting \fInet_kernel\fR\& and other necessary processes\&. .LP If \fIName\fR\& is set to \fI\fIundefined\fR\&\fR\& the distribution will be started to request a dynamic node name from the first node it connects to\&. See Dynamic Node Name\&. Setting \fIName\fR\& to \fIundefined\fR\& implies options \fIdist_listen => false\fR\& and \fIhidden => true\fR\&\&. .LP Currently supported options: .RS 2 .TP 2 .B \fIname_domain => NameDomain\fR\&: Determines the host name part of the node name\&. If \fINameDomain\fR\& equals \fIlongnames\fR\&, fully qualified domain names will be used which also is the default\&. If \fINameDomain\fR\& equals \fIshortnames\fR\&, only the short name of the host will be used\&. .TP 2 .B \fInet_ticktime => NetTickTime\fR\&: \fINet tick time\fR\& to use in seconds\&. Defaults to the value of the \fInet_ticktime\fR\& \fIkernel(7)\fR\& parameter\&. For more information about \fInet tick time\fR\& , see the \fIkernel\fR\& parameter\&. However, note that if the value of the \fIkernel\fR\& parameter is invalid, it will silently be replaced by a valid value, but if an invalid \fINetTickTime\fR\& value is passed as option value to this function, the call will fail\&. .TP 2 .B \fInet_tickintensity => NetTickIntensity\fR\&: \fINet tick intensity\fR\& to use\&. Defaults to the value of the \fInet_tickintensity\fR\& \fIkernel(7)\fR\& parameter\&. For more information about \fInet tick intensity\fR\& , see the \fIkernel\fR\& parameter\&. However, note that if the value of the \fIkernel\fR\& parameter is invalid, it will silently be replaced by a valid value, but if an invalid \fINetTickIntensity\fR\& value is passed as option value to this function, the call will fail\&. .TP 2 .B \fIdist_listen => boolean()\fR\&: Enable or disable listening for incoming connections\&. Defaults to the value of the \fI-dist_listen\fR\& \fIerl\fR\& command line argument\&. Note that \fIdist_listen => false\fR\& implies \fIhidden => true\fR\&\&. .RS 2 .LP If \fIundefined\fR\& has been passed as \fIName\fR\&, the \fIdist_listen\fR\& option will be overridden with \fIdist_listen => false\fR\&\&. .RE .TP 2 .B \fIhidden => boolean()\fR\&: Enable or disable hidden node\&. Defaults to \fItrue\fR\& if the \fI-hidden\fR\& \fIerl\fR\& command line argument has been passed; otherwise \fIfalse\fR\&\&. .RS 2 .LP If \fIundefined\fR\& has been passed as \fIName\fR\&, or the option \fIdist_listen\fR\& equals \fIfalse\fR\&, the \fIhidden\fR\& option will be overridden with \fIhidden => true\fR\&\&. .RE .RE .RE .LP .nf .B start(Options) -> {ok, pid()} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Options = [Name | NameDomain | TickTime, \&.\&.\&.] .br Name = atom() .br NameDomain = shortnames | longnames .br TickTime = integer() >= 1 .br Reason = {already_started, pid()} | term() .br .RE .RE .RS .LP .RS -4 .B Warning: .RE \fIstart/1\fR\& is deprecated\&. Use \fIstart/2\fR\& instead\&. .LP Turns a non-distributed node into a distributed node by starting \fInet_kernel\fR\& and other necessary processes\&. .LP \fIOptions\fR\& list can only be exactly one of the following lists (order is imporant): .RS 2 .TP 2 .B \fI[Name]\fR\&: The same as \fInet_kernel:start([Name, longnames, 15000])\fR\&\&. .TP 2 .B \fI[Name, NameDomain]\fR\&: The same as \fInet_kernel:start([Name, NameDomain, 15000])\fR\&\&. .TP 2 .B \fI[Name, NameDomain, TickTime]\fR\&: The same as \fInet_kernel:start(Name, #{name_domain => NameDomain, net_ticktime => ((TickTime*4-1) div 1000) + 1, net_tickintensity => 4})\fR\&\&. Note that \fITickTime\fR\& is \fInot\fR\& the same as net tick time expressed in milliseconds\&. \fITickTime\fR\& is the time between ticks when net tick intensity equals \fI4\fR\&\&. .RE .RE .LP .nf .B stop() -> ok | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Reason = not_allowed | not_found .br .RE .RE .RS .LP 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 \fIstart/2\fR\&, otherwise \fI{error, not_allowed}\fR\& is returned\&. Returns \fI{error, not_found}\fR\& if the local node is not alive\&. .RE