aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2012-12-06 15:42:18 +0100
committerIngela Anderton Andin <[email protected]>2012-12-06 15:42:18 +0100
commit6bc9c65ae207ebc2fba03521c2ca3b84264a1dcf (patch)
tree7017f536fe5557b1494d1b3844ff776b5bfcae40
parent51f1f06bafa99291daaafe22a24a1dc4ff45d067 (diff)
parent1cbd897c43f0dab1275392a3736e4629c1f80243 (diff)
downloadotp-6bc9c65ae207ebc2fba03521c2ca3b84264a1dcf.tar.gz
otp-6bc9c65ae207ebc2fba03521c2ca3b84264a1dcf.tar.bz2
otp-6bc9c65ae207ebc2fba03521c2ca3b84264a1dcf.zip
Merge branch 'maint'
Conflicts: erts/emulator/sys/vxworks/sys.c erts/vsn.mk lib/ssl/src/ssl_connection.erl lib/ssl/test/ssl_basic_SUITE.erl
-rw-r--r--erts/doc/src/notes.xml22
-rw-r--r--erts/emulator/beam/break.c18
-rw-r--r--erts/emulator/beam/sys.h2
-rw-r--r--erts/emulator/sys/unix/sys.c52
-rwxr-xr-xerts/emulator/sys/win32/sys.c7
-rw-r--r--erts/vsn.mk1
-rw-r--r--lib/ssl/doc/src/notes.xml17
-rw-r--r--lib/ssl/src/ssl.appup.src4
-rw-r--r--lib/ssl/src/ssl.erl4
-rw-r--r--lib/ssl/src/ssl_connection.erl60
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl76
-rw-r--r--lib/ssl/test/ssl_test_lib.erl27
-rw-r--r--lib/ssl/vsn.mk2
13 files changed, 243 insertions, 49 deletions
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 801966c6e7..e996d3e8e3 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -30,6 +30,28 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 5.9.3.1</title>
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ Create an erl_crash.dump if no heart exists and no
+ ERL_CRASH_DUMP_SECONDS is set (behaviour changed).</p>
+ <p>
+ Don't create an erl_crash.dump if heart do exists and no
+ ERL_CRASH_DUMP_SECONDS is set (behaviour not changed).</p>
+ <p>
+ This changes the behaviour back to the R15B02 default
+ considering if a beam was running with no heart.</p>
+ <p>
+ Own Id: OTP-10602</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 5.9.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 63136d86c9..c1e9fe536d 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -670,6 +670,7 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
char dumpnamebuf[MAXPATHLEN];
char* dumpname;
int secs;
+ int env_erl_crash_dump_seconds_set = 1;
if (ERTS_SOMEONE_IS_CRASH_DUMPING)
return;
@@ -694,6 +695,8 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
envsz = sizeof(env);
/* ERL_CRASH_DUMP_SECONDS not set
+ * if we have a heart port, break immediately
+ * otherwise dump crash indefinitely (until crash is complete)
* same as ERL_CRASH_DUMP_SECONDS = 0
* - do not write dump
* - do not set an alarm
@@ -715,8 +718,10 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
*/
if (erts_sys_getenv__("ERL_CRASH_DUMP_SECONDS", env, &envsz) != 0) {
- return; /* break immediately */
+ env_erl_crash_dump_seconds_set = 0;
+ secs = -1;
} else {
+ env_erl_crash_dump_seconds_set = 1;
secs = atoi(env);
}
@@ -724,7 +729,16 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
return;
}
- erts_sys_prepare_crash_dump(secs);
+ /* erts_sys_prepare_crash_dump returns 1 if heart port is found, otherwise 0
+ * If we don't find heart (0) and we don't have ERL_CRASH_DUMP_SECONDS set
+ * we should continue writing a dump
+ *
+ * beware: secs -1 means no alarm
+ */
+
+ if (erts_sys_prepare_crash_dump(secs) && !env_erl_crash_dump_seconds_set ) {
+ return;
+ }
if (erts_sys_getenv__("ERL_CRASH_DUMP",&dumpnamebuf[0],&dumpnamebufsize) != 0)
dumpname = "erl_crash.dump";
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index c5af5b9577..f5f10bb616 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -644,7 +644,7 @@ void erts_sys_schedule_interrupt_timed(int set, erts_short_time_t msec);
void erts_sys_main_thread(void);
#endif
-extern void erts_sys_prepare_crash_dump(int secs);
+extern int erts_sys_prepare_crash_dump(int secs);
extern void erts_sys_pre_init(void);
extern void erl_sys_init(void);
extern void erl_sys_args(int *argc, char **argv);
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index b485dbf784..9e7cbc017f 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -686,7 +686,7 @@ static RETSIGTYPE break_handler(int sig)
}
#endif /* 0 */
-static ERTS_INLINE void
+static ERTS_INLINE int
prepare_crash_dump(int secs)
{
#define NUFBUF (3)
@@ -698,19 +698,35 @@ prepare_crash_dump(int secs)
Eterm *hp = heap;
Eterm list = NIL;
int heart_fd[2] = {-1,-1};
+ int has_heart = 0;
UseTmpHeapNoproc(NUFBUF);
if (ERTS_PREPARED_CRASH_DUMP)
- return; /* We have already been called */
+ return 0; /* We have already been called */
heart_port = erts_get_heart_port();
+
+ /* Positive secs means an alarm must be set
+ * 0 or negative means no alarm
+ *
+ * Set alarm before we try to write to a port
+ * we don't want to hang on a port write with
+ * no alarm.
+ *
+ */
+
+ if (secs >= 0) {
+ alarm((unsigned int)secs);
+ }
+
if (heart_port) {
/* hearts input fd
* We "know" drv_data is the in_fd since the port is started with read|write
*/
heart_fd[0] = (int)heart_port->drv_data;
heart_fd[1] = (int)driver_data[heart_fd[0]].ofd;
+ has_heart = 1;
list = CONS(hp, make_small(8), list); hp += 2;
@@ -752,20 +768,14 @@ prepare_crash_dump(int secs)
erts_silence_warn_unused_result(nice(nice_val));
}
- /* Positive secs means an alarm must be set
- * 0 or negative means no alarm
- */
- if (secs > 0) {
- alarm((unsigned int)secs);
- }
UnUseTmpHeapNoproc(NUFBUF);
#undef NUFBUF
+ return has_heart;
}
-void
-erts_sys_prepare_crash_dump(int secs)
+int erts_sys_prepare_crash_dump(int secs)
{
- prepare_crash_dump(secs);
+ return prepare_crash_dump(secs);
}
static ERTS_INLINE void
@@ -802,12 +812,22 @@ static RETSIGTYPE request_break(int signum)
static ERTS_INLINE void
sigusr1_exit(void)
{
- /* We do this at interrupt level, since the main reason for
- wanting to generate a crash dump in this way is that the emulator
- is hung somewhere, so it won't be able to poll any flag we set here.
- */
+ char env[21]; /* enough to hold any 64-bit integer */
+ size_t envsz;
+ int i, secs = -1;
+
+ /* We do this at interrupt level, since the main reason for
+ * wanting to generate a crash dump in this way is that the emulator
+ * is hung somewhere, so it won't be able to poll any flag we set here.
+ */
ERTS_SET_GOT_SIGUSR1;
- prepare_crash_dump((int)0);
+
+ envsz = sizeof(env);
+ if ((i = erts_sys_getenv_raw("ERL_CRASH_DUMP_SECONDS", env, &envsz)) >= 0) {
+ secs = i != 0 ? 0 : atoi(env);
+ }
+
+ prepare_crash_dump(secs);
erl_exit(1, "Received SIGUSR1\n");
}
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index 47d12ed5fe..f19f4ebd8c 100755
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
@@ -255,8 +255,7 @@ void erl_sys_args(int* argc, char** argv)
#endif
}
-void
-erts_sys_prepare_crash_dump(int secs)
+int erts_sys_prepare_crash_dump(int secs)
{
Port *heart_port;
Eterm heap[3];
@@ -271,10 +270,14 @@ erts_sys_prepare_crash_dump(int secs)
/* send to heart port, CMD = 8, i.e. prepare crash dump =o */
erts_write_to_port(NIL, heart_port, list);
+
+ return 1;
}
/* Windows - free file descriptors are hopefully available */
/* Alarm not used on windows */
+
+ return 0;
}
static void
diff --git a/erts/vsn.mk b/erts/vsn.mk
index a420781e9f..a13326a02a 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -17,6 +17,7 @@
# %CopyrightEnd%
#
+
VSN = 5.10
SYSTEM_VSN = R16B
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index 7e751a215d..49bbd5d27d 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -30,7 +30,22 @@
</header>
<p>This document describes the changes made to the SSL application.</p>
- <section><title>SSL 5.1.1</title>
+ <section><title>SSL 5.1.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ ssl:ssl_accept/2 timeout is no longer ignored</p>
+ <p>
+ Own Id: OTP-10600</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 5.1.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src
index c118c129e8..9b1227fa7f 100644
--- a/lib/ssl/src/ssl.appup.src
+++ b/lib/ssl/src/ssl.appup.src
@@ -1,6 +1,8 @@
%% -*- erlang -*-
{"%VSN%",
[
+ {"5.1.1", [{restart_application, ssl}]
+ },
{"5.1", [
{load_module, ssl_connection, soft_purge, soft_purge, []}
]
@@ -10,6 +12,8 @@
{<<"3\\.*">>, [{restart_application, ssl}]}
],
[
+ {"5.1.1", [{restart_application, ssl}]
+ },
{"5.1", [
{load_module, ssl_connection, soft_purge, soft_purge, []}
]
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 771bfa5739..6224334a6e 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -47,7 +47,7 @@
-export_type([connect_option/0, listen_option/0, ssl_option/0, transport_option/0,
erl_cipher_suite/0, %% From ssl_cipher.hrl
tls_atom_version/0, %% From ssl_internal.hrl
- prf_random/0]).
+ prf_random/0, sslsocket/0]).
-record(config, {ssl, %% SSL parameters
inet_user, %% User set inet options
@@ -55,6 +55,8 @@
inet_ssl, %% inet options for internal ssl socket
cb %% Callback info
}).
+
+-type sslsocket() :: #sslsocket{}.
-type connect_option() :: socket_connect_option() | ssl_option() | transport_option().
-type socket_connect_option() :: gen_tcp:connect_option().
-type listen_option() :: socket_listen_option() | ssl_option() | transport_option().
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 87cf49d07d..cde13069b5 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -89,6 +89,7 @@
log_alert, % boolean()
renegotiation, % {boolean(), From | internal | peer}
start_or_recv_from, % "gen_fsm From"
+ timer, % start_or_recv_timer
send_queue, % queue()
terminated = false, %
allow_renegotiate = true,
@@ -775,8 +776,9 @@ handle_sync_event({application_data, Data}, From, StateName,
get_timeout(State)};
handle_sync_event({start, Timeout}, StartFrom, hello, State) ->
- start_or_recv_cancel_timer(Timeout, StartFrom),
- hello(start, State#state{start_or_recv_from = StartFrom});
+ Timer = start_or_recv_cancel_timer(Timeout, StartFrom),
+ hello(start, State#state{start_or_recv_from = StartFrom,
+ timer = Timer});
%% The two clauses below could happen if a server upgrades a socket in
%% active mode. Note that in this case we are lucky that
@@ -792,8 +794,9 @@ handle_sync_event({start,_}, _From, error, {Error, State = #state{}}) ->
{stop, {shutdown, Error}, {error, Error}, State};
handle_sync_event({start, Timeout}, StartFrom, StateName, State) ->
- start_or_recv_cancel_timer(Timeout, StartFrom),
- {next_state, StateName, State#state{start_or_recv_from = StartFrom}, get_timeout(State)};
+ Timer = start_or_recv_cancel_timer(Timeout, StartFrom),
+ {next_state, StateName, State#state{start_or_recv_from = StartFrom,
+ timer = Timer}, get_timeout(State)};
handle_sync_event(close, _, StateName, State) ->
%% Run terminate before returning
@@ -825,14 +828,16 @@ handle_sync_event({shutdown, How0}, _, StateName,
end;
handle_sync_event({recv, N, Timeout}, RecvFrom, connection = StateName, State0) ->
- start_or_recv_cancel_timer(Timeout, RecvFrom),
- passive_receive(State0#state{bytes_to_read = N, start_or_recv_from = RecvFrom}, StateName);
+ Timer = start_or_recv_cancel_timer(Timeout, RecvFrom),
+ passive_receive(State0#state{bytes_to_read = N,
+ start_or_recv_from = RecvFrom, timer = Timer}, StateName);
%% Doing renegotiate wait with handling request until renegotiate is
%% finished. Will be handled by next_state_is_connection/2.
handle_sync_event({recv, N, Timeout}, RecvFrom, StateName, State) ->
- start_or_recv_cancel_timer(Timeout, RecvFrom),
- {next_state, StateName, State#state{bytes_to_read = N, start_or_recv_from = RecvFrom},
+ Timer = start_or_recv_cancel_timer(Timeout, RecvFrom),
+ {next_state, StateName, State#state{bytes_to_read = N, start_or_recv_from = RecvFrom,
+ timer = Timer},
get_timeout(State)};
handle_sync_event({new_user, User}, _From, StateName,
@@ -996,13 +1001,20 @@ handle_info({'DOWN', MonitorRef, _, _, _}, _,
handle_info(allow_renegotiate, StateName, State) ->
{next_state, StateName, State#state{allow_renegotiate = true}, get_timeout(State)};
-
-handle_info({cancel_start_or_recv, RecvFrom}, connection = StateName, #state{start_or_recv_from = RecvFrom} = State) ->
+
+handle_info({cancel_start_or_recv, StartFrom}, StateName,
+ #state{renegotiation = {false, first}} = State) when StateName =/= connection ->
+ gen_fsm:reply(StartFrom, {error, timeout}),
+ {stop, {shutdown, user_timeout}, State#state{timer = undefined}};
+
+handle_info({cancel_start_or_recv, RecvFrom}, StateName, #state{start_or_recv_from = RecvFrom} = State) ->
gen_fsm:reply(RecvFrom, {error, timeout}),
- {next_state, StateName, State#state{start_or_recv_from = undefined}, get_timeout(State)};
+ {next_state, StateName, State#state{start_or_recv_from = undefined,
+ bytes_to_read = undefined,
+ timer = undefined}, get_timeout(State)};
handle_info({cancel_start_or_recv, _RecvFrom}, StateName, State) ->
- {next_state, StateName, State, get_timeout(State)};
+ {next_state, StateName, State#state{timer = undefined}, get_timeout(State)};
handle_info(Msg, StateName, State) ->
Report = io_lib:format("SSL: Got unexpected info: ~p ~n", [Msg]),
@@ -1770,6 +1782,7 @@ read_application_data(Data, #state{user_application = {_Mon, Pid},
socket_options = SOpts,
bytes_to_read = BytesToRead,
start_or_recv_from = RecvFrom,
+ timer = Timer,
user_data_buffer = Buffer0} = State0) ->
Buffer1 = if
Buffer0 =:= <<>> -> Data;
@@ -1779,9 +1792,11 @@ read_application_data(Data, #state{user_application = {_Mon, Pid},
case get_data(SOpts, BytesToRead, Buffer1) of
{ok, ClientData, Buffer} -> % Send data
SocketOpt = deliver_app_data(Socket, SOpts, ClientData, Pid, RecvFrom),
+ cancel_timer(Timer),
State = State0#state{user_data_buffer = Buffer,
start_or_recv_from = undefined,
- bytes_to_read = 0,
+ timer = undefined,
+ bytes_to_read = undefined,
socket_options = SocketOpt
},
if
@@ -1794,6 +1809,8 @@ read_application_data(Data, #state{user_application = {_Mon, Pid},
end;
{more, Buffer} -> % no reply, we need more data
next_record(State0#state{user_data_buffer = Buffer});
+ {passive, Buffer} ->
+ next_record_if_active(State0#state{user_data_buffer = Buffer});
{error,_Reason} -> %% Invalid packet in packet mode
deliver_packet_error(Socket, SOpts, Buffer1, Pid, RecvFrom),
{stop, normal, State0}
@@ -1835,6 +1852,9 @@ is_time_to_renegotiate(_,_) ->
%% Picks ClientData
get_data(_, _, <<>>) ->
{more, <<>>};
+%% Recv timed out save buffer data until next recv
+get_data(#socket_options{active=false}, undefined, Buffer) ->
+ {passive, Buffer};
get_data(#socket_options{active=Active, packet=Raw}, BytesToRead, Buffer)
when Raw =:= raw; Raw =:= 0 -> %% Raw Mode
if
@@ -2140,7 +2160,6 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User,
tls_record_buffer = <<>>,
tls_cipher_texts = [],
user_application = {Monitor, User},
- bytes_to_read = 0,
user_data_buffer = <<>>,
log_alert = true,
session_cache_cb = SessionCacheCb,
@@ -2363,9 +2382,11 @@ ack_connection(#state{renegotiation = {true, From}} = State) ->
gen_fsm:reply(From, ok),
State#state{renegotiation = undefined};
ack_connection(#state{renegotiation = {false, first},
- start_or_recv_from = StartFrom} = State) when StartFrom =/= undefined ->
+ start_or_recv_from = StartFrom,
+ timer = Timer} = State) when StartFrom =/= undefined ->
gen_fsm:reply(StartFrom, connected),
- State#state{renegotiation = undefined, start_or_recv_from = undefined};
+ cancel_timer(Timer),
+ State#state{renegotiation = undefined, start_or_recv_from = undefined, timer = undefined};
ack_connection(State) ->
State.
@@ -2503,10 +2524,15 @@ default_hashsign(_Version, KeyExchange)
{null, anon}.
start_or_recv_cancel_timer(infinity, _RecvFrom) ->
- ok;
+ undefined;
start_or_recv_cancel_timer(Timeout, RecvFrom) ->
erlang:send_after(Timeout, self(), {cancel_start_or_recv, RecvFrom}).
+cancel_timer(undefined) ->
+ ok;
+cancel_timer(Timer) ->
+ erlang:cancel_timer(Timer).
+
handle_unrecv_data(StateName, #state{socket = Socket, transport_cb = Transport} = State) ->
inet:setopts(Socket, [{active, false}]),
case Transport:recv(Socket, 0, 0) of
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 4c3548a703..faed91e559 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -259,7 +259,9 @@ api_tests() ->
shutdown_both,
shutdown_error,
hibernate,
- listen_socket
+ listen_socket,
+ ssl_accept_timeout,
+ ssl_recv_timeout
].
certificate_verify_tests() ->
@@ -3853,6 +3855,61 @@ listen_socket(Config) ->
{error, enotconn} = ssl:shutdown(ListenSocket, read_write),
ok = ssl:close(ListenSocket).
+%%--------------------------------------------------------------------
+ssl_accept_timeout(doc) ->
+ ["Test ssl:ssl_accept timeout"];
+ssl_accept_timeout(suite) ->
+ [];
+ssl_accept_timeout(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {ssl_test_lib,
+ no_result_msg, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {ok, CSocket} = gen_tcp:connect(Hostname, Port, [binary, {active, true}]),
+
+ receive
+ {tcp_closed, CSocket} ->
+ ssl_test_lib:check_result(Server, {error, timeout}),
+ receive
+ {'EXIT', Server, _} ->
+ [] = supervisor:which_children(ssl_connection_sup)
+ end
+ end.
+
+%%--------------------------------------------------------------------
+ssl_recv_timeout(doc) ->
+ ["Test ssl:ssl_accept timeout"];
+ssl_recv_timeout(suite) ->
+ [];
+ssl_recv_timeout(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_timeout_server, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_recv_result_timeout_client, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
@@ -4158,6 +4215,23 @@ send_recv_result(Socket) ->
{ok,"Hello world"} = ssl:recv(Socket, 11),
ok.
+send_recv_result_timeout_client(Socket) ->
+ {error, timeout} = ssl:recv(Socket, 11, 500),
+ ssl:send(Socket, "Hello world"),
+ receive
+ Msg ->
+ io:format("Msg ~p~n",[Msg])
+ after 500 ->
+ ok
+ end,
+ {ok, "Hello world"} = ssl:recv(Socket, 11, 500),
+ ok.
+send_recv_result_timeout_server(Socket) ->
+ ssl:send(Socket, "Hello"),
+ {ok, "Hello world"} = ssl:recv(Socket, 11),
+ ssl:send(Socket, " world"),
+ ok.
+
recv_close(Socket) ->
{error, closed} = ssl:recv(Socket, 11),
receive
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 63731ee25c..f1f5b9ae0a 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -72,7 +72,13 @@ run_server(Opts) ->
run_server(ListenSocket, Opts).
run_server(ListenSocket, Opts) ->
- AcceptSocket = connect(ListenSocket, Opts),
+ do_run_server(ListenSocket, connect(ListenSocket, Opts), Opts).
+
+do_run_server(_, {error, timeout} = Result, Opts) ->
+ Pid = proplists:get_value(from, Opts),
+ Pid ! {self(), Result};
+
+do_run_server(ListenSocket, AcceptSocket, Opts) ->
Node = proplists:get_value(node, Opts),
Pid = proplists:get_value(from, Opts),
{Module, Function, Args} = proplists:get_value(mfa, Opts),
@@ -102,7 +108,8 @@ run_server(ListenSocket, Opts) ->
connect(ListenSocket, Opts) ->
Node = proplists:get_value(node, Opts),
ReconnectTimes = proplists:get_value(reconnect_times, Opts, 0),
- AcceptSocket = connect(ListenSocket, Node, 1 + ReconnectTimes, dummy),
+ Timeout = proplists:get_value(timeout, Opts, infinity),
+ AcceptSocket = connect(ListenSocket, Node, 1 + ReconnectTimes, dummy, Timeout),
case ReconnectTimes of
0 ->
AcceptSocket;
@@ -111,15 +118,21 @@ connect(ListenSocket, Opts) ->
AcceptSocket
end.
-connect(_, _, 0, AcceptSocket) ->
+connect(_, _, 0, AcceptSocket, _) ->
AcceptSocket;
-connect(ListenSocket, Node, N, _) ->
+connect(ListenSocket, Node, N, _, Timeout) ->
test_server:format("ssl:transport_accept(~p)~n", [ListenSocket]),
{ok, AcceptSocket} = rpc:call(Node, ssl, transport_accept,
[ListenSocket]),
- test_server:format("ssl:ssl_accept(~p)~n", [AcceptSocket]),
- ok = rpc:call(Node, ssl, ssl_accept, [AcceptSocket]),
- connect(ListenSocket, Node, N-1, AcceptSocket).
+ test_server:format("ssl:ssl_accept(~p, ~p)~n", [AcceptSocket, Timeout]),
+
+ case rpc:call(Node, ssl, ssl_accept, [AcceptSocket, Timeout]) of
+ ok ->
+ connect(ListenSocket, Node, N-1, AcceptSocket, Timeout);
+ Result ->
+ Result
+ end.
+
remove_close_msg(0) ->
ok;
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index bc8b8fd039..adfb29e639 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1 +1 @@
-SSL_VSN = 5.1.1
+SSL_VSN = 5.1.2