From 15aa90e8d852e27a6dc28c713aee66f57574705e Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Thu, 29 Nov 2018 16:24:33 +0100 Subject: ssl: Correct ssl:shutdown When internaly using active N, bugs in shutdown implementation where reveled. --- lib/ssl/doc/src/ssl_app.xml | 2 +- lib/ssl/src/ssl_connection.erl | 42 ++++++++++++++++++++++++---------------- lib/ssl/test/ssl_basic_SUITE.erl | 6 +++--- 3 files changed, 29 insertions(+), 21 deletions(-) (limited to 'lib/ssl') diff --git a/lib/ssl/doc/src/ssl_app.xml b/lib/ssl/doc/src/ssl_app.xml index 53b899058f..893919aeb4 100644 --- a/lib/ssl/doc/src/ssl_app.xml +++ b/lib/ssl/doc/src/ssl_app.xml @@ -180,7 +180,7 @@ active once to an active N behavior (N = 100), for performance reasons, this option exist for possible tweaking or restoring of the old behavior (internal_active_n = 1) in - unforeseen scenarios. This option will not affect erlang + unforeseen scenarios. The option will not affect erlang distribution over TLS that will always run in active N mode. Added in ssl-9.1 (OTP-21.2).

diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 08197f6038..a2ba2e0940 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -1152,23 +1152,31 @@ handle_call({close, _} = Close, From, StateName, State, _Connection) -> stop_and_reply( {shutdown, normal}, {reply, From, Result}, State#state{terminated = true}); -handle_call({shutdown, How0}, From, StateName, +handle_call({shutdown, read_write = How}, From, StateName, #state{transport_cb = Transport, socket = Socket} = State, _) -> - case How0 of - How when How == write; How == both -> - send_alert(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY), - StateName, State); - _ -> - ok - end, + try send_alert(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY), + StateName, State) of + _ -> + case Transport:shutdown(Socket, How) of + ok -> + {next_state, StateName, State#state{terminated = true}, [{reply, From, ok}]}; + Error -> + {stop, StateName, State#state{terminated = true}, [{reply, From, Error}]} + end + catch + throw:Return -> + Return + end; +handle_call({shutdown, How0}, From, StateName, + #state{transport_cb = Transport, + socket = Socket} = State, _) -> case Transport:shutdown(Socket, How0) of ok -> - {keep_state_and_data, [{reply, From, ok}]}; + {next_state, StateName, State, [{reply, From, ok}]}; Error -> - gen_statem:reply(From, {error, Error}), - stop(normal, State) + {stop, StateName, State, [{reply, From, Error}]} end; handle_call({recv, _N, _Timeout}, From, _, #state{socket_options = @@ -1330,15 +1338,15 @@ terminate(downgrade = Reason, connection, #state{protocol_cb = Connection, handle_trusted_certs_db(State), Connection:close(Reason, Socket, Transport, undefined, undefined); terminate(Reason, connection, #state{protocol_cb = Connection, - connection_states = ConnectionStates, - ssl_options = #ssl_options{padding_check = Check}, - transport_cb = Transport, socket = Socket - } = State) -> + connection_states = ConnectionStates, + ssl_options = #ssl_options{padding_check = Check}, + transport_cb = Transport, socket = Socket + } = State) -> handle_trusted_certs_db(State), Alert = terminate_alert(Reason), %% Send the termination ALERT if possible - catch (ok = Connection:send_alert_in_connection(Alert, State)), - Connection:close(Reason, Socket, Transport, ConnectionStates, Check); + catch (Connection:send_alert_in_connection(Alert, State)), + Connection:close({timeout, ?DEFAULT_TIMEOUT}, Socket, Transport, ConnectionStates, Check); terminate(Reason, _StateName, #state{transport_cb = Transport, protocol_cb = Connection, socket = Socket } = State) -> diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index d93bd85c76..9633800da5 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -5223,14 +5223,14 @@ get_invalid_inet_option(Socket) -> tls_shutdown_result(Socket, server) -> ssl:send(Socket, "Hej"), - ssl:shutdown(Socket, write), + ok = ssl:shutdown(Socket, write), {ok, "Hej hopp"} = ssl:recv(Socket, 8), ok; tls_shutdown_result(Socket, client) -> - {ok, "Hej"} = ssl:recv(Socket, 3), ssl:send(Socket, "Hej hopp"), - ssl:shutdown(Socket, write), + ok = ssl:shutdown(Socket, write), + {ok, "Hej"} = ssl:recv(Socket, 3), ok. tls_shutdown_write_result(Socket, server) -> -- cgit v1.2.3