Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dgud/ssl/add ets tab to socket #9019

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -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}).
dgud marked this conversation as resolved.
Show resolved Hide resolved
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{},
dgud marked this conversation as resolved.
Show resolved Hide resolved
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