diff options
author | Paweł Chmielowski <pchmielowski@process-one.net> | 2020-04-01 14:35:49 +0200 |
---|---|---|
committer | Paweł Chmielowski <pchmielowski@process-one.net> | 2020-04-01 14:36:01 +0200 |
commit | 1bd560f3f25d0a644bac3d06904ca97e20a6f7d9 (patch) | |
tree | 3d74c9bc22f95409ebda8cc230169283096e9188 /src/mod_stream_mgmt.erl | |
parent | Use 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.erl | 15 |
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; |