Skip to content

Commit

Permalink
Merge pull request erlang#9019 from dgud/dgud/ssl/add-ets-tab-to-socket
Browse files Browse the repository at this point in the history
dgud/ssl/add ets tab to socket

OTP-19367
  • Loading branch information
dgud authored Nov 20, 2024
2 parents ce5cade + 2c05db7 commit cdd61f5
Show file tree
Hide file tree
Showing 37 changed files with 539 additions and 548 deletions.
6 changes: 4 additions & 2 deletions lib/ssl/src/dtls_client_connection.erl
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,12 @@
%%====================================================================
%% Setup
%%====================================================================
init([Role, Host, Port, Socket, Options, User, CbInfo]) ->
init([Role, Tab, Host, Port, Socket, Options, User, CbInfo]) ->
process_flag(trap_exit, true),
State0 = dtls_gen_connection:initial_state(Role, Host, Port, Socket,
State0 = dtls_gen_connection:initial_state(Role, Tab, Host, Port, Socket,
Options, User, CbInfo),
#state{static_env = #static_env{user_socket = UserSocket}} = State0,
User ! {self(), user_socket, UserSocket},
try
State = ssl_gen_statem:init_ssl_config(State0#state.ssl_options,
Role, State0),
Expand Down
34 changes: 16 additions & 18 deletions lib/ssl/src/dtls_gen_connection.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,16 @@
-module(dtls_gen_connection).
-moduledoc false.

-include_lib("public_key/include/public_key.hrl").
-include_lib("kernel/include/logger.hrl").

-include("dtls_connection.hrl").
-include("dtls_handshake.hrl").
-include("ssl_alert.hrl").
-include("dtls_record.hrl").
-include("ssl_cipher.hrl").
-include("ssl_api.hrl").
-include("ssl_internal.hrl").

%% Setup
-export([start_fsm/8,
initial_state/7,
initial_state/8,
pids/1]).

%% Handshake handling
Expand Down Expand Up @@ -67,7 +63,6 @@

%% Data handling
-export([send/3,
socket/4,
setopts/3,
getopts/3,
handle_info/3,
Expand All @@ -91,7 +86,7 @@
%%====================================================================
%% Setup
%%====================================================================
initial_state(Role, Host, Port, Socket,
initial_state(Role, Tab, Host, Port, Socket,
{SSLOptions, SocketOptions, Trackers}, User,
{CbModule, DataTag, CloseTag, ErrorTag, PassiveTag}) ->
put(log_level, maps:get(log_level, SSLOptions)),
Expand All @@ -100,7 +95,11 @@ initial_state(Role, Host, Port, Socket,
#{session_cb := SessionCacheCb} = ssl_config:pre_1_3_session_opts(Role),
InternalActiveN = ssl_config:get_internal_active_n(),
Monitor = erlang:monitor(process, User),

SslSocket = dtls_socket:socket([self()], CbModule, Socket, ?MODULE, Tab),

InitStatEnv = #static_env{
user_socket = SslSocket,
role = Role,
transport_cb = CbModule,
protocol_cb = dtls_gen_connection,
Expand All @@ -115,7 +114,9 @@ initial_state(Role, Host, Port, Socket,
trackers = Trackers
},

#state{static_env = InitStatEnv,

#state{tab = Tab,
static_env = InitStatEnv,
handshake_env = #handshake_env{
tls_handshake_history = ssl_handshake:init_handshake_history(),
renegotiation = {false, first},
Expand All @@ -138,14 +139,14 @@ initial_state(Role, Host, Port, Socket,
}
}.

start_fsm(Role, Host, Port, Socket, {_,_, Tracker} = Opts,
User, {CbModule, _, _, _, _} = CbInfo,
Timeout) ->
start_fsm(Role, Host, Port, Socket, Opts, User, CbInfo, Timeout) ->
try
{ok, Pid} = dtls_connection_sup:start_child([Role, Host, Port, Socket,
Opts, User, CbInfo]),
{ok, SslSocket} = ssl_gen_statem:socket_control(?MODULE, Socket, [Pid], CbModule, Tracker),
ssl_gen_statem:handshake(SslSocket, Timeout)
{ok, Pid} = dtls_connection_sup:start_child([Role, Host, Port, Socket,
Opts, User, CbInfo]),
receive {Pid, user_socket, SslSocket} ->
{ok, SslSocket} = ssl_gen_statem:socket_control(SslSocket),
ssl_gen_statem:handshake(SslSocket, Timeout)
end
catch
error:{badmatch, {error, _} = Error} ->
Error
Expand Down Expand Up @@ -744,9 +745,6 @@ pack_packets([P|Rest]=Packets, SoFar, Max, Acc) ->
pack_packets([], _, _, Acc) ->
{lists:reverse(Acc), []}.

socket(Pid, Transport, Socket, _Tracker) ->
dtls_socket:socket(Pid, Transport, Socket, ?MODULE).

setopts(Transport, Socket, Other) ->
dtls_socket:setopts(Transport, Socket, Other).

Expand Down
2 changes: 1 addition & 1 deletion lib/ssl/src/dtls_packet_demux.erl
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ setup_new_connection(User, From, Client, Msg, #state{dtls_processes = Processes,
case dtls_connection_sup:start_child(ConnArgs) of
{ok, Pid} ->
erlang:monitor(process, Pid),
gen_server:reply(From, {ok, Pid, {Client, Socket}}),
gen_server:reply(From, {ok, Pid}),
Pid ! Msg,
State#state{dtls_msq_queues = kv_insert(Client, {Pid, queue:new()}, MsgQueues),
dtls_processes = kv_insert(Pid, Client, Processes)};
Expand Down
8 changes: 5 additions & 3 deletions lib/ssl/src/dtls_server_connection.erl
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,15 @@
%%====================================================================
%% Setup
%%====================================================================
init([Role, Host, Port, Socket, Options, User, CbInfo]) ->
init([Role, Tab, Host, Port, Socket, Options, User, CbInfo]) ->
process_flag(trap_exit, true),
State0 = dtls_gen_connection:initial_state(Role, Host, Port, Socket,
State0 = dtls_gen_connection:initial_state(Role, Tab, Host, Port, Socket,
Options, User, CbInfo),
#state{static_env = #static_env{user_socket = UserSocket}} = State0,
User ! {self(), user_socket, UserSocket},
try
State = ssl_gen_statem:init_ssl_config(State0#state.ssl_options,
Role, State0),
Role, State0),
gen_statem:enter_loop(?MODULE, [], initial_hello, State)
catch
throw:Error ->
Expand Down
40 changes: 24 additions & 16 deletions lib/ssl/src/dtls_socket.erl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
listen/2,
accept/3,
connect/4,
socket/4,
socket/5,
setopts/3,
getopts/3,
getstat/3,
Expand Down Expand Up @@ -69,12 +69,13 @@ listen(Port, #config{inet_ssl = SockOpts,
Error
end.

accept({Listener,_}, #config{transport_info = Info,
connection_cb = ConnectionCb}, _Timeout) ->
Transport = element(1, Info),
accept({Listener,_}, #config{}, _Timeout) ->
case dtls_packet_demux:accept(Listener, self()) of
{ok, Pid, Socket} ->
{ok, socket([Pid], Transport, {Listener, Socket}, ConnectionCb)};
{ok, Pid} ->
receive
{Pid, user_socket, UserSocket} ->
{ok, UserSocket}
end;
{error, Reason} ->
{error, Reason}
end.
Expand All @@ -83,7 +84,9 @@ connect(Address, Port, #config{transport_info = {Transport, _, _, _, _} = CbInfo
connection_cb = ConnectionCb,
ssl = SslOpts,
emulated = EmOpts,
inet_ssl = SocketOpts}, Timeout) ->
inet_ssl = SocketOpts,
tab = _Tab
}, Timeout) ->
case Transport:open(0, SocketOpts ++ internal_inet_values()) of
{ok, Socket} ->
ssl_gen_statem:connect(ConnectionCb, Address, Port, {{Address, Port},Socket},
Expand Down Expand Up @@ -128,19 +131,23 @@ close(Transport, {_Client, Socket}) ->
%% Note that gen_udp:send is not blocking as gen_tcp:send is.
%% So normal DTLS can safely have the same connection handler
%% as payload sender

socket([Pid], gen_udp = Transport,
PeerAndSock = {{_Host, _Port}, _Socket}, ConnectionCb) ->
#sslsocket{socket_handle = PeerAndSock,
connection_handler = Pid,
payload_sender = Pid,
transport_cb = Transport,
connection_cb = ConnectionCb};
socket([Pid], Transport, Socket, ConnectionCb) ->
PeerAndSock = {{_Host, _Port}, _Socket}, ConnectionCb, Tab) when Tab =/= undefined ->
#sslsocket{socket_handle = PeerAndSock,
connection_handler = Pid,
payload_sender = Pid,
transport_cb = Transport,
connection_cb = ConnectionCb,
tab = Tab};
socket([Pid], Transport, Socket, ConnectionCb, Tab) when Tab =/= undefined ->
#sslsocket{socket_handle = Socket,
connection_handler = Pid,
payload_sender = Pid,
transport_cb = Transport,
connection_cb = ConnectionCb}.
connection_cb = ConnectionCb,
tab = Tab}.

setopts(_, Socket = #sslsocket{socket_handle = {ListenPid, _},
listener_config = #config{}}, Options) ->
SplitOpts = {_, EmOpts} = tls_socket:split_options(Options),
Expand Down Expand Up @@ -336,6 +343,7 @@ create_dtls_socket(#config{emulated = EmOpts} = Config,
Listener, Port) ->
Socket = #sslsocket{
socket_handle = {Listener, Port},
listener_config = Config},
listener_config = Config,
tab = dtls_listen},
check_active_n(EmOpts, Socket),
Socket.
58 changes: 36 additions & 22 deletions lib/ssl/src/ssl.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2557,9 +2557,19 @@ closed.
send(#sslsocket{payload_sender = Sender,
connection_cb = dtls_gen_connection}, Data) when is_pid(Sender) ->
ssl_gen_statem:send(Sender, Data);
send(#sslsocket{payload_sender = Sender,
connection_cb = tls_gen_connection}, Data) when is_pid(Sender) ->
tls_sender:send_data(Sender, erlang:iolist_to_iovec(Data));
send(#sslsocket{payload_sender = Sender, tab = Tab,
connection_cb = tls_gen_connection}, Data0) when is_pid(Sender) ->
try
Packet = ets:lookup_element(Tab, {socket_options, packet}, 2),
case encode_packet(Packet, Data0) of
{error, _} = Error ->
Error;
Data ->
tls_sender:send_data(Sender, erlang:iolist_to_iovec(Data))
end
catch error:badarg ->
{error, closed}
end;
send(#sslsocket{listener_config = #config{connection_cb = dtls_gen_connection}}, _) ->
{error,enotconn}; %% Emulate connection behaviour
send(#sslsocket{socket_handle = ListenSocket,
Expand Down Expand Up @@ -3136,31 +3146,21 @@ getopts(#sslsocket{}, OptionTags) ->
SslSocket :: sslsocket(),
Options :: [gen_tcp:option()].
%%--------------------------------------------------------------------
setopts(#sslsocket{connection_handler = Controller}, [{active, _}] = Active) when is_pid(Controller) ->
setopts(#sslsocket{connection_handler = Controller}, [{active, _}] = Active)
when is_pid(Controller) ->
ssl_gen_statem:set_opts(Controller, Active);
setopts(#sslsocket{connection_handler = Controller, payload_sender = Sender,
connection_cb = tls_gen_connection}, Options0) when is_pid(Controller), is_list(Options0) ->
try proplists:expand([{binary, [{mode, binary}]},
{list, [{mode, list}]}], Options0) of
setopts(#sslsocket{connection_handler = Controller, connection_cb = tls_gen_connection}, Options0)
when is_pid(Controller), is_list(Options0) ->
try proplists:expand([{binary, [{mode, binary}]}, {list, [{mode, list}]}], Options0) of
Options ->
case proplists:get_value(packet, Options, undefined) of
undefined ->
ssl_gen_statem:set_opts(Controller, Options);
PacketOpt ->
case tls_sender:setopts(Sender, [{packet, PacketOpt}]) of
ok ->
ssl_gen_statem:set_opts(Controller, Options);
Error ->
Error
end
end
ssl_gen_statem:set_opts(Controller, Options)
catch
_:_ ->
{error, {options, {not_a_proplist, Options0}}}
end;
setopts(#sslsocket{connection_handler = Controller}, Options0) when is_pid(Controller), is_list(Options0) ->
try proplists:expand([{binary, [{mode, binary}]},
{list, [{mode, list}]}], Options0) of
setopts(#sslsocket{connection_handler = Controller}, Options0)
when is_pid(Controller), is_list(Options0) ->
try proplists:expand([{binary, [{mode, binary}]}, {list, [{mode, list}]}], Options0) of
Options ->
ssl_gen_statem:set_opts(Controller, Options)
catch
Expand Down Expand Up @@ -5235,6 +5235,20 @@ unambiguous_path(Value) ->
end,
validate_filename(UP, cacertfile).

-compile({inline, encode_packet/2}).
encode_packet(Packet, Data) ->
Len = iolist_size(Data),
case Packet of
1 when Len < (1 bsl 8) -> [<<Len:8>>|Data];
2 when Len < (1 bsl 16) -> [<<Len:16>>|Data];
4 when Len < (1 bsl 32) -> [<<Len:32>>|Data];
N when N =:= 1; N =:= 2; N =:= 4 ->
{error,
{badarg, {packet_to_large, Len, (1 bsl (Packet bsl 3)) - 1}}};
_ ->
Data
end.

%%%################################################################
%%%#
%%%# Tracing
Expand Down
1 change: 1 addition & 0 deletions lib/ssl/src/ssl_api.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
payload_sender, %% pid()
transport_cb, %% ssl:transport_option()
connection_cb, %% :: tls_gen_connection | dtls_gen_connection
tab, %% ets table
listener_config %% :: #config{} (listen socket) | [pid()] list of trackers
}).

Expand Down
3 changes: 3 additions & 0 deletions lib/ssl/src/ssl_connection.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@
-include("ssl_handshake.hrl").
-include("ssl_srp.hrl").
-include("ssl_cipher.hrl").
-include("ssl_api.hrl").
-include("ssl_alert.hrl").
-include_lib("public_key/include/public_key.hrl").

-record(static_env, {
role :: client | server,
user_socket :: #sslsocket{},
transport_cb :: atom(), % callback module
protocol_cb :: tls_gen_connection | dtls_gen_connection,
data_tag :: atom(), % ex tcp.
Expand Down Expand Up @@ -126,6 +128,7 @@
}).

-record(state, {
tab :: ets:table(),
static_env :: #static_env{},
connection_env :: #connection_env{} | ssl_gen_statem:secret_printout(),
ssl_options :: ssl_options(),
Expand Down
Loading

0 comments on commit cdd61f5

Please sign in to comment.