diff options
author | Holger Weiss <holger@zedat.fu-berlin.de> | 2014-05-23 23:38:04 +0200 |
---|---|---|
committer | Holger Weiss <holger@zedat.fu-berlin.de> | 2014-05-23 23:38:04 +0200 |
commit | 59f6efeaf7fd7cf47733d4fcfe9cc9b08aac80b1 (patch) | |
tree | 9d9eb5a9a67da4d7601e97b935283700a0e0426b | |
parent | Merge branch 'weiss-check-packet-type' into 3 (diff) |
XEP-0198: Don't drop session on failed resume
The 'previd' value provided by the client during a session resume
request includes the client's JID and ejabberd's session ID. If there
is a session for the requested JID but with a different session ID,
resumption should fail, but that session shouldn't be closed. This
commit makes sure the latter won't happen.
In practice, this will only make a difference in odd corner cases.
-rw-r--r-- | src/ejabberd_c2s.erl | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 5d0cc9c08..996a3c81d 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -1312,8 +1312,8 @@ handle_sync_event(get_subscribed, _From, StateName, StateData) -> Subscribed = (?SETS):to_list(StateData#state.pres_f), {reply, Subscribed, StateName, StateData}; -handle_sync_event(resume_session, _From, _StateName, - StateData) -> +handle_sync_event({resume_session, Time}, _From, _StateName, + StateData) when element(1, StateData#state.sid) == Time -> %% The old session should be closed before the new one is opened, so we do %% this here instead of leaving it to the terminate callback ejabberd_sm:close_session(StateData#state.sid, @@ -1321,6 +1321,9 @@ handle_sync_event(resume_session, _From, _StateName, StateData#state.server, StateData#state.resource), {stop, normal, {ok, StateData}, StateData#state{mgmt_state = resumed}}; +handle_sync_event({resume_session, _Time}, _From, StateName, + StateData) -> + {reply, {error, <<"Previous session not found">>}, StateName, StateData}; handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, fsm_reply(Reply, StateName, StateData). @@ -2894,8 +2897,8 @@ inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) -> {error, <<"Previous session PID not found">>}; OldPID -> OldSID = {Time, OldPID}, - case catch resume_session(OldPID) of - {ok, #state{sid = OldSID} = OldStateData} -> + case catch resume_session(OldSID) of + {ok, OldStateData} -> NewSID = {Time, self()}, % Old time, new PID Priority = case OldStateData#state.pres_last of undefined -> @@ -2927,6 +2930,8 @@ inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) -> mgmt_stanzas_in = OldStateData#state.mgmt_stanzas_in, mgmt_stanzas_out = OldStateData#state.mgmt_stanzas_out, mgmt_state = active}}; + {error, Msg} -> + {error, Msg}; _ -> {error, <<"Cannot grab session state">>} end @@ -2935,8 +2940,8 @@ inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) -> {error, <<"Invalid 'previd' value">>} end. -resume_session(FsmRef) -> - (?GEN_FSM):sync_send_all_state_event(FsmRef, resume_session, 3000). +resume_session({Time, PID}) -> + (?GEN_FSM):sync_send_all_state_event(PID, {resume_session, Time}, 3000). make_resume_id(StateData) -> {Time, _} = StateData#state.sid, |