aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/preloaded/ebin/atomics.beambin3292 -> 3292 bytes
-rw-r--r--erts/preloaded/ebin/counters.beambin3092 -> 3092 bytes
-rw-r--r--erts/preloaded/ebin/erl_init.beambin2312 -> 2260 bytes
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin52636 -> 52540 bytes
-rw-r--r--erts/preloaded/ebin/erl_tracer.beambin2200 -> 2200 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin100196 -> 100200 bytes
-rw-r--r--erts/preloaded/ebin/erts_code_purger.beambin11204 -> 10976 bytes
-rw-r--r--erts/preloaded/ebin/erts_dirty_process_signal_handler.beambin2764 -> 2760 bytes
-rw-r--r--erts/preloaded/ebin/erts_internal.beambin17788 -> 17760 bytes
-rw-r--r--erts/preloaded/ebin/erts_literal_area_collector.beambin3268 -> 3248 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin50304 -> 50208 bytes
-rw-r--r--erts/preloaded/ebin/net.beambin6140 -> 6096 bytes
-rw-r--r--erts/preloaded/ebin/persistent_term.beambin1836 -> 1844 bytes
-rw-r--r--erts/preloaded/ebin/prim_buffer.beambin3596 -> 3592 bytes
-rw-r--r--erts/preloaded/ebin/prim_eval.beambin1496 -> 1496 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin28084 -> 27984 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin81012 -> 80932 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin22644 -> 22436 bytes
-rw-r--r--erts/preloaded/ebin/socket.beambin70300 -> 70248 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin19716 -> 19700 bytes
-rw-r--r--lib/compiler/src/beam_ssa_dead.erl18
-rw-r--r--lib/compiler/test/beam_ssa_SUITE.erl60
-rw-r--r--lib/kernel/src/code.erl18
-rw-r--r--lib/kernel/src/kernel.erl2
-rw-r--r--lib/kernel/test/code_SUITE.erl29
-rw-r--r--lib/ssl/src/ssl.erl9
-rw-r--r--lib/ssl/src/ssl_alert.erl31
-rw-r--r--lib/ssl/src/ssl_connection.erl66
-rw-r--r--lib/ssl/test/ssl_test_lib.erl30
-rw-r--r--system/doc/system_principles/system_principles.xml3
30 files changed, 204 insertions, 62 deletions
diff --git a/erts/preloaded/ebin/atomics.beam b/erts/preloaded/ebin/atomics.beam
index ef402b5fee..c74ce3ce2d 100644
--- a/erts/preloaded/ebin/atomics.beam
+++ b/erts/preloaded/ebin/atomics.beam
Binary files differ
diff --git a/erts/preloaded/ebin/counters.beam b/erts/preloaded/ebin/counters.beam
index 674d0d27fa..2aec433bcb 100644
--- a/erts/preloaded/ebin/counters.beam
+++ b/erts/preloaded/ebin/counters.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erl_init.beam b/erts/preloaded/ebin/erl_init.beam
index 0313988e3e..0c032e8e91 100644
--- a/erts/preloaded/ebin/erl_init.beam
+++ b/erts/preloaded/ebin/erl_init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index 661bcd8413..13fdd7908b 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erl_tracer.beam b/erts/preloaded/ebin/erl_tracer.beam
index ec4d6153d1..16e17b870b 100644
--- a/erts/preloaded/ebin/erl_tracer.beam
+++ b/erts/preloaded/ebin/erl_tracer.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index 62dc8702e7..866f9df79f 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_code_purger.beam b/erts/preloaded/ebin/erts_code_purger.beam
index 669149df82..d81bc08282 100644
--- a/erts/preloaded/ebin/erts_code_purger.beam
+++ b/erts/preloaded/ebin/erts_code_purger.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_dirty_process_signal_handler.beam b/erts/preloaded/ebin/erts_dirty_process_signal_handler.beam
index 6d3528c2dc..a8d492dfa5 100644
--- a/erts/preloaded/ebin/erts_dirty_process_signal_handler.beam
+++ b/erts/preloaded/ebin/erts_dirty_process_signal_handler.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_internal.beam b/erts/preloaded/ebin/erts_internal.beam
index b3af713809..dd08111aad 100644
--- a/erts/preloaded/ebin/erts_internal.beam
+++ b/erts/preloaded/ebin/erts_internal.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_literal_area_collector.beam b/erts/preloaded/ebin/erts_literal_area_collector.beam
index fc2bf6f6bd..0f7dd6efbe 100644
--- a/erts/preloaded/ebin/erts_literal_area_collector.beam
+++ b/erts/preloaded/ebin/erts_literal_area_collector.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 1d89174b25..942f29a11c 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/net.beam b/erts/preloaded/ebin/net.beam
index f61b2b4a69..88d546a3af 100644
--- a/erts/preloaded/ebin/net.beam
+++ b/erts/preloaded/ebin/net.beam
Binary files differ
diff --git a/erts/preloaded/ebin/persistent_term.beam b/erts/preloaded/ebin/persistent_term.beam
index c882e4fad4..7871b64991 100644
--- a/erts/preloaded/ebin/persistent_term.beam
+++ b/erts/preloaded/ebin/persistent_term.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_buffer.beam b/erts/preloaded/ebin/prim_buffer.beam
index cf671bf8f4..90d9596fe6 100644
--- a/erts/preloaded/ebin/prim_buffer.beam
+++ b/erts/preloaded/ebin/prim_buffer.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_eval.beam b/erts/preloaded/ebin/prim_eval.beam
index 24911123f9..19935eeee3 100644
--- a/erts/preloaded/ebin/prim_eval.beam
+++ b/erts/preloaded/ebin/prim_eval.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index 0efd954e50..a2c5f2f336 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index ff9268ad38..b7c4cbe0a8 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam
index d319d7a343..bd51c3b271 100644
--- a/erts/preloaded/ebin/prim_zip.beam
+++ b/erts/preloaded/ebin/prim_zip.beam
Binary files differ
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 558a886565..27efe10f38 100644
--- a/erts/preloaded/ebin/socket.beam
+++ b/erts/preloaded/ebin/socket.beam
Binary files differ
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index 9610c94ac2..8b7c5fe2ef 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/lib/compiler/src/beam_ssa_dead.erl b/lib/compiler/src/beam_ssa_dead.erl
index e220a89ded..64b9b3e222 100644
--- a/lib/compiler/src/beam_ssa_dead.erl
+++ b/lib/compiler/src/beam_ssa_dead.erl
@@ -436,8 +436,22 @@ get_phi_arg([{Val,From}|_], From) -> Val;
get_phi_arg([_|As], From) -> get_phi_arg(As, From).
eval_terminator(#b_br{bool=#b_var{}=Bool}=Br, Bs, _St) ->
- Val = get_value(Bool, Bs),
- beam_ssa:normalize(Br#b_br{bool=Val});
+ case get_value(Bool, Bs) of
+ #b_literal{val=Val}=Lit ->
+ case is_boolean(Val) of
+ true ->
+ beam_ssa:normalize(Br#b_br{bool=Lit});
+ false ->
+ %% Non-boolean literal. This means that this `br`
+ %% terminator will never actually be reached with
+ %% these bindings. (There must be a previous two-way
+ %% branch that branches the other way when Bool
+ %% is bound to a non-boolean literal.)
+ none
+ end;
+ #b_var{}=Var ->
+ beam_ssa:normalize(Br#b_br{bool=Var})
+ end;
eval_terminator(#b_br{bool=#b_literal{}}=Br, _Bs, _St) ->
beam_ssa:normalize(Br);
eval_terminator(#b_switch{arg=Arg,fail=Fail,list=List}=Sw, Bs, St) ->
diff --git a/lib/compiler/test/beam_ssa_SUITE.erl b/lib/compiler/test/beam_ssa_SUITE.erl
index 15cf9bcbf3..a741ebbdf9 100644
--- a/lib/compiler/test/beam_ssa_SUITE.erl
+++ b/lib/compiler/test/beam_ssa_SUITE.erl
@@ -22,7 +22,8 @@
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
init_per_group/2,end_per_group/2,
calls/1,tuple_matching/1,recv/1,maps/1,
- cover_ssa_dead/1,combine_sw/1,share_opt/1]).
+ cover_ssa_dead/1,combine_sw/1,share_opt/1,
+ beam_ssa_dead_crash/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -37,7 +38,8 @@ groups() ->
maps,
cover_ssa_dead,
combine_sw,
- share_opt
+ share_opt,
+ beam_ssa_dead_crash
]}].
init_per_suite(Config) ->
@@ -492,6 +494,60 @@ do_share_opt(A) ->
end,
receive after 1 -> ok end.
+beam_ssa_dead_crash(_Config) ->
+ not_A_B = do_beam_ssa_dead_crash(id(false), id(true)),
+ not_A_not_B = do_beam_ssa_dead_crash(false, false),
+ neither = do_beam_ssa_dead_crash(true, false),
+ neither = do_beam_ssa_dead_crash(true, true),
+ ok.
+
+do_beam_ssa_dead_crash(A, B) ->
+ %% beam_ssa_dead attempts to shortcut branches that branch other
+ %% branches. When a two-way branch is encountered, beam_ssa_dead
+ %% will simulate execution along both paths, in the hope that both
+ %% paths happens to end up in the same place.
+ %%
+ %% During the simulated execution of this function, the boolean
+ %% varible for a `br` instruction would be replaced with the
+ %% literal atom `nil`, which is not allowed, and would crash the
+ %% compiler. In practice, during the actual execution, control
+ %% would never be transferred to that `br` instruction when the
+ %% variable in question had the value `nil`.
+ %%
+ %% beam_ssa_dead has been updated to immediately abort the search
+ %% along the current path if there is an attempt to substitute a
+ %% non-boolean value into a `br` instruction.
+
+ case
+ case not A of
+ false ->
+ false;
+ true ->
+ B
+ end
+ of
+ V
+ when
+ V /= nil
+ andalso
+ V /= false ->
+ not_A_B;
+ _ ->
+ case
+ case not A of
+ false ->
+ false;
+ true ->
+ not B
+ end
+ of
+ true ->
+ not_A_not_B;
+ false ->
+ neither
+ end
+ end.
+
%% The identity function.
id(I) -> I.
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index 7faef93609..964ede9bc9 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -19,6 +19,8 @@
%%
-module(code).
+-include_lib("kernel/include/logger.hrl").
+
%% This is the interface module to the code server. It also contains
%% some implementation details. See also related modules: code_*.erl
%% in this directory.
@@ -707,8 +709,20 @@ do_s(Lib) ->
start_get_mode() ->
case init:get_argument(mode) of
- {ok,[["embedded"]]} ->
- embedded;
+ {ok, [FirstMode | Rest]} ->
+ case Rest of
+ [] ->
+ ok;
+ _ ->
+ ?LOG_WARNING("Multiple -mode given to erl, using the first, ~p",
+ [FirstMode])
+ end,
+ case FirstMode of
+ ["embedded"] ->
+ embedded;
+ _ ->
+ interactive
+ end;
_ ->
interactive
end.
diff --git a/lib/kernel/src/kernel.erl b/lib/kernel/src/kernel.erl
index bc4f09a023..c8c631ab23 100644
--- a/lib/kernel/src/kernel.erl
+++ b/lib/kernel/src/kernel.erl
@@ -141,7 +141,7 @@ init([]) ->
modules => [logger_sup]},
case init:get_argument(mode) of
- {ok, [["minimal"]]} ->
+ {ok, [["minimal"]|_]} ->
{ok, {SupFlags,
[Code, File, StdError, User, LoggerSup, Config, RefC, SafeSup]}};
_ ->
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index 4f0847084f..6b133f8d6b 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -41,7 +41,7 @@
big_boot_embedded/1,
module_status/1,
native_early_modules/1, get_mode/1,
- normalized_paths/1]).
+ normalized_paths/1, mult_embedded_flags/1]).
-export([init_per_testcase/2, end_per_testcase/2,
init_per_suite/1, end_per_suite/1]).
@@ -72,7 +72,8 @@ all() ->
on_load_purge, on_load_self_call, on_load_pending,
on_load_deleted,
module_status,
- big_boot_embedded, native_early_modules, get_mode, normalized_paths].
+ big_boot_embedded, native_early_modules, get_mode, normalized_paths,
+ mult_embedded_flags].
%% These need to run in order
groups() -> [{sequence, [sequence], [on_load_update,
@@ -354,7 +355,7 @@ load_abs(Config) when is_list(Config) ->
ensure_loaded(Config) when is_list(Config) ->
{module, lists} = code:ensure_loaded(lists),
case init:get_argument(mode) of
- {ok, [["embedded"]]} ->
+ {ok, [["embedded"] | _]} ->
{error, embedded} = code:ensure_loaded(code_b_test),
{error, badarg} = code:ensure_loaded(34),
ok;
@@ -1836,6 +1837,28 @@ do_normalized_paths([M|Ms]) ->
do_normalized_paths([]) ->
ok.
+%% Make sure that the extra -mode flags are ignored
+mult_embedded_flags(_Config) ->
+ Modes = [{" -mode embedded", embedded},
+ {" -mode interactive", interactive},
+ {" -mode invalid", interactive}],
+
+ [ begin
+ {ArgMode, ExpectedMode} = Mode,
+ {ok, Node} = start_node(mode_test, ArgMode),
+ ExpectedMode = rpc:call(Node, code, get_mode, []),
+ true = stop_node(Node)
+ end || Mode <- Modes],
+
+ [ begin
+ {ArgIgnoredMode, _} = IgnoredMode,
+ {ArgRelevantMode, ExpectedMode} = RelevantMode,
+ {ok, Node} = start_node(mode_test, ArgRelevantMode ++ ArgIgnoredMode),
+ ExpectedMode = rpc:call(Node, code, get_mode, []),
+ true = stop_node(Node)
+ end || IgnoredMode <- Modes, RelevantMode <- Modes],
+ ok.
+
%% Test that module_status/1 behaves as expected
module_status(_Config) ->
case test_server:is_cover() of
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 6af65e09f2..f99c0e2b7a 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -125,7 +125,9 @@
protocol_extensions/0,
session_id/0,
error_alert/0,
- srp_param_type/0]).
+ tls_alert/0,
+ srp_param_type/0,
+ named_curve/0]).
%% -------------------------------------------------------------------------------------------------------
@@ -192,6 +194,7 @@
| rsa_pss_pss_sha512
| rsa_pkcs1_sha1
| ecdsa_sha1.
+
-type kex_algo() :: rsa |
dhe_rsa | dhe_dss |
ecdhe_ecdsa | ecdh_ecdsa | ecdh_rsa |
@@ -236,7 +239,7 @@
sect163r2 |
secp160k1 |
secp160r1 |
- secp160r2.
+ secp160r2. % exported
-type group() :: secp256r1 | secp384r1 | secp521r1 | ffdhe2048 |
ffdhe3072 | ffdhe4096 | ffdhe6144 | ffdhe8192.
@@ -279,7 +282,7 @@
bad_certificate_status_response |
bad_certificate_hash_value |
unknown_psk_identity |
- no_application_protocol.
+ no_application_protocol. % exported
%% -------------------------------------------------------------------------------------------------------
-type common_option() :: {protocol, protocol()} |
diff --git a/lib/ssl/src/ssl_alert.erl b/lib/ssl/src/ssl_alert.erl
index 06b1b005a5..2d57b72f7b 100644
--- a/lib/ssl/src/ssl_alert.erl
+++ b/lib/ssl/src/ssl_alert.erl
@@ -32,7 +32,11 @@
-include("ssl_record.hrl").
-include("ssl_internal.hrl").
--export([decode/1, own_alert_txt/1, alert_txt/1, reason_code/2]).
+-export([decode/1,
+ own_alert_txt/1,
+ alert_txt/1,
+ alert_txt/4,
+ reason_code/4]).
%%====================================================================
%% Internal application API
@@ -48,20 +52,29 @@ decode(Bin) ->
decode(Bin, [], 0).
%%--------------------------------------------------------------------
-%% -spec reason_code(#alert{}, client | server) ->
-%% {tls_alert, unicode:chardata()} | closed.
-%-spec reason_code(#alert{}, client | server) -> closed | {essl, string()}.
+-spec reason_code(#alert{}, client | server, ProtocolName::string(), StateName::atom()) ->
+ {tls_alert, {atom(), unicode:chardata()}} | closed.
%%
%% Description: Returns the error reason that will be returned to the
%% user.
%%--------------------------------------------------------------------
-reason_code(#alert{description = ?CLOSE_NOTIFY}, _) ->
+reason_code(#alert{description = ?CLOSE_NOTIFY}, _, _, _) ->
closed;
-reason_code(#alert{description = Description, role = Role} = Alert, Role) ->
- {tls_alert, {description_atom(Description), own_alert_txt(Alert)}};
-reason_code(#alert{description = Description} = Alert, Role) ->
- {tls_alert, {description_atom(Description), alert_txt(Alert#alert{role = Role})}}.
+reason_code(#alert{description = Description, role = Role} = Alert, Role, ProtocolName, StateName) ->
+ Txt = lists:flatten(alert_txt(ProtocolName, Role, StateName, own_alert_txt(Alert))),
+ {tls_alert, {description_atom(Description), Txt}};
+reason_code(#alert{description = Description} = Alert, Role, ProtocolName, StateName) ->
+ Txt = lists:flatten(alert_txt(ProtocolName, Role, StateName, alert_txt(Alert))),
+ {tls_alert, {description_atom(Description), Txt}}.
+
+%%--------------------------------------------------------------------
+-spec alert_txt(string(), server | client, StateNam::atom(), string()) -> string().
+%%
+%% Description: Generates alert text for log or string part of error return.
+%%--------------------------------------------------------------------
+alert_txt(ProtocolName, Role, StateName, Txt) ->
+ io_lib:format("~s ~p: In state ~p ~s\n", [ProtocolName, Role, StateName, Txt]).
%%--------------------------------------------------------------------
-spec own_alert_txt(#alert{}) -> string().
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 345db7510f..7047c01657 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -328,34 +328,33 @@ prf(ConnectionPid, Secret, Label, Seed, WantedLength) ->
%%====================================================================
%% Alert and close handling
%%====================================================================
-handle_own_alert(Alert, _, StateName,
+handle_own_alert(Alert0, _, StateName,
#state{static_env = #static_env{role = Role,
protocol_cb = Connection},
ssl_options = SslOpts} = State) ->
try %% Try to tell the other side
- send_alert(Alert, StateName, State)
+ send_alert(Alert0, StateName, State)
catch _:_ -> %% Can crash if we are in a uninitialized state
ignore
end,
try %% Try to tell the local user
- log_alert(SslOpts#ssl_options.log_level, Role,
- Connection:protocol_name(), StateName,
- Alert#alert{role = Role}),
+ Alert = Alert0#alert{role = Role},
+ log_alert(SslOpts#ssl_options.log_level, Role, Connection:protocol_name(), StateName, Alert),
handle_normal_shutdown(Alert,StateName, State)
catch _:_ ->
ok
end,
{stop, {shutdown, own_alert}, State}.
-handle_normal_shutdown(Alert, _, #state{static_env = #static_env{role = Role,
- socket = Socket,
- transport_cb = Transport,
- protocol_cb = Connection,
- tracker = Tracker},
- handshake_env = #handshake_env{renegotiation = {false, first}},
- start_or_recv_from = StartFrom} = State) ->
+handle_normal_shutdown(Alert, StateName, #state{static_env = #static_env{role = Role,
+ socket = Socket,
+ transport_cb = Transport,
+ protocol_cb = Connection,
+ tracker = Tracker},
+ handshake_env = #handshake_env{renegotiation = {false, first}},
+ start_or_recv_from = StartFrom} = State) ->
Pids = Connection:pids(State),
- alert_user(Pids, Transport, Tracker,Socket, StartFrom, Alert, Role, Connection);
+ alert_user(Pids, Transport, Tracker,Socket, StartFrom, Alert, Role, StateName, Connection);
handle_normal_shutdown(Alert, StateName, #state{static_env = #static_env{role = Role,
socket = Socket,
@@ -366,9 +365,9 @@ handle_normal_shutdown(Alert, StateName, #state{static_env = #static_env{role =
socket_options = Opts,
start_or_recv_from = RecvFrom} = State) ->
Pids = Connection:pids(State),
- alert_user(Pids, Transport, Tracker, Socket, StateName, Opts, Pid, RecvFrom, Alert, Role, Connection).
+ alert_user(Pids, Transport, Tracker, Socket, StateName, Opts, Pid, RecvFrom, Alert, Role, StateName, Connection).
-handle_alert(#alert{level = ?FATAL} = Alert, StateName,
+handle_alert(#alert{level = ?FATAL} = Alert0, StateName,
#state{static_env = #static_env{role = Role,
socket = Socket,
host = Host,
@@ -382,11 +381,11 @@ handle_alert(#alert{level = ?FATAL} = Alert, StateName,
session = Session,
socket_options = Opts} = State) ->
invalidate_session(Role, Host, Port, Session),
+ Alert = Alert0#alert{role = opposite_role(Role)},
log_alert(SslOpts#ssl_options.log_level, Role, Connection:protocol_name(),
- StateName, Alert#alert{role = opposite_role(Role)}),
+ StateName, Alert),
Pids = Connection:pids(State),
- alert_user(Pids, Transport, Tracker, Socket, StateName, Opts, Pid, From, Alert,
- opposite_role(Role), Connection),
+ alert_user(Pids, Transport, Tracker, Socket, StateName, Opts, Pid, From, Alert, Role, StateName, Connection),
{stop, {shutdown, normal}, State};
handle_alert(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert,
@@ -396,13 +395,14 @@ handle_alert(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert,
StateName, State) ->
handle_normal_shutdown(Alert, StateName, State),
{stop,{shutdown, peer_close}, State};
-handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName,
+handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert0, StateName,
#state{static_env = #static_env{role = Role,
protocol_cb = Connection},
handshake_env = #handshake_env{renegotiation = {true, internal}},
ssl_options = SslOpts} = State) ->
+ Alert = Alert0#alert{role = opposite_role(Role)},
log_alert(SslOpts#ssl_options.log_level, Role,
- Connection:protocol_name(), StateName, Alert#alert{role = opposite_role(Role)}),
+ Connection:protocol_name(), StateName, Alert),
handle_normal_shutdown(Alert, StateName, State),
{stop,{shutdown, peer_close}, State};
@@ -1445,7 +1445,7 @@ handle_info({ErrorTag, Socket, econnaborted}, StateName,
} = State) when StateName =/= connection ->
Pids = Connection:pids(State),
alert_user(Pids, Transport, Tracker,Socket,
- StartFrom, ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), Role, Connection),
+ StartFrom, ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), Role, StateName, Connection),
{stop, {shutdown, normal}, State};
handle_info({ErrorTag, Socket, Reason}, StateName, #state{static_env = #static_env{socket = Socket,
@@ -2907,22 +2907,22 @@ send_user(Pid, Msg) ->
Pid ! Msg,
ok.
-alert_user(Pids, Transport, Tracker, Socket, connection, Opts, Pid, From, Alert, Role, Connection) ->
- alert_user(Pids, Transport, Tracker, Socket, Opts#socket_options.active, Pid, From, Alert, Role, Connection);
-alert_user(Pids, Transport, Tracker, Socket,_, _, _, From, Alert, Role, Connection) ->
- alert_user(Pids, Transport, Tracker, Socket, From, Alert, Role, Connection).
+alert_user(Pids, Transport, Tracker, Socket, connection, Opts, Pid, From, Alert, Role, StateName, Connection) ->
+ alert_user(Pids, Transport, Tracker, Socket, Opts#socket_options.active, Pid, From, Alert, Role, StateName, Connection);
+alert_user(Pids, Transport, Tracker, Socket,_, _, _, From, Alert, Role, StateName, Connection) ->
+ alert_user(Pids, Transport, Tracker, Socket, From, Alert, Role, StateName, Connection).
-alert_user(Pids, Transport, Tracker, Socket, From, Alert, Role, Connection) ->
- alert_user(Pids, Transport, Tracker, Socket, false, no_pid, From, Alert, Role, Connection).
+alert_user(Pids, Transport, Tracker, Socket, From, Alert, Role, StateName, Connection) ->
+ alert_user(Pids, Transport, Tracker, Socket, false, no_pid, From, Alert, Role, StateName, Connection).
-alert_user(_, _, _, _, false = Active, Pid, From, Alert, Role, _) when From =/= undefined ->
+alert_user(_, _, _, _, false = Active, Pid, From, Alert, Role, StateName, Connection) when From =/= undefined ->
%% If there is an outstanding ssl_accept | recv
%% From will be defined and send_or_reply will
%% send the appropriate error message.
- ReasonCode = ssl_alert:reason_code(Alert, Role),
+ ReasonCode = ssl_alert:reason_code(Alert, Role, Connection:protocol_name(), StateName),
send_or_reply(Active, Pid, From, {error, ReasonCode});
-alert_user(Pids, Transport, Tracker, Socket, Active, Pid, From, Alert, Role, Connection) ->
- case ssl_alert:reason_code(Alert, Role) of
+alert_user(Pids, Transport, Tracker, Socket, Active, Pid, From, Alert, Role, StateName, Connection) ->
+ case ssl_alert:reason_code(Alert, Role, Connection:protocol_name(), StateName) of
closed ->
send_or_reply(Active, Pid, From,
{ssl_closed, Connection:socket(Pids, Transport, Socket, Tracker)});
@@ -2933,11 +2933,11 @@ alert_user(Pids, Transport, Tracker, Socket, Active, Pid, From, Alert, Role, Con
log_alert(Level, Role, ProtocolName, StateName, #alert{role = Role} = Alert) ->
Txt = ssl_alert:own_alert_txt(Alert),
- Report = io_lib:format("~s ~p: In state ~p ~s\n", [ProtocolName, Role, StateName, Txt]),
+ Report = ssl_alert:alert_txt(ProtocolName, Role, StateName, Txt),
ssl_logger:notice(Level, Report);
log_alert(Level, Role, ProtocolName, StateName, Alert) ->
Txt = ssl_alert:alert_txt(Alert),
- Report = io_lib:format("~s ~p: In state ~p ~s\n", [ProtocolName, Role, StateName, Txt]),
+ Report = ssl_alert:alert_txt(ProtocolName, Role, StateName, Txt),
ssl_logger:notice(Level, Report).
invalidate_session(client, Host, Port, Session) ->
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 3b161a0c8a..733ee993a8 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -429,14 +429,17 @@ check_result(Pid, Msg) ->
end.
check_server_alert(Pid, Alert) ->
receive
- {Pid, {error, {tls_alert, {Alert, _}}}} ->
+ {Pid, {error, {tls_alert, {Alert, STxt}}}} ->
+ check_server_txt(STxt),
ok
end.
check_server_alert(Server, Client, Alert) ->
receive
- {Server, {error, {tls_alert, {Alert, _}}}} ->
+ {Server, {error, {tls_alert, {Alert, STxt}}}} ->
+ check_server_txt(STxt),
receive
- {Client, {error, {tls_alert, {Alert, _}}}} ->
+ {Client, {error, {tls_alert, {Alert, CTxt}}}} ->
+ check_client_txt(CTxt),
ok;
{Client, {error, closed}} ->
ok
@@ -444,20 +447,35 @@ check_server_alert(Server, Client, Alert) ->
end.
check_client_alert(Pid, Alert) ->
receive
- {Pid, {error, {tls_alert, {Alert, _}}}} ->
+ {Pid, {error, {tls_alert, {Alert, CTxt}}}} ->
+ check_client_txt(CTxt),
ok
end.
check_client_alert(Server, Client, Alert) ->
receive
- {Client, {error, {tls_alert, {Alert, _}}}} ->
+ {Client, {error, {tls_alert, {Alert, CTxt}}}} ->
+ check_client_txt(CTxt),
receive
- {Server, {error, {tls_alert, {Alert, _}}}} ->
+ {Server, {error, {tls_alert, {Alert, STxt}}}} ->
+ check_server_txt(STxt),
ok;
{Server, {error, closed}} ->
ok
end
end.
+check_server_txt("TLS server" ++ _) ->
+ ok;
+check_server_txt("DTLS server" ++ _) ->
+ ok;
+check_server_txt(Txt) ->
+ ct:fail({expected_server, {got, Txt}}).
+check_client_txt("TLS client" ++ _) ->
+ ok;
+check_client_txt("DTLS client" ++ _) ->
+ ok;
+check_client_txt(Txt) ->
+ ct:fail({expected_server, {got, Txt}}).
wait_for_result(Server, ServerMsg, Client, ClientMsg) ->
receive
diff --git a/system/doc/system_principles/system_principles.xml b/system/doc/system_principles/system_principles.xml
index 500522d778..6986d93ed9 100644
--- a/system/doc/system_principles/system_principles.xml
+++ b/system/doc/system_principles/system_principles.xml
@@ -156,7 +156,8 @@ init:stop()</pre>
command-line flag <c>-mode</c>.</p>
<pre>
% <input>erl -mode embedded</input></pre>
- <p>Default mode is <c>interactive</c>.</p>
+ <p>Default mode is <c>interactive</c> and extra <c>-mode</c> flags are
+ ignored.</p>
<p>The mode properties are as follows:</p>
<list type="bulleted">
<item>In embedded mode, all code is loaded during system startup