aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/erl_interface/src/prog/ei_fake_prog.c11
-rw-r--r--lib/erl_interface/src/prog/erl_call.c54
-rw-r--r--lib/erl_interface/src/prog/erl_start.c2
-rw-r--r--lib/erl_interface/test/Makefile1
-rw-r--r--lib/erl_interface/test/erl_call_SUITE.erl96
-rw-r--r--lib/ssl/doc/src/ssl.xml25
-rw-r--r--lib/ssl/src/ssl.erl77
-rw-r--r--lib/ssl/src/ssl_connection.hrl1
-rw-r--r--lib/ssl/src/tls_connection.erl12
-rw-r--r--lib/ssl/src/tls_socket.erl10
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl2
11 files changed, 192 insertions, 99 deletions
diff --git a/lib/erl_interface/src/prog/ei_fake_prog.c b/lib/erl_interface/src/prog/ei_fake_prog.c
index c7a16dc7c4..158464b385 100644
--- a/lib/erl_interface/src/prog/ei_fake_prog.c
+++ b/lib/erl_interface/src/prog/ei_fake_prog.c
@@ -98,11 +98,18 @@ int main(void)
EI_ULONGLONG ulonglongx = 0;
#endif
erlang_char_encoding enc;
+ ei_socket_callbacks cbs;
intx = erl_errno;
+ ei_init();
+
+ ei_close_connection(intx);
+
ei_connect_init(&xec, charp, charp, creation);
+ ei_connect_init_ussi(&xec, charp, charp, creation, &cbs, sizeof(cbs), NULL);
ei_connect_xinit (&xec, charp, charp, charp, thisipaddr, charp, creation);
+ ei_connect_xinit_ussi(&xec, charp, charp, charp, thisipaddr, charp, creation, &cbs, sizeof(cbs), NULL);
ei_connect(&xec, charp);
ei_xconnect (&xec, thisipaddr, charp);
@@ -121,6 +128,8 @@ int main(void)
ei_publish(&xec, intx);
ei_accept(&xec, intx, &conp);
ei_unpublish(&xec);
+ ei_listen(&xec, intp, intx);
+ ei_xlisten(&xec, thisipaddr, intp, intx);
ei_thisnodename(&xec);
ei_thishostname(&xec);
@@ -187,7 +196,7 @@ int main(void)
ei_decode_char(charp, intp, charp);
ei_decode_string(charp, intp, charp);
ei_decode_atom(charp, intp, charp);
- ei_decode_atom_as(charp, intp, charp, MAXATOMLEN_UTF8, ERLANG_WHATEVER, &enc, &enc);
+ ei_decode_atom_as(charp, intp, charp, MAXATOMLEN_UTF8, ERLANG_UTF8, &enc, &enc);
ei_decode_binary(charp, intp, (void *)0, longp);
ei_decode_fun(charp, intp, &efun);
free_fun(&efun);
diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c
index 52ad6885e8..ab91157035 100644
--- a/lib/erl_interface/src/prog/erl_call.c
+++ b/lib/erl_interface/src/prog/erl_call.c
@@ -88,10 +88,6 @@
#include "ei_resolve.h"
#include "erl_start.h" /* FIXME remove dependency */
-#ifdef __WIN32__
-static void initWinSock(void);
-#endif
-
/*
* Some nice global variables
* (I don't think "nice" is the right word actually... -gordon)
@@ -157,6 +153,8 @@ int erl_call(int argc, char **argv)
char* progname = argv[0];
ei_cnode ec;
+ ei_init();
+
/* Get the command line options */
while (i < argc) {
if (argv[i][0] != '-') {
@@ -317,14 +315,6 @@ int erl_call(int argc, char **argv)
struct in_addr h_ipadr;
char* ct;
-#ifdef __WIN32__
- /*
- * FIXME Extremly ugly, but needed to get ei_gethostbyname() below
- * to work.
- */
- initWinSock();
-#endif
-
/* gethostname requires len to be max(hostname) + 1 */
if (gethostname(h_hostname, EI_MAXHOSTNAMELEN+1) < 0) {
fprintf(stderr,"erl_call: failed to get host name: %d\n", errno);
@@ -857,46 +847,6 @@ static void usage(const char *progname) {
exit(0);
}
-
-/***************************************************************************
- *
- * OS specific functions
- *
- ***************************************************************************/
-
-#ifdef __WIN32__
-/*
- * FIXME This should not be here. This is a quick fix to make erl_call
- * work at all on Windows NT.
- */
-static void initWinSock(void)
-{
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
- static int initialized;
-
- wVersionRequested = MAKEWORD(1, 1);
- if (!initialized) {
- initialized = 1;
- err = WSAStartup(wVersionRequested, &wsaData);
-
- if (err != 0) {
- fprintf(stderr,"erl_call: "
- "Can't initialize windows sockets: %d\n", err);
- }
-
- if ( LOBYTE( wsaData.wVersion ) != 1 ||
- HIBYTE( wsaData.wVersion ) != 1 ) {
- fprintf(stderr,"erl_call: This version of "
- "windows sockets not supported\n");
- WSACleanup();
- }
- }
-}
-#endif
-
-
/***************************************************************************
*
* Utility functions
diff --git a/lib/erl_interface/src/prog/erl_start.c b/lib/erl_interface/src/prog/erl_start.c
index 670a5900c9..c766f4780e 100644
--- a/lib/erl_interface/src/prog/erl_start.c
+++ b/lib/erl_interface/src/prog/erl_start.c
@@ -657,7 +657,7 @@ static int wait_for_erlang(int sockd, int magic, struct timeval *timeout)
gettimeofday(&now,NULL);
to.tv_sec = stop_time.tv_sec - now.tv_sec;
to.tv_usec = stop_time.tv_usec - now.tv_usec;
- while ((to.tv_usec <= 0) && (to.tv_sec >= 0)) {
+ while ((to.tv_usec < 0) && (to.tv_sec > 0)) {
to.tv_usec += 1000000;
to.tv_sec--;
}
diff --git a/lib/erl_interface/test/Makefile b/lib/erl_interface/test/Makefile
index 94f4b422d6..f8f2ef0156 100644
--- a/lib/erl_interface/test/Makefile
+++ b/lib/erl_interface/test/Makefile
@@ -33,6 +33,7 @@ MODULES= \
ei_format_SUITE \
ei_print_SUITE \
ei_tmo_SUITE \
+ erl_call_SUITE \
erl_connect_SUITE \
erl_global_SUITE \
erl_eterm_SUITE \
diff --git a/lib/erl_interface/test/erl_call_SUITE.erl b/lib/erl_interface/test/erl_call_SUITE.erl
new file mode 100644
index 0000000000..9e2b2e4251
--- /dev/null
+++ b/lib/erl_interface/test/erl_call_SUITE.erl
@@ -0,0 +1,96 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(erl_call_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+
+-export([all/0, smoke/1]).
+
+all() ->
+ [smoke].
+
+smoke(Config) when is_list(Config) ->
+ ErlCall = find_erl_call(),
+ NameSwitch = case net_kernel:longnames() of
+ true ->
+ "-name";
+ false ->
+ "-sname"
+ end,
+ Name = atom_to_list(?MODULE)
+ ++ "-"
+ ++ integer_to_list(erlang:system_time(microsecond)),
+
+ ArgsList = ["-s", "-a", "erlang node", NameSwitch, Name],
+ io:format("erl_call: \"~ts\"\n~nargs list: ~p~n", [ErlCall, ArgsList]),
+ CmdRes = get_smoke_port_res(open_port({spawn_executable, ErlCall},
+ [{args, ArgsList}, eof]), []),
+ io:format("CmdRes: ~p~n", [CmdRes]),
+
+ [_, Hostname] = string:lexemes(atom_to_list(node()), "@"),
+ NodeName = list_to_atom(Name ++ "@" ++ Hostname),
+ io:format("NodeName: ~p~n~n", [NodeName]),
+
+ pong = net_adm:ping(NodeName),
+ rpc:cast(NodeName, erlang, halt, []),
+ NodeName = list_to_atom(string:trim(CmdRes, both, "'")),
+ ok.
+
+%
+% Utility functions...
+%
+
+find_erl_call() ->
+ ErlCallName = case os:type() of
+ {win32, _} -> "erl_call.exe";
+ _ -> "erl_call"
+ end,
+ LibDir = code:lib_dir(erl_interface),
+ InstalledErlCall = filename:join([LibDir, "bin", ErlCallName]),
+ TargetDir = erlang:system_info(system_architecture),
+ TargetErlCall = filename:join([LibDir, "bin", TargetDir, ErlCallName]),
+
+ try
+ lists:foreach(fun (F) ->
+ io:format("Checking: \"~ts\"~n", [F]),
+ case file:read_file_info(F) of
+ {ok, _} ->
+ throw(F);
+ _ ->
+ ok
+ end
+ end,
+ [InstalledErlCall, TargetErlCall]),
+ exit({missing, erl_call})
+ catch
+ throw:ErlCall ->
+ ErlCall
+ end.
+
+get_smoke_port_res(Port, Acc) when is_port(Port) ->
+ receive
+ {Port, {data, Data}} ->
+ get_smoke_port_res(Port, [Acc|Data]);
+ {Port, eof} ->
+ lists:flatten(Acc)
+ end.
+
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 90a9181ede..24d063e1bd 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -101,16 +101,21 @@
<datatype>
<name name="transport_option"/>
<desc>
- <p>Defaults to <c>{gen_tcp, tcp, tcp_closed, tcp_error}</c>
- for TLS and <c>{gen_udp, udp, udp_closed, udp_error}</c> for
- DTLS. Can be used to customize the transport layer. The tag
- values should be the values used by the underlying transport
- in its active mode messages. For TLS the callback module must implement a
- reliable transport protocol, behave as <c>gen_tcp</c>, and have functions
- corresponding to <c>inet:setopts/2</c>, <c>inet:getopts/2</c>,
- <c>inet:peername/1</c>, <c>inet:sockname/1</c>, and <c>inet:port/1</c>.
- The callback <c>gen_tcp</c> is treated specially and calls <c>inet</c>
- directly. For DTLS this feature must be considered exprimental.
+ <p>Defaults to <c>{gen_tcp, tcp, tcp_closed, tcp_error,
+ tcp_passive}</c> for TLS (for backward compatibility a four
+ tuple will be converted to a five tuple with the last element
+ "second_element"_passive) and <c>{gen_udp, udp, udp_closed,
+ udp_error}</c> for DTLS (might also be changed to five tuple in
+ the future). Can be used to customize the transport layer. The
+ tag values should be the values used by the underlying
+ transport in its active mode messages. For TLS the callback
+ module must implement a reliable transport protocol, behave as
+ <c>gen_tcp</c>, and have functions corresponding to
+ <c>inet:setopts/2</c>, <c>inet:getopts/2</c>,
+ <c>inet:peername/1</c>, <c>inet:sockname/1</c>, and
+ <c>inet:port/1</c>. The callback <c>gen_tcp</c> is treated
+ specially and calls <c>inet</c> directly. For DTLS this
+ feature must be considered exprimental.
</p>
</desc>
</datatype>
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index fb6b7ba8e8..7f8f1ec71c 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -94,7 +94,9 @@
-type active_msgs() :: {ssl, sslsocket(), Data::binary() | list()} | {ssl_closed, sslsocket()} |
{ssl_error, sslsocket(), Reason::term()} | {ssl_passive, sslsocket()}.
-type transport_option() :: {cb_info, {CallbackModule::atom(), DataTag::atom(),
- ClosedTag::atom(), ErrTag::atom()}}.
+ ClosedTag::atom(), ErrTag::atom()}} |
+ {cb_info, {CallbackModule::atom(), DataTag::atom(),
+ ClosedTag::atom(), ErrTag::atom(), PassiveTag::atom()}}.
-type host() :: hostname() | ip_address().
-type hostname() :: string().
-type ip_address() :: inet:ip_address().
@@ -400,9 +402,9 @@ connect(Socket, SslOptions) when is_port(Socket) ->
timeout() | list()) ->
{ok, #sslsocket{}} | {error, reason()}.
connect(Socket, SslOptions0, Timeout) when is_port(Socket),
- (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
- {Transport,_,_,_} = proplists:get_value(cb_info, SslOptions0,
- {gen_tcp, tcp, tcp_closed, tcp_error}),
+ (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
+ CbInfo = handle_option(cb_info, SslOptions0, default_cb_info(tls)),
+ Transport = element(1, CbInfo),
EmulatedOptions = tls_socket:emulated_options(),
{ok, SocketValues} = tls_socket:getopts(Transport, Socket, EmulatedOptions),
try handle_options(SslOptions0 ++ SocketValues, client) of
@@ -542,8 +544,8 @@ handshake(#sslsocket{pid = [Pid|_], fd = {_, _, _}} = Socket, SslOpts, Timeout)
end;
handshake(Socket, SslOptions, Timeout) when is_port(Socket),
(is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
- {Transport,_,_,_} =
- proplists:get_value(cb_info, SslOptions, {gen_tcp, tcp, tcp_closed, tcp_error}),
+ CbInfo = handle_option(cb_info, SslOptions, default_cb_info(tls)),
+ Transport = element(1, CbInfo),
EmulatedOptions = tls_socket:emulated_options(),
{ok, SocketValues} = tls_socket:getopts(Transport, Socket, EmulatedOptions),
ConnetionCb = connection_cb(SslOptions),
@@ -595,7 +597,7 @@ close(#sslsocket{pid = [Pid|_]}) when is_pid(Pid) ->
ssl_connection:close(Pid, {close, ?DEFAULT_TIMEOUT});
close(#sslsocket{pid = {dtls, #config{dtls_handler = {Pid, _}}}}) ->
dtls_packet_demux:close(Pid);
-close(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport,_, _, _}}}}) ->
+close(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport,_,_,_,_}}}}) ->
Transport:close(ListenSocket).
%%--------------------------------------------------------------------
@@ -611,7 +613,7 @@ close(#sslsocket{pid = [TLSPid|_]},
close(#sslsocket{pid = [TLSPid|_]}, Timeout) when is_pid(TLSPid),
(is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
ssl_connection:close(TLSPid, {close, Timeout});
-close(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport,_, _, _}}}}, _) ->
+close(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport,_,_,_,_}}}}, _) ->
Transport:close(ListenSocket).
%%--------------------------------------------------------------------
@@ -627,7 +629,8 @@ send(#sslsocket{pid = {_, #config{transport_info={_, udp, _, _}}}}, _) ->
{error,enotconn}; %% Emulate connection behaviour
send(#sslsocket{pid = {dtls,_}}, _) ->
{error,enotconn}; %% Emulate connection behaviour
-send(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport, _, _, _}}}}, Data) ->
+send(#sslsocket{pid = {ListenSocket, #config{transport_info = Info}}}, Data) ->
+ Transport = element(1, Info),
Transport:send(ListenSocket, Data). %% {error,enotconn}
%%--------------------------------------------------------------------
@@ -645,7 +648,8 @@ recv(#sslsocket{pid = [Pid|_]}, Length, Timeout) when is_pid(Pid),
recv(#sslsocket{pid = {dtls,_}}, _, _) ->
{error,enotconn};
recv(#sslsocket{pid = {Listen,
- #config{transport_info = {Transport, _, _, _}}}}, _,_) when is_port(Listen)->
+ #config{transport_info = Info}}},_,_) when is_port(Listen)->
+ Transport = element(1, Info),
Transport:recv(Listen, 0). %% {error,enotconn}
%%--------------------------------------------------------------------
@@ -660,7 +664,7 @@ controlling_process(#sslsocket{pid = {dtls, _}},
NewOwner) when is_pid(NewOwner) ->
ok; %% Meaningless but let it be allowed to conform with TLS
controlling_process(#sslsocket{pid = {Listen,
- #config{transport_info = {Transport, _, _, _}}}},
+ #config{transport_info = {Transport,_,_,_,_}}}},
NewOwner) when is_port(Listen),
is_pid(NewOwner) ->
%% Meaningless but let it be allowed to conform with normal sockets
@@ -703,13 +707,13 @@ connection_information(#sslsocket{pid = [Pid|_]}, Items) when is_pid(Pid) ->
%%
%% Description: same as inet:peername/1.
%%--------------------------------------------------------------------
-peername(#sslsocket{pid = [Pid|_], fd = {Transport, Socket, _}}) when is_pid(Pid)->
+peername(#sslsocket{pid = [Pid|_], fd = {Transport, Socket,_}}) when is_pid(Pid)->
dtls_socket:peername(Transport, Socket);
-peername(#sslsocket{pid = [Pid|_], fd = {Transport, Socket, _, _}}) when is_pid(Pid)->
+peername(#sslsocket{pid = [Pid|_], fd = {Transport, Socket,_,_}}) when is_pid(Pid)->
tls_socket:peername(Transport, Socket);
-peername(#sslsocket{pid = {dtls, #config{dtls_handler = {_Pid, _}}}}) ->
+peername(#sslsocket{pid = {dtls, #config{dtls_handler = {_Pid,_}}}}) ->
dtls_socket:peername(dtls, undefined);
-peername(#sslsocket{pid = {ListenSocket, #config{transport_info = {Transport,_,_,_}}}}) ->
+peername(#sslsocket{pid = {ListenSocket, #config{transport_info = {Transport,_,_,_,_}}}}) ->
tls_socket:peername(Transport, ListenSocket); %% Will return {error, enotconn}
peername(#sslsocket{pid = {dtls,_}}) ->
{error,enotconn}.
@@ -886,7 +890,7 @@ getopts(#sslsocket{pid = {dtls, #config{transport_info = {Transport,_,_,_}}}} =
_:Error ->
{error, {options, {socket_options, OptionTags, Error}}}
end;
-getopts(#sslsocket{pid = {_, #config{transport_info = {Transport,_,_,_}}}} = ListenSocket,
+getopts(#sslsocket{pid = {_, #config{transport_info = {Transport,_,_,_,_}}}} = ListenSocket,
OptionTags) when is_list(OptionTags) ->
try tls_socket:getopts(Transport, ListenSocket, OptionTags) of
{ok, _} = Result ->
@@ -943,7 +947,7 @@ setopts(#sslsocket{pid = {dtls, #config{transport_info = {Transport,_,_,_}}}} =
_:Error ->
{error, {options, {socket_options, Options, Error}}}
end;
-setopts(#sslsocket{pid = {_, #config{transport_info = {Transport,_,_,_}}}} = ListenSocket, Options) when is_list(Options) ->
+setopts(#sslsocket{pid = {_, #config{transport_info = {Transport,_,_,_,_}}}} = ListenSocket, Options) when is_list(Options) ->
try tls_socket:setopts(Transport, ListenSocket, Options) of
ok ->
ok;
@@ -987,8 +991,9 @@ getstat(#sslsocket{pid = [Pid|_], fd = {Transport, Socket, _, _}}, Options) when
%%
%% Description: Same as gen_tcp:shutdown/2
%%--------------------------------------------------------------------
-shutdown(#sslsocket{pid = {Listen, #config{transport_info = {Transport,_, _, _}}}},
+shutdown(#sslsocket{pid = {Listen, #config{transport_info = Info}}},
How) when is_port(Listen) ->
+ Transport = element(1, Info),
Transport:shutdown(Listen, How);
shutdown(#sslsocket{pid = {dtls,_}},_) ->
{error, enotconn};
@@ -1000,13 +1005,13 @@ shutdown(#sslsocket{pid = [Pid|_]}, How) when is_pid(Pid) ->
%%
%% Description: Same as inet:sockname/1
%%--------------------------------------------------------------------
-sockname(#sslsocket{pid = {Listen, #config{transport_info = {Transport, _, _, _}}}}) when is_port(Listen) ->
+sockname(#sslsocket{pid = {Listen, #config{transport_info = {Transport,_,_,_,_}}}}) when is_port(Listen) ->
tls_socket:sockname(Transport, Listen);
sockname(#sslsocket{pid = {dtls, #config{dtls_handler = {Pid, _}}}}) ->
dtls_packet_demux:sockname(Pid);
-sockname(#sslsocket{pid = [Pid|_], fd = {Transport, Socket, _}}) when is_pid(Pid) ->
+sockname(#sslsocket{pid = [Pid|_], fd = {Transport, Socket,_}}) when is_pid(Pid) ->
dtls_socket:sockname(Transport, Socket);
-sockname(#sslsocket{pid = [Pid| _], fd = {Transport, Socket, _, _}}) when is_pid(Pid) ->
+sockname(#sslsocket{pid = [Pid| _], fd = {Transport, Socket,_,_}}) when is_pid(Pid) ->
tls_socket:sockname(Transport, Socket).
%%---------------------------------------------------------------
@@ -1140,7 +1145,7 @@ supported_suites(all, Version) ->
supported_suites(anonymous, Version) ->
ssl_cipher:anonymous_suites(Version).
-do_listen(Port, #config{transport_info = {Transport, _, _, _}} = Config, tls_connection) ->
+do_listen(Port, #config{transport_info = {Transport, _, _, _,_}} = Config, tls_connection) ->
tls_socket:listen(Transport, Port, Config);
do_listen(Port, Config, dtls_connection) ->
@@ -1288,7 +1293,7 @@ handle_options(Opts0, Role, Host) ->
customize_hostname_check = handle_option(customize_hostname_check, Opts, [])
},
- CbInfo = proplists:get_value(cb_info, Opts, default_cb_info(Protocol)),
+ CbInfo = handle_option(cb_info, Opts, default_cb_info(Protocol)),
SslOptions = [protocol, versions, verify, verify_fun, partial_chain,
fail_if_no_peer_cert, verify_client_once,
depth, cert, certfile, key, keyfile,
@@ -1330,6 +1335,10 @@ handle_option(sni_fun, Opts, Default) ->
_ ->
throw({error, {conflict_options, [sni_fun, sni_hosts]}})
end;
+handle_option(cb_info, Opts, Default) ->
+ CbInfo = proplists:get_value(cb_info, Opts, Default),
+ true = validate_option(cb_info, CbInfo),
+ handle_cb_info(CbInfo, Default);
handle_option(OptionName, Opts, Default) ->
validate_option(OptionName,
proplists:get_value(OptionName, Opts, Default)).
@@ -1551,9 +1560,29 @@ validate_option(handshake, full = Value) ->
Value;
validate_option(customize_hostname_check, Value) when is_list(Value) ->
Value;
+validate_option(cb_info, {V1, V2, V3, V4}) when is_atom(V1),
+ is_atom(V2),
+ is_atom(V3),
+ is_atom(V4)
+ ->
+ true;
+validate_option(cb_info, {V1, V2, V3, V4, V5}) when is_atom(V1),
+ is_atom(V2),
+ is_atom(V3),
+ is_atom(V4),
+ is_atom(V5)
+ ->
+ true;
+validate_option(cb_info, _) ->
+ false;
validate_option(Opt, Value) ->
throw({error, {options, {Opt, Value}}}).
+handle_cb_info({V1, V2, V3, V4}, {_,_,_,_,_}) ->
+ {V1,V2,V3,V4, list_to_atom(atom_to_list(V2) ++ "passive")};
+handle_cb_info(CbInfo, _) ->
+ CbInfo.
+
handle_hashsigns_option(Value, Version) when is_list(Value)
andalso Version >= {3, 3} ->
case tls_v1:signature_algs(Version, Value) of
@@ -1964,7 +1993,7 @@ default_option_role(_,_,_) ->
undefined.
default_cb_info(tls) ->
- {gen_tcp, tcp, tcp_closed, tcp_error};
+ {gen_tcp, tcp, tcp_closed, tcp_error, tcp_passive};
default_cb_info(dtls) ->
{gen_udp, udp, udp_closed, udp_error}.
diff --git a/lib/ssl/src/ssl_connection.hrl b/lib/ssl/src/ssl_connection.hrl
index 9efd65b2d2..c90fe926b7 100644
--- a/lib/ssl/src/ssl_connection.hrl
+++ b/lib/ssl/src/ssl_connection.hrl
@@ -40,6 +40,7 @@
data_tag :: atom(), % ex tcp.
close_tag :: atom(), % ex tcp_closed
error_tag :: atom(), % ex tcp_error
+ passive_tag :: atom(), % ex tcp_passive
host :: string() | inet:ip_address(),
port :: integer(),
socket :: port() | tuple(), %% TODO: dtls socket
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 2b9f9f1e93..114710a92e 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -79,7 +79,7 @@
%% Setup
%%====================================================================
start_fsm(Role, Host, Port, Socket, {#ssl_options{erl_dist = false},_, Tracker} = Opts,
- User, {CbModule, _,_, _} = CbInfo,
+ User, {CbModule, _,_, _, _} = CbInfo,
Timeout) ->
try
{ok, Sender} = tls_sender:start(),
@@ -93,7 +93,7 @@ start_fsm(Role, Host, Port, Socket, {#ssl_options{erl_dist = false},_, Tracker}
end;
start_fsm(Role, Host, Port, Socket, {#ssl_options{erl_dist = true},_, Tracker} = Opts,
- User, {CbModule, _,_, _} = CbInfo,
+ User, {CbModule, _,_, _, _} = CbInfo,
Timeout) ->
try
{ok, Sender} = tls_sender:start([{spawn_opt, ?DIST_CNTRL_SPAWN_OPTS}]),
@@ -780,7 +780,7 @@ code_change(_OldVsn, StateName, State, _) ->
%%% Internal functions
%%--------------------------------------------------------------------
initial_state(Role, Sender, Host, Port, Socket, {SSLOptions, SocketOptions, Tracker}, User,
- {CbModule, DataTag, CloseTag, ErrorTag}) ->
+ {CbModule, DataTag, CloseTag, ErrorTag, PassiveTag}) ->
#ssl_options{beast_mitigation = BeastMitigation,
erl_dist = IsErlDist} = SSLOptions,
ConnectionStates = tls_record:init_connection_states(Role, BeastMitigation),
@@ -805,6 +805,7 @@ initial_state(Role, Sender, Host, Port, Socket, {SSLOptions, SocketOptions, Trac
data_tag = DataTag,
close_tag = CloseTag,
error_tag = ErrorTag,
+ passive_tag = PassiveTag,
host = Host,
port = Port,
socket = Socket,
@@ -894,8 +895,9 @@ handle_info({Protocol, _, Data}, StateName,
ssl_connection:handle_normal_shutdown(Alert, StateName, State0),
{stop, {shutdown, own_alert}, State0}
end;
-handle_info({tcp_passive, Socket}, StateName,
- #state{static_env = #static_env{socket = Socket},
+handle_info({PassiveTag, Socket}, StateName,
+ #state{static_env = #static_env{socket = Socket,
+ passive_tag = PassiveTag},
protocol_specific = PS
} = State) ->
next_event(StateName, no_record,
diff --git a/lib/ssl/src/tls_socket.erl b/lib/ssl/src/tls_socket.erl
index c3c41d3e12..6c32e6fa04 100644
--- a/lib/ssl/src/tls_socket.erl
+++ b/lib/ssl/src/tls_socket.erl
@@ -46,7 +46,7 @@
send(Transport, Socket, Data) ->
Transport:send(Socket, Data).
-listen(Transport, Port, #config{transport_info = {Transport, _, _, _},
+listen(Transport, Port, #config{transport_info = {Transport, _, _, _, _},
inet_user = Options,
ssl = SslOpts, emulated = EmOpts} = Config) ->
case Transport:listen(Port, Options ++ internal_inet_values()) of
@@ -59,7 +59,7 @@ listen(Transport, Port, #config{transport_info = {Transport, _, _, _},
Err
end.
-accept(ListenSocket, #config{transport_info = {Transport,_,_,_} = CbInfo,
+accept(ListenSocket, #config{transport_info = {Transport,_,_,_,_} = CbInfo,
connection_cb = ConnectionCb,
ssl = SslOpts,
emulated = Tracker}, Timeout) ->
@@ -80,7 +80,7 @@ accept(ListenSocket, #config{transport_info = {Transport,_,_,_} = CbInfo,
{error, Reason}
end.
-upgrade(Socket, #config{transport_info = {Transport,_,_,_}= CbInfo,
+upgrade(Socket, #config{transport_info = {Transport,_,_,_,_}= CbInfo,
ssl = SslOptions,
emulated = EmOpts, connection_cb = ConnectionCb}, Timeout) ->
ok = setopts(Transport, Socket, tls_socket:internal_inet_values()),
@@ -98,7 +98,7 @@ connect(Address, Port,
#config{transport_info = CbInfo, inet_user = UserOpts, ssl = SslOpts,
emulated = EmOpts, inet_ssl = SocketOpts, connection_cb = ConnetionCb},
Timeout) ->
- {Transport, _, _, _} = CbInfo,
+ {Transport, _, _, _, _} = CbInfo,
try Transport:connect(Address, Port, SocketOpts, Timeout) of
{ok, Socket} ->
ssl_connection:connect(ConnetionCb, Address, Port, Socket,
@@ -125,7 +125,7 @@ setopts(gen_tcp, Socket = #sslsocket{pid = {ListenSocket, #config{emulated = Tra
ok = set_emulated_opts(Tracker, EmulatedOpts),
check_active_n(EmulatedOpts, Socket),
inet:setopts(ListenSocket, SockOpts);
-setopts(_, Socket = #sslsocket{pid = {ListenSocket, #config{transport_info = {Transport,_,_,_},
+setopts(_, Socket = #sslsocket{pid = {ListenSocket, #config{transport_info = {Transport,_,_,_,_},
emulated = Tracker}}}, Options) ->
{SockOpts, EmulatedOpts} = split_options(Options),
ok = set_emulated_opts(Tracker, EmulatedOpts),
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index e86d2eaf9e..f55d1c8ea7 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -4063,7 +4063,7 @@ tls_tcp_error_propagation_in_active_mode(Config) when is_list(Config) ->
[_, _,_, _, Prop] = StatusInfo,
State = ssl_test_lib:state(Prop),
StaticEnv = element(2, State),
- Socket = element(10, StaticEnv),
+ Socket = element(11, StaticEnv),
%% Fake tcp error
Pid ! {tcp_error, Socket, etimedout},