aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2016-12-09 10:51:30 +0100
committerIngela Anderton Andin <[email protected]>2016-12-19 11:15:06 +0100
commitdd985c2097a29ca0812fdf6f0431aed2d8a7c752 (patch)
tree1b6cfdca7adfe5aa71e9f3009e3ca7a19a609c14 /lib
parent256e35e9f6969ce635ab6abb54071ffee441f7a7 (diff)
downloadotp-dd985c2097a29ca0812fdf6f0431aed2d8a7c752.tar.gz
otp-dd985c2097a29ca0812fdf6f0431aed2d8a7c752.tar.bz2
otp-dd985c2097a29ca0812fdf6f0431aed2d8a7c752.zip
ssl: Correct terminate behaviour
When the terminate function is called explicitly, to make guarantees that for instance the reuseaddr option works as expected, we must make sure that the clean up code is not run again when gen_statem calls terminate. This check was broken in the rewrite from gen_fsm to gen_statem. Caused PEM cache errors, that in some cases would cause unexpected connection failures.
Diffstat (limited to 'lib')
-rw-r--r--lib/ssl/src/ssl_connection.erl11
1 files changed, 7 insertions, 4 deletions
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 6e7c8c5ddd..6ed2fc83da 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -864,11 +864,11 @@ handle_call({close, {Pid, Timeout}}, From, StateName, State0, Connection) when i
%% When downgrading an TLS connection to a transport connection
%% we must recive the close alert from the peer before releasing the
%% transport socket.
- {next_state, downgrade, State, [{timeout, Timeout, downgrade}]};
+ {next_state, downgrade, State#state{terminated = true}, [{timeout, Timeout, downgrade}]};
handle_call({close, _} = Close, From, StateName, State, Connection) ->
%% Run terminate before returning so that the reuseaddr
- %% inet-option
- Result = Connection:terminate(Close, StateName, State),
+ %% inet-option works properly
+ Result = Connection:terminate(Close, StateName, State#state{terminated = true}),
{stop_and_reply, {shutdown, normal},
{reply, From, Result}, State};
handle_call({shutdown, How0}, From, _,
@@ -1010,7 +1010,10 @@ handle_info(Msg, StateName, #state{socket = Socket, error_tag = Tag} = State) ->
terminate(_, _, #state{terminated = true}) ->
%% Happens when user closes the connection using ssl:close/1
%% we want to guarantee that Transport:close has been called
- %% when ssl:close/1 returns.
+ %% when ssl:close/1 returns unless it is a downgrade where
+ %% we want to guarantee that close alert is recived before
+ %% returning. In both cases terminate has been run manually
+ %% before run by gen_statem which will end up here
ok;
terminate({shutdown, transport_closed} = Reason,