aboutsummaryrefslogtreecommitdiff
path: root/src/mod_stream_mgmt.erl
diff options
context:
space:
mode:
authorPaweł Chmielowski <pchmielowski@process-one.net>2020-04-01 14:35:49 +0200
committerPaweł Chmielowski <pchmielowski@process-one.net>2020-04-01 14:36:01 +0200
commit1bd560f3f25d0a644bac3d06904ca97e20a6f7d9 (patch)
tree3d74c9bc22f95409ebda8cc230169283096e9188 /src/mod_stream_mgmt.erl
parentUse different username than other tests, but still include the test chars (diff)
Fix potential message loss in terminating c2s sessions
Calling sync version of xmpp_stream_in/out:stop could lead to messages never being processed by c2s process if they were queued in p1_server. This could be reproduced by when having messages in offline storage, starting sessions, enabling stream_mgmt, sending initial presence, and then immediately </stream:stream>, messages that mod_offline would send process would not be bounced back by stream_mgmt.
Diffstat (limited to 'src/mod_stream_mgmt.erl')
-rw-r--r--src/mod_stream_mgmt.erl15
1 files changed, 9 insertions, 6 deletions
diff --git a/src/mod_stream_mgmt.erl b/src/mod_stream_mgmt.erl
index 4c9ff3c8b..fb1a609b1 100644
--- a/src/mod_stream_mgmt.erl
+++ b/src/mod_stream_mgmt.erl
@@ -217,7 +217,8 @@ c2s_handle_send(#{mgmt_state := MgmtState, mod := Mod,
active ->
State;
pending ->
- Mod:stop(State#{stop_reason => {stream, {out, Pkt}}})
+ Mod:stop_async(self()),
+ {stop, State#{stop_reason => {stream, {out, Pkt}}}}
end;
_ ->
State
@@ -250,8 +251,9 @@ c2s_handle_info(#{mgmt_state := pending, lang := Lang,
[jid:encode(JID)]),
Txt = ?T("Timed out waiting for stream resumption"),
Err = xmpp:serr_connection_timeout(Txt, Lang),
- Mod:stop(State#{mgmt_state => timeout,
- stop_reason => {stream, {out, Err}}});
+ Mod:stop_async(self()),
+ {stop, State#{mgmt_state => timeout,
+ stop_reason => {stream, {out, Err}}}};
c2s_handle_info(State, {_Ref, {resume, #{jid := JID} = OldState}}) ->
%% This happens if the resume_session/1 request timed out; the new session
%% now receives the late response.
@@ -444,7 +446,8 @@ handle_resume(#{user := User, lserver := LServer,
-spec transition_to_pending(state(), _) -> state().
transition_to_pending(#{mgmt_state := active, mod := Mod,
mgmt_timeout := 0} = State, _Reason) ->
- Mod:stop(State);
+ Mod:stop_async(self()),
+ State;
transition_to_pending(#{mgmt_state := active, jid := JID, socket := Socket,
lserver := LServer, mgmt_timeout := Timeout} = State,
Reason) ->
@@ -660,7 +663,7 @@ inherit_session_state(#{user := U, server := S,
mgmt_stanzas_out => NumStanzasOut,
mgmt_state => active},
State3 = ejabberd_c2s:open_session(State2),
- ejabberd_c2s:stop(OldPID),
+ ejabberd_c2s:stop_async(OldPID),
{ok, State3};
{error, Msg} ->
{error, Msg}
@@ -674,7 +677,7 @@ inherit_session_state(#{user := U, server := S,
{error, session_was_killed};
exit:{timeout, _} ->
ejabberd_sm:close_session(OldSID, U, S, R),
- ejabberd_c2s:stop(OldPID),
+ ejabberd_c2s:stop_async(OldPID),
{error, session_copy_timed_out}
end
end;