diff --git a/lib/ssl/src/dtls_connection_sup.erl b/lib/ssl/src/dtls_connection_sup.erl index f2b87fa1f39..2ca72724943 100644 --- a/lib/ssl/src/dtls_connection_sup.erl +++ b/lib/ssl/src/dtls_connection_sup.erl @@ -58,7 +58,7 @@ init(_) -> period => 3600 }, ChildSpecs = [#{id => undefined, - start => {ssl_gen_statem, start_link, []}, + start => {ssl_gen_statem, dtls_start_link, []}, restart => temporary, shutdown => 4000, modules => [ssl_gen_statem, dtls_connection], diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src index fa67c6ed0e4..104301129ba 100644 --- a/lib/ssl/src/ssl.app.src +++ b/lib/ssl/src/ssl.app.src @@ -92,6 +92,6 @@ {applications, [crypto, public_key, kernel, stdlib]}, {env, []}, {mod, {ssl_app, []}}, - {runtime_dependencies, ["stdlib-6.0","public_key-1.16.4","kernel-9.0", + {runtime_dependencies, ["stdlib-@OTP-19345@","public_key-1.16.4","kernel-9.0", "erts-15.0","crypto-5.0", "inets-5.10.7", "runtime_tools-1.15.1"]}]}. diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index e918db8d64d..dfc7b59b1bf 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -2174,7 +2174,7 @@ connect(TCPSocket, TLSOptions, Timeout) try tls_gen_connection = connection_cb(TLSOptions), {ok, Config} = ssl_config:handle_options(TCPSocket, TLSOptions, client, undefined), - tls_socket:upgrade(TCPSocket, Config, Timeout) + tls_socket:upgrade(client, TCPSocket, Config, Timeout) catch error:{badmatch, _} -> {error, {dtls_upgrade, notsup}}; @@ -2448,17 +2448,9 @@ handshake(Socket, SslOptions, Timeout) when is_list(SslOptions), ?IS_TIMEOUT(Timeout) -> try tls_gen_connection = connection_cb(SslOptions), - {ok, #config{transport_info = CbInfo, ssl = SslOpts, emulated = EmOpts}} = + {ok, Config} = ssl_config:handle_options(Socket, SslOptions, server, undefined), - Transport = element(1, CbInfo), - ok = tls_socket:setopts(Transport, Socket, tls_socket:internal_inet_values()), - {ok, Port} = tls_socket:port(Transport, Socket), - {ok, SessionIdHandle} = tls_socket:session_id_tracker(ssl_unknown_listener, SslOpts), - tls_gen_connection:start_fsm(server, "localhost", Port, Socket, - {SslOpts, - tls_socket:emulated_socket_options(EmOpts, #socket_options{}), - [{session_id_tracker, SessionIdHandle}]}, - self(), CbInfo, Timeout) + tls_socket:upgrade(server, Socket, Config, Timeout) catch error:{badmatch, _} -> {error, {dtls_upgrade, notsup}}; diff --git a/lib/ssl/src/ssl_gen_statem.erl b/lib/ssl/src/ssl_gen_statem.erl index df16c569fbc..e525ba6f9e7 100644 --- a/lib/ssl/src/ssl_gen_statem.erl +++ b/lib/ssl/src/ssl_gen_statem.erl @@ -34,8 +34,8 @@ -include("tls_connection.hrl"). %% Initial Erlang process setup --export([start_link/7, - start_link/8, +-export([tls_start_link/7, + dtls_start_link/7, init/1]). %% TLS connection setup @@ -108,26 +108,26 @@ %%% Initial Erlang process setup %%-------------------------------------------------------------------- %%-------------------------------------------------------------------- --spec start_link(client| server, pid(), ssl:host(), inet:port_number(), port(), tuple(), pid(), tuple()) -> +-spec tls_start_link(client | server, ssl:host(), inet:port_number(), port(), tuple(), pid(), tuple()) -> {ok, pid()} | ignore | {error, ssl:reason()}. %% %% Description: Creates a process which calls Module:init/1 to %% choose appropriat gen_statem and initialize. %%-------------------------------------------------------------------- -start_link(Role, Sender, Host, Port, Socket, {SslOpts, _, _} = Options, User, CbInfo) -> +tls_start_link(Role, Host, Port, Socket, {SslOpts, _, _} = Options, User, CbInfo) -> ReceiverOpts = maps:get(receiver_spawn_opts, SslOpts, []), Opts = [link | proplists:delete(link, ReceiverOpts)], - Pid = proc_lib:spawn_opt(?MODULE, init, [[Role, Sender, Host, Port, Socket, Options, User, CbInfo]], Opts), + Pid = proc_lib:spawn_opt(?MODULE, init, [[Role, self(), Host, Port, Socket, Options, User, CbInfo]], Opts), {ok, Pid}. %%-------------------------------------------------------------------- --spec start_link(atom(), ssl:host(), inet:port_number(), port(), tuple(), pid(), tuple()) -> +-spec dtls_start_link(client | server, ssl:host(), inet:port_number(), port(), tuple(), pid(), tuple()) -> {ok, pid()} | ignore | {error, ssl:reason()}. %% %% Description: Creates a gen_statem process which calls Module:init/1 to %% initialize. %%-------------------------------------------------------------------- -start_link(Role, Host, Port, Socket, {SslOpts, _, _} = Options, User, CbInfo) -> +dtls_start_link(Role, Host, Port, Socket, {SslOpts, _, _} = Options, User, CbInfo) -> ReceiverOpts = maps:get(receiver_spawn_opts, SslOpts, []), Opts = [link | proplists:delete(link, ReceiverOpts)], Pid = proc_lib:spawn_opt(?MODULE, init, [[Role, Host, Port, Socket, Options, User, CbInfo]], Opts), @@ -138,9 +138,11 @@ start_link(Role, Host, Port, Socket, {SslOpts, _, _} = Options, User, CbInfo) -> -spec init(list()) -> no_return(). %% Description: Initialization %%-------------------------------------------------------------------- -init([Role, Sender |[Host, Port, _Socket, {TLSOpts, _, _}, _User, _CbInfo] = InitArgs]) -> +init([Role, Sup | [Host, Port, _Socket, {TLSOpts, _, _}, _User, _CbInfo] = InitArgs]) -> process_flag(trap_exit, true), + {ok, {_, Sender,_,_}} = supervisor:which_child(Sup, sender), + case maps:get(erl_dist, TLSOpts, false) of true -> process_flag(priority, max); diff --git a/lib/ssl/src/ssl_trace.erl b/lib/ssl/src/ssl_trace.erl index 55c530deb7c..6505c10da21 100644 --- a/lib/ssl/src/ssl_trace.erl +++ b/lib/ssl/src/ssl_trace.erl @@ -432,7 +432,7 @@ trace_profiles() -> {dtls_server_connection, [{initial_hello, 3}]}, {tls_gen_connection, - [{start_connection_tree, 5}, {socket_control, 2}]} + [{start_connection_tree, 3}]} ]}, {csp, %% OCSP fun(M, F, A) -> dbg:tpl(M, F, A, x) end, diff --git a/lib/ssl/src/tls_dyn_connection_sup.erl b/lib/ssl/src/tls_dyn_connection_sup.erl index cfb490bd88b..97bc2394c38 100644 --- a/lib/ssl/src/tls_dyn_connection_sup.erl +++ b/lib/ssl/src/tls_dyn_connection_sup.erl @@ -32,8 +32,7 @@ -behaviour(supervisor). %% API --export([start_link/0]). --export([start_child/3]). +-export([start_link/2]). %% Supervisor callback -export([init/1]). @@ -41,24 +40,19 @@ %%%========================================================================= %%% API %%%========================================================================= -start_link() -> - supervisor:start_link(?MODULE, []). +start_link(SenderArgs, ReciverArgs) -> + supervisor:start_link(?MODULE, [SenderArgs, ReciverArgs]). -start_child(Sup, sender, Args) -> - supervisor:start_child(Sup, sender(Args)); -start_child(Sup, receiver, Args) -> - supervisor:start_child(Sup, receiver(Args)). - %%%========================================================================= %%% Supervisor callback %%%========================================================================= -init(_) -> +init([SenderArgs, ReciverArgs]) -> SupFlags = #{strategy => one_for_all, auto_shutdown => any_significant, intensity => 0, period => 3600 }, - ChildSpecs = [], + ChildSpecs = [sender(SenderArgs), receiver(ReciverArgs)], {ok, {SupFlags, ChildSpecs}}. sender(Args) -> @@ -74,7 +68,7 @@ receiver(Args) -> restart => temporary, type => worker, significant => true, - start => {ssl_gen_statem, start_link, Args}, + start => {ssl_gen_statem, tls_start_link, Args}, modules => [ssl_gen_statem, tls_client_connection, tls_server_connection, diff --git a/lib/ssl/src/tls_gen_connection.erl b/lib/ssl/src/tls_gen_connection.erl index ea9760e82db..adf5f94bee3 100644 --- a/lib/ssl/src/tls_gen_connection.erl +++ b/lib/ssl/src/tls_gen_connection.erl @@ -33,7 +33,8 @@ -include("tls_record_1_3.hrl"). %% Setup --export([start_fsm/8, +-export([start_fsm/6, + start_fsm/7, pids/1, initialize_tls_sender/1]). @@ -72,20 +73,33 @@ %%==================================================================== %% Setup %%==================================================================== -start_fsm(Role, Host, Port, Socket, {SSLOpts, _, _Trackers} = Opts, +start_fsm(Host, Port, Socket, {SSLOpts, _, _Trackers} = Opts, User, CbInfo, Timeout) -> ErlDist = maps:get(erl_dist, SSLOpts, false), SenderSpawnOpts = maps:get(sender_spawn_opts, SSLOpts, []), SenderOptions = handle_sender_options(ErlDist, SenderSpawnOpts), - Starter = start_connection_tree(User, ErlDist, SenderOptions, - Role, [Host, Port, Socket, Opts, User, CbInfo]), - receive - {Starter, {ok, SockReceiver}} -> - receive {SockReceiver, user_socket, UserSocket} -> - socket_control(UserSocket, Timeout) - end; - {Starter, Error} -> - Error + {ok, DynSup} = start_connection_tree(ErlDist, SenderOptions, + [client, Host, Port, Socket, Opts, User, CbInfo]), + {ok, {_, Receiver,_,_}} = supervisor:which_child(DynSup, receiver), + receive {Receiver, user_socket, UserSocket} -> + case ssl_gen_statem:socket_control(UserSocket) of + {ok, SslSocket} -> + ssl_gen_statem:handshake(SslSocket, Timeout); + Error -> + Error + end + end. + +start_fsm(Port, Socket, {SSLOpts, _, _Trackers} = Opts, + User, CbInfo, _Timeout) -> + ErlDist = maps:get(erl_dist, SSLOpts, false), + SenderSpawnOpts = maps:get(sender_spawn_opts, SSLOpts, []), + SenderOptions = handle_sender_options(ErlDist, SenderSpawnOpts), + {ok, DynSup} = start_connection_tree(ErlDist, SenderOptions, + [server, "localhost", Port, Socket, Opts, User, CbInfo]), + {ok, {_, Receiver,_,_}} = supervisor:which_child(DynSup, receiver), + receive {Receiver, user_socket, UserSocket} -> + ssl_gen_statem:socket_control(UserSocket) end. handle_sender_options(ErlDist, SpawnOpts) -> @@ -96,48 +110,13 @@ handle_sender_options(ErlDist, SpawnOpts) -> [[{spawn_opt, SpawnOpts}]] end. -start_connection_tree(User, IsErlDist, SenderOpts, Role, ReceiverOpts) -> - StartConnectionTree = - fun() -> - try start_dyn_connection_sup(IsErlDist) of - {ok, DynSup} -> - case tls_dyn_connection_sup:start_child(DynSup, sender, SenderOpts) of - {ok, Sender} -> - Args = [Role, Sender | ReceiverOpts], - case tls_dyn_connection_sup:start_child(DynSup, receiver, Args) of - {ok, Receiver} -> - User ! {self(), {ok, Receiver}}; - {error, _} = Error -> - User ! {self(), Error}, - exit(DynSup, shutdown) - end; - {error, _} = Error -> - User ! {self(), Error}, - exit(DynSup, shutdown) - end; - {error, _Error} = Error -> - User ! {self(), Error} - catch exit:{noproc, _} -> - User ! {self(), {error, ssl_not_started}}; - _:Reason:ST -> %% Don't hang signal internal error - ?SSL_LOG(notice, internal_error, [{error, Reason}, {stacktrace, ST}]), - User ! {self(), {error, internal_error}} - end - end, - spawn(StartConnectionTree). - -start_dyn_connection_sup(true) -> - tls_connection_sup:start_child_dist([]); -start_dyn_connection_sup(false) -> - tls_connection_sup:start_child([]). - -socket_control(SslSocket, Timeout) -> - case ssl_gen_statem:socket_control(SslSocket) of - {ok, SslSocket} -> - ssl_gen_statem:handshake(SslSocket, Timeout); - Error -> - Error - end. +start_connection_tree(IsErlDist, SenderOpts, ReceiverOpts) -> + case IsErlDist of + false -> + tls_connection_sup:start_child([SenderOpts, ReceiverOpts]); + true -> + tls_connection_sup:start_child_dist([SenderOpts, ReceiverOpts]) + end. pids(#state{protocol_specific = #{sender := Sender}}) -> [self(), Sender]. diff --git a/lib/ssl/src/tls_socket.erl b/lib/ssl/src/tls_socket.erl index e558dd934e7..b957f396f31 100644 --- a/lib/ssl/src/tls_socket.erl +++ b/lib/ssl/src/tls_socket.erl @@ -31,7 +31,7 @@ accept/3, socket/6, connect/4, - upgrade/3, + upgrade/4, setopts/3, getopts/3, getstat/3, @@ -51,7 +51,6 @@ start_link/3, terminate/2, inherit_tracker/3, - session_id_tracker/2, emulated_socket_options/2, get_emulated_opts/1, set_emulated_opts/2, @@ -112,25 +111,27 @@ accept(ListenSocket, #config{transport_info = {Transport,_,_,_,_} = CbInfo, {error, Reason} end. -upgrade(Socket, #config{transport_info = {Transport,_,_,_,_}= CbInfo, - ssl = SslOptions, - emulated = EmOpts}, Timeout) -> - ok = setopts(Transport, Socket, tls_socket:internal_inet_values()), +upgrade(client, Socket, #config{transport_info = CbInfo, + ssl = SslOptions, + emulated = EmOpts}, Timeout) -> + Transport = element(1, CbInfo), + ok = setopts(Transport, Socket, internal_inet_values()), case peername(Transport, Socket) of {ok, {Host, Port}} -> - try tls_gen_connection:start_fsm(client, Host, Port, Socket, - {SslOptions, - emulated_socket_options(EmOpts, #socket_options{}), undefined}, - self(), CbInfo, Timeout) of - Result -> - Result - catch - exit:{noproc, _} -> - {error, ssl_not_started} - end; + start_tls_client_connection(Host, Port, Socket, SslOptions, EmOpts, CbInfo, Timeout); {error, Error} -> {error, Error} - end. + end; +upgrade(server, Socket, #config{transport_info = CbInfo, + ssl = SslOpts, + emulated = EmOpts}, Timeout) -> + Transport = element(1, CbInfo), + ok = setopts(Transport, Socket, internal_inet_values()), + {ok, Port} = port(Transport, Socket), + {ok, SessionIdHandle} = session_id_tracker(ssl_unknown_listener, SslOpts), + Trackers = [{session_id_tracker, SessionIdHandle}], + {ok, SSocket} = start_tls_server_connection(SslOpts, Port, Socket, EmOpts, Trackers, CbInfo), + ssl_gen_statem:handshake(SSocket, Timeout). connect(Host, Port, #config{transport_info = CbInfo, inet_user = UserOpts, ssl = SslOpts, @@ -139,16 +140,7 @@ connect(Host, Port, {Transport, _, _, _, _} = CbInfo, try Transport:connect(Host, Port, SocketOpts, Timeout) of {ok, Socket} -> - try tls_gen_connection:start_fsm(client, Host, Port, Socket, - {SslOpts, - emulated_socket_options(EmOpts, #socket_options{}), undefined}, - self(), CbInfo, Timeout) of - Result -> - Result - catch - exit:{noproc, _} -> - {error, ssl_not_started} - end; + start_tls_client_connection(Host, Port, Socket, SslOpts, EmOpts, CbInfo, Timeout); {error, Reason} -> {error, Reason} catch @@ -420,19 +412,27 @@ call(Pid, Msg) -> gen_server:call(Pid, Msg, infinity). start_tls_server_connection(SslOpts, Port, Socket, EmOpts, Trackers, CbInfo) -> - try - {ok, DynSup} = tls_connection_sup:start_child([]), - SenderOpts = maps:get(sender_spawn_opts, SslOpts, []), - {ok, Sender} = tls_dyn_connection_sup:start_child(DynSup, sender, [[{spawn_opt, SenderOpts}]]), - ConnArgs = [server, Sender, "localhost", Port, Socket, - {SslOpts, emulated_socket_options(EmOpts, #socket_options{}), Trackers}, self(), CbInfo], - {ok, Pid} = tls_dyn_connection_sup:start_child(DynSup, receiver, ConnArgs), - receive {Pid, user_socket, UserSocket} -> - ssl_gen_statem:socket_control(UserSocket) - end + try tls_gen_connection:start_fsm(Port, Socket, + {SslOpts, + emulated_socket_options(EmOpts, #socket_options{}), Trackers}, + self(), CbInfo, infinity) of + Result -> + Result + catch + exit:{noproc, _} -> + {error, ssl_not_started} + end. + +start_tls_client_connection(Host, Port, Socket, SslOpts, EmOpts, CbInfo, Timeout) -> + try tls_gen_connection:start_fsm(Host, Port, Socket, + {SslOpts, + emulated_socket_options(EmOpts, #socket_options{}), undefined}, + self(), CbInfo, Timeout) of + Result -> + Result catch - error:{badmatch, {error, _} = Error} -> - Error + exit:{noproc, _} -> + {error, ssl_not_started} end. split_options(Opts) ->