Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHolger Weiss <holger@zedat.fu-berlin.de>2016-08-03 03:28:46 +0300
committerHolger Weiss <holger@zedat.fu-berlin.de>2016-08-03 03:28:46 +0300
commit78fa9e08a5a809c0c6b3c838459077b5d44c8e01 (patch)
tree4d4ffafa0165e910caa8600a1d97bb37b21e7444 /src/ejabberd_c2s.erl
parent3c1e4f0dfd75d0e51fa0ec2bc42c3dbb5530e121 (diff)
XEP-0198: Handle timeouts during stream resumption
If session resumption failed because requesting the #state from the old c2s process took too long, the new c2s process will usually receive the response. Let the new process handle that case gracefully.
Diffstat (limited to 'src/ejabberd_c2s.erl')
-rw-r--r--src/ejabberd_c2s.erl11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index d69599485..74b78512a 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -1318,7 +1318,7 @@ handle_sync_event({resume_session, Time}, _From, _StateName,
StateData#state.user,
StateData#state.server,
StateData#state.resource),
- {stop, normal, {ok, StateData}, StateData#state{mgmt_state = resumed}};
+ {stop, normal, {resume, StateData}, StateData#state{mgmt_state = resumed}};
handle_sync_event({resume_session, _Time}, _From, StateName,
StateData) ->
{reply, {error, <<"Previous session not found">>}, StateName, StateData};
@@ -1745,6 +1745,13 @@ handle_info({broadcast, Type, From, Packet}, StateName, StateData) ->
fsm_next_state(StateName, StateData);
handle_info(dont_ask_offline, StateName, StateData) ->
fsm_next_state(StateName, StateData#state{ask_offline = false});
+handle_info({_Ref, {resume, OldStateData}}, StateName, StateData) ->
+ %% This happens if the resume_session/1 request timed out; the new session
+ %% now receives the late response.
+ ?DEBUG("Received old session state for ~s after failed resumption",
+ [jid:to_string(OldStateData#state.jid)]),
+ handle_unacked_stanzas(OldStateData#state{mgmt_resend = false}),
+ fsm_next_state(StateName, StateData);
handle_info(Info, StateName, StateData) ->
?ERROR_MSG("Unexpected info: ~p", [Info]),
fsm_next_state(StateName, StateData).
@@ -3017,7 +3024,7 @@ inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) ->
OldPID ->
OldSID = {Time, OldPID},
case catch resume_session(OldSID) of
- {ok, OldStateData} ->
+ {resume, OldStateData} ->
NewSID = {Time, self()}, % Old time, new PID
Priority = case OldStateData#state.pres_last of
undefined ->