%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% %CopyrightEnd%
%%
-module(net).
%% We should really ifdef this module depending on if we actually built
%% the system with esock support (socket and prim_net), but our doc-building
%% can't handle the "variables" we need (USE_ESOCK). So instead, we just
%% leave everything hanging...
%% If one of the "hanging" functions is called when esock has been disabled,
%% the function will through a 'notsup' error (erlang:error/1).
%% Administrative and utility functions
-export([
info/0,
command/1
]).
-export([
gethostname/0,
getnameinfo/1, getnameinfo/2,
getaddrinfo/1, getaddrinfo/2,
if_name2index/1,
if_index2name/1,
if_names/0
]).
%% Deprecated functions from the "old" net module
-export([call/4,
cast/4,
broadcast/3,
ping/1,
relay/1,
sleep/1]).
%% Should we define these here or refer to the prim_net module
-export_type([
address_info/0,
name_info/0,
name_info_flags/0,
name_info_flag/0,
name_info_flag_ext/0,
network_interface_name/0,
network_interface_index/0
]).
-deprecated({call, 4, eventually}).
-deprecated({cast, 4, eventually}).
-deprecated({broadcast, 3, eventually}).
-deprecated({ping, 1, eventually}).
-deprecated({relay, 1, eventually}).
-deprecated({sleep, 1, eventually}).
-type name_info_flags() :: [name_info_flag()|name_info_flag_ext()].
-type name_info_flag() :: namereqd |
dgram |
nofqdn |
numerichost |
nomericserv.
-type name_info_flag_ext() :: idn |
idna_allow_unassigned |
idna_use_std3_ascii_rules.
-type name_info() :: #{host := string(),
service := string()}.
-type address_info() :: #{family := socket:domain(),
socktype := socket:type(),
protocol := socket:protocol(),
address := socket:sockaddr()}.
-type network_interface_name() :: string().
-type network_interface_index() :: non_neg_integer().
%% ===========================================================================
%%
%% D E P R E C A T E D F U N C T I O N S
%%
%% ===========================================================================
call(N,M,F,A) -> rpc:call(N,M,F,A).
cast(N,M,F,A) -> rpc:cast(N,M,F,A).
broadcast(M,F,A) -> rpc:eval_everywhere(M,F,A).
ping(Node) -> net_adm:ping(Node).
sleep(T) -> receive after T -> ok end.
relay(X) -> slave:relay(X).
%% ===========================================================================
%%
%% Administrative and utility API
%%
%% ===========================================================================
-spec info() -> list().
-ifdef(USE_ESOCK).
info() ->
prim_net:info().
-else.
-dialyzer({nowarn_function, info/0}).
info() ->
erlang:error(notsup).
-endif.
-spec command(Cmd :: term()) -> term().
-ifdef(USE_ESOCK).
command(Cmd) ->
prim_net:command(Cmd).
-else.
-dialyzer({nowarn_function, command/1}).
command(_Cmd) ->
erlang:error(notsup).
-endif.
%% ===========================================================================
%%
%% The proper net API
%%
%% ===========================================================================
%% ===========================================================================
%%
%% gethostname - Get the name of the current host.
%%
%%
-spec gethostname() -> {ok, HostName} | {error, Reason} when
HostName :: string(),
Reason :: term().
-ifdef(USE_ESOCK).
gethostname() ->
prim_net:gethostname().
-else.
-dialyzer({nowarn_function, gethostname/0}).
gethostname() ->
erlang:error(notsup).
-endif.
%% ===========================================================================
%%
%% getnameinfo - Address-to-name translation in protocol-independent manner.
%%
%%
-spec getnameinfo(SockAddr) -> {ok, Info} | {error, Reason} when
SockAddr :: socket:sockaddr(),
Info :: name_info(),
Reason :: term().
getnameinfo(SockAddr) ->
getnameinfo(SockAddr, undefined).
-spec getnameinfo(SockAddr, Flags) -> {ok, Info} | {error, Reason} when
SockAddr :: socket:sockaddr(),
Flags :: name_info_flags() | undefined,
Info :: name_info(),
Reason :: term().
-ifdef(USE_ESOCK).
getnameinfo(SockAddr, [] = _Flags) ->
getnameinfo(SockAddr, undefined);
getnameinfo(#{family := Fam, addr := _Addr} = SockAddr, Flags)
when ((Fam =:= inet) orelse (Fam =:= inet6)) andalso
(is_list(Flags) orelse (Flags =:= undefined)) ->
prim_net:getnameinfo(socket:ensure_sockaddr(SockAddr), Flags);
getnameinfo(#{family := Fam, path := _Path} = SockAddr, Flags)
when (Fam =:= local) andalso (is_list(Flags) orelse (Flags =:= undefined)) ->
prim_net:getnameinfo(SockAddr, Flags).
-else.
-dialyzer({nowarn_function, getnameinfo/2}).
getnameinfo(SockAddr, [] = _Flags) ->
getnameinfo(SockAddr, undefined);
getnameinfo(#{family := Fam, addr := _Addr} = _SockAddr, Flags)
when ((Fam =:= inet) orelse (Fam =:= inet6)) andalso
(is_list(Flags) orelse (Flags =:= undefined)) ->
erlang:error(notsup);
getnameinfo(#{family := Fam, path := _Path} = _SockAddr, Flags)
when (Fam =:= local) andalso (is_list(Flags) orelse (Flags =:= undefined)) ->
erlang:error(notsup).
-endif.
%% ===========================================================================
%%
%% getaddrinfo - Network address and service translation
%%
%% There is also a "hint" argument that we "at some point" should implement.
-spec getaddrinfo(Host) -> {ok, Info} | {error, Reason} when
Host :: string(),
Info :: [address_info()],
Reason :: term().
getaddrinfo(Host) when is_list(Host) ->
getaddrinfo(Host, undefined).
-spec getaddrinfo(Host, undefined) -> {ok, Info} | {error, Reason} when
Host :: string(),
Info :: [address_info()],
Reason :: term()
; (undefined, Service) -> {ok, Info} | {error, Reason} when
Service :: string(),
Info :: [address_info()],
Reason :: term()
; (Host, Service) -> {ok, Info} | {error, Reason} when
Host :: string(),
Service :: string(),
Info :: [address_info()],
Reason :: term().
-ifdef(USE_ESOCK).
getaddrinfo(Host, Service)
when (is_list(Host) orelse (Host =:= undefined)) andalso
(is_list(Service) orelse (Service =:= undefined)) andalso
(not ((Service =:= undefined) andalso (Host =:= undefined))) ->
prim_net:getaddrinfo(Host, Service).
-else.
-dialyzer({nowarn_function, getaddrinfo/2}).
getaddrinfo(Host, Service)
when (is_list(Host) orelse (Host =:= undefined)) andalso
(is_list(Service) orelse (Service =:= undefined)) andalso
(not ((Service =:= undefined) andalso (Host =:= undefined))) ->
erlang:error(notsup).
-endif.
%% ===========================================================================
%%
%% if_name2index - Mappings between network interface names and indexes:
%% name -> idx
%%
%%
-spec if_name2index(Name) -> {ok, Idx} | {error, Reason} when
Name :: network_interface_name(),
Idx :: network_interface_index(),
Reason :: term().
-ifdef(USE_ESOCK).
if_name2index(If) when is_list(If) ->
prim_net:if_name2index(If).
-else.
-dialyzer({nowarn_function, if_name2index/1}).
if_name2index(If) when is_list(If) ->
erlang:error(notsup).
-endif.
%% ===========================================================================
%%
%% if_index2name - Mappings between network interface index and names:
%% idx -> name
%%
%%
-spec if_index2name(Idx) -> {ok, Name} | {error, Reason} when
Idx :: network_interface_index(),
Name :: network_interface_name(),
Reason :: term().
-ifdef(USE_ESOCK).
if_index2name(Idx) when is_integer(Idx) ->
prim_net:if_index2name(Idx).
-else.
-dialyzer({nowarn_function, if_index2name/1}).
if_index2name(Idx) when is_integer(Idx) ->
erlang:error(notsup).
-endif.
%% ===========================================================================
%%
%% if_names - Get network interface names and indexes
%%
%%
-spec if_names() -> Names | {error, Reason} when
Names :: [{Idx, If}],
Idx :: network_interface_index(),
If :: network_interface_name(),
Reason :: term().
-ifdef(USE_ESOCK).
if_names() ->
prim_net:if_names().
-else.
-dialyzer({nowarn_function, if_names/0}).
if_names() ->
erlang:error(notsup).
-endif.