aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2018-11-29 16:24:33 +0100
committerIngela Anderton Andin <[email protected]>2018-12-03 19:42:07 +0100
commit15aa90e8d852e27a6dc28c713aee66f57574705e (patch)
tree47b0574b104b1b679d2a8254d2fba2d785be5f31
parent6168cf2f5f8b5839b1a56ce870658d76faf3c22f (diff)
downloadotp-15aa90e8d852e27a6dc28c713aee66f57574705e.tar.gz
otp-15aa90e8d852e27a6dc28c713aee66f57574705e.tar.bz2
otp-15aa90e8d852e27a6dc28c713aee66f57574705e.zip
ssl: Correct ssl:shutdown
When internaly using active N, bugs in shutdown implementation where reveled.
-rw-r--r--lib/ssl/doc/src/ssl_app.xml2
-rw-r--r--lib/ssl/src/ssl_connection.erl42
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl6
3 files changed, 29 insertions, 21 deletions
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).
</p>
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) ->