aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/src')
-rw-r--r--lib/kernel/src/dist_util.erl132
-rw-r--r--lib/kernel/src/inet.erl17
-rw-r--r--lib/kernel/src/inet_hosts.erl5
-rw-r--r--lib/kernel/src/inet_res.erl28
-rw-r--r--lib/kernel/src/net_kernel.erl8
-rw-r--r--lib/kernel/src/rpc.erl15
6 files changed, 74 insertions, 131 deletions
diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl
index 5ea0ca991f..3927b64b06 100644
--- a/lib/kernel/src/dist_util.erl
+++ b/lib/kernel/src/dist_util.erl
@@ -27,6 +27,7 @@
%%-compile(export_all).
-export([handshake_we_started/1, handshake_other_started/1,
+ strict_order_flags/0,
start_timer/1, setup_timer/2,
reset_timer/1, cancel_timer/1,
shutdown/3, shutdown/4]).
@@ -116,22 +117,8 @@ dflag2str(_) ->
"UNKNOWN".
-remove_flag(Flag, Flags) ->
- case Flags band Flag of
- 0 ->
- Flags;
- _ ->
- Flags - Flag
- end.
-
-adjust_flags(ThisFlags, OtherFlags, RejectFlags) ->
- case (?DFLAG_PUBLISHED band ThisFlags) band OtherFlags of
- 0 ->
- {remove_flag(?DFLAG_PUBLISHED, ThisFlags),
- remove_flag(?DFLAG_PUBLISHED, OtherFlags)};
- _ ->
- {ThisFlags, OtherFlags band (bnot RejectFlags)}
- end.
+adjust_flags(ThisFlags, OtherFlags) ->
+ ThisFlags band OtherFlags.
publish_flag(hidden, _) ->
0;
@@ -143,50 +130,35 @@ publish_flag(_, OtherNode) ->
0
end.
--define(DFLAGS_REMOVABLE,
- (?DFLAG_DIST_HDR_ATOM_CACHE
- bor ?DFLAG_HIDDEN_ATOM_CACHE
- bor ?DFLAG_ATOM_CACHE)).
-
--define(DFLAGS_ADDABLE,
- (?DFLAGS_ALL
- band (bnot (?DFLAG_PUBLISHED
- bor ?DFLAG_HIDDEN_ATOM_CACHE
- bor ?DFLAG_ATOM_CACHE)))).
-
--define(DFLAGS_THIS_DEFAULT,
- (?DFLAG_EXPORT_PTR_TAG
- bor ?DFLAG_EXTENDED_PIDS_PORTS
- bor ?DFLAG_EXTENDED_REFERENCES
- bor ?DFLAG_DIST_MONITOR
- bor ?DFLAG_FUN_TAGS
- bor ?DFLAG_DIST_MONITOR_NAME
- bor ?DFLAG_NEW_FUN_TAGS
- bor ?DFLAG_BIT_BINARIES
- bor ?DFLAG_NEW_FLOATS
- bor ?DFLAG_UNICODE_IO
- bor ?DFLAG_DIST_HDR_ATOM_CACHE
- bor ?DFLAG_SMALL_ATOM_TAGS
- bor ?DFLAG_UTF8_ATOMS
- bor ?DFLAG_MAP_TAG
- bor ?DFLAG_BIG_CREATION
- bor ?DFLAG_SEND_SENDER)).
-
-make_this_flags(RequestType, AddFlags, RemoveFlags, OtherNode) ->
- case RemoveFlags band (bnot ?DFLAGS_REMOVABLE) of
+
+%% Sync with dist.c
+-record(erts_dflags, {
+ default, % flags erts prefers
+ mandatory, % flags erts needs
+ addable, % flags local dist implementation is allowed to add
+ rejectable, % flags local dist implementation is allowed to reject
+ strict_order % flags for features needing strict order delivery
+}).
+
+-spec strict_order_flags() -> integer().
+strict_order_flags() ->
+ EDF = erts_internal:get_dflags(),
+ EDF#erts_dflags.strict_order.
+
+make_this_flags(RequestType, AddFlags, RejectFlags, OtherNode,
+ #erts_dflags{}=EDF) ->
+ case RejectFlags band (bnot EDF#erts_dflags.rejectable) of
0 -> ok;
Rerror -> exit({"Rejecting non rejectable flags", Rerror})
end,
- case AddFlags band (bnot ?DFLAGS_ADDABLE) of
+ case AddFlags band (bnot EDF#erts_dflags.addable) of
0 -> ok;
Aerror -> exit({"Adding non addable flags", Aerror})
end,
- Flgs0 = ?DFLAGS_THIS_DEFAULT,
+ Flgs0 = EDF#erts_dflags.default,
Flgs1 = Flgs0 bor publish_flag(RequestType, OtherNode),
Flgs2 = Flgs1 bor AddFlags,
- Flgs3 = Flgs2 band (bnot (?DFLAG_HIDDEN_ATOM_CACHE
- bor ?DFLAG_ATOM_CACHE)),
- Flgs3 band (bnot RemoveFlags).
+ Flgs2 band (bnot RejectFlags).
handshake_other_started(#hs_data{request_type=ReqType,
add_flags=AddFlgs0,
@@ -196,19 +168,18 @@ handshake_other_started(#hs_data{request_type=ReqType,
RejFlgs = convert_flags(RejFlgs0),
ReqFlgs = convert_flags(ReqFlgs0),
{PreOtherFlags,Node,Version} = recv_name(HSData0),
- PreThisFlags = make_this_flags(ReqType, AddFlgs, RejFlgs, Node),
- {ThisFlags, OtherFlags} = adjust_flags(PreThisFlags,
- PreOtherFlags,
- RejFlgs),
- HSData = HSData0#hs_data{this_flags=ThisFlags,
- other_flags=OtherFlags,
+ EDF = erts_internal:get_dflags(),
+ PreThisFlags = make_this_flags(ReqType, AddFlgs, RejFlgs, Node, EDF),
+ ChosenFlags = adjust_flags(PreThisFlags, PreOtherFlags),
+ HSData = HSData0#hs_data{this_flags=ChosenFlags,
+ other_flags=ChosenFlags,
other_version=Version,
other_node=Node,
other_started=true,
add_flags=AddFlgs,
reject_flags=RejFlgs,
require_flags=ReqFlgs},
- check_dflags(HSData),
+ check_dflags(HSData, EDF),
is_allowed(HSData),
?debug({"MD5 connection from ~p (V~p)~n",
[Node, HSData#hs_data.other_version]}),
@@ -247,14 +218,11 @@ is_allowed(#hs_data{other_node = Node,
check_dflags(#hs_data{other_node = Node,
other_flags = OtherFlags,
other_started = OtherStarted,
- require_flags = RequiredFlags} = HSData) ->
- Mandatory = ((?DFLAG_EXTENDED_REFERENCES
- bor ?DFLAG_EXTENDED_PIDS_PORTS
- bor ?DFLAG_UTF8_ATOMS
- bor ?DFLAG_NEW_FUN_TAGS)
- bor RequiredFlags),
- Missing = check_mandatory(0, ?DFLAGS_ALL, Mandatory,
- OtherFlags, []),
+ require_flags = RequiredFlags} = HSData,
+ #erts_dflags{}=EDF) ->
+
+ Mandatory = (EDF#erts_dflags.mandatory bor RequiredFlags),
+ Missing = check_mandatory(Mandatory, OtherFlags, []),
case Missing of
[] ->
ok;
@@ -274,21 +242,20 @@ check_dflags(#hs_data{other_node = Node,
?shutdown2(Node, {check_dflags_failed, Missing})
end.
-check_mandatory(_Bit, 0, _Mandatory, _OtherFlags, Missing) ->
+check_mandatory(0, _OtherFlags, Missing) ->
Missing;
-check_mandatory(Bit, Left, Mandatory, OtherFlags, Missing) ->
- DFlag = (1 bsl Bit),
- NewLeft = Left band (bnot DFlag),
- NewMissing = case {DFlag band Mandatory,
- DFlag band OtherFlags} of
- {DFlag, 0} ->
+check_mandatory(Mandatory, OtherFlags, Missing) ->
+ Left = Mandatory band (Mandatory - 1), % clear lowest set bit
+ DFlag = Mandatory bxor Left, % only lowest set bit
+ NewMissing = case DFlag band OtherFlags of
+ 0 ->
%% Mandatory and missing...
[dflag2str(DFlag) | Missing];
_ ->
- %% Not mandatory or present...
+ %% Mandatory and present...
Missing
end,
- check_mandatory(Bit+1, NewLeft, Mandatory, OtherFlags, NewMissing).
+ check_mandatory(Left, OtherFlags, NewMissing).
%% No nodedown will be sent if we fail before this process has
@@ -410,7 +377,8 @@ handshake_we_started(#hs_data{request_type=ReqType,
AddFlgs = convert_flags(AddFlgs0),
RejFlgs = convert_flags(RejFlgs0),
ReqFlgs = convert_flags(ReqFlgs0),
- PreThisFlags = make_this_flags(ReqType, AddFlgs, RejFlgs, Node),
+ EDF = erts_internal:get_dflags(),
+ PreThisFlags = make_this_flags(ReqType, AddFlgs, RejFlgs, Node, EDF),
HSData = PreHSData#hs_data{this_flags = PreThisFlags,
add_flags = AddFlgs,
reject_flags = RejFlgs,
@@ -418,13 +386,11 @@ handshake_we_started(#hs_data{request_type=ReqType,
send_name(HSData),
recv_status(HSData),
{PreOtherFlags,ChallengeA} = recv_challenge(HSData),
- {ThisFlags,OtherFlags} = adjust_flags(PreThisFlags,
- PreOtherFlags,
- RejFlgs),
- NewHSData = HSData#hs_data{this_flags = ThisFlags,
- other_flags = OtherFlags,
+ ChosenFlags = adjust_flags(PreThisFlags, PreOtherFlags),
+ NewHSData = HSData#hs_data{this_flags = ChosenFlags,
+ other_flags = ChosenFlags,
other_started = false},
- check_dflags(NewHSData),
+ check_dflags(NewHSData, EDF),
MyChallenge = gen_challenge(),
{MyCookie,HisCookie} = get_cookies(Node),
send_challenge_reply(NewHSData,MyChallenge,
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index fe91b0d33e..4bad523dff 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2018. 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.
@@ -34,7 +34,8 @@
ip/1, stats/0, options/0,
pushf/3, popf/1, close/1, gethostname/0, gethostname/1,
parse_ipv4_address/1, parse_ipv6_address/1, parse_ipv4strict_address/1,
- parse_ipv6strict_address/1, parse_address/1, parse_strict_address/1, ntoa/1]).
+ parse_ipv6strict_address/1, parse_address/1, parse_strict_address/1,
+ ntoa/1, ipv4_mapped_ipv6_address/1]).
-export([connect_options/2, listen_options/2, udp_options/2, sctp_options/2]).
-export([udp_module/1, tcp_module/1, tcp_module/2, sctp_module/1]).
@@ -675,6 +676,14 @@ parse_address(Addr) ->
parse_strict_address(Addr) ->
inet_parse:strict_address(Addr).
+-spec ipv4_mapped_ipv6_address(ip_address()) -> ip_address().
+ipv4_mapped_ipv6_address({D1,D2,D3,D4})
+ when (D1 bor D2 bor D3 bor D4) < 256 ->
+ {0,0,0,0,0,16#ffff,(D1 bsl 8) bor D2,(D3 bsl 8) bor D4};
+ipv4_mapped_ipv6_address({D1,D2,D3,D4,D5,D6,D7,D8})
+ when (D1 bor D2 bor D3 bor D4 bor D5 bor D6 bor D7 bor D8) < 65536 ->
+ {D7 bsr 8,D7 band 255,D8 bsr 8,D8 band 255}.
+
%% Return a list of available options
options() ->
[
@@ -1244,9 +1253,7 @@ gethostbyname_string(Name, Type)
inet ->
inet_parse:ipv4_address(Name);
inet6 ->
- %% XXX should we really translate IPv4 addresses here
- %% even if we do not know if this host can do IPv6?
- inet_parse:ipv6_address(Name)
+ inet_parse:ipv6strict_address(Name)
end of
{ok,IP} ->
{ok,make_hostent(Name, [IP], [], Type)};
diff --git a/lib/kernel/src/inet_hosts.erl b/lib/kernel/src/inet_hosts.erl
index 0bdf00ac30..fc653bf0d3 100644
--- a/lib/kernel/src/inet_hosts.erl
+++ b/lib/kernel/src/inet_hosts.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2018. 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.
@@ -72,9 +72,6 @@ gethostbyname(Name, Type, Byname, Byaddr) ->
gethostbyaddr({A,B,C,D}=IP) when ?ip(A,B,C,D) ->
gethostbyaddr(IP, inet);
-%% ipv4 only ipv6 address
-gethostbyaddr({0,0,0,0,0,16#ffff=F,G,H}) when ?ip6(0,0,0,0,0,F,G,H) ->
- gethostbyaddr({G bsr 8, G band 255, H bsr 8, H band 255});
gethostbyaddr({A,B,C,D,E,F,G,H}=IP) when ?ip6(A,B,C,D,E,F,G,H) ->
gethostbyaddr(IP, inet6);
gethostbyaddr(Addr) when is_list(Addr) ->
diff --git a/lib/kernel/src/inet_res.erl b/lib/kernel/src/inet_res.erl
index 49aa5f8bda..6454802b04 100644
--- a/lib/kernel/src/inet_res.erl
+++ b/lib/kernel/src/inet_res.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2018. 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.
@@ -349,9 +349,6 @@ gethostbyaddr_tm({A,B,C,D} = IP, Timer) when ?ip(A,B,C,D) ->
{ok, HEnt} -> {ok, HEnt};
_ -> res_gethostbyaddr(dn_in_addr_arpa(A,B,C,D), IP, Timer)
end;
-%% ipv4 only ipv6 address
-gethostbyaddr_tm({0,0,0,0,0,16#ffff,G,H},Timer) when is_integer(G+H) ->
- gethostbyaddr_tm({G div 256, G rem 256, H div 256, H rem 256},Timer);
gethostbyaddr_tm({A,B,C,D,E,F,G,H} = IP, Timer) when ?ip6(A,B,C,D,E,F,G,H) ->
inet_db:res_update_conf(),
case inet_db:gethostbyaddr(IP) of
@@ -431,28 +428,7 @@ gethostbyname(Name,Family,Timeout) ->
gethostbyname_tm(Name,inet,Timer) ->
getbyname_tm(Name,?S_A,Timer);
gethostbyname_tm(Name,inet6,Timer) ->
- case getbyname_tm(Name,?S_AAAA,Timer) of
- {ok,HEnt} -> {ok,HEnt};
- {error,nxdomain} ->
- case getbyname_tm(Name, ?S_A,Timer) of
- {ok, HEnt} ->
- %% rewrite to a ipv4 only ipv6 address
- {ok,
- HEnt#hostent {
- h_addrtype = inet6,
- h_length = 16,
- h_addr_list =
- lists:map(
- fun({A,B,C,D}) ->
- {0,0,0,0,0,16#ffff,A*256+B,C*256+D}
- end, HEnt#hostent.h_addr_list)
- }};
- Error ->
- Error
- end;
- Error ->
- Error
- end;
+ getbyname_tm(Name,?S_AAAA,Timer);
gethostbyname_tm(_Name, _Family, _Timer) ->
{error, einval}.
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index cdb10a7b12..f38989d103 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.erl
@@ -1777,16 +1777,16 @@ async_reply({reply, Msg, State}, From) ->
async_gen_server_reply(From, Msg) ->
{Pid, Tag} = From,
M = {Tag, Msg},
- case catch erlang:send(Pid, M, [nosuspend, noconnect]) of
+ try erlang:send(Pid, M, [nosuspend, noconnect]) of
ok ->
ok;
nosuspend ->
_ = spawn(fun() -> catch erlang:send(Pid, M, [noconnect]) end),
ok;
noconnect ->
- ok; % The gen module takes care of this case.
- {'EXIT', _} ->
- ok
+ ok % The gen module takes care of this case.
+ catch
+ _:_ -> ok
end.
call_owner(Owner, Msg) ->
diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl
index 0e0b7dffa3..d197de942f 100644
--- a/lib/kernel/src/rpc.erl
+++ b/lib/kernel/src/rpc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. 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.
@@ -418,10 +418,7 @@ abcast(Name, Mess) ->
abcast([Node|Tail], Name, Mess) ->
Dest = {Name,Node},
- case catch erlang:send(Dest, Mess, [noconnect]) of
- noconnect -> spawn(erlang, send, [Dest,Mess]), ok;
- _ -> ok
- end,
+ try erlang:send(Dest, Mess) catch error:_ -> ok end,
abcast(Tail, Name, Mess);
abcast([], _,_) -> abcast.
@@ -498,7 +495,7 @@ start_monitor(Node, Name) ->
Module :: module(),
Function :: atom(),
Args :: [term()],
- ResL :: [term()],
+ ResL :: [Res :: term() | {'badrpc', Reason :: term()}],
BadNodes :: [node()].
multicall(M, F, A) ->
@@ -509,14 +506,14 @@ multicall(M, F, A) ->
Module :: module(),
Function :: atom(),
Args :: [term()],
- ResL :: [term()],
+ ResL :: [Res :: term() | {'badrpc', Reason :: term()}],
BadNodes :: [node()];
(Module, Function, Args, Timeout) -> {ResL, BadNodes} when
Module :: module(),
Function :: atom(),
Args :: [term()],
Timeout :: timeout(),
- ResL :: [term()],
+ ResL :: [Res :: term() | {'badrpc', Reason :: term()}],
BadNodes :: [node()].
multicall(Nodes, M, F, A) when is_list(Nodes) ->
@@ -531,7 +528,7 @@ multicall(M, F, A, Timeout) ->
Function :: atom(),
Args :: [term()],
Timeout :: timeout(),
- ResL :: [term()],
+ ResL :: [Res :: term() | {'badrpc', Reason :: term()}],
BadNodes :: [node()].
multicall(Nodes, M, F, A, infinity)