Skip to content

Commit

Permalink
Create a common ets table for client and server
Browse files Browse the repository at this point in the history
And move packet encoding to user process.

Socket options like packet-mode must be accessable from both user and
ssl-processes.

But we could move more stuff to that table to minimize the process state.
  • Loading branch information
dgud committed Nov 11, 2024
1 parent c4c9286 commit 746bd74
Show file tree
Hide file tree
Showing 20 changed files with 185 additions and 149 deletions.
4 changes: 2 additions & 2 deletions lib/ssl/src/dtls_client_connection.erl
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@
%%====================================================================
%% 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},
Expand Down
14 changes: 6 additions & 8 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 @@ -90,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 +96,7 @@ initial_state(Role, Host, Port, Socket,
InternalActiveN = ssl_config:get_internal_active_n(),
Monitor = erlang:monitor(process, User),

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

InitStatEnv = #static_env{
user_socket = SslSocket,
Expand All @@ -118,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 Down
4 changes: 2 additions & 2 deletions lib/ssl/src/dtls_server_connection.erl
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@
%%====================================================================
%% 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},
Expand Down
29 changes: 18 additions & 11 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 @@ -84,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 @@ -129,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 @@ -337,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 @@ -2551,9 +2551,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 @@ -3130,31 +3140,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 @@ -5229,6 +5229,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
1 change: 1 addition & 0 deletions lib/ssl/src/ssl_connection.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -128,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 746bd74

Please sign in to comment.