File 3836-Move-generic-hs_data-creation-to-inet_tcp_dist.patch of Package erlang
From b9af2bd7849e019ac8abadbcd2f6c0298c116885 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Wed, 17 Aug 2022 16:00:27 +0200
Subject: [PATCH 06/11] Move generic #hs_data{} creation to inet_tcp_dist
Create functions gen_hs_data/2 and nodelay/0 as OTP
internal in Kernel/inet_tcp_dist to be used by
e.g SSL/inet_tls_dist when creating a #hs_data{}
distribution handshake record.
This simplifies code both in inet_tcp_dist and in
inet_tls_dist.
Clarify where the distribution ?PROTOCOL name
shall be used (in #net_address.protocol, and in
the {accept, self, _, _, ?PROTOCOL} message).
---
lib/kernel/src/inet_tcp_dist.erl | 148 +++++++++++++---------------
lib/ssl/src/inet_tls_dist.erl | 156 +++++++++++-------------------
lib/ssl/test/inet_crypto_dist.erl | 24 +----
3 files changed, 129 insertions(+), 199 deletions(-)
diff --git a/lib/kernel/src/inet_tcp_dist.erl b/lib/kernel/src/inet_tcp_dist.erl
index b6a0cec0ab..968d286c3d 100644
--- a/lib/kernel/src/inet_tcp_dist.erl
+++ b/lib/kernel/src/inet_tcp_dist.erl
@@ -30,6 +30,8 @@
%% Generalized dist API
-export([gen_listen/3, gen_accept/2, gen_accept_connection/6,
gen_setup/6, gen_select/2, gen_address/1]).
+%% OTP internal (e.g ssl)
+-export([gen_hs_data/2, nodelay/0]).
%% internal exports
@@ -42,6 +44,8 @@
-include("dist.hrl").
-include("dist_util.hrl").
+-define(PROTOCOL, tcp).
+
%% ------------------------------------------------------------
%% Select this protocol based on node name
%% select(Node) => Bool
@@ -71,6 +75,34 @@ address() ->
gen_address(Driver) ->
get_tcp_address(Driver).
+%% ------------------------------------------------------------
+%% Set up the general fields in #hs_data{}
+%% ------------------------------------------------------------
+gen_hs_data(Driver, Socket) ->
+ Nodelay = nodelay(),
+ #hs_data{
+ socket = Socket,
+ f_send = fun Driver:send/2,
+ f_recv = fun Driver:recv/3,
+ f_setopts_pre_nodeup =
+ fun (S) ->
+ inet:setopts(
+ S,
+ [{active, false}, {packet, 4}, Nodelay])
+ end,
+ f_setopts_post_nodeup =
+ fun (S) ->
+ inet:setopts(
+ S,
+ [{active, true}, {packet,4},
+ {deliver, port}, binary, Nodelay])
+ end,
+ f_getll = fun inet:getll/1,
+ mf_tick = fun (S) -> ?MODULE:tick(Driver, S) end,
+ mf_getstat = fun ?MODULE:getstat/1,
+ mf_setopts = fun ?MODULE:setopts/2,
+ mf_getopts = fun ?MODULE:getopts/2}.
+
%% ------------------------------------------------------------
%% Create the listen socket, i.e. the port that this erlang
%% node is accessible through.
@@ -167,7 +199,7 @@ gen_accept(Driver, Listen) ->
accept_loop(Driver, Kernel, Listen) ->
case Driver:accept(Listen) of
{ok, Socket} ->
- Kernel ! {accept,self(),Socket,Driver:family(),tcp},
+ Kernel ! {accept,self(),Socket,Driver:family(),?PROTOCOL},
_ = controller(Driver, Kernel, Socket),
accept_loop(Driver, Kernel, Listen);
Error ->
@@ -216,40 +248,19 @@ do_accept(Driver, Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
Timer = dist_util:start_timer(SetupTime),
case check_ip(Driver, Socket) of
true ->
- HSData = #hs_data{
- kernel_pid = Kernel,
- this_node = MyNode,
- socket = Socket,
- timer = Timer,
- this_flags = 0,
- allowed = Allowed,
- f_send = fun Driver:send/2,
- f_recv = fun Driver:recv/3,
- f_setopts_pre_nodeup =
- fun(S) ->
- inet:setopts(S,
- [{active, false},
- {packet, 4},
- nodelay()])
- end,
- f_setopts_post_nodeup =
- fun(S) ->
- inet:setopts(S,
- [{active, true},
- {deliver, port},
- {packet, 4},
- binary,
- nodelay()])
- end,
- f_getll = fun(S) ->
- inet:getll(S)
- end,
- f_address = fun(S, Node) -> get_remote_id(Driver, S, Node) end,
- mf_tick = fun(S) -> ?MODULE:tick(Driver, S) end,
- mf_getstat = fun ?MODULE:getstat/1,
- mf_setopts = fun ?MODULE:setopts/2,
- mf_getopts = fun ?MODULE:getopts/2
- },
+ Family = Driver:family(),
+ HSData =
+ (gen_hs_data(Driver, Socket))
+ #hs_data{
+ kernel_pid = Kernel,
+ this_node = MyNode,
+ timer = Timer,
+ this_flags = 0,
+ allowed = Allowed,
+ f_address =
+ fun (S, Node) ->
+ get_remote_id(Family, S, Node)
+ end},
dist_util:handshake_other_started(HSData);
{false,IP} ->
error_msg("** Connection attempt from "
@@ -277,13 +288,13 @@ nodelay() ->
%% ------------------------------------------------------------
%% Get remote information about a Socket.
%% ------------------------------------------------------------
-get_remote_id(Driver, Socket, Node) ->
+get_remote_id(Family, Socket, Node) ->
case inet:peername(Socket) of
{ok,Address} ->
case split_node(atom_to_list(Node), $@, []) of
[_,Host] ->
#net_address{address=Address,host=Host,
- protocol=tcp,family=Driver:family()};
+ protocol=?PROTOCOL,family=Family};
_ ->
%% No '@' or more than one '@' in node name.
?shutdown(no_node)
@@ -346,49 +357,24 @@ do_setup_connect(Driver, Kernel, Node, Address, AddressFamily,
connect_options([{active, false}, {packet, 2}]))
of
{ok, Socket} ->
- HSData = #hs_data{
- kernel_pid = Kernel,
- other_node = Node,
- this_node = MyNode,
- socket = Socket,
- timer = Timer,
- this_flags = 0,
- other_version = Version,
- f_send = fun Driver:send/2,
- f_recv = fun Driver:recv/3,
- f_setopts_pre_nodeup =
- fun(S) ->
- inet:setopts
- (S,
- [{active, false},
- {packet, 4},
- nodelay()])
- end,
- f_setopts_post_nodeup =
- fun(S) ->
- inet:setopts
- (S,
- [{active, true},
- {deliver, port},
- {packet, 4},
- nodelay()])
- end,
-
- f_getll = fun inet:getll/1,
- f_address =
- fun(_,_) ->
- #net_address{
- address = {Ip,TcpPort},
- host = Address,
- protocol = tcp,
- family = AddressFamily}
- end,
- mf_tick = fun(S) -> ?MODULE:tick(Driver, S) end,
- mf_getstat = fun ?MODULE:getstat/1,
- request_type = Type,
- mf_setopts = fun ?MODULE:setopts/2,
- mf_getopts = fun ?MODULE:getopts/2
- },
+ HSData =
+ (gen_hs_data(Driver, Socket))
+ #hs_data{
+ kernel_pid = Kernel,
+ other_node = Node,
+ this_node = MyNode,
+ timer = Timer,
+ this_flags = 0,
+ other_version = Version,
+ f_address =
+ fun(_,_) ->
+ #net_address{
+ address = {Ip,TcpPort},
+ host = Address,
+ protocol = ?PROTOCOL,
+ family = AddressFamily}
+ end,
+ request_type = Type},
dist_util:handshake_we_started(HSData);
_ ->
%% Other Node may have closed since
@@ -465,7 +451,7 @@ get_tcp_address(Driver) ->
{ok, Host} = inet:gethostname(),
#net_address {
host = Host,
- protocol = tcp,
+ protocol = ?PROTOCOL,
family = Driver:family()
}.
diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl
index 6cc10c3bf4..be0357240e 100644
--- a/lib/ssl/src/inet_tls_dist.erl
+++ b/lib/ssl/src/inet_tls_dist.erl
@@ -29,8 +29,6 @@
-export([gen_listen/3, gen_accept/2, gen_accept_connection/6,
gen_setup/6, gen_close/2, gen_select/2, gen_address/1]).
--export([nodelay/0]).
-
-export([verify_client/3, cert_nodes/1]).
-export([dbg/0]). % Debug
@@ -45,6 +43,8 @@
-include("ssl_internal.hrl").
-include_lib("kernel/include/logger.hrl").
+-define(PROTOCOL, tls).
+
%% -------------------------------------------------------------------------
childspecs() ->
@@ -72,53 +72,25 @@ is_node_name(Node) ->
%% -------------------------------------------------------------------------
-hs_data_common(Socket) when is_port(Socket) ->
- {ok, {Ip, Port}} = inet:peername(Socket),
+hs_data_inet_tcp(Driver, Socket) ->
+ Family = Driver:family(),
+ {ok, Peername} = inet:peername(Socket),
+ (inet_tcp_dist:gen_hs_data(Driver, Socket))
#hs_data{
- socket = Socket,
- f_send = fun inet_tcp:send/2,
- f_recv = fun inet_tcp:recv/3,
- f_setopts_pre_nodeup =
- fun(S) ->
- inet:setopts(
- S,
- [
- {active, false},
- {packet, 4},
- nodelay()
- ]
- )
- end,
- f_setopts_post_nodeup =
- fun(S) ->
- inet:setopts(
- S,
- [
- {active, true},
- {deliver, port},
- {packet, 4},
- nodelay()
- ]
- )
- end,
-
- f_getll = fun inet:getll/1,
- f_address =
- fun(_, Node) ->
- {node, _, Host} = dist_util:split_node(Node),
- #net_address{
- address = {Ip, Port},
- host = Host,
- protocol = tls,
- family = inet
- }
- end,
- mf_tick = fun(S) -> inet_tcp_dist:tick(inet_tcp, S) end,
- mf_getstat = fun inet_tcp_dist:getstat/1,
- mf_setopts = fun inet_tcp_dist:setopts/2,
- mf_getopts = fun inet_tcp_dist:getopts/2
- };
-hs_data_common(#sslsocket{pid = [_, DistCtrl|_]} = SslSocket) ->
+ f_address =
+ fun(_, Node) ->
+ {node, _, Host} = dist_util:split_node(Node),
+ #net_address{
+ address = Peername,
+ host = Host,
+ protocol = ?PROTOCOL,
+ family = Family
+ }
+ end}.
+
+hs_data_ssl(Driver, #sslsocket{pid = [_, DistCtrl|_]} = SslSocket) ->
+ Family = Driver:family(),
+ {ok, Peername} = ssl:peername(SslSocket),
#hs_data{
socket = DistCtrl,
f_send =
@@ -144,7 +116,7 @@ hs_data_common(#sslsocket{pid = [_, DistCtrl|_]} = SslSocket) ->
end,
f_address =
fun (Ctrl, Node) when Ctrl == DistCtrl ->
- f_address(SslSocket, Node)
+ f_address(Family, Peername, Node)
end,
mf_tick =
fun (Ctrl) when Ctrl == DistCtrl ->
@@ -182,22 +154,19 @@ f_setopts_pre_nodeup(_SslSocket) ->
ok.
f_setopts_post_nodeup(SslSocket) ->
- ssl:setopts(SslSocket, [nodelay()]).
+ ssl:setopts(SslSocket, [inet_tcp_dist:nodelay()]).
f_getll(DistCtrl) ->
{ok, DistCtrl}.
-f_address(SslSocket, Node) ->
- case ssl:peername(SslSocket) of
- {ok, Address} ->
- case dist_util:split_node(Node) of
- {node,_,Host} ->
- #net_address{
- address=Address, host=Host,
- protocol=tls, family=inet};
- _ ->
- {error, no_node}
- end
+f_address(Family, Address, Node) ->
+ case dist_util:split_node(Node) of
+ {node,_,Host} ->
+ #net_address{
+ address=Address, host=Host,
+ protocol=?PROTOCOL, family=Family};
+ _ ->
+ {error, no_node}
end.
mf_tick(DistCtrl) ->
@@ -249,7 +218,7 @@ gen_listen(Driver, Name, Host) ->
case inet_tcp_dist:gen_listen(Driver, Name, Host) of
{ok, {Socket, Address, Creation}} ->
inet:setopts(Socket, [{packet, 4}, {nodelay, true}]),
- {ok, {Socket, Address#net_address{protocol=tls}, Creation}};
+ {ok, {Socket, Address#net_address{protocol=?PROTOCOL}, Creation}};
Other ->
Other
end.
@@ -365,7 +334,7 @@ accept_one(Driver, Kernel, Socket) ->
end.
%%
accept_one(Driver, Kernel, DistCtrl, ControllingProcessFun, DistSocket) ->
- trace(Kernel ! {accept, self(), DistCtrl, Driver:family(), tls}),
+ trace(Kernel ! {accept, self(), DistCtrl, Driver:family(), ?PROTOCOL}),
receive
{Kernel, controller, Pid} ->
case ControllingProcessFun(DistSocket, Pid) of
@@ -514,20 +483,23 @@ gen_accept_connection(
dist_util:net_ticker_spawn_options())).
do_accept(
- _Driver, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime, Kernel) ->
+ Driver, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime, Kernel) ->
MRef = erlang:monitor(process, AcceptPid),
receive
{AcceptPid, controller} ->
erlang:demonitor(MRef, [flush]),
Timer = dist_util:start_timer(SetupTime),
- {HSData0, NewAllowed} = case is_port(DistCtrl) of
- true ->
- {hs_data_common(DistCtrl), Allowed};
- false ->
- {ok, SslSocket} = tls_sender:dist_tls_socket(DistCtrl),
- link(DistCtrl),
- {hs_data_common(SslSocket), allowed_nodes(SslSocket, Allowed)}
- end,
+ {HSData0, NewAllowed} =
+ case is_port(DistCtrl) of
+ true ->
+ {hs_data_inet_tcp(Driver, DistCtrl),
+ Allowed};
+ false ->
+ {ok, SslSocket} = tls_sender:dist_tls_socket(DistCtrl),
+ link(DistCtrl),
+ {hs_data_ssl(Driver, SslSocket),
+ allowed_nodes(SslSocket, Allowed)}
+ end,
HSData =
HSData0#hs_data{
kernel_pid = Kernel,
@@ -657,12 +629,13 @@ do_setup_connect(Driver, Kernel, Node, Address, Ip, TcpPort, Version, Type, MyNo
dist_util:reset_timer(Timer),
case ssl:connect(
Ip, TcpPort,
- [binary, {active, false}, {packet, 4}, {server_name_indication, Address},
+ [binary, {active, false}, {packet, 4},
+ {server_name_indication, Address},
Driver:family(), {nodelay, true}] ++ Opts,
net_kernel:connecttime()
) of
{ok, #sslsocket{pid = [Receiver, Sender| _]} = SslSocket} ->
- DistSocket =
+ HSData =
case KTLS of
true ->
{ok, KtlsInfo} =
@@ -670,7 +643,7 @@ do_setup_connect(Driver, Kernel, Node, Address, Ip, TcpPort, Version, Type, MyNo
case set_ktls(KtlsInfo) of
ok ->
#{socket := Socket} = KtlsInfo,
- Socket;
+ hs_data_inet_tcp(Driver, Socket);
{error, KtlsReason} ->
?shutdown2(
Node,
@@ -680,10 +653,8 @@ do_setup_connect(Driver, Kernel, Node, Address, Ip, TcpPort, Version, Type, MyNo
_ = monitor_pid(Sender),
ok = ssl:controlling_process(SslSocket, self()),
link(Sender),
- SslSocket
- end,
- HSData =
- (hs_data_common(DistSocket))
+ hs_data_ssl(Driver, SslSocket)
+ end
#hs_data{
kernel_pid = Kernel,
other_node = Node,
@@ -883,21 +854,6 @@ connect_options(Opts) ->
Opts
end.
-%% we may not always want the nodelay behaviour
-%% for performance reasons
-nodelay() ->
- case application:get_env(kernel, dist_nodelay) of
- undefined ->
- {nodelay, true};
- {ok, true} ->
- {nodelay, true};
- {ok, false} ->
- {nodelay, false};
- _ ->
- {nodelay, true}
- end.
-
-
get_ssl_options(Type) ->
try ets:lookup(ssl_dist_opts, Type) of
[{Type, Opts0}] ->
@@ -1014,13 +970,17 @@ set_ktls_1(
%%
SOL_TCP = 6,
TCP_ULP = 31,
- _ = inet:setopts(Socket, [{raw, SOL_TCP, TCP_ULP, <<"tls">>}]),
+ KtlsMod = <<"tls">>, % Linux kernel module name
+ KtlsModSize = byte_size(KtlsMod),
+ _ = inet:setopts(Socket, [{raw, SOL_TCP, TCP_ULP, KtlsMod}]),
%%
%% Check if kernel module loaded,
- %% i.e if getopts SOL_TCP,TCP_ULP returns "tls"
+ %% i.e if getopts SOL_TCP,TCP_ULP returns KtlsMod
%%
- case inet:getopts(Socket, [{raw, SOL_TCP, TCP_ULP, 4}]) of
- {ok, [{raw, SOL_TCP, TCP_ULP, <<"tls",0>>}]} ->
+ case
+ inet:getopts(Socket, [{raw, SOL_TCP, TCP_ULP, KtlsModSize + 1}])
+ of
+ {ok, [{raw, SOL_TCP, TCP_ULP, <<KtlsMod:KtlsModSize/binary,0>>}]} ->
set_ktls_2(KtlsInfo, Socket);
Other ->
{error, {ktls_not_supported, Other}}
diff --git a/lib/ssl/test/inet_crypto_dist.erl b/lib/ssl/test/inet_crypto_dist.erl
index 58a303f48c..d0fa550948 100644
--- a/lib/ssl/test/inet_crypto_dist.erl
+++ b/lib/ssl/test/inet_crypto_dist.erl
@@ -36,8 +36,6 @@
-export([gen_listen/2, gen_accept/2, gen_accept_connection/6,
gen_setup/6, gen_close/2, gen_select/2]).
--export([nodelay/0]).
-
%% Debug
%%%-compile(export_all).
-export([dbg/0, test_server/0, test_client/1]).
@@ -439,7 +437,7 @@ do_accept(
{Acceptor, controller, Socket} ->
Timer = dist_util:start_timer(SetupTime),
HSData =
- hs_data_common(
+ hs_data(
NetKernel, MyNode, DistCtrl, Timer,
Socket, Driver:family()),
HSData_1 =
@@ -529,7 +527,7 @@ do_setup_connect(
end,
%% DistCtrl is a "socket"
HSData =
- hs_data_common(
+ hs_data(
NetKernel, MyNode, DistCtrl, Timer,
Socket, Driver:family()),
HSData_1 =
@@ -558,7 +556,7 @@ gen_close(Socket, Driver) ->
%% -------------------------------------------------------------------------
-hs_data_common(NetKernel, MyNode, DistCtrl, Timer, Socket, Family) ->
+hs_data(NetKernel, MyNode, DistCtrl, Timer, Socket, Family) ->
%% Field 'socket' below is set to DistCtrl, which makes
%% the distribution handshake process (ticker) call
%% the funs below with DistCtrl as the S argument.
@@ -739,20 +737,6 @@ connect_options(Opts) ->
Opts
end.
-%% we may not always want the nodelay behaviour
-%% for performance reasons
-nodelay() ->
- case application:get_env(kernel, dist_nodelay) of
- undefined ->
- {nodelay, true};
- {ok, true} ->
- {nodelay, true};
- {ok, false} ->
- {nodelay, false};
- _ ->
- {nodelay, true}
- end.
-
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% The DistCtrl process(es).
@@ -1401,7 +1401,7 @@ input_handler(#params{socket = Socket} = Params, Seq, DistHandle) ->
try
ok =
inet:setopts(
- Socket, [{active, ?TCP_ACTIVE}, nodelay()]),
+ Socket, [{active, ?TCP_ACTIVE}, inet_tcp_dist:nodelay()]),
input_handler(
Params#params{dist_handle = DistHandle},
Seq)
--
2.35.3