aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_c2s.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/ejabberd_c2s.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/ejabberd_c2s.erl')
-rw-r--r--src/ejabberd_c2s.erl12
1 files changed, 6 insertions, 6 deletions
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 8f069bcbe..f533fbed3 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -43,7 +43,7 @@
process_closed/2, process_terminated/2, process_info/2]).
%% API
-export([get_presence/1, set_presence/2, resend_presence/1, resend_presence/2,
- open_session/1, call/3, cast/2, send/2, close/1, close/2, stop/1,
+ open_session/1, call/3, cast/2, send/2, close/1, close/2, stop_async/1,
reply/2, copy_state/2, set_timeout/2, route/2, format_reason/2,
host_up/1, host_down/1, send_ws_ping/1, bounce_message_queue/2]).
@@ -110,10 +110,9 @@ close(Ref) ->
close(Ref, Reason) ->
xmpp_stream_in:close(Ref, Reason).
--spec stop(pid()) -> ok;
- (state()) -> no_return().
-stop(Ref) ->
- xmpp_stream_in:stop(Ref).
+-spec stop_async(pid()) -> ok.
+stop_async(Pid) ->
+ xmpp_stream_in:stop_async(Pid).
-spec send(pid(), xmpp_element()) -> ok;
(state(), xmpp_element()) -> state().
@@ -285,7 +284,8 @@ process_auth_result(#{sasl_mech := Mech,
State.
process_closed(State, Reason) ->
- stop(State#{stop_reason => Reason}).
+ stop_async(self()),
+ State#{stop_reason => Reason}.
process_terminated(#{sid := SID, socket := Socket,
jid := JID, user := U, server := S, resource := R} = State,