Skip to content

Commit

Permalink
Merge pull request erlang#8786 from IngelaAndin/ingela/ssl/refactor-s…
Browse files Browse the repository at this point in the history
…ocket

ssl:  Refactor sslsocket to ease maintenance and extension
  • Loading branch information
IngelaAndin authored Sep 25, 2024
2 parents 67db49f + d3cdc73 commit 695714d
Show file tree
Hide file tree
Showing 15 changed files with 295 additions and 230 deletions.
33 changes: 20 additions & 13 deletions lib/ssl/src/dtls_packet_demux.erl
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,9 @@ handle_call({new_connection, Old, _Pid}, _,
end;

handle_call({get_sock_opts, {SocketOptNames, EmOptNames}}, _, #state{listener = Socket,
transport = TransportInfo,
emulated_options = EmOpts} = State) ->
case get_socket_opts(Socket, SocketOptNames) of
case get_socket_opts(Socket, SocketOptNames, element(1, TransportInfo)) of
{ok, Opts} ->
{reply, {ok, emulated_opts_list(EmOpts, EmOptNames, []) ++ Opts}, State};
{error, Reason} ->
Expand All @@ -183,15 +184,17 @@ handle_call({get_sock_opts, {SocketOptNames, EmOptNames}}, _, #state{listener =
handle_call(get_all_opts, _, #state{dtls_options = DTLSOptions,
emulated_options = EmOpts} = State) ->
{reply, {ok, EmOpts, DTLSOptions}, State};
handle_call({set_sock_opts, {SocketOpts, NewEmOpts}}, _, #state{listener = Socket, emulated_options = EmOpts0} = State) ->
set_socket_opts(Socket, SocketOpts),
handle_call({set_sock_opts, {SocketOpts, NewEmOpts}}, _, #state{listener = Socket, emulated_options = EmOpts0,
transport = TransportInfo} = State) ->
set_socket_opts(Socket, SocketOpts, element(1, TransportInfo)),
EmOpts = do_set_emulated_opts(NewEmOpts, EmOpts0),
{reply, ok, State#state{emulated_options = EmOpts}};
handle_call({set_all_opts, {SocketOpts, NewEmOpts, SslOpts}}, _, #state{listener = Socket} = State) ->
set_socket_opts(Socket, SocketOpts),
handle_call({set_all_opts, {SocketOpts, NewEmOpts, SslOpts}}, _, #state{listener = Socket,
transport = TransportInfo} = State) ->
set_socket_opts(Socket, SocketOpts, element(1, TransportInfo)),
{reply, ok, State#state{emulated_options = NewEmOpts, dtls_options = SslOpts}};
handle_call({getstat, Options}, _, #state{listener = Socket, transport = {TransportCb, _,_,_,_}} = State) ->
Stats = dtls_socket:getstat(TransportCb, Socket, Options),
handle_call({getstat, Options}, _, #state{listener = Socket, transport = TransportInfo} = State) ->
Stats = dtls_socket:getstat(element(1, TransportInfo), Socket, Options),
{reply, Stats, State}.

handle_cast({active_once, Client, Pid}, State0) ->
Expand Down Expand Up @@ -386,15 +389,19 @@ call(Server, Msg) ->
{error, closed}
end.

set_socket_opts(_, []) ->
set_socket_opts(_, [], _) ->
ok;
set_socket_opts(Socket, SocketOpts) ->
inet:setopts(Socket, SocketOpts).
set_socket_opts(Socket, SocketOpts, gen_udp) ->
inet:setopts(Socket, SocketOpts);
set_socket_opts(Socket, SocketOpts, Cb) ->
Cb:setopts(Socket, SocketOpts).

get_socket_opts(_, []) ->
get_socket_opts(_, [], _) ->
{ok, []};
get_socket_opts(Socket, SocketOpts) ->
inet:getopts(Socket, SocketOpts).
get_socket_opts(Socket, SocketOpts, gen_udp) ->
inet:getopts(Socket, SocketOpts);
get_socket_opts(Socket, SocketOpts, Cb) ->
Cb:getopts(Socket, SocketOpts).

do_set_emulated_opts([], Opts) ->
Opts;
Expand Down
69 changes: 32 additions & 37 deletions lib/ssl/src/dtls_socket.erl
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ listen(Port, #config{inet_ssl = SockOpts,
Error
end.

accept(dtls, #config{transport_info = {Transport,_,_,_,_},
connection_cb = ConnectionCb,
dtls_handler = {Listener, _}}, _Timeout) ->
accept({Listener,_}, #config{transport_info = Info,
connection_cb = ConnectionCb}, _Timeout) ->
Transport = element(1, Info),
case dtls_packet_demux:accept(Listener, self()) of
{ok, Pid, Socket} ->
{ok, socket([Pid], Transport, {Listener, Socket}, ConnectionCb)};
Expand All @@ -80,10 +80,10 @@ accept(dtls, #config{transport_info = {Transport,_,_,_,_},
end.

connect(Address, Port, #config{transport_info = {Transport, _, _, _, _} = CbInfo,
connection_cb = ConnectionCb,
ssl = SslOpts,
emulated = EmOpts,
inet_ssl = SocketOpts}, Timeout) ->
connection_cb = ConnectionCb,
ssl = SslOpts,
emulated = EmOpts,
inet_ssl = SocketOpts}, Timeout) ->
case Transport:open(0, SocketOpts ++ internal_inet_values()) of
{ok, Socket} ->
ssl_gen_statem:connect(ConnectionCb, Address, Port, {{Address, Port},Socket},
Expand All @@ -94,8 +94,8 @@ connect(Address, Port, #config{transport_info = {Transport, _, _, _, _} = CbInfo
Error
end.

close_listen(#sslsocket{pid = {dtls, #config{dtls_handler = {Pid, Port0},
inet_ssl = SockOpts}}}, Timeout) ->
close_listen(#sslsocket{socket_handle = {Pid, Port0},
listener_config = #config{inet_ssl = SockOpts}}, Timeout) ->
IP = proplists:get_value(ip, SockOpts, default_ip(SockOpts)),
Port = get_real_port(Pid, Port0),
dtls_listener_sup:register_listener({undefined, Pid}, IP, Port),
Expand Down Expand Up @@ -124,16 +124,25 @@ close(gen_udp, {_Client, _Socket}) ->
close(Transport, {_Client, Socket}) ->
Transport:close(Socket).

socket(Pids, gen_udp = Transport,

%% 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{pid = Pids,
%% "The name "fd" is kept for backwards compatibility
fd = {Transport, PeerAndSock, ConnectionCb}};
socket(Pids, Transport, Socket, ConnectionCb) ->
#sslsocket{pid = Pids,
%% "The name "fd" is kept for backwards compatibility
fd = {Transport, Socket, ConnectionCb}}.
setopts(_, Socket = #sslsocket{pid = {dtls, #config{dtls_handler = {ListenPid, _}}}}, Options) ->
#sslsocket{socket_handle = PeerAndSock,
connection_handler = Pid,
payload_sender = Pid,
transport_cb = Transport,
connection_cb = ConnectionCb};
socket([Pid], Transport, Socket, ConnectionCb) ->
#sslsocket{socket_handle = Socket,
connection_handler = Pid,
payload_sender = Pid,
transport_cb = Transport,
connection_cb = ConnectionCb}.
setopts(_, Socket = #sslsocket{socket_handle = {ListenPid, _},
listener_config = #config{}}, Options) ->
SplitOpts = {_, EmOpts} = tls_socket:split_options(Options),
check_active_n(EmOpts, Socket),
dtls_packet_demux:set_sock_opts(ListenPid, SplitOpts);
Expand All @@ -143,7 +152,8 @@ setopts(gen_udp, Socket, Options) ->
setopts(Transport, Socket, Options) ->
Transport:setopts(Socket, Options).

check_active_n(EmulatedOpts, Socket = #sslsocket{pid = {dtls, #config{dtls_handler = {ListenPid, _}}}}) ->
check_active_n(EmulatedOpts, Socket = #sslsocket{socket_handle = {ListenPid, _},
listener_config = #config{}}) ->
%% We check the resulting options to send an ssl_passive message if necessary.
case proplists:lookup(active, EmulatedOpts) of
%% The provided value is out of bound.
Expand All @@ -169,19 +179,9 @@ check_active_n(EmulatedOpts, Socket = #sslsocket{pid = {dtls, #config{dtls_handl
ok
end.

getopts(_, #sslsocket{pid = {dtls, #config{dtls_handler = {ListenPid, _}}}}, Options) ->
getopts(_, #sslsocket{socket_handle = {ListenPid, _}, listener_config =#config{}}, Options) ->
SplitOpts = tls_socket:split_options(Options),
dtls_packet_demux:get_sock_opts(ListenPid, SplitOpts);
getopts(gen_udp, #sslsocket{pid = {Socket, #config{emulated = EmOpts}}}, Options) ->
{SockOptNames, EmulatedOptNames} = tls_socket:split_options(Options),
EmulatedOpts = get_emulated_opts(EmOpts, EmulatedOptNames),
SocketOpts = tls_socket:get_socket_opts(Socket, SockOptNames, inet),
{ok, EmulatedOpts ++ SocketOpts};
getopts(_Transport, #sslsocket{pid = {Socket, #config{emulated = EmOpts}}}, Options) ->
{SockOptNames, EmulatedOptNames} = tls_socket:split_options(Options),
EmulatedOpts = get_emulated_opts(EmOpts, EmulatedOptNames),
SocketOpts = tls_socket:get_socket_opts(Socket, SockOptNames, inet),
{ok, EmulatedOpts ++ SocketOpts};
%%% Following clauses will not be called for emulated options, they are handled in the connection process
getopts(gen_udp, {_,{{_, _},Socket}}, Options) ->
inet:getopts(Socket, Options);
Expand Down Expand Up @@ -235,11 +235,6 @@ default_inet_values() ->
default_cb_info() ->
{gen_udp, udp, udp_closed, udp_error, udp_passive}.

get_emulated_opts(EmOpts, EmOptNames) ->
lists:map(fun(Name) -> {value, Value} = lists:keysearch(Name, 1, EmOpts),
Value end,
EmOptNames).

emulated_socket_options(InetValues, #socket_options{
mode = Mode,
packet = Packet,
Expand Down Expand Up @@ -340,7 +335,7 @@ start_dtls_packet_demux(#config{
create_dtls_socket(#config{emulated = EmOpts} = Config,
Listener, Port) ->
Socket = #sslsocket{
pid = {dtls, Config#config{dtls_handler = {Listener, Port}}}},
socket_handle = {Listener, Port},
listener_config = Config},
check_active_n(EmOpts, Socket),
Socket.

8 changes: 4 additions & 4 deletions lib/ssl/src/inet_tls_dist.erl
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ hs_data_inet_tcp(Driver, Socket) ->
}
end}.

hs_data_ssl(Family, #sslsocket{pid = [_, DistCtrl|_]} = SslSocket) ->
hs_data_ssl(Family, #sslsocket{payload_sender = DistCtrl} = SslSocket) ->
{ok, Address} =
maybe
{error, einval} ?= ssl:peername(SslSocket),
Expand Down Expand Up @@ -347,7 +347,7 @@ accept_one(Family, Socket, NetKernel) ->
net_kernel:connecttime())
of
{ok, SslSocket} ->
Receiver = hd(SslSocket#sslsocket.pid),
Receiver = SslSocket#sslsocket.connection_handler,
case KTLS of
true ->
{ok, KtlsInfo} = ssl_gen_statem:ktls_handover(Receiver),
Expand Down Expand Up @@ -512,7 +512,7 @@ do_accept(
Timer = dist_util:start_timer(SetupTime),
{HSData0, NewAllowed} =
case DistSocket of
SslSocket = #sslsocket{pid = [_Receiver, Sender| _]} ->
SslSocket = #sslsocket{payload_sender = Sender} ->
link(Sender),
{hs_data_ssl(Family, SslSocket),
allowed_nodes(SslSocket, Allowed)};
Expand Down Expand Up @@ -647,7 +647,7 @@ do_setup(
KTLS = proplists:get_value(ktls, Opts, false),
dist_util:reset_timer(Timer),
maybe
{ok, #sslsocket{pid = [Receiver, Sender| _]} = SslSocket} ?=
{ok, #sslsocket{connection_handler = Receiver, payload_sender = Sender} = SslSocket} ?=
ssl:connect(Ip, PortNum, Opts, net_kernel:connecttime()),
HSData =
case KTLS of
Expand Down
18 changes: 3 additions & 15 deletions lib/ssl/src/ssl.appup.src
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
%% -*- erlang -*-
{"%VSN%",
[
[
{<<"11\\..*">>, [{restart_application, ssl}]},
{<<"10\\..*">>, [{restart_application, ssl}]},
{<<"9\\..*">>, [{restart_application, ssl}]},
{<<"8\\..*">>, [{restart_application, ssl}]},
{<<"7\\..*">>, [{restart_application, ssl}]},
{<<"6\\..*">>, [{restart_application, ssl}]},
{<<"5\\..*">>, [{restart_application, ssl}]},
{<<"4\\..*">>, [{restart_application, ssl}]},
{<<"3\\..*">>, [{restart_application, ssl}]}
{<<"9\\..*">>, [{restart_application, ssl}]}
],
[
{<<"11\\..*">>, [{restart_application, ssl}]},
{<<"10\\..*">>, [{restart_application, ssl}]},
{<<"9\\..*">>, [{restart_application, ssl}]},
{<<"8\\..*">>, [{restart_application, ssl}]},
{<<"7\\..*">>, [{restart_application, ssl}]},
{<<"6\\..*">>, [{restart_application, ssl}]},
{<<"5\\..*">>, [{restart_application, ssl}]},
{<<"4\\..*">>, [{restart_application, ssl}]},
{<<"3\\..*">>, [{restart_application, ssl}]}
{<<"9\\..*">>, [{restart_application, ssl}]}
]
}.
Loading

0 comments on commit 695714d

Please sign in to comment.