aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src
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 /lib/ssl/src
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.
Diffstat (limited to 'lib/ssl/src')
-rw-r--r--lib/ssl/src/ssl_connection.erl42
1 files changed, 25 insertions, 17 deletions
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) ->